Blame SOURCES/pki-core-Make-PKCS12-files-compatible-with-PBES2.patch

120910
From 137832b2892dfc596ed067a86242d341f2c325e7 Mon Sep 17 00:00:00 2001
120910
From: Fraser Tweedale <ftweedal@redhat.com>
120910
Date: Thu, 14 Sep 2017 12:22:47 +1000
120910
Subject: [PATCH] Make PKCS #12 files compatible with OpenSSL, NSS >= 3.31
120910
120910
For compatibility with OpenSSL and NSS >= 3.31, the passphrase must
120910
not be BMPString-encoded when non-PKCS #12 PBE schemes such as
120910
PBES2.
120910
120910
Fixes: https://pagure.io/dogtagpki/issue/2809
120910
120910
Change-Id: Ic78ad337ac0b9b2f5d2e75581cc0ee55e6d82782
120910
(cherry picked from commit ed5cccefebf98e588a5385191e43f727349b54a9)
120910
---
120910
 base/kra/src/com/netscape/kra/RecoveryService.java | 26 +++++++++++++++----
120910
 .../cms/servlet/csadmin/ConfigurationUtils.java    | 15 ++++++++---
120910
 .../src/netscape/security/pkcs/PKCS12Util.java     | 29 ++++++++++++++++++----
120910
 3 files changed, 57 insertions(+), 13 deletions(-)
120910
120910
diff --git a/base/kra/src/com/netscape/kra/RecoveryService.java b/base/kra/src/com/netscape/kra/RecoveryService.java
120910
index a7d639208..0d293e411 100644
120910
--- a/base/kra/src/com/netscape/kra/RecoveryService.java
120910
+++ b/base/kra/src/com/netscape/kra/RecoveryService.java
120910
@@ -508,10 +508,21 @@ public class RecoveryService implements IService {
120910
                 }
120910
             } else {
120910
                 byte[] epkiBytes = ct.getCryptoStore().getEncryptedPrivateKeyInfo(
120910
+                    /* For compatibility with OpenSSL and NSS >= 3.31,
120910
+                     * do not BMPString-encode the passphrase when using
120910
+                     * non-PKCS #12 PBE scheme such as PKCS #5 PBES2.
120910
+                     *
120910
+                     * The resulting PKCS #12 is not compatible with
120910
+                     * NSS < 3.31.
120910
+                     */
120910
+                    null /* passConverter */,
120910
+                    pass,
120910
                     /* NSS has a bug that causes any AES CBC encryption
120910
                      * to use AES-256, but AlgorithmID contains chosen
120910
                      * alg.  To avoid mismatch, use AES_256_CBC. */
120910
-                    passConverter, pass, EncryptionAlgorithm.AES_256_CBC, 0, priKey);
120910
+                    EncryptionAlgorithm.AES_256_CBC,
120910
+                    0 /* iterations (use default) */,
120910
+                    priKey);
120910
                 CMS.debug("RecoverService: createPFX() getEncryptedPrivateKeyInfo() returned");
120910
                 if (epkiBytes == null) {
120910
                     CMS.debug("RecoverService: createPFX() epkiBytes null");
120910
@@ -646,8 +657,6 @@ public class RecoveryService implements IService {
120910
                             pwd.toCharArray());
120910
 
120910
             SEQUENCE safeContents = new SEQUENCE();
120910
-            PasswordConverter passConverter = new
120910
-                    PasswordConverter();
120910
             PrivateKeyInfo pki = (PrivateKeyInfo)
120910
                     ASN1Util.decode(PrivateKeyInfo.getTemplate(),
120910
                             priData);
120910
@@ -662,14 +671,21 @@ public class RecoveryService implements IService {
120910
                 byte salt[] = { 0x01, 0x01, 0x01, 0x01 };
120910
                 epki = EncryptedPrivateKeyInfo.createPBE(
120910
                     PBEAlgorithm.PBE_SHA1_DES3_CBC,
120910
-                    pass, salt, 1, passConverter, pki);
120910
+                    pass, salt, 1, new PasswordConverter(), pki);
120910
             } else {
120910
                 epki = EncryptedPrivateKeyInfo.createPBES2(
120910
                     16, // saltLen
120910
                     2000, // kdfIterations
120910
                     EncryptionAlgorithm.AES_128_CBC_PAD,
120910
                     pass,
120910
-                    passConverter,
120910
+                    /* For compatibility with OpenSSL and NSS >= 3.31,
120910
+                     * do not BMPString-encode the passphrase when using
120910
+                     * non-PKCS #12 PBE scheme such as PKCS #5 PBES2.
120910
+                     *
120910
+                     * The resulting PKCS #12 is not compatible with
120910
+                     * NSS < 3.31.
120910
+                     */
120910
+                    null /* passConverter */,
120910
                     pki);
120910
             }
