diff options
author | jpierre%netscape.com <devnull@localhost> | 2002-08-07 03:44:12 +0000 |
---|---|---|
committer | jpierre%netscape.com <devnull@localhost> | 2002-08-07 03:44:12 +0000 |
commit | 46f54e9ae3b5c87f37e4b7214537417f37718e70 (patch) | |
tree | 9b1f8b5ee023f168d652d8c59fb09abac84d50cd | |
parent | 92021a7312ec3eca66ac3ea566f652c5a29751f2 (diff) | |
download | nss-hg-46f54e9ae3b5c87f37e4b7214537417f37718e70.tar.gz |
Implement partial CRL decoding. Fix for 149816. r=wtc . Uses new quick DER decoder
-rw-r--r-- | security/nss/lib/certdb/cert.h | 9 | ||||
-rw-r--r-- | security/nss/lib/certdb/certi.h | 50 | ||||
-rw-r--r-- | security/nss/lib/certdb/certt.h | 2 | ||||
-rw-r--r-- | security/nss/lib/certdb/crl.c | 107 | ||||
-rw-r--r-- | security/nss/lib/nss/nss.def | 1 |
5 files changed, 165 insertions, 4 deletions
diff --git a/security/nss/lib/certdb/cert.h b/security/nss/lib/certdb/cert.h index de93e960f..ba28a2713 100644 --- a/security/nss/lib/certdb/cert.h +++ b/security/nss/lib/certdb/cert.h @@ -393,7 +393,7 @@ CERT_DecodeDERCrl (PRArenaPool *arena, SECItem *derSignedCrl,int type); * same as CERT_DecodeDERCrl, plus allow options to be passed in */ -CERTSignedCrl * +extern CERTSignedCrl * CERT_DecodeDERCrlEx(PRArenaPool *narena, SECItem *derSignedCrl, int type, PRInt32 options); @@ -407,7 +407,14 @@ CERT_DecodeDERCrlEx(PRArenaPool *narena, SECItem *derSignedCrl, int type, and pass that arena in as the first argument to CERT_DecodeDERCrlEx */ #define CRL_DECODE_DONT_COPY_DER 0x00000001 +#define CRL_DECODE_SKIP_ENTRIES 0x00000002 + +/* complete the decoding of a partially decoded CRL, ie. decode the + entries. Note that entries is an optional field in a CRL, so the + "entries" pointer in CERTCrlStr may still be NULL even after + function returns SECSuccess */ +extern SECStatus CERT_CompleteCRLDecodeEntries(CERTSignedCrl* crl); /* 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. diff --git a/security/nss/lib/certdb/certi.h b/security/nss/lib/certdb/certi.h new file mode 100644 index 000000000..05bcd4c7c --- /dev/null +++ b/security/nss/lib/certdb/certi.h @@ -0,0 +1,50 @@ +/* + * The contents of this file are subject to the Mozilla Public + * License Version 1.1 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS + * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or + * implied. See the License for the specific language governing + * rights and limitations under the License. + * + * The Original Code is the Netscape security libraries. + * + * The Initial Developer of the Original Code is Netscape + * Communications Corporation. Portions created by Netscape are + * Copyright (C) 1994-2000 Netscape Communications Corporation. All + * Rights Reserved. + * + * Contributor(s): + * + * Alternatively, the contents of this file may be used under the + * terms of the GNU General Public License Version 2 or later (the + * "GPL"), in which case the provisions of the GPL are applicable + * instead of those above. If you wish to allow use of your + * version of this file only under the terms of the GPL and not to + * allow others to use your version of this file under the MPL, + * indicate your decision by deleting the provisions above and + * replace them with the notice and other provisions required by + * the GPL. If you do not delete the provisions above, a recipient + * may use your version of this file under either the MPL or the + * GPL. + */ +/* + * certt.h - public data structures for the certificate library + * + * $Id$ + */ +#ifndef _CERTI_H_ +#define _CERTI_H_ + +#include "certt.h" + +typedef struct OpaqueCRLFieldsStr OpaqueCRLFields; + +struct OpaqueCRLFieldsStr { + /* these fields are subject to change */ + PRBool partial; +}; + +#endif /* _CERTI_H_ */ diff --git a/security/nss/lib/certdb/certt.h b/security/nss/lib/certdb/certt.h index 4b87c1dfb..80c3d8fc8 100644 --- a/security/nss/lib/certdb/certt.h +++ b/security/nss/lib/certdb/certt.h @@ -384,6 +384,7 @@ struct CERTCrlStr { SECItem nextUpdate; /* optional for x.509 CRL */ CERTCrlEntry **entries; CERTCertExtension **extensions; + /* can't add anything there for binary backwards compatibility reasons */ }; struct CERTCrlKeyStr { @@ -408,6 +409,7 @@ struct CERTSignedCrlStr { SECItem *derCrl; PK11SlotInfo *slot; CK_OBJECT_HANDLE pkcs11ID; + void* opaque; /* do not touch */ }; diff --git a/security/nss/lib/certdb/crl.c b/security/nss/lib/certdb/crl.c index 38fedffe5..7613f924a 100644 --- a/security/nss/lib/certdb/crl.c +++ b/security/nss/lib/certdb/crl.c @@ -38,8 +38,10 @@ */ #include "cert.h" +#include "certi.h" #include "secder.h" #include "secasn1.h" +#include "quickder.h" #include "secoid.h" #include "certdb.h" #include "certxutl.h" @@ -178,6 +180,46 @@ const SEC_ASN1Template CERT_CrlTemplate[] = { { 0 } }; +const SEC_ASN1Template CERT_CrlTemplateNoEntries[] = { + { SEC_ASN1_SEQUENCE, + 0, NULL, sizeof(CERTCrl) }, + { SEC_ASN1_INTEGER | SEC_ASN1_OPTIONAL, offsetof (CERTCrl, version) }, + { SEC_ASN1_INLINE, + offsetof(CERTCrl,signatureAlg), + SECOID_AlgorithmIDTemplate }, + { SEC_ASN1_SAVE, + offsetof(CERTCrl,derName) }, + { SEC_ASN1_INLINE, + offsetof(CERTCrl,name), + CERT_NameTemplate }, + { SEC_ASN1_UTC_TIME, + offsetof(CERTCrl,lastUpdate) }, + { SEC_ASN1_OPTIONAL | SEC_ASN1_UTC_TIME, + offsetof(CERTCrl,nextUpdate) }, + { SEC_ASN1_OPTIONAL | SEC_ASN1_SEQUENCE_OF | + SEC_ASN1_SKIP }, /* skip entries */ + { SEC_ASN1_OPTIONAL | SEC_ASN1_CONSTRUCTED | SEC_ASN1_CONTEXT_SPECIFIC | + SEC_ASN1_EXPLICIT | 0, + offsetof(CERTCrl,extensions), + SEC_CERTExtensionsTemplate }, + { 0 } +}; + +const SEC_ASN1Template CERT_CrlTemplateEntriesOnly[] = { + { SEC_ASN1_SEQUENCE, + 0, NULL, sizeof(CERTCrl) }, + { SEC_ASN1_SKIP | SEC_ASN1_INTEGER | SEC_ASN1_OPTIONAL }, + { SEC_ASN1_SKIP }, + { SEC_ASN1_SKIP }, + { SEC_ASN1_SKIP | SEC_ASN1_UTC_TIME }, + { SEC_ASN1_SKIP | SEC_ASN1_OPTIONAL | SEC_ASN1_UTC_TIME }, + { SEC_ASN1_OPTIONAL | SEC_ASN1_SEQUENCE_OF, + offsetof(CERTCrl,entries), + cert_CrlEntryTemplate }, /* decode entries */ + { SEC_ASN1_SKIP_REST }, + { 0 } +}; + static const SEC_ASN1Template cert_SignedCrlTemplate[] = { { SEC_ASN1_SEQUENCE, 0, NULL, sizeof(CERTSignedCrl) }, @@ -194,6 +236,22 @@ static const SEC_ASN1Template cert_SignedCrlTemplate[] = { { 0 } }; +static const SEC_ASN1Template cert_SignedCrlTemplateNoEntries[] = { + { SEC_ASN1_SEQUENCE, + 0, NULL, sizeof(CERTSignedCrl) }, + { SEC_ASN1_SAVE, + offsetof(CERTSignedCrl,signatureWrap.data) }, + { SEC_ASN1_INLINE, + offsetof(CERTSignedCrl,crl), + CERT_CrlTemplateNoEntries }, + { SEC_ASN1_INLINE, + offsetof(CERTSignedCrl,signatureWrap.signatureAlgorithm), + SECOID_AlgorithmIDTemplate }, + { SEC_ASN1_BIT_STRING, + offsetof(CERTSignedCrl,signatureWrap.signature) }, + { 0 } +}; + const SEC_ASN1Template CERT_SetOfSignedCrlTemplate[] = { { SEC_ASN1_SET_OF, 0, cert_SignedCrlTemplate }, }; @@ -307,6 +365,37 @@ CERT_KeyFromDERCrl(PRArenaPool *arena, SECItem *derCrl, SECItem *key) return(SECSuccess); } +SECStatus CERT_CompleteCRLDecodeEntries(CERTSignedCrl* crl) +{ + SECStatus rv = SECSuccess; + SECItem* crldata = NULL; + OpaqueCRLFields* extended = NULL; + + if ( (!crl) || + (!(extended = (OpaqueCRLFields*) crl->opaque)) ) { + rv = SECFailure; + } else { + if (PR_FALSE == extended->partial) { + /* the CRL has already been fully decoded */ + return SECSuccess; + } + crldata = &crl->signatureWrap.data; + if (!crldata) { + rv = SECFailure; + } + } + + if (SECSuccess == rv) { + rv = SEC_QuickDERDecodeItem(crl->arena, + &crl->crl, + CERT_CrlTemplateEntriesOnly, + crldata); + if (SECSuccess == rv) + extended->partial = PR_FALSE; + } + return rv; +} + /* * take a DER CRL or KRL and decode it into a CRL structure * allow reusing the input DER without making a copy @@ -318,6 +407,8 @@ CERT_DecodeDERCrlEx(PRArenaPool *narena, SECItem *derSignedCrl, int type, PRArenaPool *arena; CERTSignedCrl *crl; SECStatus rv; + OpaqueCRLFields* extended = NULL; + const SEC_ASN1Template* crlTemplate = cert_SignedCrlTemplate; /* make a new arena */ if (narena == NULL) { @@ -334,9 +425,16 @@ CERT_DecodeDERCrlEx(PRArenaPool *narena, SECItem *derSignedCrl, int type, if ( !crl ) { goto loser; } - + crl->arena = arena; + /* allocate opaque fields */ + crl->opaque = (void*)PORT_ArenaZAlloc(arena, sizeof(OpaqueCRLFields)); + if ( !crl->opaque ) { + goto loser; + } + extended = (OpaqueCRLFields*) crl->opaque; + if (options & CRL_DECODE_DONT_COPY_DER) { crl->derCrl = derSignedCrl; /* DER is not copied . The application must keep derSignedCrl until it @@ -354,12 +452,15 @@ CERT_DecodeDERCrlEx(PRArenaPool *narena, SECItem *derSignedCrl, int type, /* Save the arena in the inner crl for CRL extensions support */ crl->crl.arena = arena; + if (options & CRL_DECODE_SKIP_ENTRIES) { + crlTemplate = cert_SignedCrlTemplateNoEntries; + extended->partial = PR_TRUE; + } /* decode the CRL info */ switch (type) { case SEC_CRL_TYPE: - rv = SEC_ASN1DecodeItem - (arena, crl, cert_SignedCrlTemplate, derSignedCrl); + rv = SEC_QuickDERDecodeItem(arena, crl, crlTemplate, crl->derCrl); if (rv != SECSuccess) break; /* check for critical extentions */ diff --git a/security/nss/lib/nss/nss.def b/security/nss/lib/nss/nss.def index 2c96ee319..0bb2419df 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_CompleteCRLDecodeEntries; CERT_DecodeDERCrlEx; CERT_CreateOCSPCertID; CERT_CreateOCSPRequest; |