diff options
author | Fraser Tweedale <ftweedal@redhat.com> | 2017-06-15 12:38:26 +1000 |
---|---|---|
committer | Fraser Tweedale <ftweedal@redhat.com> | 2017-06-16 09:52:39 +1000 |
commit | a411492fe5ad2030bb9f18db9a8ed8d1c45ee7de (patch) | |
tree | 3a67cac3c933be55c37b0a675674a88402fe5d2d | |
parent | 63c9582009b3858a6878863b9658d04c9aad45c1 (diff) | |
download | pki-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.java | 58 |
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); |