Blame SOURCES/pki-core-Fix-regression-in-pkcs12-key-bag-creation.patch

b80204
From 887d70ce1b8c4a00f62c2b4eec24326e487da5bd Mon Sep 17 00:00:00 2001
b80204
From: Fraser Tweedale <ftweedal@redhat.com>
b80204
Date: Thu, 15 Jun 2017 12:38:26 +1000
b80204
Subject: [PATCH 3/4] Fix regression in pkcs12 key bag creation
b80204
b80204
Commit 633c7c6519c925af7e3700adff29961d72435c7f changed the PKCS #12
b80204
file handing to never deal with raw private key material.
b80204
PKCS12Util.addKeyBag() was changed to export the PrivateKey handle,
b80204
or fail.  This change missed this case where a PKCS #12 file is
b80204
loaded from file, possibly modified, then written back to a file,
b80204
without involving an NSSDB.  One example is pkcs12-cert-del which
b80204
deletes a certificate and associated key from a PKCS #12 file.
b80204
b80204
Fix the PKCS12Util.addKeyBag() method to use the stored
b80204
EncryptedPricateKeyInfo if available, otherwise export the
b80204
PrivateKey handle.
b80204
b80204
Fixes: https://pagure.io/dogtagpki/issue/2741
b80204
Change-Id: Ib8098126bc5a79b5dae19103e25b270e2f10ab5a
b80204
(cherry picked from commit a411492fe5ad2030bb9f18db9a8ed8d1c45ee7de)
b80204
---
b80204
 .../src/netscape/security/pkcs/PKCS12Util.java     | 58 ++++++++++++++--------
b80204
 1 file changed, 37 insertions(+), 21 deletions(-)
b80204
b80204
diff --git a/base/util/src/netscape/security/pkcs/PKCS12Util.java b/base/util/src/netscape/security/pkcs/PKCS12Util.java
b80204
index 31c7126..1bc1bae 100644
b80204
--- a/base/util/src/netscape/security/pkcs/PKCS12Util.java
b80204
+++ b/base/util/src/netscape/security/pkcs/PKCS12Util.java
b80204
@@ -102,33 +102,49 @@ public class PKCS12Util {
b80204
         icert.setObjectSigningTrust(PKCS12.decodeFlags(flags[2]));
b80204
     }
b80204
 
b80204
-    /**
b80204
-     * Used during EXPORT to add a private key to the PKCS12.
b80204
+    /** Add a private key to the PKCS #12 object.
b80204
+     *
b80204
+     * The PKCS12KeyInfo object received comes about in two
b80204
+     * different scenarios:
b80204
+     *
b80204
+     * - The private key could be in encrypted byte[] form (e.g.
b80204
+     *   when we have merely loaded a PKCS #12 file for inspection
b80204
+     *   or e.g. to delete a certificate and its associated key).
b80204
+     *   In this case we simply re-use this encrypted private key
b80204
+     *   info byte[].
b80204
      *
b80204
-     * The private key is exported directly from the token, into
b80204
-     * an EncryptedPrivateKeyInfo value, then added as a
b80204
-     * "Shrouded Key Bag" to the PKCS #12 object.  Unencrypted
b80204
-     * key material is never seen.
b80204
+     * - The private key could be a be an NSS PrivateKey handle.  In
b80204
+     *   this case we must export the PrivateKey from the token to
b80204
+     *   obtain the EncryptedPrivateKeyInfo.
b80204
+     *
b80204
+     * The common final step is to add the encrypted private key
b80204
+     * data to a "Shrouded Key Bag" to the PKCS #12 object.
b80204
+     * Unencrypted key material is never seen.
b80204
      */
b80204
     public void addKeyBag(PKCS12KeyInfo keyInfo, Password password,
b80204
             SEQUENCE encSafeContents) throws Exception {
b80204
-        PrivateKey k = keyInfo.getPrivateKey();
b80204
-        if (k == null) {
b80204
-            logger.debug("NO PRIVATE KEY for " + keyInfo.subjectDN);
b80204
-            return;
b80204
-        }
b80204
-
b80204
         logger.debug("Creating key bag for " + keyInfo.subjectDN);
b80204
 
b80204
-        PasswordConverter passConverter = new PasswordConverter();
b80204
-        byte[] epkiBytes = CryptoManager.getInstance()
b80204
-            .getInternalKeyStorageToken()
b80204
-            .getCryptoStore()
b80204
-            .getEncryptedPrivateKeyInfo(
b80204
-                /* NSS has a bug that causes any AES CBC encryption
b80204
-                 * to use AES-256, but AlgorithmID contains chosen
b80204
-                 * alg.  To avoid mismatch, use AES_256_CBC. */
b80204
-                passConverter, password, EncryptionAlgorithm.AES_256_CBC, 0, k);
b80204
+        byte[] epkiBytes = keyInfo.getEncryptedPrivateKeyInfoBytes();
b80204
+        if (epkiBytes == null) {
b80204
+            PrivateKey k = keyInfo.getPrivateKey();
b80204
+            if (k == null) {
b80204
+                logger.debug("NO PRIVATE KEY for " + keyInfo.subjectDN);
b80204
+                return;
b80204
+            }
b80204
+            logger.debug("Encrypting private key for " + keyInfo.subjectDN);
b80204
+
b80204
+            PasswordConverter passConverter = new PasswordConverter();
b80204
+            epkiBytes = CryptoManager.getInstance()
b80204
+                .getInternalKeyStorageToken()
b80204
+                .getCryptoStore()
b80204
+                .getEncryptedPrivateKeyInfo(
b80204
+                    /* NSS has a bug that causes any AES CBC encryption
b80204
+                     * to use AES-256, but AlgorithmID contains chosen
b80204
+                     * alg.  To avoid mismatch, use AES_256_CBC. */
b80204
+                    passConverter, password,
b80204
+                    EncryptionAlgorithm.AES_256_CBC, 0, k);
b80204
+        }
b80204
 
b80204
         SET keyAttrs = createKeyBagAttrs(keyInfo);
b80204
 
b80204
-- 
b80204
1.8.3.1
b80204