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