Blob Blame History Raw
diff --git a/lib/pkcs12/p12d.c b/lib/pkcs12/p12d.c
--- a/lib/pkcs12/p12d.c
+++ b/lib/pkcs12/p12d.c
@@ -335,35 +335,42 @@
     sec_PKCS12SafeContentsContext *safeContentsCtx =
         (sec_PKCS12SafeContentsContext *)arg;
     SEC_PKCS12DecoderContext *p12dcx;
     SECStatus rv;
 
-    /* make sure that we are not skipping the current safeBag,
-     * and that there are no errors.  If so, just return rather
-     * than continuing to process.
-     */
-    if (!safeContentsCtx || !safeContentsCtx->p12dcx ||
-        safeContentsCtx->p12dcx->error || safeContentsCtx->skipCurrentSafeBag) {
+    if (!safeContentsCtx || !safeContentsCtx->p12dcx || !safeContentsCtx->currentSafeBagA1Dcx) {
         return;
     }
     p12dcx = safeContentsCtx->p12dcx;
 
+    /* make sure that there are no errors and we are not skipping the current safeBag */
+    if (p12dcx->error || safeContentsCtx->skipCurrentSafeBag) {
+        goto loser;
+    }
+
     rv = SEC_ASN1DecoderUpdate(safeContentsCtx->currentSafeBagA1Dcx, data, len);
     if (rv != SECSuccess) {
         p12dcx->errorValue = PORT_GetError();
+        p12dcx->error = PR_TRUE;
+        goto loser;
+    }
+
+    /* The update may have set safeContentsCtx->skipCurrentSafeBag, and we
+     * may not get another opportunity to clean up the decoder context.
+     */
+    if (safeContentsCtx->skipCurrentSafeBag) {
         goto loser;
     }
 
     return;
 
 loser:
-    /* set the error, and finish the decoder context.  because there
+    /* Finish the decoder context. Because there
      * is not a way of returning an error message, it may be worth
      * while to do a check higher up and finish any decoding contexts
      * that are still open.
      */
-    p12dcx->error = PR_TRUE;
     SEC_ASN1DecoderFinish(safeContentsCtx->currentSafeBagA1Dcx);
     safeContentsCtx->currentSafeBagA1Dcx = NULL;
     return;
 }
 
diff --git a/lib/pkcs12/p12t.h b/lib/pkcs12/p12t.h
--- a/lib/pkcs12/p12t.h
+++ b/lib/pkcs12/p12t.h
@@ -71,10 +71,11 @@
         SECKEYEncryptedPrivateKeyInfo *pkcs8ShroudedKeyBag;
         sec_PKCS12CertBag *certBag;
         sec_PKCS12CRLBag *crlBag;
         sec_PKCS12SecretBag *secretBag;
         sec_PKCS12SafeContents *safeContents;
+        SECItem *unknownBag;
     } safeBagContent;
 
     sec_PKCS12Attribute **attribs;
 
     /* used locally */
diff --git a/lib/pkcs12/p12tmpl.c b/lib/pkcs12/p12tmpl.c
--- a/lib/pkcs12/p12tmpl.c
+++ b/lib/pkcs12/p12tmpl.c
@@ -28,16 +28,16 @@
 
     safeBag = (sec_PKCS12SafeBag *)src_or_dest;
 
     oiddata = SECOID_FindOID(&safeBag->safeBagType);
     if (oiddata == NULL) {
-        return SEC_ASN1_GET(SEC_AnyTemplate);
+        return SEC_ASN1_GET(SEC_PointerToAnyTemplate);
     }
 
     switch (oiddata->offset) {
         default:
-            theTemplate = SEC_ASN1_GET(SEC_AnyTemplate);
+            theTemplate = SEC_ASN1_GET(SEC_PointerToAnyTemplate);
             break;
         case SEC_OID_PKCS12_V1_KEY_BAG_ID:
             theTemplate = SEC_ASN1_GET(SECKEY_PointerToPrivateKeyInfoTemplate);
             break;
         case SEC_OID_PKCS12_V1_CERT_BAG_ID: