mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-10-14 13:55:43 +00:00
Implement the CRL cache . Bug 149854
This commit is contained in:
parent
c8c32a582e
commit
29333f104f
@ -34,7 +34,7 @@
|
||||
/*
|
||||
* cert.h - public data structures and prototypes for the certificate library
|
||||
*
|
||||
* $Id: cert.h,v 1.20 2002/08/07 03:42:45 jpierre%netscape.com Exp $
|
||||
* $Id: cert.h,v 1.21 2002/08/30 22:56:51 jpierre%netscape.com Exp $
|
||||
*/
|
||||
|
||||
#ifndef _CERT_H_
|
||||
@ -408,6 +408,7 @@ CERT_DecodeDERCrlEx(PRArenaPool *narena, SECItem *derSignedCrl, int type,
|
||||
|
||||
#define CRL_DECODE_DONT_COPY_DER 0x00000001
|
||||
#define CRL_DECODE_SKIP_ENTRIES 0x00000002
|
||||
#define CRL_DECODE_KEEP_BAD_CRL 0x00000004
|
||||
|
||||
/* complete the decoding of a partially decoded CRL, ie. decode the
|
||||
entries. Note that entries is an optional field in a CRL, so the
|
||||
@ -1429,6 +1430,14 @@ CERT_SPKDigestValueForCert(PRArenaPool *arena, CERTCertificate *cert,
|
||||
*/
|
||||
extern SECStatus CERT_GetCertType(CERTCertificate *cert);
|
||||
|
||||
|
||||
SECStatus InitCRLCache(void);
|
||||
SECStatus ShutdownCRLCache(void);
|
||||
|
||||
SECStatus CERT_CheckCRL(CERTCertificate* cert, CERTCertificate* issuer,
|
||||
SECItem* dp, int64 t, void* wincx);
|
||||
|
||||
|
||||
SEC_END_PROTOS
|
||||
|
||||
#endif /* _CERT_H_ */
|
||||
|
@ -31,20 +31,147 @@
|
||||
* GPL.
|
||||
*/
|
||||
/*
|
||||
* certt.h - public data structures for the certificate library
|
||||
* certi.h - private data structures for the certificate library
|
||||
*
|
||||
* $Id: certi.h,v 1.1 2002/08/07 03:42:46 jpierre%netscape.com Exp $
|
||||
* $Id: certi.h,v 1.2 2002/08/30 22:56:52 jpierre%netscape.com Exp $
|
||||
*/
|
||||
#ifndef _CERTI_H_
|
||||
#define _CERTI_H_
|
||||
|
||||
#include "certt.h"
|
||||
#include "nssrwlkt.h"
|
||||
|
||||
typedef struct OpaqueCRLFieldsStr OpaqueCRLFields;
|
||||
#define USE_RWLOCK 1
|
||||
|
||||
/* all definitions in this file are subject to change */
|
||||
|
||||
typedef struct OpaqueCRLFieldsStr OpaqueCRLFields;
|
||||
typedef struct CRLEntryCacheStr CRLEntryCache;
|
||||
typedef struct CRLDPCacheStr CRLDPCache;
|
||||
typedef struct CRLIssuerCacheStr CRLIssuerCache;
|
||||
typedef struct CRLCacheStr CRLCache;
|
||||
|
||||
struct OpaqueCRLFieldsStr {
|
||||
/* these fields are subject to change */
|
||||
PRBool partial;
|
||||
PRBool bad;
|
||||
PRBool badDER;
|
||||
PRBool badExtensions;
|
||||
PRBool deleted;
|
||||
PRBool heapDER;
|
||||
};
|
||||
|
||||
typedef struct PreAllocatorStr PreAllocator;
|
||||
|
||||
struct PreAllocatorStr
|
||||
{
|
||||
PRSize len;
|
||||
void* data;
|
||||
PRSize used;
|
||||
PRArenaPool* arena;
|
||||
PRSize extra;
|
||||
};
|
||||
|
||||
/* CRL entry cache.
|
||||
This is the same as an entry plus the next/prev pointers for the hash table
|
||||
*/
|
||||
|
||||
struct CRLEntryCacheStr {
|
||||
CERTCrlEntry entry;
|
||||
CRLEntryCache *prev, *next;
|
||||
};
|
||||
|
||||
#define CRL_CACHE_INVALID_CRLS 0x0001 /* this state will be set
|
||||
if we have CRL objects with an invalid DER or signature. Can be
|
||||
cleared if the invalid objects are deleted from the token */
|
||||
#define CRL_CACHE_LAST_FETCH_FAILED 0x0002 /* this state will be set
|
||||
if the last CRL fetch encountered an error. Can be cleared if a
|
||||
new fetch succeeds */
|
||||
|
||||
/* CRL distribution point cache object
|
||||
This is a cache of CRL entries for a given distribution point of an issuer
|
||||
It is built from a collection of one full and 0 or more delta CRLs.
|
||||
*/
|
||||
|
||||
struct CRLDPCacheStr {
|
||||
#ifdef USE_RWLOCK
|
||||
NSSRWLock* lock;
|
||||
#else
|
||||
PRLock* lock;
|
||||
#endif
|
||||
CERTCertificate* issuer; /* DER of cert issuer */
|
||||
SECItem* distributionPoint; /* DER of distribution point. This may be
|
||||
NULL when distribution points aren't
|
||||
in use (ie. the CA has a single CRL) */
|
||||
|
||||
/* hash table of entries. We use a PLHashTable and pre-allocate the
|
||||
required amount of memory in one shot, so that our allocator can
|
||||
simply pass offsets into it when hashing.
|
||||
|
||||
This won't work anymore when we support delta CRLs and iCRLs, because
|
||||
the size of the hash table will vary over time. At that point, the best
|
||||
solution will be to allocate large CRLEntry structures by modifying
|
||||
the DER decoding template. The extra space would be for next/prev
|
||||
pointers. This would allow entries from different CRLs to be mixed in
|
||||
the same hash table.
|
||||
*/
|
||||
PLHashTable* entries;
|
||||
PreAllocator* prebuffer; /* big pre-allocated buffer mentioned above */
|
||||
|
||||
/* array of CRLs matching this distribution point */
|
||||
PRUint32 ncrls; /* total number of CRLs in crls */
|
||||
CERTSignedCrl** crls; /* array of all matching DER CRLs
|
||||
from all tokens */
|
||||
/* XCRL With iCRLs and multiple DPs, the CRL can be shared accross several
|
||||
issuers. In the future, we'll need to globally recycle the CRL in a
|
||||
separate list in order to avoid extra lookups, decodes, and copies */
|
||||
|
||||
/* pointers to good decoded CRLs used to build the cache */
|
||||
CERTSignedCrl* full; /* full CRL used for the cache */
|
||||
#if 0
|
||||
/* for future use */
|
||||
PRInt32 numdeltas; /* number of delta CRLs used for the cache */
|
||||
CERTSignedCrl** deltas; /* delta CRLs used for the cache */
|
||||
#endif
|
||||
/* invalidity bitflag */
|
||||
PRUint16 invalid; /* this state will be set if either
|
||||
CRL_CACHE_INVALID_CRLS or CRL_CACHE_LAST_FETCH_FAILED is set.
|
||||
In those cases, all certs are considered revoked as a
|
||||
security precaution. The invalid state can only be cleared
|
||||
during an update if all error states are cleared */
|
||||
};
|
||||
|
||||
/* CRL issuer cache object
|
||||
This object tracks all the distribution point caches for a given issuer.
|
||||
XCRL once we support multiple issuing distribution points, this object
|
||||
will be a hash table. For now, it just holds the single CRL distribution
|
||||
point cache structure.
|
||||
*/
|
||||
|
||||
struct CRLIssuerCacheStr {
|
||||
PRUint32 refcount;
|
||||
CERTCertificate* issuer;
|
||||
CRLDPCache dp;
|
||||
CRLDPCache* dpp;
|
||||
#if 0
|
||||
/* XCRL for future use.
|
||||
We don't need to lock at the moment because we only have one DP,
|
||||
which gets created at the same time as this object */
|
||||
NSSRWLock* lock;
|
||||
CRLDPCache** dps;
|
||||
PLHashTable* distributionpoints;
|
||||
#endif
|
||||
};
|
||||
|
||||
/* CRL revocation cache object
|
||||
This object tracks all the issuer caches
|
||||
*/
|
||||
|
||||
struct CRLCacheStr {
|
||||
PRLock* lock;
|
||||
/* hash table of issuer to CRLIssuerCacheStr,
|
||||
indexed by issuer DER subject */
|
||||
PLHashTable* issuers;
|
||||
};
|
||||
|
||||
#endif /* _CERTI_H_ */
|
||||
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -113,7 +113,7 @@ CERT_VerifySignedData(CERTSignedData *sd, CERTCertificate *cert,
|
||||
if ( !pubKey ) {
|
||||
return(SECFailure);
|
||||
}
|
||||
|
||||
|
||||
/* check the signature */
|
||||
sig = sd->signature;
|
||||
DER_ConvertBitString(&sig);
|
||||
@ -267,37 +267,7 @@ SECStatus
|
||||
SEC_CheckCRL(CERTCertDBHandle *handle,CERTCertificate *cert,
|
||||
CERTCertificate *caCert, int64 t, void * wincx)
|
||||
{
|
||||
CERTSignedCrl *crl = NULL;
|
||||
SECStatus rv = SECSuccess;
|
||||
CERTCrlEntry **crlEntry;
|
||||
|
||||
/* first look up the CRL */
|
||||
crl = SEC_FindCrlByName(handle,&caCert->derSubject, SEC_CRL_TYPE);
|
||||
if (crl == NULL) {
|
||||
/* XXX for now no CRL is ok */
|
||||
goto done;
|
||||
}
|
||||
|
||||
/* now verify the CRL signature */
|
||||
rv = CERT_VerifySignedData(&crl->signatureWrap, caCert, t, wincx);
|
||||
if (rv != SECSuccess) {
|
||||
PORT_SetError(SEC_ERROR_CRL_BAD_SIGNATURE);
|
||||
rv = SECWouldBlock; /* Soft error, ask the user */
|
||||
goto done;
|
||||
}
|
||||
|
||||
/* now make sure the key is not on the revocation list */
|
||||
for (crlEntry = crl->crl.entries; crlEntry && *crlEntry; crlEntry++) {
|
||||
if (SECITEM_CompareItem(&(*crlEntry)->serialNumber,&cert->serialNumber) == SECEqual) {
|
||||
PORT_SetError(SEC_ERROR_REVOKED_CERTIFICATE);
|
||||
rv = SECFailure; /* cert is revoked */
|
||||
goto done;
|
||||
}
|
||||
}
|
||||
|
||||
done:
|
||||
if (crl) SEC_DestroyCrl(crl);
|
||||
return rv;
|
||||
return CERT_CheckCRL(cert, caCert, NULL, t, wincx);
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -32,7 +32,7 @@
|
||||
*/
|
||||
|
||||
#ifdef DEBUG
|
||||
static const char CVS_ID[] = "@(#) $RCSfile: ckhelper.c,v $ $Revision: 1.25 $ $Date: 2002/08/27 23:37:55 $ $Name: $";
|
||||
static const char CVS_ID[] = "@(#) $RCSfile: ckhelper.c,v $ $Revision: 1.26 $ $Date: 2002/08/30 22:56:57 $ $Name: $";
|
||||
#endif /* DEBUG */
|
||||
|
||||
#ifndef NSSCKEPV_H
|
||||
@ -611,6 +611,8 @@ nssCryptokiCRL_GetAttributes
|
||||
nssSession *sessionOpt,
|
||||
NSSArena *arenaOpt,
|
||||
NSSItem *encodingOpt,
|
||||
NSSItem *subjectOpt,
|
||||
CK_ULONG* crl_class,
|
||||
NSSUTF8 **urlOpt,
|
||||
PRBool *isKRLOpt
|
||||
)
|
||||
@ -619,11 +621,14 @@ nssCryptokiCRL_GetAttributes
|
||||
NSSSlot *slot;
|
||||
nssSession *session;
|
||||
CK_ATTRIBUTE_PTR attr;
|
||||
CK_ATTRIBUTE crl_template[5];
|
||||
CK_ATTRIBUTE crl_template[7];
|
||||
CK_ULONG crl_size;
|
||||
PRUint32 i;
|
||||
|
||||
NSS_CK_TEMPLATE_START(crl_template, attr, crl_size);
|
||||
if (crl_class) {
|
||||
NSS_CK_SET_ATTRIBUTE_NULL(attr, CKA_CLASS);
|
||||
}
|
||||
if (encodingOpt) {
|
||||
NSS_CK_SET_ATTRIBUTE_NULL(attr, CKA_VALUE);
|
||||
}
|
||||
@ -633,6 +638,9 @@ nssCryptokiCRL_GetAttributes
|
||||
if (isKRLOpt) {
|
||||
NSS_CK_SET_ATTRIBUTE_NULL(attr, CKA_NETSCAPE_KRL);
|
||||
}
|
||||
if (subjectOpt) {
|
||||
NSS_CK_SET_ATTRIBUTE_NULL(attr, CKA_SUBJECT);
|
||||
}
|
||||
NSS_CK_TEMPLATE_FINISH(crl_template, attr, crl_size);
|
||||
|
||||
status = nssToken_GetCachedObjectAttributes(crlObject->token, NULL,
|
||||
@ -655,6 +663,9 @@ nssCryptokiCRL_GetAttributes
|
||||
}
|
||||
|
||||
i=0;
|
||||
if (crl_class) {
|
||||
NSS_CK_ATTRIBUTE_TO_ULONG(&crl_template[i], *crl_class); i++;
|
||||
}
|
||||
if (encodingOpt) {
|
||||
NSS_CK_ATTRIBUTE_TO_ITEM(&crl_template[i], encodingOpt); i++;
|
||||
}
|
||||
@ -664,6 +675,9 @@ nssCryptokiCRL_GetAttributes
|
||||
if (isKRLOpt) {
|
||||
NSS_CK_ATTRIBUTE_TO_BOOL(&crl_template[i], *isKRLOpt); i++;
|
||||
}
|
||||
if (subjectOpt) {
|
||||
NSS_CK_ATTRIBUTE_TO_ITEM(&crl_template[i], subjectOpt); i++;
|
||||
}
|
||||
return PR_SUCCESS;
|
||||
}
|
||||
|
||||
|
@ -41,7 +41,7 @@
|
||||
#define CKHELPER_H
|
||||
|
||||
#ifdef DEBUG
|
||||
static const char CKHELPER_CVS_ID[] = "@(#) $RCSfile: ckhelper.h,v $ $Revision: 1.16 $ $Date: 2002/04/18 17:29:53 $ $Name: $";
|
||||
static const char CKHELPER_CVS_ID[] = "@(#) $RCSfile: ckhelper.h,v $ $Revision: 1.17 $ $Date: 2002/08/30 22:56:58 $ $Name: $";
|
||||
#endif /* DEBUG */
|
||||
|
||||
#ifndef NSSCKT_H
|
||||
@ -118,6 +118,11 @@ NSS_EXTERN_DATA const NSSItem g_ck_class_privkey;
|
||||
} \
|
||||
}
|
||||
|
||||
#define NSS_CK_ATTRIBUTE_TO_ULONG(attrib, ulongvar) \
|
||||
if ((attrib)->ulValueLen > 0) { \
|
||||
ulongvar = *((CK_ULONG*)(attrib)->pValue); \
|
||||
}
|
||||
|
||||
/* NSS_CK_ATTRIBUTE_TO_UTF8(attrib, str)
|
||||
*
|
||||
* Convert a CK_ATTRIBUTE to a string.
|
||||
|
@ -41,7 +41,7 @@
|
||||
*/
|
||||
|
||||
#ifdef DEBUG
|
||||
static const char DEV_CVS_ID[] = "@(#) $RCSfile: dev.h,v $ $Revision: 1.30 $ $Date: 2002/08/27 23:37:56 $ $Name: $";
|
||||
static const char DEV_CVS_ID[] = "@(#) $RCSfile: dev.h,v $ $Revision: 1.31 $ $Date: 2002/08/30 22:56:58 $ $Name: $";
|
||||
#endif /* DEBUG */
|
||||
|
||||
#ifndef NSSCKT_H
|
||||
@ -755,6 +755,8 @@ nssCryptokiCRL_GetAttributes
|
||||
nssSession *sessionOpt,
|
||||
NSSArena *arenaOpt,
|
||||
NSSItem *encodingOpt,
|
||||
NSSItem * subjectOpt,
|
||||
CK_ULONG * crl_class,
|
||||
NSSUTF8 **urlOpt,
|
||||
PRBool *isKRLOpt
|
||||
);
|
||||
|
@ -32,7 +32,7 @@
|
||||
* may use your version of this file under either the MPL or the
|
||||
* GPL.
|
||||
*
|
||||
# $Id: nssinit.c,v 1.54 2002/07/18 23:08:55 jpierre%netscape.com Exp $
|
||||
# $Id: nssinit.c,v 1.55 2002/08/30 22:56:59 jpierre%netscape.com Exp $
|
||||
*/
|
||||
|
||||
#include <ctype.h>
|
||||
@ -411,6 +411,10 @@ nss_Init(const char *configdir, const char *certPrefix, const char *keyPrefix,
|
||||
return SECSuccess;
|
||||
}
|
||||
|
||||
if (SECSuccess != InitCRLCache()) {
|
||||
return SECFailure;
|
||||
}
|
||||
|
||||
flags = nss_makeFlags(readOnly,noCertDB,noModDB,forceOpen,
|
||||
pk11_password_required, optimizeSpace);
|
||||
if (flags == NULL) return rv;
|
||||
@ -536,6 +540,7 @@ NSS_Shutdown(void)
|
||||
{
|
||||
SECStatus rv;
|
||||
|
||||
ShutdownCRLCache();
|
||||
SECOID_Shutdown();
|
||||
STAN_Shutdown();
|
||||
rv = SECMOD_Shutdown();
|
||||
|
@ -32,7 +32,7 @@
|
||||
*/
|
||||
|
||||
#ifdef DEBUG
|
||||
static const char CVS_ID[] = "@(#) $RCSfile: certificate.c,v $ $Revision: 1.40 $ $Date: 2002/08/29 22:11:06 $ $Name: $";
|
||||
static const char CVS_ID[] = "@(#) $RCSfile: certificate.c,v $ $Revision: 1.41 $ $Date: 2002/08/30 22:57:03 $ $Name: $";
|
||||
#endif /* DEBUG */
|
||||
|
||||
#ifndef NSSPKI_H
|
||||
@ -1098,6 +1098,8 @@ nssCRL_Create
|
||||
NULL, /* XXX sessionOpt */
|
||||
arena,
|
||||
&rvCRL->encoding,
|
||||
NULL, /* subject */
|
||||
NULL, /* class */
|
||||
&rvCRL->url,
|
||||
&rvCRL->isKRL);
|
||||
if (status != PR_SUCCESS) {
|
||||
|
@ -32,7 +32,7 @@
|
||||
*/
|
||||
|
||||
#ifdef DEBUG
|
||||
static const char CVS_ID[] = "@(#) $RCSfile: pkibase.c,v $ $Revision: 1.13 $ $Date: 2002/08/02 17:43:36 $ $Name: $";
|
||||
static const char CVS_ID[] = "@(#) $RCSfile: pkibase.c,v $ $Revision: 1.14 $ $Date: 2002/08/30 22:57:03 $ $Name: $";
|
||||
#endif /* DEBUG */
|
||||
|
||||
#ifndef DEV_H
|
||||
@ -1157,6 +1157,8 @@ crl_getUIDFromInstance(nssCryptokiObject *instance, NSSItem *uid,
|
||||
NULL, /* XXX sessionOpt */
|
||||
arena, /* arena */
|
||||
&uid[0], /* encoding */
|
||||
NULL, /* subject */
|
||||
NULL, /* class */
|
||||
NULL, /* url */
|
||||
NULL); /* isKRL */
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user