From f875c6da102de85e37846cb92ac1fe1b79806faf Mon Sep 17 00:00:00 2001
From: Ade Lee <alee@redhat.com>
Date: Tue, 8 Nov 2016 21:34:41 -0500
Subject: [PATCH 337/338] Add field to KeyData to allow request to be returned
 when non-synchronous

If a retrieval is non-sychronous, we create a non-ephemeral recovery
request and return this Request ID to the client.
---
 base/common/src/com/netscape/certsrv/key/Key.java  | 18 ++++++++++++++++--
 .../src/com/netscape/certsrv/key/KeyClient.java    |  7 ++++---
 .../src/com/netscape/certsrv/key/KeyData.java      | 22 ++++++++++++++++++++++
 .../com/netscape/cmstools/key/KeyRetrieveCLI.java  | 18 ++++++++++++------
 .../org/dogtagpki/server/kra/rest/KeyService.java  | 20 ++++++++++++++++++++
 5 files changed, 74 insertions(+), 11 deletions(-)

diff --git a/base/common/src/com/netscape/certsrv/key/Key.java b/base/common/src/com/netscape/certsrv/key/Key.java
index 5f5baf7075e0cbcc474483cf69322b4a1fffa780..60cc1b0c8657b4a4211552888ea71601a3144511 100644
--- a/base/common/src/com/netscape/certsrv/key/Key.java
+++ b/base/common/src/com/netscape/certsrv/key/Key.java
@@ -5,6 +5,7 @@ import javax.xml.bind.annotation.XmlAccessorType;
 import javax.xml.bind.annotation.XmlElement;
 import javax.xml.bind.annotation.XmlRootElement;
 
+import com.netscape.certsrv.request.RequestId;
 import com.netscape.cmsutil.util.Utils;
 
 /**
@@ -37,16 +38,22 @@ public class Key {
     @XmlElement
     private byte[] data;
 
+    @XmlElement
+    private RequestId requestId;
+
     public Key() {
         super();
     }
 
     public Key(KeyData data) {
-        encryptedData = Utils.base64decode(data.getWrappedPrivateData());
-        nonceData = Utils.base64decode(data.getNonceData());
+        if (data.getWrappedPrivateData() != null)
+            encryptedData = Utils.base64decode(data.getWrappedPrivateData());
+        if (data.getNonceData() != null)
+            nonceData = Utils.base64decode(data.getNonceData());
         p12Data = data.getP12Data();
         algorithm = data.getAlgorithm();
         size = data.getSize();
+        requestId = data.requestID;
     }
 
     public byte[] getEncryptedData() {
@@ -97,4 +104,11 @@ public class Key {
         this.data = data;
     }
 
+    public RequestId getRequestId() {
+        return requestId;
+    }
+
+    public void setRequestId(RequestId requestId) {
+        this.requestId = requestId;
+    }
 }
diff --git a/base/common/src/com/netscape/certsrv/key/KeyClient.java b/base/common/src/com/netscape/certsrv/key/KeyClient.java
index 415c68e5ae5b1e01509bbbee7e71b9844b19dd90..8236d7f6b153f1768c517a2c3f876f6996cead30 100644
--- a/base/common/src/com/netscape/certsrv/key/KeyClient.java
+++ b/base/common/src/com/netscape/certsrv/key/KeyClient.java
@@ -367,8 +367,8 @@ public class KeyClient extends Client {
         byte[] transWrappedSessionKey = crypto.wrapSessionKeyWithTransportCert(sessionKey, transportCert);
 
         Key data = retrieveKey(keyId, transWrappedSessionKey);
-
-        data.setData(crypto.unwrapWithSessionKey(data.getEncryptedData(), sessionKey,
+        if (data.getEncryptedData()!= null)
+            data.setData(crypto.unwrapWithSessionKey(data.getEncryptedData(), sessionKey,
                 KeyRequestResource.DES3_ALGORITHM, data.getNonceData()));
 
         return data;
@@ -386,7 +386,8 @@ public class KeyClient extends Client {
         recoveryRequest.setTransWrappedSessionKey(Utils.base64encode(transWrappedSessionKey));
 
         Key data = retrieveKeyData(recoveryRequest);
-        data.setData(crypto.unwrapWithSessionKey(data.getEncryptedData(), sessionKey,
+        if (data.getEncryptedData() != null)
+            data.setData(crypto.unwrapWithSessionKey(data.getEncryptedData(), sessionKey,
                 KeyRequestResource.DES3_ALGORITHM, data.getNonceData()));
         return data;
     }
diff --git a/base/common/src/com/netscape/certsrv/key/KeyData.java b/base/common/src/com/netscape/certsrv/key/KeyData.java
index e31cfb3e705f6b6e22e9a33cbc1f4a73a5f7e3d5..ee13812b1bf7ac8f9646069c8ba4261c287b92ba 100644
--- a/base/common/src/com/netscape/certsrv/key/KeyData.java
+++ b/base/common/src/com/netscape/certsrv/key/KeyData.java
@@ -25,6 +25,10 @@ import javax.xml.bind.annotation.XmlAccessType;
 import javax.xml.bind.annotation.XmlAccessorType;
 import javax.xml.bind.annotation.XmlElement;
 import javax.xml.bind.annotation.XmlRootElement;
+import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter;
+
+import com.netscape.certsrv.request.RequestId;
+import com.netscape.certsrv.request.RequestIdAdapter;
 
 /**
  * @author alee
@@ -54,6 +58,10 @@ public class KeyData {
     // Will contain wrapped shared secret data.
     // Can be used for anything in other scenarios
 
+    @XmlElement
+    @XmlJavaTypeAdapter(RequestIdAdapter.class)
+    RequestId requestID;
+
     public KeyData() {
         // required for JAXB (defaults)
     }
@@ -139,5 +147,19 @@ public class KeyData {
         this.size = size;
     }
 
+    /**
+     * ID for the recovery request
+     * @return recovery request id
+     */
+    public RequestId getRequestID() {
+        return requestID;
+    }
 
