Fix for 160805 . Make a copy of items into the arena before calling SEC_QuickDERDecodeItem where needed
authorjpierre%netscape.com
Sat, 31 Aug 2002 00:37:52 +0000
changeset 3523 8d71d58990fde33986c57b6f4c12746468c4b67b
parent 3522 0ed4d96eafbf4ebae38fdf1bcb6cde5e4c3812bb
child 3524 34b69743fed093792805f20eff188c7f3c49b510
push idunknown
push userunknown
push dateunknown
bugs160805
Fix for 160805 . Make a copy of items into the arena before calling SEC_QuickDERDecodeItem where needed
security/nss/lib/certdb/polcyxtn.c
security/nss/lib/certdb/xauthkid.c
security/nss/lib/certhigh/ocsp.c
security/nss/lib/certhigh/xcrldist.c
security/nss/lib/cryptohi/seckey.c
security/nss/lib/fortcrypt/swfort/swfparse.c
security/nss/lib/softoken/lowcert.c
security/nss/lib/softoken/pkcs11c.c
security/nss/lib/util/quickder.c
--- a/security/nss/lib/certdb/polcyxtn.c
+++ b/security/nss/lib/certdb/polcyxtn.c
@@ -133,16 +133,17 @@ breakLines(char *string)
 CERTCertificatePolicies *
 CERT_DecodeCertificatePoliciesExtension(SECItem *extnValue)
 {
     PRArenaPool *arena = NULL;
     SECStatus rv;
     CERTCertificatePolicies *policies;
     CERTPolicyInfo **policyInfos, *policyInfo;
     CERTPolicyQualifier **policyQualifiers, *policyQualifier;
+    SECItem newExtnValue;
     
     /* make a new arena */
     arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
     
     if ( !arena ) {
 	goto loser;
     }
 
@@ -151,19 +152,26 @@ CERT_DecodeCertificatePoliciesExtension(
 	PORT_ArenaZAlloc(arena, sizeof(CERTCertificatePolicies));
     
     if ( policies == NULL ) {
 	goto loser;
     }
     
     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;
     }
 
     /* initialize the oid tags */
     policyInfos = policies->policyInfos;
     while (*policyInfos != NULL ) {
@@ -200,16 +208,17 @@ CERT_DestroyCertificatePoliciesExtension
 
 
 CERTUserNotice *
 CERT_DecodeUserNotice(SECItem *noticeItem)
 {
     PRArenaPool *arena = NULL;
     SECStatus rv;
     CERTUserNotice *userNotice;
+    SECItem newNoticeItem;
     
     /* make a new arena */
     arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
     
     if ( !arena ) {
 	goto loser;
     }
 
@@ -218,34 +227,41 @@ CERT_DecodeUserNotice(SECItem *noticeIte
 						    sizeof(CERTUserNotice));
     
     if ( userNotice == NULL ) {
 	goto loser;
     }
     
     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;
     }
 
     if (userNotice->derNoticeReference.data != NULL) {
 	/* sigh, the asn1 parser stripped the sequence encoding, re add it
 	 * before we decode.
 	 */
 	SECItem tmpbuf;
 	int	newBytes;
 
 	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;
 	}
 	tmpbuf.data[0] = SEC_ASN1_SEQUENCE | SEC_ASN1_CONSTRUCTED;
 	SEC_ASN1EncodeLength(&tmpbuf.data[1],userNotice->derNoticeReference.len);
 	PORT_Memcpy(&tmpbuf.data[newBytes],userNotice->derNoticeReference.data,
 				userNotice->derNoticeReference.len);
 
@@ -444,16 +460,17 @@ const SEC_ASN1Template CERT_OidSeqTempla
 };
 
 CERTOidSequence *
 CERT_DecodeOidSequence(SECItem *seqItem)
 {
     PRArenaPool *arena = NULL;
     SECStatus rv;
     CERTOidSequence *oidSeq;
+    SECItem newSeqItem;
     
     /* make a new arena */
     arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
     
     if ( !arena ) {
 	goto loser;
     }
 
@@ -462,18 +479,25 @@ CERT_DecodeOidSequence(SECItem *seqItem)
 						 sizeof(CERTOidSequence));
     
     if ( oidSeq == NULL ) {
 	goto loser;
     }
     
     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;
     }
 
     return(oidSeq);
     
 loser:
