Blob Blame History Raw
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