+    /**
+     * Set request ID
+     * @param requestID
+     */
+    public void setRequestID(RequestId requestID) {
+        this.requestID = requestID;
+    }
 }
diff --git a/base/java-tools/src/com/netscape/cmstools/key/KeyRetrieveCLI.java b/base/java-tools/src/com/netscape/cmstools/key/KeyRetrieveCLI.java
index 555faa00dd5e4f5e81aa10eb38d8226355a17e60..5a2b77e509de777cb31be6707bd702765c68a231 100644
--- a/base/java-tools/src/com/netscape/cmstools/key/KeyRetrieveCLI.java
+++ b/base/java-tools/src/com/netscape/cmstools/key/KeyRetrieveCLI.java
@@ -173,15 +173,21 @@ public class KeyRetrieveCLI extends CLI {
     }
 
     public void printKeyData(Key key) {
-        System.out.println("  Key Algorithm: " + key.getAlgorithm());
-        System.out.println("  Key Size: " + key.getSize());
-        System.out.println("  Nonce data: " + Utils.base64encode(key.getNonceData()));
+        if (key.getRequestId() != null)
+            System.out.println("  Recovery Request ID: " + key.getRequestId());
+        if (key.getAlgorithm() != null)
+            System.out.println("  Key Algorithm: " + key.getAlgorithm());
+        if (key.getSize() != null)
+            System.out.println("  Key Size: " + key.getSize());
+        if (key.getNonceData() != null)
+            System.out.println("  Nonce data: " + Utils.base64encode(key.getNonceData()));
 
         if (clientEncryption) {
-            System.out.println("  Encrypted Data:" + Utils.base64encode(key.getEncryptedData()));
-
+            if (key.getEncryptedData() != null)
+                System.out.println("  Encrypted Data:" + Utils.base64encode(key.getEncryptedData()));
         } else {
-            System.out.println("  Actual archived data: " + Utils.base64encode(key.getData()));
+            if (key.getData() !=  null)
+                System.out.println("  Actual archived data: " + Utils.base64encode(key.getData()));
         }
 
         if (key.getP12Data() != null) {
diff --git a/base/kra/src/org/dogtagpki/server/kra/rest/KeyService.java b/base/kra/src/org/dogtagpki/server/kra/rest/KeyService.java
index bef03c5f1109d5971fa38997eeeed424fbae9919..72138e6789d13d6800389bcf36fb3b86242908a4 100644
--- a/base/kra/src/org/dogtagpki/server/kra/rest/KeyService.java
+++ b/base/kra/src/org/dogtagpki/server/kra/rest/KeyService.java
@@ -177,6 +177,9 @@ public class KeyService extends PKIService implements KeyResource {
             synchronous = kra.isRetrievalSynchronous(realm);
             ephemeral = kra.isEphemeral(realm);
 
+            // Only synchronous requests can be ephemeral
+            if (!synchronous) ephemeral = false;
+
             auditInfo += ";synchronous=" + Boolean.toString(synchronous);
             auditInfo += ";ephemeral=" + Boolean.toString(ephemeral);
 
@@ -189,6 +192,23 @@ public class KeyService extends PKIService implements KeyResource {
 
             requestId = request.getRequestId();
             auditInfo += ";requestID=" + requestId.toString();
+
+            if (!synchronous) {
+                // store the request in LDAP
+                try {
+                    queue.updateRequest(request);
+                } catch (EBaseException e) {
+                    errorOut(e.getMessage(), new PKIException(e.getMessage(), e));
+                    e.printStackTrace();
+                }
+
+                CMS.debug("Returning created recovery request");
+                auditRetrieveKey(ILogger.SUCCESS, "Created recovery request");
+
+                KeyData keyData = new KeyData();
+                keyData.setRequestID(requestId);
+                return createOKResponse(keyData);
+            }
         }
 
         data.setRequestId(requestId);
-- 
2.7.4

