diff options
author | jpierre%netscape.com <devnull@localhost> | 2002-07-19 00:59:34 +0000 |
---|---|---|
committer | jpierre%netscape.com <devnull@localhost> | 2002-07-19 00:59:34 +0000 |
commit | 30d1579ccdb7b921c9d3df9938cb96299f1d4bd9 (patch) | |
tree | 64236c319825d88278266ed7225acab82fc63e07 | |
parent | d131b94b5f0499af8e9d8e1ceab3af96769af015 (diff) | |
download | nss-hg-30d1579ccdb7b921c9d3df9938cb96299f1d4bd9.tar.gz |
158005 - add new CRL decode and import functions . Benefits are :
- ability to import to any slot
- ability to specify decode options, such as "don't copy DER"
- ability to specify import options, such as "don't do CRL checks"
This patch also maps the existing functions SEC_NewCrl and CERT_ImportCRL
to this new function, eliminating the code duplication that existed
-rw-r--r-- | security/nss/lib/certdb/cert.h | 20 | ||||
-rw-r--r-- | security/nss/lib/certdb/crl.c | 70 | ||||
-rw-r--r-- | security/nss/lib/certhigh/certhigh.c | 65 | ||||
-rw-r--r-- | security/nss/lib/nss/nss.def | 2 | ||||
-rw-r--r-- | security/nss/lib/pk11wrap/pk11cert.c | 67 | ||||
-rw-r--r-- | security/nss/lib/pk11wrap/pk11func.h | 6 |
6 files changed, 131 insertions, 99 deletions
diff --git a/security/nss/lib/certdb/cert.h b/security/nss/lib/certdb/cert.h index 56269f5f2..cf4f269e9 100644 --- a/security/nss/lib/certdb/cert.h +++ b/security/nss/lib/certdb/cert.h @@ -389,6 +389,26 @@ CERT_DecodeDERCertificate (SECItem *derSignedCert, PRBool copyDER, char *nicknam extern CERTSignedCrl * CERT_DecodeDERCrl (PRArenaPool *arena, SECItem *derSignedCrl,int type); +/* + * same as CERT_DecodeDERCrl, plus allow options to be passed in + */ + +CERTSignedCrl * +CERT_DecodeDERCrlEx(PRArenaPool *narena, SECItem *derSignedCrl, int type, + PRInt32 options); + +/* CRL options to pass */ + +#define CRL_DECODE_DEFAULT_OPTIONS 0x00000000 + +/* when CRL_DECODE_DONT_COPY_DER is set, the DER is not copied . The + application must then keep derSignedCrl until it destroys the + CRL . Ideally, it should allocate derSignedCrl in an arena + and pass that arena in as the first argument to CERT_DecodeDERCrlEx */ + +#define CRL_DECODE_DONT_COPY_DER 0x00000001 + + /* Validate CRL then import it to the dbase. If there is already a CRL with the * same CA in the dbase, it will be replaced if derCRL is more up to date. * If the process successes, a CRL will be returned. Otherwise, a NULL will diff --git a/security/nss/lib/certdb/crl.c b/security/nss/lib/certdb/crl.c index 58ac7bb1c..38fedffe5 100644 --- a/security/nss/lib/certdb/crl.c +++ b/security/nss/lib/certdb/crl.c @@ -309,9 +309,11 @@ CERT_KeyFromDERCrl(PRArenaPool *arena, SECItem *derCrl, SECItem *key) /* * take a DER CRL or KRL and decode it into a CRL structure + * allow reusing the input DER without making a copy */ CERTSignedCrl * -CERT_DecodeDERCrl(PRArenaPool *narena, SECItem *derSignedCrl, int type) +CERT_DecodeDERCrlEx(PRArenaPool *narena, SECItem *derSignedCrl, int type, + PRInt32 options) { PRArenaPool *arena; CERTSignedCrl *crl; @@ -335,13 +337,19 @@ CERT_DecodeDERCrl(PRArenaPool *narena, SECItem *derSignedCrl, int type) crl->arena = arena; - crl->derCrl = (SECItem *)PORT_ArenaZAlloc(arena,sizeof(SECItem)); - if (crl->derCrl == NULL) { - goto loser; - } - rv = SECITEM_CopyItem(arena, crl->derCrl, derSignedCrl); - if (rv != SECSuccess) { - goto loser; + if (options & CRL_DECODE_DONT_COPY_DER) { + crl->derCrl = derSignedCrl; /* DER is not copied . The application + must keep derSignedCrl until it + destroys the CRL */ + } else { + crl->derCrl = (SECItem *)PORT_ArenaZAlloc(arena,sizeof(SECItem)); + if (crl->derCrl == NULL) { + goto loser; + } + rv = SECITEM_CopyItem(arena, crl->derCrl, derSignedCrl); + if (rv != SECSuccess) { + goto loser; + } } /* Save the arena in the inner crl for CRL extensions support */ @@ -349,7 +357,7 @@ CERT_DecodeDERCrl(PRArenaPool *narena, SECItem *derSignedCrl, int type) /* decode the CRL info */ switch (type) { - case SEC_CRL_TYPE: + case SEC_CRL_TYPE: rv = SEC_ASN1DecodeItem (arena, crl, cert_SignedCrlTemplate, derSignedCrl); if (rv != SECSuccess) @@ -385,6 +393,15 @@ loser: } /* + * take a DER CRL or KRL and decode it into a CRL structure + */ +CERTSignedCrl * +CERT_DecodeDERCrl(PRArenaPool *narena, SECItem *derSignedCrl, int type) +{ + return CERT_DecodeDERCrlEx(narena, derSignedCrl, type, CRL_DECODE_DEFAULT_OPTIONS); +} + +/* * Lookup a CRL in the databases. We mirror the same fast caching data base * caching stuff used by certificates....? */ @@ -440,8 +457,6 @@ crl_storeCRL (PK11SlotInfo *slot,char *url, oldCrl = SEC_FindCrlByKeyOnSlot(slot, &newCrl->crl.derName, type); - - /* if there is an old crl, make sure the one we are installing * is newer. If not, exit out, otherwise delete the old crl. */ @@ -517,36 +532,15 @@ SEC_FindCrlByName(CERTCertDBHandle *handle, SECItem *crlKey, int type) CERTSignedCrl * SEC_NewCrl(CERTCertDBHandle *handle, char *url, SECItem *derCrl, int type) { - CERTSignedCrl *newCrl = NULL, *crl = NULL; - PK11SlotInfo *slot; - - /* make this decode dates! */ - newCrl = CERT_DecodeDERCrl(NULL, derCrl, type); - if (newCrl == NULL) { - if (type == SEC_CRL_TYPE) { - PORT_SetError(SEC_ERROR_CRL_INVALID); - } else { - PORT_SetError(SEC_ERROR_KRL_INVALID); - } - goto done; - } - - slot = PK11_GetInternalKeySlot(); - crl = crl_storeCRL(slot, url, newCrl, derCrl, type); + CERTSignedCrl* retCrl = NULL; + PK11SlotInfo* slot = PK11_GetInternalKeySlot(); + retCrl = PK11_ImportCRL(slot, derCrl, url, type, NULL, + CRL_IMPORT_BYPASS_CHECKS, NULL, CRL_DECODE_DEFAULT_OPTIONS); PK11_FreeSlot(slot); - -done: - if (crl == NULL) { - if (newCrl) { - PORT_FreeArena(newCrl->arena, PR_FALSE); - } - } - - return crl; + return retCrl; } - - + CERTSignedCrl * SEC_FindCrlByDERCert(CERTCertDBHandle *handle, SECItem *derCrl, int type) { diff --git a/security/nss/lib/certhigh/certhigh.c b/security/nss/lib/certhigh/certhigh.c index 0e2befcaf..6c8831aae 100644 --- a/security/nss/lib/certhigh/certhigh.c +++ b/security/nss/lib/certhigh/certhigh.c @@ -50,9 +50,6 @@ #include "pki3hack.h" -CERTSignedCrl * crl_storeCRL (PK11SlotInfo *slot,char *url, - CERTSignedCrl *newCrl, SECItem *derCrl, int type); - PRBool CERT_MatchNickname(char *name1, char *name2) { char *nickname1= NULL; @@ -497,7 +494,6 @@ CERT_GetCertNicknames(CERTCertDBHandle *handle, int what, void *wincx) PRArenaPool *arena; CERTCertNicknames *names; int i; - SECStatus rv; stringNode *node; arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE); @@ -786,62 +782,13 @@ CERT_FindCRLDistributionPoints (CERTCertificate *cert) CERTSignedCrl * CERT_ImportCRL (CERTCertDBHandle *handle, SECItem *derCRL, char *url, int type, void *wincx) { - CERTCertificate *caCert; - CERTSignedCrl *newCrl, *crl; - SECStatus rv; - PK11SlotInfo *slot; - - newCrl = crl = NULL; - - PORT_Assert (handle != NULL); - do { - - newCrl = CERT_DecodeDERCrl(NULL, derCRL, type); - if (newCrl == NULL) { - if (type == SEC_CRL_TYPE) { - /* only promote error when the error code is too generic */ - if (PORT_GetError () == SEC_ERROR_BAD_DER) - PORT_SetError(SEC_ERROR_CRL_INVALID); - } else { - PORT_SetError(SEC_ERROR_KRL_INVALID); - } - break; - } - - caCert = CERT_FindCertByName (handle, &newCrl->crl.derName); - if (caCert == NULL) { - PORT_SetError(SEC_ERROR_UNKNOWN_ISSUER); - break; - } + CERTSignedCrl* retCrl = NULL; + PK11SlotInfo* slot = PK11_GetInternalKeySlot(); + retCrl = PK11_ImportCRL(slot, derCRL, url, type, wincx, + CRL_IMPORT_DEFAULT_OPTIONS, NULL, CRL_DECODE_DEFAULT_OPTIONS); + PK11_FreeSlot(slot); - /* If caCert is a v3 certificate, make sure that it can be used for - crl signing purpose */ - rv = CERT_CheckCertUsage (caCert, KU_CRL_SIGN); - if (rv != SECSuccess) { - break; - } - - rv = CERT_VerifySignedData(&newCrl->signatureWrap, caCert, - PR_Now(), wincx); - if (rv != SECSuccess) { - if (type == SEC_CRL_TYPE) { - PORT_SetError(SEC_ERROR_CRL_BAD_SIGNATURE); - } else { - PORT_SetError(SEC_ERROR_KRL_BAD_SIGNATURE); - } - break; - } - - slot = PK11_GetInternalKeySlot(); - crl = crl_storeCRL(slot, url, newCrl, derCRL, type); - PK11_FreeSlot(slot); - - } while (0); - - if (crl == NULL) { - SEC_DestroyCrl (newCrl); - } - return (crl); + return retCrl; } /* From certdb.c */ diff --git a/security/nss/lib/nss/nss.def b/security/nss/lib/nss/nss.def index d1e6817ca..d9faff971 100644 --- a/security/nss/lib/nss/nss.def +++ b/security/nss/lib/nss/nss.def @@ -683,6 +683,7 @@ SECMOD_CanDeleteInternalModule; ;+NSS_3.6 { # NSS 3.6 release ;+ global: CERT_AddOCSPAcceptableResponses; +CERT_DecodeDERCrlEx; CERT_CreateOCSPCertID; CERT_CreateOCSPRequest; CERT_DecodeOCSPResponse; @@ -696,6 +697,7 @@ CERT_VerifyCertificate; CERT_VerifyCertificateNow; CERT_VerifyOCSPResponseSignature; PK11_GetPBEIV; +PK11_ImportCRL; PK11_SaveContextAlloc; ;+ local: ;+ *; diff --git a/security/nss/lib/pk11wrap/pk11cert.c b/security/nss/lib/pk11wrap/pk11cert.c index d7c52aa51..cb81be09c 100644 --- a/security/nss/lib/pk11wrap/pk11cert.c +++ b/security/nss/lib/pk11wrap/pk11cert.c @@ -3255,7 +3255,6 @@ pk11ListCertCallback(NSSCertificate *c, void *arg) CERTCertificate *newCert = NULL; PK11CertListType type = listCertP->type; CERTCertList *certList = listCertP->certList; - CERTCertTrust *trust; PRBool isUnique = PR_FALSE; PRBool isCA = PR_FALSE; char *nickname = NULL; @@ -4007,3 +4006,69 @@ PK11_SaveSMimeProfile(PK11SlotInfo *slot, char *emailAddr, SECItem *derSubj, } +CERTSignedCrl * crl_storeCRL (PK11SlotInfo *slot,char *url, + CERTSignedCrl *newCrl, SECItem *derCrl, int type); + +/* import the CRL into the token */ + +CERTSignedCrl* PK11_ImportCRL(PK11SlotInfo * slot, SECItem *derCRL, char *url, + int type, void *wincx, PRInt32 importOptions, PRArenaPool* arena, + PRInt32 decodeoptions) +{ + CERTSignedCrl *newCrl, *crl; + SECStatus rv; + + newCrl = crl = NULL; + + do { + newCrl = CERT_DecodeDERCrlEx(arena, derCRL, type, decodeoptions); + if (newCrl == NULL) { + if (type == SEC_CRL_TYPE) { + /* only promote error when the error code is too generic */ + if (PORT_GetError () == SEC_ERROR_BAD_DER) + PORT_SetError(SEC_ERROR_CRL_INVALID); + } else { + PORT_SetError(SEC_ERROR_KRL_INVALID); + } + break; + } + + if (0 == (importOptions & CRL_IMPORT_BYPASS_CHECKS)){ + CERTCertificate *caCert; + CERTCertDBHandle* handle = CERT_GetDefaultCertDB(); + PR_ASSERT(handle != NULL); + caCert = CERT_FindCertByName (handle, + &newCrl->crl.derName); + if (caCert == NULL) { + PORT_SetError(SEC_ERROR_UNKNOWN_ISSUER); + break; + } + + /* If caCert is a v3 certificate, make sure that it can be used for + crl signing purpose */ + rv = CERT_CheckCertUsage (caCert, KU_CRL_SIGN); + if (rv != SECSuccess) { + break; + } + + rv = CERT_VerifySignedData(&newCrl->signatureWrap, caCert, + PR_Now(), wincx); + if (rv != SECSuccess) { + if (type == SEC_CRL_TYPE) { + PORT_SetError(SEC_ERROR_CRL_BAD_SIGNATURE); + } else { + PORT_SetError(SEC_ERROR_KRL_BAD_SIGNATURE); + } + break; + } + } + + crl = crl_storeCRL(slot, url, newCrl, derCRL, type); + + } while (0); + + if (crl == NULL) { + SEC_DestroyCrl (newCrl); + } + return (crl); +} diff --git a/security/nss/lib/pk11wrap/pk11func.h b/security/nss/lib/pk11wrap/pk11func.h index e1a2f39d6..360043ca4 100644 --- a/security/nss/lib/pk11wrap/pk11func.h +++ b/security/nss/lib/pk11wrap/pk11func.h @@ -442,7 +442,11 @@ SECStatus PK11_TraverseCertsInSlot(PK11SlotInfo *slot, CERTCertList * PK11_ListCerts(PK11CertListType type, void *pwarg); CERTCertList * PK11_ListCertsInSlot(PK11SlotInfo *slot); SECStatus PK11_LookupCrls(CERTCrlHeadNode *nodes, int type, void *wincx); - +CERTSignedCrl* PK11_ImportCRL(PK11SlotInfo * slot, SECItem *derCRL, char *url, + int type, void *wincx, PRInt32 importOptions, PRArenaPool* arena, PRInt32 decodeOptions); +/* import options */ +#define CRL_IMPORT_DEFAULT_OPTIONS 0x00000000 +#define CRL_IMPORT_BYPASS_CHECKS 0x00000001 /********************************************************************** * Sign/Verify |