Fix for 164744 - fix for pk12util to export multiple certs

This commit is contained in:
jpierre%netscape.com 2002-10-02 04:32:17 +00:00
Родитель 7990613828
Коммит 2e48c1c8a4
2 изменённых файлов: 128 добавлений и 57 удалений

Просмотреть файл

@ -39,6 +39,7 @@
#include "pk12util.h"
#include "nss.h"
#include "secport.h"
#include "certdb.h"
#define PKCS12_IN_BUFFER_SIZE 200
@ -551,6 +552,38 @@ p12u_WriteToExportFile(void *arg, const char *buf, unsigned long len)
}
}
static SECStatus
cert_UserCertsOnly(CERTCertList *certList)
{
CERTCertListNode *node, *freenode;
CERTCertificate *cert;
PRUint32 numusercerts = 0;
node = CERT_LIST_HEAD(certList);
while ( ! CERT_LIST_END(node, certList) ) {
cert = node->cert;
if ( !( cert->trust->sslFlags & CERTDB_USER ) &&
!( cert->trust->emailFlags & CERTDB_USER ) &&
!( cert->trust->objectSigningFlags & CERTDB_USER ) ) {
/* Not a User Cert, so remove this cert from the list */
freenode = node;
node = CERT_LIST_NEXT(node);
CERT_RemoveCertListNode(freenode);
} else {
/* Is a User cert, so leave it in the list */
node = CERT_LIST_NEXT(node);
numusercerts ++;
}
}
if (numusercerts) {
return(SECSuccess);
} else {
return(SECFailure);
}
}
void
P12U_ExportPKCS12Object(char *nn, char *outfile, PK11SlotInfo *inSlot,
secuPWData *slotPw, secuPWData *p12FilePw)
@ -559,7 +592,9 @@ P12U_ExportPKCS12Object(char *nn, char *outfile, PK11SlotInfo *inSlot,
SEC_PKCS12SafeInfo *keySafe = NULL, *certSafe = NULL;
SECItem *pwitem = NULL;
p12uContext *p12cxt = NULL;
CERTCertificate *cert = NULL;
CERTCertList* certlist = NULL;
CERTCertListNode* node = NULL;
PK11SlotInfo* slot = NULL;
if (P12U_InitSlot(inSlot, slotPw) != SECSuccess) {
SECU_PrintError(progName,"Failed to authenticate to \"%s\"",
@ -567,17 +602,17 @@ P12U_ExportPKCS12Object(char *nn, char *outfile, PK11SlotInfo *inSlot,
pk12uErrno = PK12UERR_PK11GETSLOT;
goto loser;
}
cert = PK11_FindCertFromNickname(nn, slotPw);
if(!cert) {
SECU_PrintError(progName,"find cert by nickname failed");
certlist = PK11_FindCertsFromNickname(nn, slotPw);
if(!certlist) {
SECU_PrintError(progName,"find user certs from nickname failed");
pk12uErrno = PK12UERR_FINDCERTBYNN;
return;
}
if (!cert->slot) {
SECU_PrintError(progName,"cert does not have a slot");
pk12uErrno = PK12UERR_FINDCERTBYNN;
goto loser;
if (SECSuccess != cert_UserCertsOnly(certlist)) {
SECU_PrintError(progName,"find user certs from nickname failed");
pk12uErrno = PK12UERR_FINDCERTBYNN;
return;
}
/* Password to use for PKCS12 file. */
@ -586,43 +621,6 @@ P12U_ExportPKCS12Object(char *nn, char *outfile, PK11SlotInfo *inSlot,
goto loser;
}
p12ecx = SEC_PKCS12CreateExportContext(NULL, NULL, cert->slot, slotPw);
if(!p12ecx) {
SECU_PrintError(progName,"export context creation failed");
pk12uErrno = PK12UERR_EXPORTCXCREATE;
goto loser;
}
if(SEC_PKCS12AddPasswordIntegrity(p12ecx, pwitem, SEC_OID_SHA1)
!= SECSuccess) {
SECU_PrintError(progName,"PKCS12 add password integrity failed");
pk12uErrno = PK12UERR_PK12ADDPWDINTEG;
goto loser;
}
keySafe = SEC_PKCS12CreateUnencryptedSafe(p12ecx);
if(/*!SEC_PKCS12IsEncryptionAllowed() || */ PK11_IsFIPS()) {
certSafe = keySafe;
} else {
certSafe = SEC_PKCS12CreatePasswordPrivSafe(p12ecx, pwitem,
SEC_OID_PKCS12_V2_PBE_WITH_SHA1_AND_40_BIT_RC2_CBC);
}
if(!certSafe || !keySafe) {
SECU_PrintError(progName,"key or cert safe creation failed");
pk12uErrno = PK12UERR_CERTKEYSAFE;
goto loser;
}
if(SEC_PKCS12AddCertAndKey(p12ecx, certSafe, NULL, cert,
CERT_GetDefaultCertDB(), keySafe, NULL, PR_TRUE, pwitem,
SEC_OID_PKCS12_V2_PBE_WITH_SHA1_AND_3KEY_TRIPLE_DES_CBC)
!= SECSuccess) {
SECU_PrintError(progName,"add cert and key failed");
pk12uErrno = PK12UERR_ADDCERTKEY;
goto loser;
}
p12cxt = p12u_InitFile(PR_FALSE, outfile);
if(!p12cxt) {
SECU_PrintError(progName,"Initialization failed: %s", outfile);
@ -630,17 +628,80 @@ P12U_ExportPKCS12Object(char *nn, char *outfile, PK11SlotInfo *inSlot,
goto loser;
}
if (certlist) {
CERTCertificate* cert = NULL;
node = CERT_LIST_HEAD(certlist);
if (node) {
cert = node->cert;
}
if (cert) {
slot = cert->slot; /* use the slot from the first matching
certificate to create the context . This is for keygen */
}
}
if (!slot) {
SECU_PrintError(progName,"cert does not have a slot");
pk12uErrno = PK12UERR_FINDCERTBYNN;
goto loser;
}
p12ecx = SEC_PKCS12CreateExportContext(NULL, NULL, slot, slotPw);
if(!p12ecx) {
SECU_PrintError(progName,"export context creation failed");
pk12uErrno = PK12UERR_EXPORTCXCREATE;
goto loser;
}
if(SEC_PKCS12AddPasswordIntegrity(p12ecx, pwitem, SEC_OID_SHA1)
!= SECSuccess) {
SECU_PrintError(progName,"PKCS12 add password integrity failed");
pk12uErrno = PK12UERR_PK12ADDPWDINTEG;
goto loser;
}
for (node = CERT_LIST_HEAD(certlist);!CERT_LIST_END(node,certlist);node=CERT_LIST_NEXT(node))
{
CERTCertificate* cert = node->cert;
if (!cert->slot) {
SECU_PrintError(progName,"cert does not have a slot");
pk12uErrno = PK12UERR_FINDCERTBYNN;
goto loser;
}
keySafe = SEC_PKCS12CreateUnencryptedSafe(p12ecx);
if(/*!SEC_PKCS12IsEncryptionAllowed() || */ PK11_IsFIPS()) {
certSafe = keySafe;
} else {
certSafe = SEC_PKCS12CreatePasswordPrivSafe(p12ecx, pwitem,
SEC_OID_PKCS12_V2_PBE_WITH_SHA1_AND_40_BIT_RC2_CBC);
}
if(!certSafe || !keySafe) {
SECU_PrintError(progName,"key or cert safe creation failed");
pk12uErrno = PK12UERR_CERTKEYSAFE;
goto loser;
}
if(SEC_PKCS12AddCertAndKey(p12ecx, certSafe, NULL, cert,
CERT_GetDefaultCertDB(), keySafe, NULL, PR_TRUE, pwitem,
SEC_OID_PKCS12_V2_PBE_WITH_SHA1_AND_3KEY_TRIPLE_DES_CBC)
!= SECSuccess) {
SECU_PrintError(progName,"add cert and key failed");
pk12uErrno = PK12UERR_ADDCERTKEY;
goto loser;
}
CERT_DestroyCertificate(cert);
node->cert = NULL;
}
if(SEC_PKCS12Encode(p12ecx, p12u_WriteToExportFile, p12cxt)
!= SECSuccess) {
SECU_PrintError(progName,"PKCS12 encode failed");
pk12uErrno = PK12UERR_ENCODE;
goto loser;
!= SECSuccess) {
SECU_PrintError(progName,"PKCS12 encode failed");
pk12uErrno = PK12UERR_ENCODE;
goto loser;
}
p12u_DestroyExportFileInfo(&p12cxt, PR_FALSE);
SECITEM_ZfreeItem(pwitem, PR_TRUE);
CERT_DestroyCertificate(cert);
fprintf(stdout, "%s: PKCS12 EXPORT SUCCESSFUL\n", progName);
SEC_PKCS12DestroyExportContext(p12ecx);
@ -649,18 +710,27 @@ P12U_ExportPKCS12Object(char *nn, char *outfile, PK11SlotInfo *inSlot,
loser:
SEC_PKCS12DestroyExportContext(p12ecx);
for (node = CERT_LIST_HEAD(certlist);!CERT_LIST_END(node,certlist);node=CERT_LIST_NEXT(node))
{
CERTCertificate* cert = node->cert;
if (!node->cert) {
continue;
}
if(cert) {
CERT_DestroyCertificate(cert);
}
}
if (slotPw)
PR_Free(slotPw->data);
PR_Free(slotPw->data);
if (p12FilePw)
PR_Free(p12FilePw->data);
PR_Free(p12FilePw->data);
if(cert) {
CERT_DestroyCertificate(cert);
}
p12u_DestroyExportFileInfo(&p12cxt, PR_TRUE);
if(pwitem) {
SECITEM_ZfreeItem(pwitem, PR_TRUE);
SECITEM_ZfreeItem(pwitem, PR_TRUE);
}
p12u_DoPKCS12ExportErrors();
return;

Просмотреть файл

@ -693,6 +693,7 @@ CERT_DestroyOCSPRequest;
CERT_EncodeOCSPRequest;
CERT_GetOCSPResponseStatus;
CERT_GetOCSPStatusForCertID;
CERT_RemoveCertListNode;
CERT_VerifyCACertForUsage;
CERT_VerifyCertificate;
CERT_VerifyCertificateNow;