summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorjpierre%netscape.com <devnull@localhost>2002-08-07 03:44:12 +0000
committerjpierre%netscape.com <devnull@localhost>2002-08-07 03:44:12 +0000
commit46f54e9ae3b5c87f37e4b7214537417f37718e70 (patch)
tree9b1f8b5ee023f168d652d8c59fb09abac84d50cd
parent92021a7312ec3eca66ac3ea566f652c5a29751f2 (diff)
downloadnss-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.h9
-rw-r--r--security/nss/lib/certdb/certi.h50
-rw-r--r--security/nss/lib/certdb/certt.h2
-rw-r--r--security/nss/lib/certdb/crl.c107
-rw-r--r--security/nss/lib/nss/nss.def1
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;