diff --git a/security/nss/lib/certdb/polcyxtn.c b/security/nss/lib/certdb/polcyxtn.c index da2097ffe15..d19cb862e2e 100644 --- a/security/nss/lib/certdb/polcyxtn.c +++ b/security/nss/lib/certdb/polcyxtn.c @@ -34,7 +34,7 @@ /* * Support for various policy related extensions * - * $Id: polcyxtn.c,v 1.2 2002-08-24 00:46:35 jpierre%netscape.com Exp $ + * $Id: polcyxtn.c,v 1.3 2002-08-31 00:37:29 jpierre%netscape.com Exp $ */ #include "seccomon.h" @@ -138,6 +138,7 @@ CERT_DecodeCertificatePoliciesExtension(SECItem *extnValue) CERTCertificatePolicies *policies; CERTPolicyInfo **policyInfos, *policyInfo; CERTPolicyQualifier **policyQualifiers, *policyQualifier; + SECItem newExtnValue; /* make a new arena */ arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE); @@ -156,9 +157,16 @@ CERT_DecodeCertificatePoliciesExtension(SECItem *extnValue) policies->arena = arena; + /* copy the DER into the arena, since Quick DER returns data that points + into the DER input, which may get freed by the caller */ + rv = SECITEM_CopyItem(arena, &newExtnValue, extnValue); + if ( rv != SECSuccess ) { + goto loser; + } + /* decode the policy info */ rv = SEC_QuickDERDecodeItem(arena, policies, CERT_CertificatePoliciesTemplate, - extnValue); + &newExtnValue); if ( rv != SECSuccess ) { goto loser; @@ -205,6 +213,7 @@ CERT_DecodeUserNotice(SECItem *noticeItem) PRArenaPool *arena = NULL; SECStatus rv; CERTUserNotice *userNotice; + SECItem newNoticeItem; /* make a new arena */ arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE); @@ -223,9 +232,16 @@ CERT_DecodeUserNotice(SECItem *noticeItem) userNotice->arena = arena; + /* copy the DER into the arena, since Quick DER returns data that points + into the DER input, which may get freed by the caller */ + rv = SECITEM_CopyItem(arena, &newNoticeItem, noticeItem); + if ( rv != SECSuccess ) { + goto loser; + } + /* decode the user notice */ rv = SEC_QuickDERDecodeItem(arena, userNotice, CERT_UserNoticeTemplate, - noticeItem); + &newNoticeItem); if ( rv != SECSuccess ) { goto loser; @@ -240,7 +256,7 @@ CERT_DecodeUserNotice(SECItem *noticeItem) newBytes = SEC_ASN1LengthLength(userNotice->derNoticeReference.len)+1; tmpbuf.len = newBytes + userNotice->derNoticeReference.len; - tmpbuf.data = PORT_ZAlloc(tmpbuf.len); + tmpbuf.data = PORT_ArenaZAlloc(arena, tmpbuf.len); if (tmpbuf.data == NULL) { goto loser; } @@ -449,6 +465,7 @@ CERT_DecodeOidSequence(SECItem *seqItem) PRArenaPool *arena = NULL; SECStatus rv; CERTOidSequence *oidSeq; + SECItem newSeqItem; /* make a new arena */ arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE); @@ -467,8 +484,15 @@ CERT_DecodeOidSequence(SECItem *seqItem) oidSeq->arena = arena; + /* copy the DER into the arena, since Quick DER returns data that points + into the DER input, which may get freed by the caller */ + rv = SECITEM_CopyItem(arena, &newSeqItem, seqItem); + if ( rv != SECSuccess ) { + goto loser; + } + /* decode the user notice */ - rv = SEC_QuickDERDecodeItem(arena, oidSeq, CERT_OidSeqTemplate, seqItem); + rv = SEC_QuickDERDecodeItem(arena, oidSeq, CERT_OidSeqTemplate, &newSeqItem); if ( rv != SECSuccess ) { goto loser; diff --git a/security/nss/lib/certdb/xauthkid.c b/security/nss/lib/certdb/xauthkid.c index 6e84f579d18..089d16f14ce 100644 --- a/security/nss/lib/certdb/xauthkid.c +++ b/security/nss/lib/certdb/xauthkid.c @@ -110,6 +110,7 @@ CERT_DecodeAuthKeyID (PRArenaPool *arena, SECItem *encodedValue) CERTAuthKeyID * value = NULL; SECStatus rv = SECFailure; void * mark; + SECItem newEncodedValue; PORT_Assert (arena); @@ -119,8 +120,15 @@ CERT_DecodeAuthKeyID (PRArenaPool *arena, SECItem *encodedValue) value->DERAuthCertIssuer = NULL; if (value == NULL) break; - rv = SEC_QuickDERDecodeItem - (arena, value, CERTAuthKeyIDTemplate, encodedValue); + /* copy the DER into the arena, since Quick DER returns data that points + into the DER input, which may get freed by the caller */ + rv = SECITEM_CopyItem(arena, &newEncodedValue, encodedValue); + if ( rv != SECSuccess ) { + break; + } + + rv = SEC_QuickDERDecodeItem + (arena, value, CERTAuthKeyIDTemplate, &newEncodedValue); if (rv != SECSuccess) break; diff --git a/security/nss/lib/certhigh/ocsp.c b/security/nss/lib/certhigh/ocsp.c index 770aaf1edbc..144aee5fb1d 100644 --- a/security/nss/lib/certhigh/ocsp.c +++ b/security/nss/lib/certhigh/ocsp.c @@ -35,7 +35,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.12 2002-08-24 00:47:30 jpierre%netscape.com Exp $ + * $Id: ocsp.c,v 1.13 2002-08-31 00:37:33 jpierre%netscape.com Exp $ */ #include "prerror.h" @@ -559,7 +559,7 @@ CERT_DecodeOCSPRequest(SECItem *src) SECStatus rv = SECFailure; CERTOCSPRequest *dest = NULL; int i; - + SECItem newSrc; arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE); if (arena == NULL) { @@ -572,7 +572,14 @@ CERT_DecodeOCSPRequest(SECItem *src) } dest->arena = arena; - rv = SEC_QuickDERDecodeItem(arena, dest, ocsp_OCSPRequestTemplate, src); + /* copy the DER into the arena, since Quick DER returns data that points + into the DER input, which may get freed by the caller */ + rv = SECITEM_CopyItem(arena, &newSrc, src); + if ( rv != SECSuccess ) { + goto loser; + } + + rv = SEC_QuickDERDecodeItem(arena, dest, ocsp_OCSPRequestTemplate, &newSrc); if (rv != SECSuccess) { if (PORT_GetError() == SEC_ERROR_BAD_DER) PORT_SetError(SEC_ERROR_OCSP_MALFORMED_REQUEST); @@ -1296,6 +1303,7 @@ ocsp_DecodeBasicOCSPResponse(PRArenaPool *arena, SECItem *src) const SEC_ASN1Template *responderIDTemplate; int derTag; SECStatus rv; + SECItem newsrc; mark = PORT_ArenaMark(arena); @@ -1304,8 +1312,15 @@ ocsp_DecodeBasicOCSPResponse(PRArenaPool *arena, SECItem *src) goto loser; } + /* copy the DER into the arena, since Quick DER returns data that points + into the DER input, which may get freed by the caller */ + rv = SECITEM_CopyItem(arena, &newsrc, src); + if ( rv != SECSuccess ) { + goto loser; + } + rv = SEC_QuickDERDecodeItem(arena, basicResponse, - ocsp_BasicOCSPResponseTemplate, src); + ocsp_BasicOCSPResponseTemplate, &newsrc); if (rv != SECSuccess) { if (PORT_GetError() == SEC_ERROR_BAD_DER) PORT_SetError(SEC_ERROR_OCSP_MALFORMED_RESPONSE); @@ -1333,6 +1348,7 @@ ocsp_DecodeBasicOCSPResponse(PRArenaPool *arena, SECItem *src) if (responderID == NULL) { goto loser; } + rv = SEC_QuickDERDecodeItem(arena, responderID, responderIDTemplate, &responseData->derResponderID); if (rv != SECSuccess) { @@ -1421,6 +1437,7 @@ CERT_DecodeOCSPResponse(SECItem *src) CERTOCSPResponse *response = NULL; SECStatus rv = SECFailure; ocspResponseStatus sv; + SECItem newSrc; arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE); if (arena == NULL) { @@ -1433,7 +1450,14 @@ CERT_DecodeOCSPResponse(SECItem *src) } response->arena = arena; - rv = SEC_QuickDERDecodeItem(arena, response, ocsp_OCSPResponseTemplate, src); + /* copy the DER into the arena, since Quick DER returns data that points + into the DER input, which may get freed by the caller */ + rv = SECITEM_CopyItem(arena, &newSrc, src); + if ( rv != SECSuccess ) { + goto loser; + } + + rv = SEC_QuickDERDecodeItem(arena, response, ocsp_OCSPResponseTemplate, &newSrc); if (rv != SECSuccess) { if (PORT_GetError() == SEC_ERROR_BAD_DER) PORT_SetError(SEC_ERROR_OCSP_MALFORMED_RESPONSE); diff --git a/security/nss/lib/certhigh/xcrldist.c b/security/nss/lib/certhigh/xcrldist.c index 6f8a014f09a..d428d73c853 100644 --- a/security/nss/lib/certhigh/xcrldist.c +++ b/security/nss/lib/certhigh/xcrldist.c @@ -146,6 +146,7 @@ CERT_DecodeCRLDistributionPoints (PRArenaPool *arena, SECItem *encodedValue) CERTCrlDistributionPoints *value = NULL; CRLDistributionPoint **pointList, *point; SECStatus rv; + SECItem newEncodedValue; PORT_Assert (arena); do { @@ -154,10 +155,17 @@ CERT_DecodeCRLDistributionPoints (PRArenaPool *arena, SECItem *encodedValue) rv = SECFailure; break; } - + + /* copy the DER into the arena, since Quick DER returns data that points + into the DER input, which may get freed by the caller */ + rv = SECITEM_CopyItem(arena, &newEncodedValue, encodedValue); + if ( rv != SECSuccess ) { + break; + } + rv = SEC_QuickDERDecodeItem (arena, &value->distPoints, CERTCRLDistributionPointsTemplate, - encodedValue); + &newEncodedValue); if (rv != SECSuccess) break; diff --git a/security/nss/lib/cryptohi/seckey.c b/security/nss/lib/cryptohi/seckey.c index 7f0b4025aaf..f6c2f0f7ce3 100644 --- a/security/nss/lib/cryptohi/seckey.c +++ b/security/nss/lib/cryptohi/seckey.c @@ -891,7 +891,7 @@ static SECKEYPublicKey * seckey_ExtractPublicKey(CERTSubjectPublicKeyInfo *spki) { SECKEYPublicKey *pubk; - SECItem os; + SECItem os, newOs, newParms; SECStatus rv; PRArenaPool *arena; SECOidTag tag; @@ -916,12 +916,17 @@ seckey_ExtractPublicKey(CERTSubjectPublicKeyInfo *spki) DER_ConvertBitString (&os); tag = SECOID_GetAlgorithmTag(&spki->algorithm); + + /* copy the DER into the arena, since Quick DER returns data that points + into the DER input, which may get freed by the caller */ + rv = SECITEM_CopyItem(arena, &newOs, &os); + if ( rv == SECSuccess ) switch ( tag ) { case SEC_OID_X500_RSA_ENCRYPTION: case SEC_OID_PKCS1_RSA_ENCRYPTION: pubk->keyType = rsaKey; - prepare_rsa_pub_key_for_asn1(pubk); - rv = SEC_QuickDERDecodeItem(arena, pubk, SECKEY_RSAPublicKeyTemplate, &os); + prepare_rsa_pub_key_for_asn1(pubk); + rv = SEC_QuickDERDecodeItem(arena, pubk, SECKEY_RSAPublicKeyTemplate, &newOs); if (rv == SECSuccess) return pubk; break; @@ -929,7 +934,7 @@ seckey_ExtractPublicKey(CERTSubjectPublicKeyInfo *spki) case SEC_OID_SDN702_DSA_SIGNATURE: pubk->keyType = dsaKey; prepare_dsa_pub_key_for_asn1(pubk); - rv = SEC_QuickDERDecodeItem(arena, pubk, SECKEY_DSAPublicKeyTemplate, &os); + rv = SEC_QuickDERDecodeItem(arena, pubk, SECKEY_DSAPublicKeyTemplate, &newOs); if (rv != SECSuccess) break; rv = SECKEY_DSADecodePQG(arena, pubk, @@ -940,11 +945,17 @@ seckey_ExtractPublicKey(CERTSubjectPublicKeyInfo *spki) case SEC_OID_X942_DIFFIE_HELMAN_KEY: pubk->keyType = dhKey; prepare_dh_pub_key_for_asn1(pubk); - rv = SEC_QuickDERDecodeItem(arena, pubk, SECKEY_DHPublicKeyTemplate, &os); + rv = SEC_QuickDERDecodeItem(arena, pubk, SECKEY_DHPublicKeyTemplate, &newOs); if (rv != SECSuccess) break; + /* copy the DER into the arena, since Quick DER returns data that points + into the DER input, which may get freed by the caller */ + rv = SECITEM_CopyItem(arena, &newParms, &spki->algorithm.parameters); + if ( rv != SECSuccess ) + break; + rv = SEC_QuickDERDecodeItem(arena, pubk, SECKEY_DHParamKeyTemplate, - &spki->algorithm.parameters); + &newParms); if (rv == SECSuccess) return pubk; break; @@ -953,7 +964,7 @@ seckey_ExtractPublicKey(CERTSubjectPublicKeyInfo *spki) case SEC_OID_MISSI_DSS_OLD: case SEC_OID_MISSI_DSS: pubk->keyType = fortezzaKey; - rv = SECKEY_FortezzaDecodeCertKey(arena, pubk, &os, + rv = SECKEY_FortezzaDecodeCertKey(arena, pubk, &newOs, &spki->algorithm.parameters); if (rv == SECSuccess) return pubk; @@ -964,12 +975,17 @@ seckey_ExtractPublicKey(CERTSubjectPublicKeyInfo *spki) prepare_kea_pub_key_for_asn1(pubk); rv = SEC_QuickDERDecodeItem(arena, pubk, - SECKEY_KEAPublicKeyTemplate, &os); + SECKEY_KEAPublicKeyTemplate, &newOs); if (rv != SECSuccess) break; + /* copy the DER into the arena, since Quick DER returns data that points + into the DER input, which may get freed by the caller */ + rv = SECITEM_CopyItem(arena, &newParms, &spki->algorithm.parameters); + if ( rv != SECSuccess ) + break; rv = SEC_QuickDERDecodeItem(arena, pubk, SECKEY_KEAParamsTemplate, - &spki->algorithm.parameters); + &newParms); if (rv == SECSuccess) return pubk; @@ -979,11 +995,17 @@ seckey_ExtractPublicKey(CERTSubjectPublicKeyInfo *spki) case SEC_OID_MISSI_ALT_KEA: pubk->keyType = keaKey; - rv = SECITEM_CopyItem(arena,&pubk->u.kea.publicValue,&os); + rv = SECITEM_CopyItem(arena,&pubk->u.kea.publicValue,&newOs); if (rv != SECSuccess) break; + /* copy the DER into the arena, since Quick DER returns data that points + into the DER input, which may get freed by the caller */ + rv = SECITEM_CopyItem(arena, &newParms, &spki->algorithm.parameters); + if ( rv != SECSuccess ) + break; + rv = SEC_QuickDERDecodeItem(arena, pubk, SECKEY_KEAParamsTemplate, - &spki->algorithm.parameters); + &newParms); if (rv == SECSuccess) return pubk; @@ -1430,6 +1452,7 @@ SECKEY_DecodeDERPublicKey(SECItem *pubkder) PRArenaPool *arena; SECKEYPublicKey *pubk; SECStatus rv; + SECItem newPubkder; arena = PORT_NewArena (DER_DEFAULT_CHUNKSIZE); if (arena == NULL) { @@ -1443,8 +1466,13 @@ SECKEY_DecodeDERPublicKey(SECItem *pubkder) pubk->pkcs11Slot = NULL; pubk->pkcs11ID = 0; prepare_rsa_pub_key_for_asn1(pubk); - rv = SEC_QuickDERDecodeItem(arena, pubk, SECKEY_RSAPublicKeyTemplate, - pubkder); + /* copy the DER into the arena, since Quick DER returns data that points + into the DER input, which may get freed by the caller */ + rv = SECITEM_CopyItem(arena, &newPubkder, pubkder); + if ( rv == SECSuccess ) { + rv = SEC_QuickDERDecodeItem(arena, pubk, SECKEY_RSAPublicKeyTemplate, + &newPubkder); + } if (rv == SECSuccess) return pubk; SECKEY_DestroyPublicKey (pubk); @@ -1505,6 +1533,7 @@ SECKEY_DecodeDERSubjectPublicKeyInfo(SECItem *spkider) PRArenaPool *arena; CERTSubjectPublicKeyInfo *spki; SECStatus rv; + SECItem newSpkider; arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE); if (arena == NULL) { @@ -1516,8 +1545,14 @@ SECKEY_DecodeDERSubjectPublicKeyInfo(SECItem *spkider) PORT_ArenaZAlloc(arena, sizeof (CERTSubjectPublicKeyInfo)); if (spki != NULL) { spki->arena = arena; - rv = SEC_QuickDERDecodeItem(arena,spki, - CERT_SubjectPublicKeyInfoTemplate,spkider); + + /* copy the DER into the arena, since Quick DER returns data that points + into the DER input, which may get freed by the caller */ + rv = SECITEM_CopyItem(arena, &newSpkider, spkider); + if ( rv == SECSuccess ) { + rv = SEC_QuickDERDecodeItem(arena,spki, + CERT_SubjectPublicKeyInfoTemplate, &newSpkider); + } if (rv == SECSuccess) return spki; SECKEY_DestroySubjectPublicKeyInfo(spki); diff --git a/security/nss/lib/fortcrypt/swfort/swfparse.c b/security/nss/lib/fortcrypt/swfort/swfparse.c index 92b5bae2dcd..7e6d14032eb 100644 --- a/security/nss/lib/fortcrypt/swfort/swfparse.c +++ b/security/nss/lib/fortcrypt/swfort/swfparse.c @@ -320,6 +320,7 @@ FORT_GetSWFile(SECItem *initBits) PRArenaPool *arena = NULL; SECStatus rv; int i, count; + SECItem newInitBits; /* get the local arena... be sure to free this at the end */ @@ -331,8 +332,15 @@ FORT_GetSWFile(SECItem *initBits) PORT_ArenaZAlloc(arena,sizeof(FORTSignedSWFile)); if (sw_init_file == NULL) goto fail; + /* copy the DER into the arena, since Quick DER returns data that points + into the DER input, which may get freed by the caller */ + rv = SECITEM_CopyItem(arena, &newInitBits, &initBits); + if ( rv != SECSuccess ) { + goto fail; + } + /* ANS1 decode the complete init file */ - rv = SEC_QuickDERDecodeItem(arena,sw_init_file,fortSwFortezzaInitFile,initBits); + rv = SEC_QuickDERDecodeItem(arena,sw_init_file,fortSwFortezzaInitFile,&newInitBits); if (rv != SECSuccess) { goto fail; } diff --git a/security/nss/lib/softoken/lowcert.c b/security/nss/lib/softoken/lowcert.c index 27fe57fdb2d..51745ece320 100644 --- a/security/nss/lib/softoken/lowcert.c +++ b/security/nss/lib/softoken/lowcert.c @@ -34,7 +34,7 @@ /* * Certificate handling code * - * $Id: lowcert.c,v 1.12 2002-08-24 00:49:11 jpierre%netscape.com Exp $ + * $Id: lowcert.c,v 1.13 2002-08-31 00:37:46 jpierre%netscape.com Exp $ */ #include "seccomon.h" @@ -496,6 +496,7 @@ nsslowcert_ExtractPublicKey(NSSLOWCERTCertificate *cert) SECStatus rv; PRArenaPool *arena; SECOidTag tag; + SECItem newDerSubjKeyInfo; arena = PORT_NewArena (DER_DEFAULT_CHUNKSIZE); if (arena == NULL) @@ -511,9 +512,17 @@ nsslowcert_ExtractPublicKey(NSSLOWCERTCertificate *cert) pubk->arena = arena; PORT_Memset(&spki,0,sizeof(spki)); + /* copy the DER into the arena, since Quick DER returns data that points + into the DER input, which may get freed by the caller */ + rv = SECITEM_CopyItem(arena, &newDerSubjKeyInfo, &cert->derSubjKeyInfo); + if ( rv != SECSuccess ) { + PORT_FreeArena (arena, PR_FALSE); + return NULL; + } + /* we haven't bothered decoding the spki struct yet, do it now */ rv = SEC_QuickDERDecodeItem(arena, &spki, - nsslowcert_SubjectPublicKeyInfoTemplate, &cert->derSubjKeyInfo); + nsslowcert_SubjectPublicKeyInfoTemplate, &newDerSubjKeyInfo); if (rv != SECSuccess) { PORT_FreeArena (arena, PR_FALSE); return NULL; diff --git a/security/nss/lib/softoken/pkcs11c.c b/security/nss/lib/softoken/pkcs11c.c index 7b706d5f6c5..6043fa53028 100644 --- a/security/nss/lib/softoken/pkcs11c.c +++ b/security/nss/lib/softoken/pkcs11c.c @@ -3655,6 +3655,7 @@ pk11_unwrapPrivateKey(PK11Object *key, SECItem *bpki) NSSLOWKEYPrivateKeyInfo *pki = NULL; SECItem *ck_id = NULL; CK_RV crv = CKR_KEY_TYPE_INCONSISTENT; + SECItem newBpki; arena = PORT_NewArena(2048); if(!arena) { @@ -3668,7 +3669,15 @@ pk11_unwrapPrivateKey(PK11Object *key, SECItem *bpki) return SECFailure; } - if(SEC_QuickDERDecodeItem(arena, pki, nsslowkey_PrivateKeyInfoTemplate, bpki) + /* copy the DER into the arena, since Quick DER returns data that points + into the DER input, which may get freed by the caller */ + rv = SECITEM_CopyItem(arena, &newBpki, bpki); + if ( rv != SECSuccess ) { + PORT_FreeArena (arena, PR_FALSE); + return SECFailure; + } + + if(SEC_QuickDERDecodeItem(arena, pki, nsslowkey_PrivateKeyInfoTemplate, &newBpki) != SECSuccess) { PORT_FreeArena(arena, PR_FALSE); return SECFailure; diff --git a/security/nss/lib/util/quickder.c b/security/nss/lib/util/quickder.c index d7758acb4a0..bd65cdf3668 100644 --- a/security/nss/lib/util/quickder.c +++ b/security/nss/lib/util/quickder.c @@ -887,17 +887,7 @@ SECStatus SEC_QuickDERDecodeItem(PRArenaPool* arena, void* dest, rv = SECFailure; } - /* temporarily copy the item until a new patch for 160805 is made */ - if (SECSuccess != SECITEM_CopyItem(arena, &newsrc, src)) - { - rv = SECFailure; - } -#if 0 - /* - we don't really want to copy the item. - */ newsrc = *src; -#endif if (SECSuccess == rv) {