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
This commit is contained in:
jpierre%netscape.com 2002-07-19 00:59:34 +00:00
Родитель f909572ef9
Коммит 6a2b391359
6 изменённых файлов: 133 добавлений и 101 удалений

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

@ -34,7 +34,7 @@
/*
* cert.h - public data structures and prototypes for the certificate library
*
* $Id: cert.h,v 1.17 2002-07-04 03:09:29 jpierre%netscape.com Exp $
* $Id: cert.h,v 1.18 2002-07-19 00:59:20 jpierre%netscape.com Exp $
*/
#ifndef _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

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

@ -34,7 +34,7 @@
/*
* Moved from secpkcs7.c
*
* $Id: crl.c,v 1.11 2002-07-19 00:12:13 jpierre%netscape.com Exp $
* $Id: crl.c,v 1.12 2002-07-19 00:59:23 jpierre%netscape.com Exp $
*/
#include "cert.h"
@ -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)
@ -384,6 +392,15 @@ loser:
return(0);
}
/*
* 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)
{

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

@ -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;
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);
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;
}
/* 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 */

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

@ -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:
;+ *;

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

@ -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);
}

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

@ -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