--- a/security/nss/lib/certdb/xauthkid.c
+++ b/security/nss/lib/certdb/xauthkid.c
@@ -105,27 +105,35 @@ SECStatus CERT_EncodeAuthKeyID (PRArenaP
 }
 
 CERTAuthKeyID *
 CERT_DecodeAuthKeyID (PRArenaPool *arena, SECItem *encodedValue)
 {
     CERTAuthKeyID * value = NULL;
     SECStatus       rv    = SECFailure;
     void *          mark;
+    SECItem         newEncodedValue;
 
     PORT_Assert (arena);
    
     do {
 	mark = PORT_ArenaMark (arena);
         value = (CERTAuthKeyID*)PORT_ArenaZAlloc (arena, sizeof (*value));
 	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;
 
         value->authCertIssuer = cert_DecodeGeneralNames (arena, value->DERAuthCertIssuer);
 	if (value->authCertIssuer == NULL)
 	    break;
 	
 	/* what if the general name contains other format but not URI ?
--- a/security/nss/lib/certhigh/ocsp.c
+++ b/security/nss/lib/certhigh/ocsp.c
@@ -554,30 +554,37 @@ CERT_EncodeOCSPRequest(PRArenaPool *aren
  */
 CERTOCSPRequest *
 CERT_DecodeOCSPRequest(SECItem *src)
 {
     PRArenaPool *arena = NULL;
     SECStatus rv = SECFailure;
     CERTOCSPRequest *dest = NULL;
     int i;
-
+    SECItem newSrc;
 
     arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
     if (arena == NULL) {
 	goto loser;
     }
     dest = (CERTOCSPRequest *) PORT_ArenaZAlloc(arena, 
 						sizeof(CERTOCSPRequest));
     if (dest == NULL) {
 	goto loser;
     }
     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);
 	goto loser;
     }
 
     /*
      * XXX I would like to find a way to get rid of the necessity
@@ -1291,26 +1298,34 @@ ocsp_DecodeBasicOCSPResponse(PRArenaPool
     void *mark;
     ocspBasicOCSPResponse *basicResponse;
     ocspResponseData *responseData;
     ocspResponderID *responderID;
     ocspResponderIDType responderIDType;
     const SEC_ASN1Template *responderIDTemplate;
     int derTag;
     SECStatus rv;
+    SECItem newsrc;
 
     mark = PORT_ArenaMark(arena);
 
     basicResponse = PORT_ArenaZAlloc(arena, sizeof(ocspBasicOCSPResponse));
     if (basicResponse == NULL) {
 	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);
 	goto loser;
     }
 
     responseData = basicResponse->tbsResponseData;
 
@@ -1328,16 +1343,17 @@ ocsp_DecodeBasicOCSPResponse(PRArenaPool
     derTag = responseData->derResponderID.data[0] & SEC_ASN1_TAGNUM_MASK;
     responderIDType = ocsp_ResponderIDTypeByTag(derTag);
     responderIDTemplate = ocsp_ResponderIDTemplateByType(responderIDType);
 
     responderID = PORT_ArenaZAlloc(arena, sizeof(ocspResponderID));
     if (responderID == NULL) {
 	goto loser;
     }
+
     rv = SEC_QuickDERDecodeItem(arena, responderID, responderIDTemplate,
 			    &responseData->derResponderID);
     if (rv != SECSuccess) {
 	if (PORT_GetError() == SEC_ERROR_BAD_DER)
 	    PORT_SetError(SEC_ERROR_OCSP_MALFORMED_RESPONSE);
 	goto loser;
     }
 
@@ -1416,29 +1432,37 @@ ocsp_DecodeResponseBytes(PRArenaPool *ar
  */
 CERTOCSPResponse *
 CERT_DecodeOCSPResponse(SECItem *src)
 {
     PRArenaPool *arena = NULL;
     CERTOCSPResponse *response = NULL;
     SECStatus rv = SECFailure;
     ocspResponseStatus sv;
+    SECItem newSrc;
 
     arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
     if (arena == NULL) {
 	goto loser;
     }
     response = (CERTOCSPResponse *) PORT_ArenaZAlloc(arena,
 						     sizeof(CERTOCSPResponse));
     if (response == NULL) {
 	goto loser;
     }
     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);
 	goto loser;
     }
 
     sv = (ocspResponseStatus) DER_GetInteger(&response->responseStatus);
     response->statusValue = sv;
