From fdff7d618958162b3a30d63c9c50bd71faace530 Mon Sep 17 00:00:00 2001
From: "Endi S. Dewata" <edewata@redhat.com>
Date: Sat, 29 Oct 2016 07:52:36 +0200
Subject: [PATCH 1/2] Reformatted SecurityDataRecoveryService.serviceRequest().
The code in SecurityDataRecoveryService.serviceRequest() has been
reformatted for clarity.
https://fedorahosted.org/pki/ticket/2500
(cherry picked from commit 613d8e8281cc336d7e1c8291abedb4b2321f93ec)
(cherry picked from commit ec165a0d6cd805d1b5d4fbd4fff44ff00bfcaee0)
---
.../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 f12222b..478f7a8 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");
--
1.8.3.1
From 7fe0c22d09017fc45b251fd4fb2dd5f5dd23c603 Mon Sep 17 00:00:00 2001
From: "Endi S. Dewata" <edewata@redhat.com>
Date: Tue, 1 Nov 2016 22:49:22 +0100
Subject: [PATCH 2/2] 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
(cherry picked from commit 650b00dc57bb0c51c1e327ec3064531c26f80c43)
(cherry picked from commit 8bef45df5e3d287111df8e0a33519a065e3e7b70)
---
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 23a1f77..575dda7 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 478f7a8..83c1fb1 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) {
--
1.8.3.1