summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorFraser Tweedale <ftweedal@redhat.com>2017-06-15 12:38:26 +1000
committerFraser Tweedale <ftweedal@redhat.com>2017-06-16 09:52:39 +1000
commita411492fe5ad2030bb9f18db9a8ed8d1c45ee7de (patch)
tree3a67cac3c933be55c37b0a675674a88402fe5d2d
parent63c9582009b3858a6878863b9658d04c9aad45c1 (diff)
downloadpki-a411492fe5ad2030bb9f18db9a8ed8d1c45ee7de.tar.gz
pki-a411492fe5ad2030bb9f18db9a8ed8d1c45ee7de.tar.xz
pki-a411492fe5ad2030bb9f18db9a8ed8d1c45ee7de.zip
Fix regression in pkcs12 key bag creation
Commit 633c7c6519c925af7e3700adff29961d72435c7f changed the PKCS #12 file handing to never deal with raw private key material. PKCS12Util.addKeyBag() was changed to export the PrivateKey handle, or fail. This change missed this case where a PKCS #12 file is loaded from file, possibly modified, then written back to a file, without involving an NSSDB. One example is pkcs12-cert-del which deletes a certificate and associated key from a PKCS #12 file. Fix the PKCS12Util.addKeyBag() method to use the stored EncryptedPricateKeyInfo if available, otherwise export the PrivateKey handle. Fixes: https://pagure.io/dogtagpki/issue/2741 Change-Id: Ib8098126bc5a79b5dae19103e25b270e2f10ab5a
-rw-r--r--base/util/src/netscape/security/pkcs/PKCS12Util.java58
1 files changed, 37 insertions, 21 deletions
diff --git a/base/util/src/netscape/security/pkcs/PKCS12Util.java b/base/util/src/netscape/security/pkcs/PKCS12Util.java
index 31c712691..1bc1baee5 100644
--- a/base/util/src/netscape/security/pkcs/PKCS12Util.java
+++ b/base/util/src/netscape/security/pkcs/PKCS12Util.java
@@ -102,33 +102,49 @@ public class PKCS12Util {
icert.setObjectSigningTrust(PKCS12.decodeFlags(flags[2]));
}
- /**
- * Used during EXPORT to add a private key to the PKCS12.
+ /** Add a private key to the PKCS #12 object.
+ *
+ * The PKCS12KeyInfo object received comes about in two
+ * different scenarios:
+ *
+ * - The private key could be in encrypted byte[] form (e.g.
+ * when we have merely loaded a PKCS #12 file for inspection
+ * or e.g. to delete a certificate and its associated key).
+ * In this case we simply re-use this encrypted private key
+ * info byte[].
*
- * The private key is exported directly from the token, into
- * an EncryptedPrivateKeyInfo value, then added as a
- * "Shrouded Key Bag" to the PKCS #12 object. Unencrypted
- * key material is never seen.
+ * - The private key could be a be an NSS PrivateKey handle. In
+ * this case we must export the PrivateKey from the token to
+ * obtain the EncryptedPrivateKeyInfo.
+ *
+ * The common final step is to add the encrypted private key
+ * data to a "Shrouded Key Bag" to the PKCS #12 object.
+ * Unencrypted key material is never seen.
*/
public void addKeyBag(PKCS12KeyInfo keyInfo, Password password,
SEQUENCE encSafeContents) throws Exception {
- PrivateKey k = keyInfo.getPrivateKey();
- if (k == null) {
- logger.debug("NO PRIVATE KEY for " + keyInfo.subjectDN);
- return;
- }
-
logger.debug("Creating key bag for " + keyInfo.subjectDN);
- PasswordConverter passConverter = new PasswordConverter();
- byte[] epkiBytes = CryptoManager.getInstance()
- .getInternalKeyStorageToken()
- .getCryptoStore()
- .getEncryptedPrivateKeyInfo(
- /* 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);
+ byte[] epkiBytes = keyInfo.getEncryptedPrivateKeyInfoBytes();
+ if (epkiBytes == null) {
+ PrivateKey k = keyInfo.getPrivateKey();
+ if (k == null) {
+ logger.debug("NO PRIVATE KEY for " + keyInfo.subjectDN);
+ return;
+ }
+ logger.debug("Encrypting private key for " + keyInfo.subjectDN);
+
+ PasswordConverter passConverter = new PasswordConverter();
+ epkiBytes = CryptoManager.getInstance()
+ .getInternalKeyStorageToken()
+ .getCryptoStore()
+ .getEncryptedPrivateKeyInfo(
+ /* 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);
+ }
SET keyAttrs = createKeyBagAttrs(keyInfo);