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