--- a/security/nss/lib/certhigh/xcrldist.c
+++ b/security/nss/lib/certhigh/xcrldist.c
@@ -141,28 +141,36 @@ CERT_EncodeCRLDistributionPoints (PRAren
 }
 
 CERTCrlDistributionPoints *
 CERT_DecodeCRLDistributionPoints (PRArenaPool *arena, SECItem *encodedValue)
 {
    CERTCrlDistributionPoints *value = NULL;    
    CRLDistributionPoint **pointList, *point;    
    SECStatus rv;
+   SECItem newEncodedValue;
 
    PORT_Assert (arena);
    do {
 	value = (CERTCrlDistributionPoints*)PORT_ArenaZAlloc (arena, sizeof (*value));
 	if (value == NULL) {
 	    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;
 
 	pointList = value->distPoints;
 	while (*pointList) {
 	    point = *pointList;
 
 	    /* get the data if the distributionPointName is not omitted */
--- a/security/nss/lib/cryptohi/seckey.c
+++ b/security/nss/lib/cryptohi/seckey.c
@@ -886,17 +886,17 @@ CERT_GetCertKeyType (CERTSubjectPublicKe
     }
     return keyType;
 }
 
 static SECKEYPublicKey *
 seckey_ExtractPublicKey(CERTSubjectPublicKeyInfo *spki)
 {
     SECKEYPublicKey *pubk;
-    SECItem os;
+    SECItem os, newOs, newParms;
     SECStatus rv;
     PRArenaPool *arena;
     SECOidTag tag;
 
     arena = PORT_NewArena (DER_DEFAULT_CHUNKSIZE);
     if (arena == NULL)
 	return NULL;
 
@@ -911,84 +911,106 @@ seckey_ExtractPublicKey(CERTSubjectPubli
     pubk->pkcs11ID = CK_INVALID_HANDLE;
 
 
     /* Convert bit string length from bits to bytes */
     os = spki->subjectPublicKey;
     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;
       case SEC_OID_ANSIX9_DSA_SIGNATURE:
       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,
                                  &spki->algorithm.parameters); 
 
 	if (rv == SECSuccess) return pubk;
 	break;
       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;
       case SEC_OID_MISSI_KEA_DSS_OLD:
       case SEC_OID_MISSI_KEA_DSS:
       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;
 	break;
 
       case SEC_OID_MISSI_KEA:
 	pubk->keyType = keaKey;
 
 	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;
 
         break;
 
       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;
 
         break;
 
 
       default:
@@ -1425,31 +1447,37 @@ SECKEY_DestroySubjectPublicKeyInfo(CERTS
  * similiar to CERT_ExtractPublicKey for other key times.
  */
 SECKEYPublicKey *
 SECKEY_DecodeDERPublicKey(SECItem *pubkder)
 {
     PRArenaPool *arena;
     SECKEYPublicKey *pubk;
     SECStatus rv;
+    SECItem newPubkder;
 
     arena = PORT_NewArena (DER_DEFAULT_CHUNKSIZE);
     if (arena == NULL) {
 	PORT_SetError (SEC_ERROR_NO_MEMORY);
 	return NULL;
     }
 
     pubk = (SECKEYPublicKey *) PORT_ArenaZAlloc (arena, sizeof (SECKEYPublicKey));
     if (pubk != NULL) {
 	pubk->arena = arena;
 	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);
     } else {
 	PORT_SetError (SEC_ERROR_NO_MEMORY);
     }
 
     PORT_FreeArena (arena, PR_FALSE);
@@ -1500,29 +1528,36 @@ finish:
 
 
 CERTSubjectPublicKeyInfo *
 SECKEY_DecodeDERSubjectPublicKeyInfo(SECItem *spkider)
 {
     PRArenaPool *arena;
     CERTSubjectPublicKeyInfo *spki;
     SECStatus rv;
+    SECItem newSpkider;
 
     arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
     if (arena == NULL) {
 	PORT_SetError(SEC_ERROR_NO_MEMORY);
 	return NULL;
     }
 
     spki = (CERTSubjectPublicKeyInfo *)
 		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);
     } else {
 	PORT_SetError(SEC_ERROR_NO_MEMORY);
     }
 
     PORT_FreeArena(arena, PR_FALSE);
--- a/security/nss/lib/fortcrypt/swfort/swfparse.c
+++ b/security/nss/lib/fortcrypt/swfort/swfparse.c
@@ -315,29 +315,37 @@ fort_getNextPhrase( FORTSWFile *file, fo
  */
 FORTSignedSWFile *
 FORT_GetSWFile(SECItem *initBits)
 {
     FORTSignedSWFile *sw_init_file;
     PRArenaPool *arena = NULL;
     SECStatus rv;
     int i, count;
+    SECItem newInitBits;
 
     /* get the local arena... be sure to free this at the end */
 
     /* get the local arena... be sure to free this at the end */
     arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
     if (arena == NULL) goto fail;
 
     sw_init_file = (FORTSignedSWFile *)
 		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;
     }
 
     /* count the certs */
     count = 0;
     while (sw_init_file->file.slotEntries[count]) count++;
 
--- a/security/nss/lib/softoken/lowcert.c
+++ b/security/nss/lib/softoken/lowcert.c
@@ -491,34 +491,43 @@ NSSLOWKEYPublicKey *
 nsslowcert_ExtractPublicKey(NSSLOWCERTCertificate *cert)
 {
     NSSLOWCERTSubjectPublicKeyInfo spki;
     NSSLOWKEYPublicKey *pubk;
     SECItem os;
     SECStatus rv;
     PRArenaPool *arena;
     SECOidTag tag;
+    SECItem newDerSubjKeyInfo;
 
     arena = PORT_NewArena (DER_DEFAULT_CHUNKSIZE);
     if (arena == NULL)
         return NULL;
 
     pubk = (NSSLOWKEYPublicKey *) 
 		PORT_ArenaZAlloc(arena, sizeof(NSSLOWKEYPublicKey));
     if (pubk == NULL) {
         PORT_FreeArena (arena, PR_FALSE);
         return NULL;
     }
 
     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;
     }
 
     /* Convert bit string length from bits to bytes */
     os = spki.subjectPublicKey;
     DER_ConvertBitString (&os);
--- a/security/nss/lib/softoken/pkcs11c.c
+++ b/security/nss/lib/softoken/pkcs11c.c
@@ -3650,30 +3650,39 @@ pk11_unwrapPrivateKey(PK11Object *key, S
     SECStatus rv = SECFailure;
     const SEC_ASN1Template *keyTemplate, *paramTemplate;
     void *paramDest = NULL;
     PLArenaPool *arena;
     NSSLOWKEYPrivateKey *lpk = NULL;
     NSSLOWKEYPrivateKeyInfo *pki = NULL;
     SECItem *ck_id = NULL;
     CK_RV crv = CKR_KEY_TYPE_INCONSISTENT;
+    SECItem newBpki;
 
     arena = PORT_NewArena(2048);
     if(!arena) {
 	return SECFailure;
     }
 
     pki = (NSSLOWKEYPrivateKeyInfo*)PORT_ArenaZAlloc(arena, 
 					sizeof(NSSLOWKEYPrivateKeyInfo));
     if(!pki) {
 	PORT_FreeArena(arena, PR_TRUE);
 	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;
     }
 
     lpk = (NSSLOWKEYPrivateKey *)PORT_ArenaZAlloc(arena,
 						  sizeof(NSSLOWKEYPrivateKey));
     if(lpk == NULL) {
--- a/security/nss/lib/util/quickder.c
+++ b/security/nss/lib/util/quickder.c
@@ -882,27 +882,17 @@ SECStatus SEC_QuickDERDecodeItem(PRArena
     SECItem newsrc;
 
     if (!arena || !templateEntry || !src)
     {
         PORT_SetError(SEC_ERROR_INVALID_ARGS);
         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)
     {
         rv = DecodeItem(dest, templateEntry, &newsrc, arena, PR_TRUE);
     }
 
     return rv;
 }