>From 73c5985e6c69e591cbc93db7dc3bc4767c81d54a Mon Sep 17 00:00:00 2001
From: Ade Lee <alee@redhat.com>
Date: Thu, 19 Jan 2012 00:50:47 -0500
Subject: [PATCH 12/14] Change RecoveryRequest fields

When sending a passphrase in the recovery request, we need to wrap it
in a session key and store it in sessionWrappedPassphrase.  We also
then wrap the session key in transWrappedSessionKey.

The server needs to do PBE if the sessionWrappedPassphrase
is present, and symkey based encryption otherwise.

Also changed the DRM test to reflect these changes, and fixed some errors.
---
 .../servlet/request/model/RecoveryRequestData.java |   18 ++--
 .../netscape/cms/servlet/test/DRMRestClient.java   |    7 +-
 .../src/com/netscape/cms/servlet/test/DRMTest.java |  105 +++++++++++---------
 3 files changed, 73 insertions(+), 57 deletions(-)

diff --git a/pki/base/common/src/com/netscape/cms/servlet/request/model/RecoveryRequestData.java b/pki/base/common/src/com/netscape/cms/servlet/request/model/RecoveryRequestData.java
index 88533a38da070b578984b720374b4152abd08178..c84d8f4912404451667ff8699a512874731a434a 100644
--- a/pki/base/common/src/com/netscape/cms/servlet/request/model/RecoveryRequestData.java
+++ b/pki/base/common/src/com/netscape/cms/servlet/request/model/RecoveryRequestData.java
@@ -38,7 +38,7 @@ public class RecoveryRequestData {
     private static final String KEY_ID = "keyId";
     private static final String REQUEST_ID = "requestId";
     private static final String TRANS_WRAPPED_SESSION_KEY = "transWrappedSessionKey";
-    private static final String TRANS_WRAPPED_PASSPHRASE = "transWrappedPassphrase";
+    private static final String SESSION_WRAPPED_PASSPHRASE = "sessionWrappedPassphrase";
 
     @XmlElement
     protected String keyId;
@@ -50,7 +50,7 @@ public class RecoveryRequestData {
     protected String transWrappedSessionKey;
     
     @XmlElement
-    protected String transWrappedPassphrase;
+    protected String sessionWrappedPassphrase;
     
     public RecoveryRequestData() {
         // required for JAXB (defaults)
@@ -60,7 +60,7 @@ public class RecoveryRequestData {
         keyId = form.getFirst(KEY_ID);
         requestId = form.getFirst(REQUEST_ID);
         transWrappedSessionKey = form.getFirst(TRANS_WRAPPED_SESSION_KEY);
-        transWrappedPassphrase = form.getFirst(TRANS_WRAPPED_PASSPHRASE);
+        sessionWrappedPassphrase = form.getFirst(SESSION_WRAPPED_PASSPHRASE);
     }
 
     /**
@@ -106,17 +106,17 @@ public class RecoveryRequestData {
     }
 
     /**
-     * @return the transWrappedPassphrase
+     * @return the sessionWrappedPassphrase
      */
-    public String getTransWrappedPassphrase() {
-        return transWrappedPassphrase;
+    public String getSessionWrappedPassphrase() {
+        return sessionWrappedPassphrase;
     }
 
     /**
-     * @param transWrappedPassphrase the transWrappedPassphrase to set
+     * @param sessionWrappedPassphrase the sessionWrappedPassphrase to set
      */
-    public void setTransWrappedPassphrase(String transWrappedPassphrase) {
-        this.transWrappedPassphrase = transWrappedPassphrase;
+    public void setSessionWrappedPassphrase(String sessionWrappedPassphrase) {
+        this.sessionWrappedPassphrase = sessionWrappedPassphrase;
     }
 
 }
diff --git a/pki/base/kra/functional/src/com/netscape/cms/servlet/test/DRMRestClient.java b/pki/base/kra/functional/src/com/netscape/cms/servlet/test/DRMRestClient.java
index 8447faaec9aa85c5e993c2b8aa3366a048207908..412df39a9d903f726be9c6c6fb858188f7688de3 100644
--- a/pki/base/kra/functional/src/com/netscape/cms/servlet/test/DRMRestClient.java
+++ b/pki/base/kra/functional/src/com/netscape/cms/servlet/test/DRMRestClient.java
@@ -81,7 +81,7 @@ public class DRMRestClient {
         RecoveryRequestData data = new RecoveryRequestData();
         data.setKeyId(keyId);
         if (rpwd != null) {
-            data.setTransWrappedPassphrase(com.netscape.osutil.OSUtil.BtoA(rpwd));
+            data.setSessionWrappedPassphrase(com.netscape.osutil.OSUtil.BtoA(rpwd));
         }
         if (rkey != null) {
             data.setTransWrappedSessionKey(com.netscape.osutil.OSUtil.BtoA(rkey));
@@ -102,8 +102,9 @@ public class DRMRestClient {
         data.setRequestId(requestId);
         if (rkey != null) {
             data.setTransWrappedSessionKey(com.netscape.osutil.OSUtil.BtoA(rkey));
-        } else {
-            data.setTransWrappedPassphrase(com.netscape.osutil.OSUtil.BtoA(rpwd));
+        }
+        if (rpwd != null) {
+            data.setSessionWrappedPassphrase(com.netscape.osutil.OSUtil.BtoA(rpwd));
         }
         KeyData key = keyClient.retrieveKey(data);
         return key;
diff --git a/pki/base/kra/functional/src/com/netscape/cms/servlet/test/DRMTest.java b/pki/base/kra/functional/src/com/netscape/cms/servlet/test/DRMTest.java
index f222e54130e55f162044bf43b768b4ff600c2880..bf15381a9809c06d1fbaaaacae97b0dd0c624bd6 100644
--- a/pki/base/kra/functional/src/com/netscape/cms/servlet/test/DRMTest.java
+++ b/pki/base/kra/functional/src/com/netscape/cms/servlet/test/DRMTest.java
@@ -226,19 +226,32 @@ public class DRMTest {
         log("Getting key: " + keyId);
 
         KeyData keyData = client.retrieveKey(keyId, recoveryRequestId, null, wrappedRecoveryKey);
-        String recoveredWrappedKey = keyData.getWrappedPrivateData();
-        String recoveredKey = unwrap(recoveredWrappedKey, recoveryKey);
+        String wrappedRecoveredKey = keyData.getWrappedPrivateData();
+        String recoveredKey = unwrap(wrappedRecoveredKey, recoveryKey);
 
         if (!recoveredKey.equals(com.netscape.osutil.OSUtil.BtoA(vek.getEncoded()))) {
             log("Error: recovered and archived keys do not match!");
         }
 
         // Test 9: Submit a recovery request for the symmetric key using a passphrase
-        log("Submitting a recovery request for the  symmetric key using session key");
+        log("Submitting a recovery request for the  symmetric key using a passphrase");
         String recoveryPassphrase = "Gimme me keys please";
-        byte[] wrappedRecoveryPassphrase = wrapPassphrase(recoveryPassphrase, transportCert);
-        KeyRequestInfo info = client.requestRecovery(keyId, wrappedRecoveryPassphrase, null);
-        recoveryRequestId = getId(info.getRequestURL());
+        byte[] wrappedRecoveryPassphrase = null;
+        KeyRequestInfo info = null;
+        byte iv[] = { 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1 };
+        IVParameterSpec IV = null;
+        IV = new IVParameterSpec(iv);
+        
+        try {
+            recoveryKey = kg1.generate();
+            wrappedRecoveryPassphrase = wrapPassphrase(token, recoveryPassphrase, IV, recoveryKey);
+            wrappedRecoveryKey = wrapSymmetricKey(manager, token, transportCert, recoveryKey);
+            info = client.requestRecovery(keyId, wrappedRecoveryPassphrase, wrappedRecoveryKey);
+            recoveryRequestId = getId(info.getRequestURL());
+        } catch (Exception e) {
+            log("Exception in recovering symmetric key using passphrase" + e.toString());
+            e.printStackTrace();
+        }
 
         //Test 10: Approve recovery
         log("Approving recovery request: " + recoveryRequestId);
@@ -246,9 +259,9 @@ public class DRMTest {
 
         // Test 11: Get key
         log("Getting key: " + keyId);
-        keyData = client.retrieveKey(keyId, recoveryRequestId, wrappedRecoveryPassphrase, null);
-        recoveredWrappedKey = keyData.getWrappedPrivateData();
-        recoveredKey = unwrap(recoveredWrappedKey, recoveryKey);
+        keyData = client.retrieveKey(keyId, recoveryRequestId, wrappedRecoveryPassphrase, wrappedRecoveryKey);
+        wrappedRecoveredKey = keyData.getWrappedPrivateData();
+        recoveredKey = unwrap(wrappedRecoveredKey, recoveryPassphrase);
 
         if (!recoveredKey.equals(com.netscape.osutil.OSUtil.BtoA(vek.getEncoded()))) {
             log("Error: recovered and archived keys do not match!");
@@ -304,16 +317,16 @@ public class DRMTest {
         log("Getting passphrase: " + keyId);
 
         keyData = client.retrieveKey(keyId, recoveryRequestId, null, wrappedRecoveryKey);
-        recoveredWrappedKey = keyData.getWrappedPrivateData();
-        recoveredKey = unwrap(recoveredWrappedKey, recoveryKey);
+        wrappedRecoveredKey = keyData.getWrappedPrivateData();
+        recoveredKey = unwrap(wrappedRecoveredKey, recoveryKey);
 
-        if (!unwrap(recoveredKey).equals(passphrase)) {
+        if (!recoveredKey.equals(passphrase)) {
             log("Error: recovered and archived passphrases do not match!");
         }
          
         // Test 17: Submit a recovery request for the passphrase using a passphrase
         log("Submitting a recovery request for the passphrase using a passphrase");
-        info = client.requestRecovery(keyId, wrappedRecoveryPassphrase, null);
+        info = client.requestRecovery(keyId, wrappedRecoveryPassphrase, wrappedRecoveryKey);
         recoveryRequestId = getId(info.getRequestURL());
 
         //Test 18: Approve recovery
@@ -322,22 +335,17 @@ public class DRMTest {
 
         // Test 19: Get key
         log("Getting passphrase: " + keyId);
-        keyData = client.retrieveKey(keyId, recoveryRequestId, wrappedRecoveryPassphrase, null);
-        recoveredWrappedKey = keyData.getWrappedPrivateData();
-        recoveredKey = unwrap(recoveredWrappedKey, recoveryKey);
+        keyData = client.retrieveKey(keyId, recoveryRequestId, wrappedRecoveryPassphrase, wrappedRecoveryKey);
+        wrappedRecoveredKey = keyData.getWrappedPrivateData();
+        recoveredKey = unwrap(wrappedRecoveredKey, recoveryPassphrase);
 
-        if (!unwrap(recoveredKey).equals(passphrase)) {
+        if (!recoveredKey.equals(passphrase)) {
             log("Error: recovered and archived passphrases do not match!");
         }
         
     }
 
-    private static String unwrap(String recoveredKey) {
-        // TODO Auto-generated method stub
-        return null;
-    }
-
-    private static byte[] wrapPassphrase(String recoveryPassphrase, String transportCert) {
+    private static String unwrap(String wrappedRecoveredKey, String recoveryPassphrase) {
         // TODO Auto-generated method stub
         return null;
     }
@@ -347,7 +355,7 @@ public class DRMTest {
         System.out.println(string);
     }
 
-    private static String unwrap(String recoveredWrappedKey, SymmetricKey recoveryKey) {
+    private static String unwrap(String wrappedRecoveredKey, SymmetricKey recoveryKey) {
         // TODO Auto-generated method stub
         return null;
     }
@@ -361,7 +369,6 @@ public class DRMTest {
             NoSuchAlgorithmException, InvalidKeyException, InvalidAlgorithmParameterException,
             CertificateEncodingException, IOException, IllegalStateException, IllegalBlockSizeException,
             BadPaddingException {
-        EncryptionAlgorithm encryptionAlgorithm = null;
         byte[] key_data = null;
         byte iv[] = { 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1 };
         IVParameterSpec IV = null;
@@ -371,29 +378,11 @@ public class DRMTest {
         SymmetricKey sk = kg1.generate();
 
         if (passphrase != null) {
-            Cipher cipher = null;
-            encryptionAlgorithm = EncryptionAlgorithm.DES3_CBC_PAD;
-            cipher = token.getCipherContext(encryptionAlgorithm);
-            log("cipher " + cipher);
-
-            if (cipher != null) {
-                cipher.initEncrypt(sk, IV);
-                key_data = cipher.doFinal(passphrase.getBytes());
-                log("Pass phrase mode key_data: " + key_data);
-
-                // Try to decrypt
-                cipher.initDecrypt(sk, IV);
-                byte[] decrypted = cipher.doFinal(key_data);
-                String s = new String(decrypted);
-                log("Re decrypted pass phrase " + s);
-
-            } else {
-                throw new IOException("Failed to create cipher");
-            }
+            key_data = wrapPassphrase(token, passphrase, IV, sk);
         } else {
             // wrap payload using session key
             KeyWrapper wrapper1 = token.getKeyWrapper(KeyWrapAlgorithm.DES3_CBC_PAD);
-            wrapper1.initWrap(sk, new IVParameterSpec(iv));
+            wrapper1.initWrap(sk, IV);
             key_data = wrapper1.wrap(vek);
         }
 
@@ -416,6 +405,32 @@ public class DRMTest {
         return encoded;
     }
 
+    private static byte[] wrapPassphrase(CryptoToken token, String passphrase, IVParameterSpec IV, SymmetricKey sk)
+            throws NoSuchAlgorithmException, TokenException, InvalidKeyException,
+            InvalidAlgorithmParameterException, IllegalBlockSizeException, BadPaddingException, IOException {
+        byte[] key_data = null;
+        Cipher cipher = null;
+        EncryptionAlgorithm encryptionAlgorithm = EncryptionAlgorithm.DES3_CBC_PAD;
+        cipher = token.getCipherContext(encryptionAlgorithm);
+        log("cipher " + cipher);
+
+        if (cipher != null) {
+            cipher.initEncrypt(sk, IV);
+            key_data = cipher.doFinal(passphrase.getBytes());
+            log("Pass phrase mode key_data: " + key_data);
+
+            // Try to decrypt
+            cipher.initDecrypt(sk, IV);
+            byte[] decrypted = cipher.doFinal(key_data);
+            String s = new String(decrypted);
+            log("Re decrypted pass phrase " + s);
+
+        } else {
+            throw new IOException("Failed to create cipher");
+        }
+        return key_data;
+    }
+
     private static byte[] wrapSymmetricKey(CryptoManager manager, CryptoToken token, String transportCert,
             SymmetricKey sk) throws CertificateEncodingException, TokenException, NoSuchAlgorithmException,
             InvalidKeyException, InvalidAlgorithmParameterException {
-- 
1.7.6.4

