diff --git a/security/nss/lib/certdb/cert.h b/security/nss/lib/certdb/cert.h index 62e49255029..dd42342c4b8 100644 --- a/security/nss/lib/certdb/cert.h +++ b/security/nss/lib/certdb/cert.h @@ -37,7 +37,7 @@ /* * cert.h - public data structures and prototypes for the certificate library * - * $Id: cert.h,v 1.53 2005-03-09 23:02:47 neil.williams%sun.com Exp $ + * $Id: cert.h,v 1.54 2006-08-07 19:09:41 julien.pierre.bugs%sun.com Exp $ */ #ifndef _CERT_H_ @@ -348,7 +348,7 @@ CERT_EncodeGeneralName(CERTGeneralName *genName, SECItem *dest, PRArenaPool *arena); extern CERTGeneralName * -CERT_DecodeGeneralName(PRArenaPool *arena, SECItem *encodedName, +CERT_DecodeGeneralName(PRArenaPool *reqArena, SECItem *encodedName, CERTGeneralName *genName); @@ -360,7 +360,8 @@ CERT_DecodeGeneralName(PRArenaPool *arena, SECItem *encodedName, ** "derCert" the DER encoded certificate ** "key" the returned key */ -extern SECStatus CERT_KeyFromDERCert(PRArenaPool *arena, SECItem *derCert, SECItem *key); +extern SECStatus CERT_KeyFromDERCert(PRArenaPool *reqArena, SECItem *derCert, + SECItem *key); extern SECStatus CERT_KeyFromIssuerAndSN(PRArenaPool *arena, SECItem *issuer, SECItem *sn, SECItem *key); @@ -1148,7 +1149,7 @@ CERTUserNotice * CERT_DecodeUserNotice(SECItem *noticeItem); extern CERTGeneralName * -CERT_DecodeAltNameExtension(PRArenaPool *arena, SECItem *EncodedAltName); +CERT_DecodeAltNameExtension(PRArenaPool *reqArena, SECItem *EncodedAltName); extern CERTNameConstraints * CERT_DecodeNameConstraintsExtension(PRArenaPool *arena, @@ -1156,7 +1157,7 @@ CERT_DecodeNameConstraintsExtension(PRArenaPool *arena, /* returns addr of a NULL termainated array of pointers to CERTAuthInfoAccess */ extern CERTAuthInfoAccess ** -CERT_DecodeAuthInfoAccessExtension(PRArenaPool *arena, +CERT_DecodeAuthInfoAccessExtension(PRArenaPool *reqArena, SECItem *encodedExtension); extern CERTPrivKeyUsagePeriod * diff --git a/security/nss/lib/certdb/certdb.c b/security/nss/lib/certdb/certdb.c index 90fd6cd5e90..366465c9cb7 100644 --- a/security/nss/lib/certdb/certdb.c +++ b/security/nss/lib/certdb/certdb.c @@ -38,7 +38,7 @@ /* * Certificate handling code * - * $Id: certdb.c,v 1.77 2006-02-16 00:06:23 julien.pierre.bugs%sun.com Exp $ + * $Id: certdb.c,v 1.78 2006-08-07 19:09:41 julien.pierre.bugs%sun.com Exp $ */ #include "nssilock.h" @@ -390,27 +390,34 @@ loser: * DER certificate. */ SECStatus -CERT_KeyFromDERCert(PRArenaPool *arena, SECItem *derCert, SECItem *key) +CERT_KeyFromDERCert(PRArenaPool *reqArena, SECItem *derCert, SECItem *key) { int rv; CERTSignedData sd; CERTCertKey certkey; + if (!reqArena) { + PORT_SetError(SEC_ERROR_INVALID_ARGS); + return SECFailure; + } + PORT_Memset(&sd, 0, sizeof(CERTSignedData)); - rv = SEC_ASN1DecodeItem(arena, &sd, CERT_SignedDataTemplate, derCert); + rv = SEC_QuickDERDecodeItem(reqArena, &sd, CERT_SignedDataTemplate, + derCert); if ( rv ) { goto loser; } PORT_Memset(&certkey, 0, sizeof(CERTCertKey)); - rv = SEC_ASN1DecodeItem(arena, &certkey, CERT_CertKeyTemplate, &sd.data); + rv = SEC_QuickDERDecodeItem(reqArena, &certkey, CERT_CertKeyTemplate, + &sd.data); if ( rv ) { goto loser; } - return(CERT_KeyFromIssuerAndSN(arena, &certkey.derIssuer, + return(CERT_KeyFromIssuerAndSN(reqArena, &certkey.derIssuer, &certkey.serialNumber, key)); loser: return(SECFailure); diff --git a/security/nss/lib/certdb/crl.c b/security/nss/lib/certdb/crl.c index 60c177e0a75..85368781fd7 100644 --- a/security/nss/lib/certdb/crl.c +++ b/security/nss/lib/certdb/crl.c @@ -37,7 +37,7 @@ /* * Moved from secpkcs7.c * - * $Id: crl.c,v 1.52 2006-05-31 01:57:55 julien.pierre.bugs%sun.com Exp $ + * $Id: crl.c,v 1.53 2006-08-07 19:09:41 julien.pierre.bugs%sun.com Exp $ */ #include "cert.h" @@ -381,23 +381,32 @@ CERT_KeyFromDERCrl(PRArenaPool *arena, SECItem *derCrl, SECItem *key) SECStatus rv; CERTSignedData sd; CERTCrlKey crlkey; + PRArenaPool* myArena; + if (!arena) { + /* arena needed for QuickDER */ + myArena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE); + } else { + myArena = arena; + } PORT_Memset (&sd, 0, sizeof (sd)); - rv = SEC_ASN1DecodeItem (arena, &sd, CERT_SignedDataTemplate, derCrl); - if (rv != SECSuccess) { - return rv; + rv = SEC_QuickDERDecodeItem (myArena, &sd, CERT_SignedDataTemplate, derCrl); + if (SECSuccess == rv) { + PORT_Memset (&crlkey, 0, sizeof (crlkey)); + rv = SEC_QuickDERDecodeItem(myArena, &crlkey, cert_CrlKeyTemplate, &sd.data); } - PORT_Memset (&crlkey, 0, sizeof (crlkey)); - rv = SEC_ASN1DecodeItem(arena, &crlkey, cert_CrlKeyTemplate, &sd.data); - if (rv != SECSuccess) { - return rv; + /* make a copy so the data doesn't point to memory inside derCrl, which + may be temporary */ + if (SECSuccess == rv) { + rv = SECITEM_CopyItem(arena, key, &crlkey.derName); } - key->len = crlkey.derName.len; - key->data = crlkey.derName.data; + if (myArena != arena) { + PORT_FreeArena(myArena, PR_FALSE); + } - return(SECSuccess); + return rv; } #define GetOpaqueCRLFields(x) ((OpaqueCRLFields*)x->opaque) diff --git a/security/nss/lib/certdb/genname.c b/security/nss/lib/certdb/genname.c index 1f6a1d06321..e903fb25d2c 100644 --- a/security/nss/lib/certdb/genname.c +++ b/security/nss/lib/certdb/genname.c @@ -413,25 +413,36 @@ loser: } CERTGeneralName * -CERT_DecodeGeneralName(PRArenaPool *arena, +CERT_DecodeGeneralName(PRArenaPool *reqArena, SECItem *encodedName, CERTGeneralName *genName) { const SEC_ASN1Template * template; CERTGeneralNameType genNameType; SECStatus rv = SECSuccess; + SECItem* newEncodedName; - PORT_Assert(arena); + if (!reqArena) { + PORT_SetError(SEC_ERROR_INVALID_ARGS); + return NULL; + } + /* make a copy for decoding so the data decoded with QuickDER doesn't + point to temporary memory */ + newEncodedName = SECITEM_ArenaDupItem(reqArena, encodedName); + if (!newEncodedName) { + return NULL; + } /* TODO: mark arena */ - genNameType = (CERTGeneralNameType)((*(encodedName->data) & 0x0f) + 1); + genNameType = (CERTGeneralNameType)((*(newEncodedName->data) & 0x0f) + 1); if (genName == NULL) { - genName = cert_NewGeneralName(arena, genNameType); + genName = cert_NewGeneralName(reqArena, genNameType); if (!genName) goto loser; } else { genName->type = genNameType; genName->l.prev = genName->l.next = &genName->l; } + switch (genNameType) { case certURI: template = CERT_URITemplate; break; case certRFC822Name: template = CERT_RFC822NameTemplate; break; @@ -445,11 +456,11 @@ CERT_DecodeGeneralName(PRArenaPool *arena, default: goto loser; } - rv = SEC_ASN1DecodeItem(arena, genName, template, encodedName); + rv = SEC_QuickDERDecodeItem(reqArena, genName, template, newEncodedName); if (rv != SECSuccess) goto loser; if (genNameType == certDirectoryName) { - rv = SEC_ASN1DecodeItem(arena, &(genName->name.directoryName), + rv = SEC_QuickDERDecodeItem(reqArena, &(genName->name.directoryName), CERT_NameTemplate, &(genName->derDirectoryName)); if (rv != SECSuccess) @@ -624,25 +635,34 @@ loser: CERTNameConstraint * -cert_DecodeNameConstraint(PRArenaPool *arena, +cert_DecodeNameConstraint(PRArenaPool *reqArena, SECItem *encodedConstraint) { CERTNameConstraint *constraint; SECStatus rv = SECSuccess; CERTGeneralName *temp; + SECItem* newEncodedConstraint; - PORT_Assert(arena); + if (!reqArena) { + PORT_SetError(SEC_ERROR_INVALID_ARGS); + return NULL; + } + newEncodedConstraint = SECITEM_ArenaDupItem(reqArena, encodedConstraint); + if (!newEncodedConstraint) { + return NULL; + } /* TODO: mark arena */ - constraint = PORT_ArenaZNew(arena, CERTNameConstraint); + constraint = PORT_ArenaZNew(reqArena, CERTNameConstraint); if (!constraint) goto loser; - rv = SEC_ASN1DecodeItem(arena, constraint, CERTNameConstraintTemplate, - encodedConstraint); + rv = SEC_QuickDERDecodeItem(reqArena, constraint, + CERTNameConstraintTemplate, + newEncodedConstraint); if (rv != SECSuccess) { goto loser; } - temp = CERT_DecodeGeneralName(arena, &(constraint->DERName), - &(constraint->name)); + temp = CERT_DecodeGeneralName(reqArena, &(constraint->DERName), + &(constraint->name)); if (temp != &(constraint->name)) { goto loser; } @@ -693,29 +713,37 @@ loser: } CERTNameConstraints * -cert_DecodeNameConstraints(PRArenaPool *arena, +cert_DecodeNameConstraints(PRArenaPool *reqArena, SECItem *encodedConstraints) { CERTNameConstraints *constraints; SECStatus rv; + SECItem* newEncodedConstraints; - PORT_Assert(arena); + if (!reqArena) { + PORT_SetError(SEC_ERROR_INVALID_ARGS); + return NULL; + } PORT_Assert(encodedConstraints); + newEncodedConstraints = SECITEM_ArenaDupItem(reqArena, encodedConstraints); + /* TODO: mark arena */ - constraints = PORT_ArenaZNew(arena, CERTNameConstraints); + constraints = PORT_ArenaZNew(reqArena, CERTNameConstraints); if (constraints == NULL) { goto loser; } - rv = SEC_ASN1DecodeItem(arena, constraints, CERTNameConstraintsTemplate, - encodedConstraints); + rv = SEC_QuickDERDecodeItem(reqArena, constraints, + CERTNameConstraintsTemplate, + newEncodedConstraints); if (rv != SECSuccess) { goto loser; } if (constraints->DERPermited != NULL && constraints->DERPermited[0] != NULL) { constraints->permited = - cert_DecodeNameConstraintSubTree(arena, constraints->DERPermited, - PR_TRUE); + cert_DecodeNameConstraintSubTree(reqArena, + constraints->DERPermited, + PR_TRUE); if (constraints->permited == NULL) { goto loser; } @@ -723,8 +751,9 @@ cert_DecodeNameConstraints(PRArenaPool *arena, if (constraints->DERExcluded != NULL && constraints->DERExcluded[0] != NULL) { constraints->excluded = - cert_DecodeNameConstraintSubTree(arena, constraints->DERExcluded, - PR_FALSE); + cert_DecodeNameConstraintSubTree(reqArena, + constraints->DERExcluded, + PR_FALSE); if (constraints->excluded == NULL) { goto loser; } @@ -1458,7 +1487,7 @@ SECStatus CERT_CompareNameSpace(CERTCertificate *cert, CERTGeneralName *namesList, CERTCertificate **certsList, - PRArenaPool *arena, + PRArenaPool *reqArena, CERTCertificate **pBadCert) { SECStatus rv; @@ -1481,7 +1510,7 @@ CERT_CompareNameSpace(CERTCertificate *cert, goto done; } /* TODO: mark arena */ - constraints = cert_DecodeNameConstraints(arena, &constraintsExtension); + constraints = cert_DecodeNameConstraints(reqArena, &constraintsExtension); PORT_Free(constraintsExtension.data); currentName = namesList; if (constraints == NULL) { /* decode failed */ @@ -1493,7 +1522,7 @@ CERT_CompareNameSpace(CERTCertificate *cert, if (constraints->excluded != NULL) { rv = CERT_GetNameConstraintByType(constraints->excluded, currentName->type, - &matchingConstraints, arena); + &matchingConstraints, reqArena); if (rv == SECSuccess && matchingConstraints != NULL) { rv = cert_CompareNameWithConstraints(currentName, matchingConstraints, @@ -1505,7 +1534,7 @@ CERT_CompareNameSpace(CERTCertificate *cert, if (constraints->permited != NULL) { rv = CERT_GetNameConstraintByType(constraints->permited, currentName->type, - &matchingConstraints, arena); + &matchingConstraints, reqArena); if (rv == SECSuccess && matchingConstraints != NULL) { rv = cert_CompareNameWithConstraints(currentName, matchingConstraints, @@ -1582,7 +1611,7 @@ CERT_GetNickName(CERTCertificate *cert, if (!found) goto loser; - rv = SEC_ASN1DecodeItem(arena, &nick, SEC_IA5StringTemplate, + rv = SEC_QuickDERDecodeItem(arena, &nick, SEC_IA5StringTemplate, ¤t->name.OthName.name); if (rv != SECSuccess) { goto loser; diff --git a/security/nss/lib/certdb/genname.h b/security/nss/lib/certdb/genname.h index 71507a2f2fe..d7ab0f10821 100644 --- a/security/nss/lib/certdb/genname.h +++ b/security/nss/lib/certdb/genname.h @@ -130,7 +130,7 @@ SECStatus CERT_CompareNameSpace(CERTCertificate *cert, CERTGeneralName *namesList, CERTCertificate **certsList, - PRArenaPool *arena, + PRArenaPool *reqArena, CERTCertificate **pBadCert); SEC_END_PROTOS diff --git a/security/nss/lib/certdb/xconst.c b/security/nss/lib/certdb/xconst.c index 94bc697ce3e..5dd3c07b88a 100644 --- a/security/nss/lib/certdb/xconst.c +++ b/security/nss/lib/certdb/xconst.c @@ -205,20 +205,32 @@ CERT_EncodeAltNameExtension(PRArenaPool *arena, CERTGeneralName *value, SECIte } CERTGeneralName * -CERT_DecodeAltNameExtension(PRArenaPool *arena, SECItem *EncodedAltName) +CERT_DecodeAltNameExtension(PRArenaPool *reqArena, SECItem *EncodedAltName) { - SECStatus rv = SECSuccess; + SECStatus rv = SECSuccess; CERTAltNameEncodedContext encodedContext; + SECItem* newEncodedAltName; + + if (!reqArena) { + PORT_SetError(SEC_ERROR_INVALID_ARGS); + return NULL; + } + + newEncodedAltName = SECITEM_ArenaDupItem(reqArena, EncodedAltName); + if (!newEncodedAltName) { + return NULL; + } encodedContext.encodedGenName = NULL; PORT_Memset(&encodedContext, 0, sizeof(CERTAltNameEncodedContext)); - rv = SEC_ASN1DecodeItem (arena, &encodedContext, CERT_GeneralNamesTemplate, - EncodedAltName); + rv = SEC_QuickDERDecodeItem (reqArena, &encodedContext, + CERT_GeneralNamesTemplate, newEncodedAltName); if (rv == SECFailure) { goto loser; } if (encodedContext.encodedGenName && encodedContext.encodedGenName[0]) - return cert_DecodeGeneralNames(arena, encodedContext.encodedGenName); + return cert_DecodeGeneralNames(reqArena, + encodedContext.encodedGenName); /* Extension contained an empty GeneralNames sequence */ /* Treat as extension not found */ PORT_SetError(SEC_ERROR_EXTENSION_NOT_FOUND); @@ -248,21 +260,32 @@ CERT_DecodeNameConstraintsExtension(PRArenaPool *arena, CERTAuthInfoAccess ** -CERT_DecodeAuthInfoAccessExtension(PRArenaPool *arena, +CERT_DecodeAuthInfoAccessExtension(PRArenaPool *reqArena, SECItem *encodedExtension) { CERTAuthInfoAccess **info = NULL; SECStatus rv; int i; + SECItem* newEncodedExtension; - rv = SEC_ASN1DecodeItem(arena, &info, CERTAuthInfoAccessTemplate, - encodedExtension); + if (!reqArena) { + PORT_SetError(SEC_ERROR_INVALID_ARGS); + return NULL; + } + + newEncodedExtension = SECITEM_ArenaDupItem(reqArena, encodedExtension); + if (!newEncodedExtension) { + return NULL; + } + + rv = SEC_QuickDERDecodeItem(reqArena, &info, CERTAuthInfoAccessTemplate, + newEncodedExtension); if (rv != SECSuccess || info == NULL) { return NULL; } for (i = 0; info[i] != NULL; i++) { - info[i]->location = CERT_DecodeGeneralName(arena, + info[i]->location = CERT_DecodeGeneralName(reqArena, &(info[i]->derLocation), NULL); } diff --git a/security/nss/lib/certhigh/ocsp.c b/security/nss/lib/certhigh/ocsp.c index 36cb47c647d..7b54094af22 100644 --- a/security/nss/lib/certhigh/ocsp.c +++ b/security/nss/lib/certhigh/ocsp.c @@ -38,7 +38,7 @@ * Implementation of OCSP services, for both client and server. * (XXX, really, mostly just for client right now, but intended to do both.) * - * $Id: ocsp.c,v 1.26 2006-07-19 00:08:52 nelson%bolyard.com Exp $ + * $Id: ocsp.c,v 1.27 2006-08-07 19:09:41 julien.pierre.bugs%sun.com Exp $ */ #include "prerror.h" @@ -1280,7 +1280,7 @@ ocsp_CertStatusTypeByTag(int derTag) * have allocated; it expects its caller to do that. */ static SECStatus -ocsp_FinishDecodingSingleResponses(PRArenaPool *arena, +ocsp_FinishDecodingSingleResponses(PRArenaPool *reqArena, CERTOCSPSingleResponse **responses) { ocspCertStatus *certStatus; @@ -1290,10 +1290,16 @@ ocsp_FinishDecodingSingleResponses(PRArenaPool *arena, int i; SECStatus rv = SECFailure; + if (!reqArena) { + PORT_SetError(SEC_ERROR_INVALID_ARGS); + return NULL; + } + if (responses == NULL) /* nothing to do */ return SECSuccess; for (i = 0; responses[i] != NULL; i++) { + SECItem* newStatus; /* * The following assert points out internal errors (problems in * the template definitions or in the ASN.1 decoder itself, etc.). @@ -1304,12 +1310,16 @@ ocsp_FinishDecodingSingleResponses(PRArenaPool *arena, certStatusType = ocsp_CertStatusTypeByTag(derTag); certStatusTemplate = ocsp_CertStatusTemplateByType(certStatusType); - certStatus = PORT_ArenaZAlloc(arena, sizeof(ocspCertStatus)); + certStatus = PORT_ArenaZAlloc(reqArena, sizeof(ocspCertStatus)); if (certStatus == NULL) { goto loser; } - rv = SEC_ASN1DecodeItem(arena, certStatus, certStatusTemplate, - &responses[i]->derCertStatus); + newStatus = SECITEM_ArenaDupItem(reqArena, &responses[i]->derCertStatus); + if (!newStatus) { + goto loser; + } + rv = SEC_QuickDERDecodeItem(reqArena, certStatus, certStatusTemplate, + newStatus); if (rv != SECSuccess) { if (PORT_GetError() == SEC_ERROR_BAD_DER) PORT_SetError(SEC_ERROR_OCSP_MALFORMED_RESPONSE);