forked from mirrors/gecko-dev
Bug 142867: pk12util needs to be able to import intermediate CA's into hw
tokens.
This commit is contained in:
parent
668a59ec9b
commit
126930373b
8 changed files with 68 additions and 4 deletions
|
|
@ -34,7 +34,7 @@
|
||||||
/*
|
/*
|
||||||
* cert.h - public data structures and prototypes for the certificate library
|
* cert.h - public data structures and prototypes for the certificate library
|
||||||
*
|
*
|
||||||
* $Id: cert.h,v 1.33 2002/12/24 02:25:33 wtc%netscape.com Exp $
|
* $Id: cert.h,v 1.34 2003/03/24 19:08:56 relyea%netscape.com Exp $
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef _CERT_H_
|
#ifndef _CERT_H_
|
||||||
|
|
@ -1061,6 +1061,9 @@ CERT_IsCACert(CERTCertificate *cert, unsigned int *rettype);
|
||||||
PRBool
|
PRBool
|
||||||
CERT_IsCADERCert(SECItem *derCert, unsigned int *rettype);
|
CERT_IsCADERCert(SECItem *derCert, unsigned int *rettype);
|
||||||
|
|
||||||
|
PRBool
|
||||||
|
CERT_IsRootDERCert(SECItem *derCert);
|
||||||
|
|
||||||
SECStatus
|
SECStatus
|
||||||
CERT_SaveSMimeProfile(CERTCertificate *cert, SECItem *emailProfile,
|
CERT_SaveSMimeProfile(CERTCertificate *cert, SECItem *emailProfile,
|
||||||
SECItem *profileTime);
|
SECItem *profileTime);
|
||||||
|
|
|
||||||
|
|
@ -34,7 +34,7 @@
|
||||||
/*
|
/*
|
||||||
* Certificate handling code
|
* Certificate handling code
|
||||||
*
|
*
|
||||||
* $Id: certdb.c,v 1.50 2003/01/31 02:49:13 nelsonb%netscape.com Exp $
|
* $Id: certdb.c,v 1.51 2003/03/24 19:08:58 relyea%netscape.com Exp $
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "nssilock.h"
|
#include "nssilock.h"
|
||||||
|
|
@ -1861,6 +1861,21 @@ CERT_IsCADERCert(SECItem *derCert, unsigned int *type) {
|
||||||
return isCA;
|
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.
|
* is certa newer than certb? If one is expired, pick the other one.
|
||||||
|
|
|
||||||
|
|
@ -741,6 +741,7 @@ PK11_TokenRefresh;
|
||||||
;+};
|
;+};
|
||||||
;+NSS_3.8 { # NSS 3.8 release
|
;+NSS_3.8 { # NSS 3.8 release
|
||||||
;+ global:
|
;+ global:
|
||||||
|
CERT_IsRootDERCert;
|
||||||
HASH_GetHashObjectByOidTag;
|
HASH_GetHashObjectByOidTag;
|
||||||
HASH_GetHashTypeByOidTag;
|
HASH_GetHashTypeByOidTag;
|
||||||
PK11_GetDefaultArray;
|
PK11_GetDefaultArray;
|
||||||
|
|
|
||||||
|
|
@ -160,6 +160,10 @@ SEC_PKCS12DecoderStart(SECItem *pwitem, PK11SlotInfo *slot, void *wincx,
|
||||||
digestOpenFn dOpen, digestCloseFn dClose,
|
digestOpenFn dOpen, digestCloseFn dClose,
|
||||||
digestIOFn dRead, digestIOFn dWrite, void *dArg);
|
digestIOFn dRead, digestIOFn dWrite, void *dArg);
|
||||||
|
|
||||||
|
extern SECStatus
|
||||||
|
SEC_PKCS12DecoderSetTargetTokenCAs(SEC_PKCS12DecoderContext *p12dcx,
|
||||||
|
SECPKCS12TargetTokenCAs tokenCAs);
|
||||||
|
|
||||||
extern SECStatus
|
extern SECStatus
|
||||||
SEC_PKCS12DecoderUpdate(SEC_PKCS12DecoderContext *p12dcx, unsigned char *data,
|
SEC_PKCS12DecoderUpdate(SEC_PKCS12DecoderContext *p12dcx, unsigned char *data,
|
||||||
unsigned long len);
|
unsigned long len);
|
||||||
|
|
|
||||||
|
|
@ -141,6 +141,7 @@ struct SEC_PKCS12DecoderContextStr {
|
||||||
PRInt32 filesize; /* actual data size */
|
PRInt32 filesize; /* actual data size */
|
||||||
PRInt32 allocated; /* total buffer size allocated */
|
PRInt32 allocated; /* total buffer size allocated */
|
||||||
PRInt32 currentpos; /* position counter */
|
PRInt32 currentpos; /* position counter */
|
||||||
|
SECPKCS12TargetTokenCAs tokenCAs;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -264,6 +265,8 @@ sec_pkcs12_decoder_init_new_safe_bag(sec_PKCS12SafeContentsContext
|
||||||
safeContentsCtx->currentSafeBag->swapUnicodeBytes =
|
safeContentsCtx->currentSafeBag->swapUnicodeBytes =
|
||||||
safeContentsCtx->p12dcx->swapUnicodeBytes;
|
safeContentsCtx->p12dcx->swapUnicodeBytes;
|
||||||
safeContentsCtx->currentSafeBag->arena = safeContentsCtx->p12dcx->arena;
|
safeContentsCtx->currentSafeBag->arena = safeContentsCtx->p12dcx->arena;
|
||||||
|
safeContentsCtx->currentSafeBag->tokenCAs =
|
||||||
|
safeContentsCtx->p12dcx->tokenCAs;
|
||||||
|
|
||||||
PORT_ArenaUnmark(p12dcx->arena, mark);
|
PORT_ArenaUnmark(p12dcx->arena, mark);
|
||||||
return SECSuccess;
|
return SECSuccess;
|
||||||
|
|
@ -1194,6 +1197,7 @@ SEC_PKCS12DecoderStart(SECItem *pwitem, PK11SlotInfo *slot, void *wincx,
|
||||||
p12dcx->slot = (slot ? PK11_ReferenceSlot(slot)
|
p12dcx->slot = (slot ? PK11_ReferenceSlot(slot)
|
||||||
: PK11_GetInternalKeySlot());
|
: PK11_GetInternalKeySlot());
|
||||||
p12dcx->wincx = wincx;
|
p12dcx->wincx = wincx;
|
||||||
|
p12dcx->tokenCAs = SECPKCS12TargetTokenNoCAs;
|
||||||
#ifdef IS_LITTLE_ENDIAN
|
#ifdef IS_LITTLE_ENDIAN
|
||||||
p12dcx->swapUnicodeBytes = PR_TRUE;
|
p12dcx->swapUnicodeBytes = PR_TRUE;
|
||||||
#else
|
#else
|
||||||
|
|
@ -1231,6 +1235,18 @@ loser:
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
SECStatus
|
||||||
|
SEC_PKCS12DecoderSetTargetTokenCAs(SEC_PKCS12DecoderContext *p12dcx,
|
||||||
|
SECPKCS12TargetTokenCAs tokenCAs)
|
||||||
|
{
|
||||||
|
if (!p12dcx || p12dcx->error) {
|
||||||
|
return SECFailure;
|
||||||
|
}
|
||||||
|
p12dcx->tokenCAs = tokenCAs;
|
||||||
|
return SECSuccess;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/* SEC_PKCS12DecoderUpdate
|
/* SEC_PKCS12DecoderUpdate
|
||||||
* Streaming update sending more data to the decoder. If
|
* Streaming update sending more data to the decoder. If
|
||||||
* an error occurs, SECFailure is returned.
|
* an error occurs, SECFailure is returned.
|
||||||
|
|
@ -2310,6 +2326,7 @@ sec_pkcs12_add_cert(sec_PKCS12SafeBag *cert, PRBool keyExists, void *wincx)
|
||||||
{
|
{
|
||||||
SECItem *derCert, *nickName;
|
SECItem *derCert, *nickName;
|
||||||
char *nickData = NULL;
|
char *nickData = NULL;
|
||||||
|
PRBool isIntermediateCA;
|
||||||
SECStatus rv;
|
SECStatus rv;
|
||||||
|
|
||||||
if(!cert) {
|
if(!cert) {
|
||||||
|
|
@ -2329,6 +2346,9 @@ sec_pkcs12_add_cert(sec_PKCS12SafeBag *cert, PRBool keyExists, void *wincx)
|
||||||
nickData = (char *)nickName->data;
|
nickData = (char *)nickName->data;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
isIntermediateCA = CERT_IsCADERCert(derCert, NULL) &&
|
||||||
|
!CERT_IsRootDERCert(derCert);
|
||||||
|
|
||||||
if(keyExists) {
|
if(keyExists) {
|
||||||
CERTCertificate *newCert;
|
CERTCertificate *newCert;
|
||||||
|
|
||||||
|
|
@ -2344,12 +2364,18 @@ sec_pkcs12_add_cert(sec_PKCS12SafeBag *cert, PRBool keyExists, void *wincx)
|
||||||
rv = PK11_ImportCertForKeyToSlot(cert->slot, newCert, nickData,
|
rv = PK11_ImportCertForKeyToSlot(cert->slot, newCert, nickData,
|
||||||
PR_TRUE, wincx);
|
PR_TRUE, wincx);
|
||||||
CERT_DestroyCertificate(newCert);
|
CERT_DestroyCertificate(newCert);
|
||||||
} else {
|
} else if ((cert->tokenCAs == SECPKCS12TargetTokenNoCAs) ||
|
||||||
|
((cert->tokenCAs == SECPKCS12TargetTokenIntermediateCAs) &&
|
||||||
|
!isIntermediateCA)) {
|
||||||
SECItem *certList[2];
|
SECItem *certList[2];
|
||||||
certList[0] = derCert;
|
certList[0] = derCert;
|
||||||
certList[1] = NULL;
|
certList[1] = NULL;
|
||||||
|
|
||||||
rv = CERT_ImportCerts(CERT_GetDefaultCertDB(), certUsageUserCertImport,
|
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;
|
cert->installed = PR_TRUE;
|
||||||
|
|
@ -2901,6 +2927,7 @@ sec_pkcs12_decoder_convert_old_key(SEC_PKCS12DecoderContext *p12dcx,
|
||||||
keyBag->slot = p12dcx->slot;
|
keyBag->slot = p12dcx->slot;
|
||||||
keyBag->arena = p12dcx->arena;
|
keyBag->arena = p12dcx->arena;
|
||||||
keyBag->pwitem = p12dcx->pwitem;
|
keyBag->pwitem = p12dcx->pwitem;
|
||||||
|
keyBag->tokenCAs = p12dcx->tokenCAs;
|
||||||
keyBag->oldBagType = PR_TRUE;
|
keyBag->oldBagType = PR_TRUE;
|
||||||
|
|
||||||
keyTag = (isEspvk) ? SEC_OID_PKCS12_V1_PKCS8_SHROUDED_KEY_BAG_ID :
|
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->pwitem = p12dcx->pwitem;
|
||||||
certBag->swapUnicodeBytes = p12dcx->swapUnicodeBytes;
|
certBag->swapUnicodeBytes = p12dcx->swapUnicodeBytes;
|
||||||
certBag->arena = p12dcx->arena;
|
certBag->arena = p12dcx->arena;
|
||||||
|
certBag->tokenCAs = p12dcx->tokenCAs;
|
||||||
|
|
||||||
oid = SECOID_FindOIDByTag(SEC_OID_PKCS9_X509_CERT);
|
oid = SECOID_FindOIDByTag(SEC_OID_PKCS9_X509_CERT);
|
||||||
certBag->safeBagContent.certBag =
|
certBag->safeBagContent.certBag =
|
||||||
|
|
@ -3257,6 +3285,7 @@ sec_PKCS12ConvertOldSafeToNew(PRArenaPool *arena, PK11SlotInfo *slot,
|
||||||
p12dcx->error = PR_FALSE;
|
p12dcx->error = PR_FALSE;
|
||||||
p12dcx->swapUnicodeBytes = swapUnicode;
|
p12dcx->swapUnicodeBytes = swapUnicode;
|
||||||
p12dcx->pwitem = pwitem;
|
p12dcx->pwitem = pwitem;
|
||||||
|
p12dcx->tokenCAs = SECPKCS12TargetTokenNoCAs;
|
||||||
|
|
||||||
if(sec_pkcs12_decoder_convert_old_safe_to_bags(p12dcx, safe, baggage)
|
if(sec_pkcs12_decoder_convert_old_safe_to_bags(p12dcx, safe, baggage)
|
||||||
!= SECSuccess) {
|
!= SECSuccess) {
|
||||||
|
|
|
||||||
|
|
@ -39,6 +39,7 @@
|
||||||
#include "pkcs11.h"
|
#include "pkcs11.h"
|
||||||
#include "secpkcs7.h"
|
#include "secpkcs7.h"
|
||||||
#include "secdig.h" /* for SGNDigestInfo */
|
#include "secdig.h" /* for SGNDigestInfo */
|
||||||
|
#include "pkcs12t.h"
|
||||||
|
|
||||||
#define SEC_PKCS12_VERSION 3
|
#define SEC_PKCS12_VERSION 3
|
||||||
|
|
||||||
|
|
@ -118,6 +119,7 @@ struct sec_PKCS12SafeBagStr {
|
||||||
PK11SlotInfo *slot;
|
PK11SlotInfo *slot;
|
||||||
SECItem *pwitem;
|
SECItem *pwitem;
|
||||||
PRBool oldBagType;
|
PRBool oldBagType;
|
||||||
|
SECPKCS12TargetTokenCAs tokenCAs;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct sec_PKCS12SafeContentsStr {
|
struct sec_PKCS12SafeContentsStr {
|
||||||
|
|
|
||||||
|
|
@ -42,6 +42,15 @@
|
||||||
#include "secpkcs7.h"
|
#include "secpkcs7.h"
|
||||||
#include "secdig.h" /* for SGNDigestInfo */
|
#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 */
|
/* PKCS12 Structures */
|
||||||
typedef struct SEC_PKCS12PFXItemStr SEC_PKCS12PFXItem;
|
typedef struct SEC_PKCS12PFXItemStr SEC_PKCS12PFXItem;
|
||||||
typedef struct SEC_PKCS12MacDataStr SEC_PKCS12MacData;
|
typedef struct SEC_PKCS12MacDataStr SEC_PKCS12MacData;
|
||||||
|
|
|
||||||
|
|
@ -236,6 +236,7 @@ NSS_CMSRecipientInfo_CreateNew;
|
||||||
NSS_CMSRecipientInfo_CreateFromDER;
|
NSS_CMSRecipientInfo_CreateFromDER;
|
||||||
NSS_CMSRecipientInfo_Encode;
|
NSS_CMSRecipientInfo_Encode;
|
||||||
NSS_CMSRecipientInfo_GetCertAndKey;
|
NSS_CMSRecipientInfo_GetCertAndKey;
|
||||||
|
SEC_PKCS12DecoderSetTargetTokenCAs;
|
||||||
;+ local:
|
;+ local:
|
||||||
;+ *;
|
;+ *;
|
||||||
;+};
|
;+};
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue