Based on investigation and solution provided by cfu and jmagne, the SecurityDataRecoveryService.serviceRequest() has been modified to use EncryptionUnit.unwrap_temp() for key recovery via CLI in FIPS mode.
The code in SecurityDataRecoveryService.serviceRequest() has been reformatted for clarity. https://fedorahosted.org/pki/ticket/2500 ACKed and tested by cfu and jmagne. Pushed to master. -- Endi S. Dewata
>From 7f2cf7808b3c3f27d568c0f713ef7466b41af530 Mon Sep 17 00:00:00 2001 From: "Endi S. Dewata" <[email protected]> Date: Sat, 29 Oct 2016 07:52:36 +0200 Subject: [PATCH] Reformatted SecurityDataRecoveryService.serviceRequest(). The code in SecurityDataRecoveryService.serviceRequest() has been reformatted for clarity. https://fedorahosted.org/pki/ticket/2500 --- .../netscape/kra/SecurityDataRecoveryService.java | 30 ++++++++++++++++++---- 1 file changed, 25 insertions(+), 5 deletions(-) diff --git a/base/kra/src/com/netscape/kra/SecurityDataRecoveryService.java b/base/kra/src/com/netscape/kra/SecurityDataRecoveryService.java index f12222bc70dcbccb49d2835c671eb7cce44e036e..478f7a863e10d65fadc24bb2865528d047f1d8fe 100644 --- a/base/kra/src/com/netscape/kra/SecurityDataRecoveryService.java +++ b/base/kra/src/com/netscape/kra/SecurityDataRecoveryService.java @@ -24,6 +24,7 @@ import java.math.BigInteger; import java.security.InvalidAlgorithmParameterException; import java.security.InvalidKeyException; import java.security.NoSuchAlgorithmException; +import java.security.PublicKey; import java.security.spec.AlgorithmParameterSpec; import java.util.Arrays; import java.util.Hashtable; @@ -31,9 +32,6 @@ import java.util.Random; import javax.crypto.spec.RC2ParameterSpec; -import netscape.security.util.DerValue; -import netscape.security.x509.X509Key; - import org.dogtagpki.server.kra.rest.KeyRequestService; import org.mozilla.jss.CryptoManager; import org.mozilla.jss.asn1.OCTET_STRING; @@ -73,6 +71,9 @@ import com.netscape.certsrv.security.ITransportKeyUnit; import com.netscape.cmscore.dbs.KeyRecord; import com.netscape.cmsutil.util.Utils; +import netscape.security.util.DerValue; +import netscape.security.x509.X509Key; + /** * This implementation services SecurityData Recovery requests. * <p> @@ -184,6 +185,7 @@ public class SecurityDataRecoveryService implements IService { } catch (Exception e) { iv = iv_default; } + String ivStr = Utils.base64encode(iv); KeyRecord keyRecord = (KeyRecord) mStorage.readKeyRecord(serialno); @@ -200,20 +202,27 @@ public class SecurityDataRecoveryService implements IService { if (allowEncDecrypt_recovery == true) { CMS.debug("Recover symmetric key by decrypting as per allowEncDecrypt_recovery: true."); unwrappedSecData = recoverSecurityData(keyRecord); + } else { symKey = recoverSymKey(keyRecord); } } else if (dataType.equals(KeyRequestResource.PASS_PHRASE_TYPE)) { unwrappedSecData = recoverSecurityData(keyRecord); + } else if (dataType.equals(KeyRequestResource.ASYMMETRIC_KEY_TYPE)) { try { if (allowEncDecrypt_recovery == true) { CMS.debug("Recover asymmetric key by decrypting as per allowEncDecrypt_recovery: true."); unwrappedSecData = recoverSecurityData(keyRecord); + } else { - privateKey = mStorageUnit.unwrap(keyRecord.getPrivateKeyData(), - X509Key.parsePublicKey(new DerValue(keyRecord.getPublicKeyData()))); + + byte[] publicKeyData = keyRecord.getPublicKeyData(); + byte[] privateKeyData = keyRecord.getPrivateKeyData(); + + PublicKey publicKey = X509Key.parsePublicKey(new DerValue(publicKeyData)); + privateKey = mStorageUnit.unwrap(privateKeyData, publicKey); } } catch (IOException e) { @@ -244,22 +253,29 @@ public class SecurityDataRecoveryService implements IService { passStr = null; if (dataType.equals(KeyRequestResource.SYMMETRIC_KEY_TYPE)) { + CMS.debug("SecurityDataRecoveryService: wrap or encrypt stored symmetric key with transport passphrase"); if (allowEncDecrypt_recovery == true) { CMS.debug("SecurityDataRecoveryServic: allowEncDecyypt_recovery: true, symmetric key: create blob with unwrapped key."); pbeWrappedData = createEncryptedContentInfo(ct, null, unwrappedSecData, null, pass); + } else { pbeWrappedData = createEncryptedContentInfo(ct, symKey, null, null, pass); } + } else if (dataType.equals(KeyRequestResource.PASS_PHRASE_TYPE)) { + CMS.debug("SecurityDataRecoveryService: encrypt stored passphrase with transport passphrase"); pbeWrappedData = createEncryptedContentInfo(ct, null, unwrappedSecData, null, pass); + } else if (dataType.equals(KeyRequestResource.ASYMMETRIC_KEY_TYPE)) { + if (allowEncDecrypt_recovery == true) { CMS.debug("SecurityDataRecoveryService: allowEncDecyypt_recovery: true, asymmetric key: create blob with unwrapped key."); pbeWrappedData = createEncryptedContentInfo(ct, null, unwrappedSecData, null, pass); + } else { CMS.debug("SecurityDataRecoveryService: wrap stored private key with transport passphrase"); pbeWrappedData = createEncryptedContentInfo(ct, null, null, privateKey, @@ -294,9 +310,11 @@ public class SecurityDataRecoveryService implements IService { CMS.debug("SecurityDataRecoveryService: encrypt symmetric key with session key as per allowEncDecrypt_recovery: true."); unwrappedSess = mTransportUnit.unwrap_sym(wrappedSessKey, SymmetricKey.Usage.ENCRYPT); Cipher encryptor = ct.getCipherContext(EncryptionAlgorithm.DES3_CBC_PAD); + if (encryptor != null) { encryptor.initEncrypt(unwrappedSess, new IVParameterSpec(iv)); key_data = encryptor.doFinal(unwrappedSecData); + } else { auditRecoveryRequestProcessed(auditSubjectID, ILogger.FAILURE, requestID, serialno.toString(), "Failed to create cipher encrypting symmetric key"); @@ -344,9 +362,11 @@ public class SecurityDataRecoveryService implements IService { CMS.debug("SecurityDataRecoveryService: encrypt symmetric key with session key as per allowEncDecrypt_recovery: true."); unwrappedSess = mTransportUnit.unwrap_sym(wrappedSessKey, SymmetricKey.Usage.ENCRYPT); Cipher encryptor = ct.getCipherContext(EncryptionAlgorithm.DES3_CBC_PAD); + if (encryptor != null) { encryptor.initEncrypt(unwrappedSess, new IVParameterSpec(iv)); key_data = encryptor.doFinal(unwrappedSecData); + } else { auditRecoveryRequestProcessed(auditSubjectID, ILogger.FAILURE, requestID, serialno.toString(), "Failed to create cipher encrypting asymmetric key"); -- 2.5.5
>From 2d6e3a492b192ff3077d9d212a2c0b57f5242e96 Mon Sep 17 00:00:00 2001 From: "Endi S. Dewata" <[email protected]> Date: Tue, 1 Nov 2016 22:49:22 +0100 Subject: [PATCH] Fixed KRA key recovery via CLI in FIPS mode. Based on investigation and solution provided by cfu and jmagne, the SecurityDataRecoveryService.serviceRequest() has been modified to use EncryptionUnit.unwrap_temp() for key recovery via CLI in FIPS mode. https://fedorahosted.org/pki/ticket/2500 --- base/common/src/com/netscape/certsrv/security/IEncryptionUnit.java | 3 +++ base/kra/src/com/netscape/kra/SecurityDataRecoveryService.java | 2 +- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/base/common/src/com/netscape/certsrv/security/IEncryptionUnit.java b/base/common/src/com/netscape/certsrv/security/IEncryptionUnit.java index 23a1f773f78884ff70a3c89adaa1e70428e43532..575dda72e1c432b861ffe9d82e9c1f02205f35e8 100644 --- a/base/common/src/com/netscape/certsrv/security/IEncryptionUnit.java +++ b/base/common/src/com/netscape/certsrv/security/IEncryptionUnit.java @@ -142,6 +142,9 @@ public interface IEncryptionUnit extends IToken { public SymmetricKey unwrap_sym(byte encSymmKey[], SymmetricKey.Usage usage); + public PrivateKey unwrap_temp(byte privateKey[], PublicKey pubKey) + throws EBaseException; + /** * Unwraps data. This method rebuilds the private key by * unwrapping the private key data. diff --git a/base/kra/src/com/netscape/kra/SecurityDataRecoveryService.java b/base/kra/src/com/netscape/kra/SecurityDataRecoveryService.java index 478f7a863e10d65fadc24bb2865528d047f1d8fe..83c1fb1f5323011116d99c063236120c8f80cafe 100644 --- a/base/kra/src/com/netscape/kra/SecurityDataRecoveryService.java +++ b/base/kra/src/com/netscape/kra/SecurityDataRecoveryService.java @@ -222,7 +222,7 @@ public class SecurityDataRecoveryService implements IService { byte[] privateKeyData = keyRecord.getPrivateKeyData(); PublicKey publicKey = X509Key.parsePublicKey(new DerValue(publicKeyData)); - privateKey = mStorageUnit.unwrap(privateKeyData, publicKey); + privateKey = mStorageUnit.unwrap_temp(privateKeyData, publicKey); } } catch (IOException e) { -- 2.5.5
_______________________________________________ Pki-devel mailing list [email protected] https://www.redhat.com/mailman/listinfo/pki-devel
