Patch 340:
commit 0e1c6e0634f5d3b3d4b8a3d7293b23f1953cf542
Author: Ade Lee <[email protected]>
Date:   Mon Nov 21 17:42:11 2016 -0500

    Fix bug in getting secrets from approved request
    
    When request was approved and retrieved through the rest
    interface, the corresponding volatile requests object was not
    created due to the new flow.  This makes sure the volatile request
    is created.

Patch 339:
commit 2e37a2fe6173a9968fd76fb7ff93e7cc188aa700
Author: Ade Lee <[email protected]>
Date:   Mon Nov 21 12:01:09 2016 -0500

    Add python-client code for key resource changes
From 0e1c6e0634f5d3b3d4b8a3d7293b23f1953cf542 Mon Sep 17 00:00:00 2001
From: Ade Lee <[email protected]>
Date: Mon, 21 Nov 2016 17:42:11 -0500
Subject: [PATCH 340/340] Fix bug in getting secrets from approved request

When request was approved and retrieved through the rest
interface, the corresponding volatile requests object was not
created due to the new flow.  This makes sure the volatile request
is created.
---
 .../org/dogtagpki/server/kra/rest/KeyService.java  | 35 +++++++-----------
 .../netscape/cms/servlet/key/KeyRequestDAO.java    | 43 ++++++++++++----------
 2 files changed, 37 insertions(+), 41 deletions(-)

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 1d67cbc7b18b83ba3b21c675d231c365d69ccdcc..d2c24c888c3a8835fe69cb087c6986887bf1ef41 100644
--- a/base/kra/src/org/dogtagpki/server/kra/rest/KeyService.java
+++ b/base/kra/src/org/dogtagpki/server/kra/rest/KeyService.java
@@ -197,7 +197,8 @@ public class KeyService extends PKIService implements KeyResource {
 
             KeyRequestDAO reqDAO = new KeyRequestDAO();
             try {
-                request = reqDAO.createRecoveryRequest(data, uriInfo, getRequestor(), getAuthToken(), ephemeral);
+                request = reqDAO.createRecoveryRequest(data, uriInfo, getRequestor(),
+                        getAuthToken(), ephemeral);
             } catch (EBaseException e) {
                 throw new PKIException(e.getMessage(), e);
             }
@@ -270,6 +271,7 @@ public class KeyService extends PKIService implements KeyResource {
         String method = "KeyService.getKey:";
         auditInfo = method;
         KeyData keyData;
+        KeyRequestDAO dao = new KeyRequestDAO();
         CMS.debug(method + "begins.");
 
         if (data == null) {
@@ -294,16 +296,9 @@ public class KeyService extends PKIService implements KeyResource {
         auditInfo += ";synchronous=" + Boolean.toString(synchronous);
         auditInfo += ";ephemeral=" + Boolean.toString(ephemeral);
 
-
-        // get data from the KeyRecoveryRequest
-        String transWrappedSessionKey   = data.getTransWrappedSessionKey();
-        String sessionWrappedPassphrase = data.getSessionWrappedPassphrase();
-
         // get data from IRequest
-        Hashtable<String, Object> requestParams = kra.getVolatileRequest(request.getRequestId());
-        if(requestParams == null) {
-            throw new PKIException("Can't obtain Volatile requestParams in getKey!");
-        }
+        Hashtable<String, Object> requestParams = dao.getTransientData(request);
+
         String sessWrappedKeyData = (String) requestParams.get(IRequest.SECURITY_DATA_SESS_WRAPPED_DATA);
         String passWrappedKeyData = (String) requestParams.get(IRequest.SECURITY_DATA_PASS_WRAPPED_DATA);
         String nonceData = (String) requestParams.get(IRequest.SECURITY_DATA_IV_STRING_OUT);
@@ -318,18 +313,7 @@ public class KeyService extends PKIService implements KeyResource {
             // the info now needed to process the recovery request.
 
             nonceData = data.getNonceData();
-
-            if (sessionWrappedPassphrase != null) {
-                requestParams.put(IRequest.SECURITY_DATA_SESS_PASS_PHRASE, sessionWrappedPassphrase);
-            }
-
-            if (transWrappedSessionKey != null) {
-                requestParams.put(IRequest.SECURITY_DATA_TRANS_SESS_KEY, transWrappedSessionKey);
-            }
-
-            if (nonceData != null) {
-                requestParams.put(IRequest.SECURITY_DATA_IV_STRING_IN, nonceData);
-            }
+            dao.setTransientData(data, request);
 
             try {
                 if (!synchronous) {
@@ -682,6 +666,13 @@ public class KeyService extends PKIService implements KeyResource {
             throw new UnauthorizedException("Request not approved");
         }
 
+        KeyRequestDAO dao = new KeyRequestDAO();
+        try {
+            dao.setTransientData(data, request);
+        } catch(EBaseException e) {
+            throw new PKIException("Cannot set transient data", e);
+        }
+
         String passphrase = data.getPassphrase();
         byte pkcs12[] = null;
         try {
diff --git a/base/server/cms/src/com/netscape/cms/servlet/key/KeyRequestDAO.java b/base/server/cms/src/com/netscape/cms/servlet/key/KeyRequestDAO.java
index bab7d3d142dc44bd1c4c3624b7d5c88aa2a2dc5b..b83ab1afde65b1ce95efb6ccdfc42377a86638f0 100644
--- a/base/server/cms/src/com/netscape/cms/servlet/key/KeyRequestDAO.java
+++ b/base/server/cms/src/com/netscape/cms/servlet/key/KeyRequestDAO.java
@@ -253,10 +253,6 @@ public class KeyRequestDAO extends CMSRequestDAO {
             throw new UnauthorizedException("Recovery must be initiated by an agent");
         }
 
-        String wrappedSessionKeyStr = data.getTransWrappedSessionKey();
-        String wrappedPassPhraseStr = data.getSessionWrappedPassphrase();
-        String nonceDataStr = data.getNonceData();
-
         KeyId keyId = data.getKeyId();
         IKeyRecord rec = null;
         try {
@@ -279,15 +275,20 @@ public class KeyRequestDAO extends CMSRequestDAO {
             request.setRealm(rec.getRealm());
         }
 
-        Hashtable<String, Object> requestParams;
+        request.setExtData(ATTR_SERIALNO, keyId.toString());
+        request.setExtData(IRequest.ATTR_REQUEST_OWNER, requestor);
+        request.setExtData(IRequest.ATTR_APPROVE_AGENTS, requestor);
 
-        requestParams = ((IKeyRecoveryAuthority) authority).createVolatileRequest(request.getRequestId());
+        return request;
+    }
 
-        if (requestParams == null) {
-            throw new EBaseException("Can not create Volatile params in createRecoveryRequest!");
-        }
+    public void setTransientData(KeyRecoveryRequest data, IRequest request) throws EBaseException {
 
-        CMS.debug("Create volatile  params for recovery request. " + requestParams);
+        Hashtable<String, Object> requestParams = getTransientData(request);
+
+        String wrappedSessionKeyStr = data.getTransWrappedSessionKey();
+        String wrappedPassPhraseStr = data.getSessionWrappedPassphrase();
+        String nonceDataStr = data.getNonceData();
 
         if (wrappedPassPhraseStr != null) {
             requestParams.put(IRequest.SECURITY_DATA_SESS_PASS_PHRASE, wrappedPassPhraseStr);
@@ -300,15 +301,18 @@ public class KeyRequestDAO extends CMSRequestDAO {
         if (nonceDataStr != null) {
             requestParams.put(IRequest.SECURITY_DATA_IV_STRING_IN, nonceDataStr);
         }
-
-        request.setExtData(ATTR_SERIALNO, keyId.toString());
-
-        request.setExtData(IRequest.ATTR_REQUEST_OWNER, requestor);
-        request.setExtData(IRequest.ATTR_APPROVE_AGENTS, requestor);
-
-        // do we need to destroy the requestParams?
-
-        return request;
+    }
+
+    public Hashtable<String, Object> getTransientData(IRequest request) throws EBaseException {
+        Hashtable<String, Object> requestParams;
+        requestParams = ((IKeyRecoveryAuthority) authority).getVolatileRequest(request.getRequestId());
+        if (requestParams == null) {
+            requestParams = ((IKeyRecoveryAuthority) authority).createVolatileRequest(request.getRequestId());
+            if (requestParams == null) {
+                throw new EBaseException("Can not create Volatile params in createRecoveryRequest!");
+            }
+        }
+        return requestParams;
     }
 
     /**
@@ -325,6 +329,7 @@ public class KeyRequestDAO extends CMSRequestDAO {
             IAuthToken authToken)
             throws EBaseException {
         IRequest request = createRecoveryRequest(data, uriInfo, requestor, authToken, false);
+        setTransientData(data, request);
         queue.processRequest(request);
 
         return createKeyRequestResponse(request, uriInfo);
-- 
2.7.4

From 2e37a2fe6173a9968fd76fb7ff93e7cc188aa700 Mon Sep 17 00:00:00 2001
From: Ade Lee <[email protected]>
Date: Mon, 21 Nov 2016 12:01:09 -0500
Subject: [PATCH 339/340] Add python-client code for key resource changes

---
 base/common/python/pki/key.py | 88 +++++++++++++++++++++++++------------------
 1 file changed, 52 insertions(+), 36 deletions(-)

diff --git a/base/common/python/pki/key.py b/base/common/python/pki/key.py
index 14e0b14250709b7e04299b81684b0c2ee1402e6b..da4efd69fcd73c41bc2de6af0231029d3c37a95d 100644
--- a/base/common/python/pki/key.py
+++ b/base/common/python/pki/key.py
@@ -56,7 +56,9 @@ class KeyData(object):
     """
 
     json_attribute_names = {
-        'nonceData': 'nonce_data', 'wrappedPrivateData': 'wrapped_private_data'
+        'nonceData': 'nonce_data',
+        'wrappedPrivateData': 'wrapped_private_data',
+        'requestID': 'request_id'
     }
 
     # pylint: disable=C0103
@@ -64,6 +66,7 @@ class KeyData(object):
         """ Constructor """
         self.algorithm = None
         self.nonce_data = None
+        self.request_id = None
         self.size = None
         self.wrapped_private_data = None
 
@@ -88,9 +91,14 @@ class Key(object):
 
     def __init__(self, key_data):
         """ Constructor """
-        self.encrypted_data = base64.b64decode(
-            key_data.wrapped_private_data)
-        self.nonce_data = base64.b64decode(key_data.nonce_data)
+        self.encrypted_data = None
+        if key_data.wrapped_private_data is not None:
+            self.encrypted_data = base64.b64decode(
+                key_data.wrapped_private_data)
+        if key_data.nonce_data is not None:
+            self.nonce_data = base64.b64decode(key_data.nonce_data)
+        if key_data.request_id is not None:
+            self.request_id = key_data.request_id
         self.algorithm = key_data.algorithm
         self.size = key_data.size
 
@@ -884,12 +892,28 @@ class KeyClient(object):
         return Key(key_data)
 
     @pki.handle_exceptions()
-    def retrieve_key(self, key_id, trans_wrapped_session_key=None):
+    def retrieve_key(self, key_id=None, trans_wrapped_session_key=None,
+                     request_id=None):
         """ Retrieve a secret (passphrase or symmetric key) from the DRM.
 
-        This function generates a key recovery request, approves it, and
-        retrieves the secret referred to by key_id.  This assumes that only one
-        approval is required to authorize the recovery.
+        This method will retrieve a key from the KRA given the key_id or
+        request_id (one of which must be specified).  The data is returned
+        as a KeyData object (which is recast to a Key object).
+
+        If request_id is specified, then the value of key_id is ignored.
+        Exceptions will be thrown if the caller is not the originator of the
+        request, or the request is not approved.
+
+        If key_id is specified instead, the following behavior applies:
+
+        *  If the key can be retrieved synchronously - ie. only one agent's
+           approval is required, then the KeyData will include the secret.
+
+        *  If the key cannot be retrieved synchronously - ie. if more than one
+           approval is needed, then the KeyData obect will include the request
+           ID for a recovery request that was created on the server.  When that
+           request is approved, callers can retrieve the key using
+           retrieve_key() and setting the request_id.
 
         To ensure data security in transit, the data will be returned encrypted
         by a session key (168 bit 3DES symmetric key) - which is first wrapped
@@ -897,41 +921,32 @@ class KeyClient(object):
         being sent to the DRM.  The parameter trans_wrapped_session_key refers
         to this wrapped session key.
 
-        There are two ways of using this function:
-
-        1) trans_wrapped_session_key is not provided by caller.
-
-        In this case, the function will call CryptoProvider methods to generate
-        and wrap the session key.  The function will return the KeyData object
-        with a private_data attribute which stores the unwrapped key
-        information.
-
-        2)  The trans_wrapped_session_key is provided by the caller.
-
-        In this case, the function will simply pass the data to the DRM, and
-        will return the secret wrapped in the session key.  The secret will
-        still need to be unwrapped by the caller.
-
-        The function will return the KeyData object, where the KeyData structure
-        includes the wrapped secret and some nonce data to be used as a salt
-        when unwrapping.
+        If the trans_wrapped_session_key is not provided by caller, the method
+        will call CryptoProvider methods to generate and wrap the session key.
+        The function will return the KeyData object with a private_data
+        attribute which stores the unwrapped key information.
+
+        If the trans_wrapped_session_key is provided by the caller, the method
+        will simply pass the data to the KRA, and will return the secret
+        wrapped in the session key.  The secret will still need to be unwrapped
+        by the caller.  The function will return the KeyData object, where the
+        KeyData structure includes the wrapped secret and some nonce data to be
+        used as a salt when unwrapping.
         """
-        if key_id is None:
-            raise TypeError("Key ID must be specified")
+        if request_id is not None:
+            # ignore the key_id if set
+            key_id = None
+        elif key_id is None:
+            raise TypeError("Either request_id or Key ID must be specified")
 
-        key_provided = True
+        key_provided = (trans_wrapped_session_key is not None)
         session_key = None
         if trans_wrapped_session_key is None:
-            key_provided = False
             session_key = self.crypto.generate_session_key()
             trans_wrapped_session_key = self.crypto.asymmetric_wrap(
                 session_key,
                 self.transport_cert)
 
-        response = self.recover_key(key_id)
-        request_id = response.get_request_id()
-        self.approve_request(request_id)
-
         request = KeyRecoveryRequest(
             key_id=key_id,
             request_id=request_id,
@@ -939,7 +954,7 @@ class KeyClient(object):
                 trans_wrapped_session_key))
 
         key = self.retrieve_key_data(request)
-        if not key_provided:
+        if not key_provided and key.encrypted_data is not None:
             key.data = self.crypto.symmetric_unwrap(
                 key.encrypted_data,
                 session_key,
@@ -947,7 +962,8 @@ class KeyClient(object):
         return key
 
     @pki.handle_exceptions()
-    def retrieve_key_by_passphrase(self, key_id, passphrase=None,
+    def retrieve_key_by_passphrase(self, key_id=None, request_id=None,
+                                   passphrase=None,
                                    trans_wrapped_session_key=None,
                                    session_wrapped_passphrase=None,
                                    nonce_data=None):
-- 
2.7.4

_______________________________________________
Pki-devel mailing list
[email protected]
https://www.redhat.com/mailman/listinfo/pki-devel

Reply via email to