120910
 
120910
diff --git a/base/server/cms/src/com/netscape/cms/servlet/csadmin/ConfigurationUtils.java b/base/server/cms/src/com/netscape/cms/servlet/csadmin/ConfigurationUtils.java
120910
index ebade36bc..df3b4672d 100644
120910
--- a/base/server/cms/src/com/netscape/cms/servlet/csadmin/ConfigurationUtils.java
120910
+++ b/base/server/cms/src/com/netscape/cms/servlet/csadmin/ConfigurationUtils.java
120910
@@ -1058,9 +1058,18 @@ public class ConfigurationUtils {
120910
                 // this is OK
120910
             }
120910
 
120910
-            // import private key into database
120910
-            store.importEncryptedPrivateKeyInfo(
120910
-                new PasswordConverter(), password, nickname, publicKey, epki);
120910
+            try {
120910
+                // first true without BMPString-encoding the passphrase.
120910
+                store.importEncryptedPrivateKeyInfo(
120910
+                    null, password, nickname, publicKey, epki);
120910
+            } catch (Exception e) {
120910
+                // if that failed, try again with BMPString-encoded
120910
+                // passphrase.  This is required for PKCS #12 PBE
120910
+                // schemes and for PKCS #12 files using PBES2 generated
120910
+                // by NSS < 3.31
120910
+                store.importEncryptedPrivateKeyInfo(
120910
+                    new PasswordConverter(), password, nickname, publicKey, epki);
120910
+            }
120910
         }
120910
 
120910
         CMS.debug("Importing new certificates:");
120910
diff --git a/base/util/src/netscape/security/pkcs/PKCS12Util.java b/base/util/src/netscape/security/pkcs/PKCS12Util.java
120910
index 1bc1baee5..1018b21f6 100644
120910
--- a/base/util/src/netscape/security/pkcs/PKCS12Util.java
120910
+++ b/base/util/src/netscape/security/pkcs/PKCS12Util.java
120910
@@ -134,16 +134,25 @@ public class PKCS12Util {
120910
             }
120910
             logger.debug("Encrypting private key for " + keyInfo.subjectDN);
120910
 
120910
-            PasswordConverter passConverter = new PasswordConverter();
120910
             epkiBytes = CryptoManager.getInstance()
120910
                 .getInternalKeyStorageToken()
120910
                 .getCryptoStore()
120910
                 .getEncryptedPrivateKeyInfo(
120910
+                    /* For compatibility with OpenSSL and NSS >= 3.31,
120910
+                     * do not BMPString-encode the passphrase when using
120910
+                     * non-PKCS #12 PBE scheme such as PKCS #5 PBES2.
120910
+                     *
120910
+                     * The resulting PKCS #12 is not compatible with
120910
+                     * NSS < 3.31.
120910
+                     */
120910
+                    null /* passConverter */,
120910
+                    password,
120910
                     /* NSS has a bug that causes any AES CBC encryption
120910
                      * to use AES-256, but AlgorithmID contains chosen
120910
                      * alg.  To avoid mismatch, use AES_256_CBC. */
120910
-                    passConverter, password,
120910
-                    EncryptionAlgorithm.AES_256_CBC, 0, k);
120910
+                    EncryptionAlgorithm.AES_256_CBC,
120910
+                    0 /* iterations (default) */,
120910
+                    k);
120910
         }
120910
 
120910
         SET keyAttrs = createKeyBagAttrs(keyInfo);
120910
@@ -616,8 +625,18 @@ public class PKCS12Util {
120910
                 "No EncryptedPrivateKeyInfo for key '"
120910
                 + keyInfo.subjectDN + "'; skipping key");
120910
         }
120910
-        store.importEncryptedPrivateKeyInfo(
120910
-            new PasswordConverter(), password, nickname, publicKey, epkiBytes);
120910
+        try {
120910
+            // first true without BMPString-encoding the passphrase.
120910
+            store.importEncryptedPrivateKeyInfo(
120910
+                null, password, nickname, publicKey, epkiBytes);
120910
+        } catch (Exception e) {
120910
+            // if that failed, try again with BMPString-encoded
120910
+            // passphrase.  This is required for PKCS #12 PBE
120910
+            // schemes and for PKCS #12 files using PBES2 generated
120910
+            // by NSS < 3.31
120910
+            store.importEncryptedPrivateKeyInfo(
120910
+                new PasswordConverter(), password, nickname, publicKey, epkiBytes);
120910
+        }
120910
 
120910
         // delete the cert again (it will be imported again later
120910
         // with the correct nickname)
120910
-- 
120910
2.13.5
120910