From 65c4ab6e41f4f99a04aafc09eb051f6d1a4c53cc Mon Sep 17 00:00:00 2001 From: "relyea%netscape.com" Date: Mon, 24 Mar 2003 19:09:08 +0000 Subject: Bug 142867: pk12util needs to be able to import intermediate CA's into hw tokens. --- security/nss/lib/certdb/cert.h | 3 +++ security/nss/lib/certdb/certdb.c | 15 +++++++++++++++ security/nss/lib/nss/nss.def | 1 + security/nss/lib/pkcs12/p12.h | 4 ++++ security/nss/lib/pkcs12/p12d.c | 33 +++++++++++++++++++++++++++++++-- security/nss/lib/pkcs12/p12t.h | 2 ++ security/nss/lib/pkcs12/pkcs12t.h | 9 +++++++++ security/nss/lib/smime/smime.def | 1 + 8 files changed, 66 insertions(+), 2 deletions(-) diff --git a/security/nss/lib/certdb/cert.h b/security/nss/lib/certdb/cert.h index 98c184d8a..bf1881e83 100644 --- a/security/nss/lib/certdb/cert.h +++ b/security/nss/lib/certdb/cert.h @@ -1061,6 +1061,9 @@ CERT_IsCACert(CERTCertificate *cert, unsigned int *rettype); PRBool CERT_IsCADERCert(SECItem *derCert, unsigned int *rettype); +PRBool +CERT_IsRootDERCert(SECItem *derCert); + SECStatus CERT_SaveSMimeProfile(CERTCertificate *cert, SECItem *emailProfile, SECItem *profileTime); diff --git a/security/nss/lib/certdb/certdb.c b/security/nss/lib/certdb/certdb.c index adc131584..e6b5dc4b1 100644 --- a/security/nss/lib/certdb/certdb.c +++ b/security/nss/lib/certdb/certdb.c @@ -1861,6 +1861,21 @@ CERT_IsCADERCert(SECItem *derCert, unsigned int *type) { return isCA; } +PRBool +CERT_IsRootDERCert(SECItem *derCert) +{ + CERTCertificate *cert; + PRBool isRoot; + + /* This is okay -- only looks at extensions */ + cert = CERT_DecodeDERCertificate(derCert, PR_FALSE, NULL); + if (cert == NULL) return PR_FALSE; + + isRoot = cert->isRoot; + CERT_DestroyCertificate (cert); + return isRoot; +} + /* * is certa newer than certb? If one is expired, pick the other one. diff --git a/security/nss/lib/nss/nss.def b/security/nss/lib/nss/nss.def index ccffb93a7..142e0c59a 100644 --- a/security/nss/lib/nss/nss.def +++ b/security/nss/lib/nss/nss.def @@ -741,6 +741,7 @@ PK11_TokenRefresh; ;+}; ;+NSS_3.8 { # NSS 3.8 release ;+ global: +CERT_IsRootDERCert; HASH_GetHashObjectByOidTag; HASH_GetHashTypeByOidTag; PK11_GetDefaultArray; diff --git a/security/nss/lib/pkcs12/p12.h b/security/nss/lib/pkcs12/p12.h index 05cd4d64a..3e27ecf80 100644 --- a/security/nss/lib/pkcs12/p12.h +++ b/security/nss/lib/pkcs12/p12.h @@ -160,6 +160,10 @@ SEC_PKCS12DecoderStart(SECItem *pwitem, PK11SlotInfo *slot, void *wincx, digestOpenFn dOpen, digestCloseFn dClose, digestIOFn dRead, digestIOFn dWrite, void *dArg); +extern SECStatus +SEC_PKCS12DecoderSetTargetTokenCAs(SEC_PKCS12DecoderContext *p12dcx, + SECPKCS12TargetTokenCAs tokenCAs); + extern SECStatus SEC_PKCS12DecoderUpdate(SEC_PKCS12DecoderContext *p12dcx, unsigned char *data, unsigned long len); diff --git a/security/nss/lib/pkcs12/p12d.c b/security/nss/lib/pkcs12/p12d.c index 708842bfc..dade3417b 100644 --- a/security/nss/lib/pkcs12/p12d.c +++ b/security/nss/lib/pkcs12/p12d.c @@ -141,6 +141,7 @@ struct SEC_PKCS12DecoderContextStr { PRInt32 filesize; /* actual data size */ PRInt32 allocated; /* total buffer size allocated */ PRInt32 currentpos; /* position counter */ + SECPKCS12TargetTokenCAs tokenCAs; }; @@ -264,6 +265,8 @@ sec_pkcs12_decoder_init_new_safe_bag(sec_PKCS12SafeContentsContext safeContentsCtx->currentSafeBag->swapUnicodeBytes = safeContentsCtx->p12dcx->swapUnicodeBytes; safeContentsCtx->currentSafeBag->arena = safeContentsCtx->p12dcx->arena; + safeContentsCtx->currentSafeBag->tokenCAs = + safeContentsCtx->p12dcx->tokenCAs; PORT_ArenaUnmark(p12dcx->arena, mark); return SECSuccess; @@ -1194,6 +1197,7 @@ SEC_PKCS12DecoderStart(SECItem *pwitem, PK11SlotInfo *slot, void *wincx, p12dcx->slot = (slot ? PK11_ReferenceSlot(slot) : PK11_GetInternalKeySlot()); p12dcx->wincx = wincx; + p12dcx->tokenCAs = SECPKCS12TargetTokenNoCAs; #ifdef IS_LITTLE_ENDIAN p12dcx->swapUnicodeBytes = PR_TRUE; #else @@ -1231,6 +1235,18 @@ loser: return NULL; } +SECStatus +SEC_PKCS12DecoderSetTargetTokenCAs(SEC_PKCS12DecoderContext *p12dcx, + SECPKCS12TargetTokenCAs tokenCAs) +{ + if (!p12dcx || p12dcx->error) { + return SECFailure; + } + p12dcx->tokenCAs = tokenCAs; + return SECSuccess; +} + + /* SEC_PKCS12DecoderUpdate * Streaming update sending more data to the decoder. If * an error occurs, SECFailure is returned. @@ -2310,6 +2326,7 @@ sec_pkcs12_add_cert(sec_PKCS12SafeBag *cert, PRBool keyExists, void *wincx) { SECItem *derCert, *nickName; char *nickData = NULL; + PRBool isIntermediateCA; SECStatus rv; if(!cert) { @@ -2329,6 +2346,9 @@ sec_pkcs12_add_cert(sec_PKCS12SafeBag *cert, PRBool keyExists, void *wincx) nickData = (char *)nickName->data; } + isIntermediateCA = CERT_IsCADERCert(derCert, NULL) && + !CERT_IsRootDERCert(derCert); + if(keyExists) { CERTCertificate *newCert; @@ -2344,12 +2364,18 @@ sec_pkcs12_add_cert(sec_PKCS12SafeBag *cert, PRBool keyExists, void *wincx) rv = PK11_ImportCertForKeyToSlot(cert->slot, newCert, nickData, PR_TRUE, wincx); CERT_DestroyCertificate(newCert); - } else { + } else if ((cert->tokenCAs == SECPKCS12TargetTokenNoCAs) || + ((cert->tokenCAs == SECPKCS12TargetTokenIntermediateCAs) && + !isIntermediateCA)) { SECItem *certList[2]; certList[0] = derCert; certList[1] = NULL; + rv = CERT_ImportCerts(CERT_GetDefaultCertDB(), certUsageUserCertImport, - 1, certList, NULL, PR_TRUE, PR_FALSE, nickData); + 1, certList, NULL, PR_TRUE, PR_FALSE, nickData); + } else { + rv = PK11_ImportDERCert(cert->slot, derCert, CK_INVALID_HANDLE, + nickData, PR_FALSE); } cert->installed = PR_TRUE; @@ -2901,6 +2927,7 @@ sec_pkcs12_decoder_convert_old_key(SEC_PKCS12DecoderContext *p12dcx, keyBag->slot = p12dcx->slot; keyBag->arena = p12dcx->arena; keyBag->pwitem = p12dcx->pwitem; + keyBag->tokenCAs = p12dcx->tokenCAs; keyBag->oldBagType = PR_TRUE; keyTag = (isEspvk) ? SEC_OID_PKCS12_V1_PKCS8_SHROUDED_KEY_BAG_ID : @@ -3025,6 +3052,7 @@ sec_pkcs12_decoder_create_cert(SEC_PKCS12DecoderContext *p12dcx, certBag->pwitem = p12dcx->pwitem; certBag->swapUnicodeBytes = p12dcx->swapUnicodeBytes; certBag->arena = p12dcx->arena; + certBag->tokenCAs = p12dcx->tokenCAs; oid = SECOID_FindOIDByTag(SEC_OID_PKCS9_X509_CERT); certBag->safeBagContent.certBag = @@ -3257,6 +3285,7 @@ sec_PKCS12ConvertOldSafeToNew(PRArenaPool *arena, PK11SlotInfo *slot, p12dcx->error = PR_FALSE; p12dcx->swapUnicodeBytes = swapUnicode; p12dcx->pwitem = pwitem; + p12dcx->tokenCAs = SECPKCS12TargetTokenNoCAs; if(sec_pkcs12_decoder_convert_old_safe_to_bags(p12dcx, safe, baggage) != SECSuccess) { diff --git a/security/nss/lib/pkcs12/p12t.h b/security/nss/lib/pkcs12/p12t.h index 74e803c60..9e5e5eb39 100644 --- a/security/nss/lib/pkcs12/p12t.h +++ b/security/nss/lib/pkcs12/p12t.h @@ -39,6 +39,7 @@ #include "pkcs11.h" #include "secpkcs7.h" #include "secdig.h" /* for SGNDigestInfo */ +#include "pkcs12t.h" #define SEC_PKCS12_VERSION 3 @@ -118,6 +119,7 @@ struct sec_PKCS12SafeBagStr { PK11SlotInfo *slot; SECItem *pwitem; PRBool oldBagType; + SECPKCS12TargetTokenCAs tokenCAs; }; struct sec_PKCS12SafeContentsStr { diff --git a/security/nss/lib/pkcs12/pkcs12t.h b/security/nss/lib/pkcs12/pkcs12t.h index 53c36c3f7..c6e829374 100644 --- a/security/nss/lib/pkcs12/pkcs12t.h +++ b/security/nss/lib/pkcs12/pkcs12t.h @@ -42,6 +42,15 @@ #include "secpkcs7.h" #include "secdig.h" /* for SGNDigestInfo */ +typedef enum { + SECPKCS12TargetTokenNoCAs, /* CA get loaded intothe fixed token, + * User certs go to target token */ + SECPKCS12TargetTokenIntermediateCAs, /* User certs and intermediates go to + * target token, root certs got to + * fixed token */ + SECPKCS12TargetTokenAllCAs, /* All certs go to target token */ +} SECPKCS12TargetTokenCAs; + /* PKCS12 Structures */ typedef struct SEC_PKCS12PFXItemStr SEC_PKCS12PFXItem; typedef struct SEC_PKCS12MacDataStr SEC_PKCS12MacData; diff --git a/security/nss/lib/smime/smime.def b/security/nss/lib/smime/smime.def index ac0bbd408..c220d38c0 100644 --- a/security/nss/lib/smime/smime.def +++ b/security/nss/lib/smime/smime.def @@ -236,6 +236,7 @@ NSS_CMSRecipientInfo_CreateNew; NSS_CMSRecipientInfo_CreateFromDER; NSS_CMSRecipientInfo_Encode; NSS_CMSRecipientInfo_GetCertAndKey; +SEC_PKCS12DecoderSetTargetTokenCAs; ;+ local: ;+ *; ;+}; -- cgit v1.2.1