From 08b53102230b3177f0efb6c4c6560f2a5e21ba4e Mon Sep 17 00:00:00 2001 From: "jpierre%netscape.com" Date: Wed, 7 Aug 2002 03:44:12 +0000 Subject: [PATCH] Implement partial CRL decoding. Fix for 149816. r=wtc . Uses new quick DER decoder git-svn-id: svn://10.0.0.236/trunk@126597 18797224-902f-48f8-a5cc-f745e15eee43 --- mozilla/security/nss/lib/certdb/cert.h | 11 ++- mozilla/security/nss/lib/certdb/certi.h | 50 +++++++++++ mozilla/security/nss/lib/certdb/certt.h | 4 +- mozilla/security/nss/lib/certdb/crl.c | 109 +++++++++++++++++++++++- mozilla/security/nss/lib/nss/nss.def | 1 + 5 files changed, 168 insertions(+), 7 deletions(-) create mode 100644 mozilla/security/nss/lib/certdb/certi.h diff --git a/mozilla/security/nss/lib/certdb/cert.h b/mozilla/security/nss/lib/certdb/cert.h index 4a9000b3c6d..98ee3d9c73d 100644 --- a/mozilla/security/nss/lib/certdb/cert.h +++ b/mozilla/security/nss/lib/certdb/cert.h @@ -34,7 +34,7 @@ /* * cert.h - public data structures and prototypes for the certificate library * - * $Id: cert.h,v 1.19 2002-08-02 17:51:17 relyea%netscape.com Exp $ + * $Id: cert.h,v 1.20 2002-08-07 03:42:45 jpierre%netscape.com Exp $ */ #ifndef _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/mozilla/security/nss/lib/certdb/certi.h b/mozilla/security/nss/lib/certdb/certi.h new file mode 100644 index 00000000000..67d78f9d866 --- /dev/null +++ b/mozilla/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: certi.h,v 1.1 2002-08-07 03:42:46 jpierre%netscape.com Exp $ + */ +#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/mozilla/security/nss/lib/certdb/certt.h b/mozilla/security/nss/lib/certdb/certt.h index 7b03c4274d5..abd1d46d22b 100644 --- a/mozilla/security/nss/lib/certdb/certt.h +++ b/mozilla/security/nss/lib/certdb/certt.h @@ -33,7 +33,7 @@ /* * certt.h - public data structures for the certificate library * - * $Id: certt.h,v 1.19 2002-07-04 03:09:29 jpierre%netscape.com Exp $ + * $Id: certt.h,v 1.20 2002-08-07 03:42:45 jpierre%netscape.com Exp $ */ #ifndef _CERTT_H_ #define _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/mozilla/security/nss/lib/certdb/crl.c b/mozilla/security/nss/lib/certdb/crl.c index fe58b51036c..8989c0d9518 100644 --- a/mozilla/security/nss/lib/certdb/crl.c +++ b/mozilla/security/nss/lib/certdb/crl.c @@ -34,12 +34,14 @@ /* * Moved from secpkcs7.c * - * $Id: crl.c,v 1.12 2002-07-19 00:59:23 jpierre%netscape.com Exp $ + * $Id: crl.c,v 1.13 2002-08-07 03:42:45 jpierre%netscape.com Exp $ */ #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/mozilla/security/nss/lib/nss/nss.def b/mozilla/security/nss/lib/nss/nss.def index 2c96ee31972..0bb2419df16 100644 --- a/mozilla/security/nss/lib/nss/nss.def +++ b/mozilla/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;