summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAde Lee <alee@redhat.com>2014-02-24 15:31:12 -0500
committerAde Lee <alee@redhat.com>2014-02-26 01:18:56 -0500
commit62d4b2b3934507b1ddf699bcea4a6295565bb008 (patch)
tree624b07de5aa7dc1b824f4094f3b3a1fb4fab2320
parent4488bb70e2b762d5282fcf88f1c4a349300dd6ea (diff)
downloadpki-62d4b2b3934507b1ddf699bcea4a6295565bb008.tar.gz
pki-62d4b2b3934507b1ddf699bcea4a6295565bb008.tar.xz
pki-62d4b2b3934507b1ddf699bcea4a6295565bb008.zip
Add ability to archive without sending pkiArchiveOptions object.
With this patch, you can now either send a pkiArchiveOptions object or the exploded parameters. This reduces the processing required on the client side.
-rw-r--r--base/common/python/pki/__init__.py14
-rw-r--r--base/common/python/pki/key.py174
-rw-r--r--base/common/src/com/netscape/certsrv/key/KeyArchivalRequest.java70
-rw-r--r--base/common/src/com/netscape/certsrv/key/KeyClient.java23
-rw-r--r--base/common/src/com/netscape/certsrv/profile/IEnrollProfile.java20
-rw-r--r--base/kra/functional/drmtest.py15
-rw-r--r--base/kra/functional/src/com/netscape/cms/servlet/test/DRMTest.java12
-rw-r--r--base/kra/src/com/netscape/kra/SecurityDataService.java81
-rw-r--r--base/server/cms/src/com/netscape/cms/servlet/key/KeyRequestDAO.java18
-rw-r--r--base/server/cms/src/com/netscape/cms/servlet/request/KeyRequestService.java17
10 files changed, 337 insertions, 107 deletions
diff --git a/base/common/python/pki/__init__.py b/base/common/python/pki/__init__.py
index 7e4e2771c..a747ddb2d 100644
--- a/base/common/python/pki/__init__.py
+++ b/base/common/python/pki/__init__.py
@@ -94,6 +94,7 @@ def implementation_version():
raise Exception('Missing implementation version.')
+#pylint: disable-msg=R0903
class Attribute(object):
'''
Class representing a key/value pair.
@@ -106,6 +107,7 @@ class Attribute(object):
self.name = name
self.value = value
+#pylint: disable-msg=R0903
class AttributeList(object):
'''
Class representing a list of attributes.
@@ -113,6 +115,7 @@ class AttributeList(object):
This class is needed because of a JavaMapper used in the REST API.
'''
+ # pylint: disable-msg=C0103
def __init__(self):
''' Constructor '''
self.Attribute = []
@@ -123,6 +126,7 @@ class ResourceMessage(object):
It is essentially a list of attributes.
'''
+ # pylint: disable-msg=C0103
def __init__(self, class_name):
''' Constructor '''
self.Attributes = AttributeList()
@@ -246,24 +250,24 @@ class PropertyFile(object):
self.lines = []
def read(self):
- ''' Read from propert file '''
+ ''' Read from property file '''
self.lines = []
if not os.path.exists(self.filename):
return
# read all lines and preserve the original order
- with open(self.filename, 'r') as f:
- for line in f:
+ with open(self.filename, 'r') as f_in:
+ for line in f_in:
line = line.strip('\n')
self.lines.append(line)
def write(self):
''' Write to property file '''
# write all lines in the original order
- with open(self.filename, 'w') as f:
+ with open(self.filename, 'w') as f_out:
for line in self.lines:
- f.write(line + '\n')
+ f_out.write(line + '\n')
def show(self):
''' Show contents of property file.'''
diff --git a/base/common/python/pki/key.py b/base/common/python/pki/key.py
index b4158fed6..de9fcc959 100644
--- a/base/common/python/pki/key.py
+++ b/base/common/python/pki/key.py
@@ -30,6 +30,7 @@ import pki
import types
import urllib
+#pylint: disable-msg=R0903
class KeyId(object):
'''
Class representing a key ID
@@ -39,6 +40,7 @@ class KeyId(object):
self.value = key_id
#should be moved to request.py
+#pylint: disable-msg=R0903
class RequestId(object):
'''
Class representing a Request ID
@@ -47,12 +49,14 @@ class RequestId(object):
''' Constructor'''
self.value = req_id
+#pylint: disable-msg=R0903
class KeyData(object):
'''
This is the object that contains the wrapped secret
when that secret is retrieved.
'''
+ # pylint: disable-msg=C0103
def __init__(self):
''' Constructor '''
self.algorithm = None
@@ -75,6 +79,7 @@ class KeyInfo(object):
contain the secret itself.
'''
+ # pylint: disable-msg=C0103
def __init__(self):
''' Constructor '''
self.clientKeyID = None
@@ -99,7 +104,7 @@ class KeyInfo(object):
return str(self.keyURL)[indx:]
return None
-
+#pylint: disable-msg=R0903
class KeyInfoCollection(object):
'''
This class represents data returned when searching the DRM archived
@@ -129,6 +134,7 @@ class KeyRequestInfo(object):
key generation etc.) in the DRM.
'''
+ # pylint: disable-msg=C0103
def __init__(self):
''' Constructor '''
self.requestURL = None
@@ -158,6 +164,7 @@ class KeyRequestInfo(object):
return str(self.keyURL)[indx:]
return None
+#pylint: disable-msg=R0903
class KeyRequestInfoCollection(object):
'''
This class represents the data returned when searching the key
@@ -190,6 +197,7 @@ class KeyRequestResponse(object):
which contains the wrapped secret (if that operation is supported).
'''
+ # pylint: disable-msg=C0103
def __init__(self):
''' Constructor '''
self.requestInfo = None
@@ -221,15 +229,32 @@ class KeyArchivalRequest(pki.ResourceMessage):
'''
def __init__(self, client_key_id=None, data_type=None, wrapped_private_data=None,
+ trans_wrapped_session_key=None, pki_archive_options=None,
+ algorithm_oid = None, symkey_params = None,
key_algorithm=None, key_size=None):
''' Constructor '''
pki.ResourceMessage.__init__(self,
"com.netscape.certsrv.key.KeyArchivalRequest")
self.add_attribute("clientKeyID", client_key_id)
self.add_attribute("dataType", data_type)
- self.add_attribute("wrappedPrivateData", wrapped_private_data)
- self.add_attribute("keyAlgorithm", key_algorithm)
- self.add_attribute("keySize", key_size)
+
+ if wrapped_private_data is not None:
+ self.add_attribute("wrappedPrivateData", wrapped_private_data)
+ if trans_wrapped_session_key is not None:
+ self.add_attribute("transWrappedSessionKey", trans_wrapped_session_key)
+ if algorithm_oid is not None:
+ self.add_attribute("algorithmOID", algorithm_oid)
+ if symkey_params is not None:
+ self.add_attribute("symmetricAlgorithmParams", symkey_params)
+
+ if pki_archive_options is not None:
+ self.add_attribute("pkiArchiveOptions", pki_archive_options)
+
+ if key_algorithm is not None:
+ self.add_attribute("keyAlgorithm", key_algorithm)
+
+ if key_size is not None:
+ self.add_attribute("keySize", key_size)
class KeyRecoveryRequest(pki.ResourceMessage):
'''
@@ -292,13 +317,20 @@ class KeyClient(object):
KEY_STATUS_ACTIVE = "active"
KEY_STATUS_INACTIVE = "inactive"
+ DES_ALGORITHM = "DES"
+ DESEDE_ALGORITHM = "DESede"
+ DES3_ALGORITHM = "DES3"
+ RC2_ALGORITHM = "RC2"
+ RC4_ALGORITHM = "RC4"
+ AES_ALGORITHM = "AES"
+
def __init__(self, connection, crypto, transport_cert_nick=None):
''' Constructor '''
self.connection = connection
self.headers = {'Content-type': 'application/json',
'Accept': 'application/json'}
- self.keyURL = '/rest/agent/keys'
- self.keyRequestsURL = '/rest/agent/keyrequests'
+ self.key_url = '/rest/agent/keys'
+ self.key_requests_url = '/rest/agent/keyrequests'
self.crypto = crypto
if transport_cert_nick is not None:
@@ -324,7 +356,7 @@ class KeyClient(object):
query_params = {'clientKeyID':client_key_id, 'status':status,
'maxResults':max_results, 'maxTime':max_time,
'start':start, 'size':size}
- response = self.connection.get(self.keyURL, self.headers, params=query_params)
+ response = self.connection.get(self.key_url, self.headers, params=query_params)
return KeyInfoCollection.from_json(response.json())
@pki.handle_exceptions()
@@ -338,7 +370,7 @@ class KeyClient(object):
query_params = {'requestState':request_state, 'requestType':request_type,
'clientKeyID':client_key_id, 'start':start, 'pageSize':page_size,
'maxResults':max_results, 'maxTime':max_time}
- response = self.connection.get(self.keyRequestsURL, self.headers,
+ response = self.connection.get(self.key_requests_url, self.headers,
params=query_params)
return KeyRequestInfoCollection.from_json(response.json())
@@ -348,7 +380,7 @@ class KeyClient(object):
if request_id is None:
raise ValueError("request_id must be specified")
- url = self.keyRequestsURL + '/' + request_id
+ url = self.key_requests_url + '/' + request_id
response = self.connection.get(url, self.headers)
return KeyRequestInfo.from_json(response.json())
@@ -358,7 +390,7 @@ class KeyClient(object):
if key_id is None:
raise ValueError("key_id must be specified")
- url = self.keyURL + '/' + key_id
+ url = self.key_url + '/' + key_id
response = self.connection.get(url, headers=self.headers)
return KeyInfo.from_json(response.json())
@@ -368,7 +400,7 @@ class KeyClient(object):
if client_key_id is None:
raise ValueError("client_key_id must be specified")
- url = self.keyURL + '/active/' + urllib.quote_plus(client_key_id)
+ url = self.key_url + '/active/' + urllib.quote_plus(client_key_id)
response = self.connection.get(url, headers=self.headers)
return KeyInfo.from_json(response.json())
@@ -378,7 +410,7 @@ class KeyClient(object):
if (key_id is None) or (status is None):
raise ValueError("key_id and status must be specified")
- url = self.keyURL + '/' + key_id
+ url = self.key_url + '/' + key_id
params = {'status':status}
self.connection.post(url, None, headers=self.headers, params=params)
@@ -388,7 +420,7 @@ class KeyClient(object):
if request_id is None:
raise ValueError("request_id must be specified")
- url = self.keyRequestsURL + '/' + request_id + '/approve'
+ url = self.key_requests_url + '/' + request_id + '/approve'
self.connection.post(url, self.headers)
@pki.handle_exceptions()
@@ -397,7 +429,7 @@ class KeyClient(object):
if request_id is None:
raise ValueError("request_id must be specified")
- url = self.keyRequestsURL + '/' + request_id + '/reject'
+ url = self.key_requests_url + '/' + request_id + '/reject'
self.connection.post(url, self.headers)
@pki.handle_exceptions()
@@ -406,39 +438,9 @@ class KeyClient(object):
if request_id is None:
raise ValueError("request_id must be specified")
- url = self.keyRequestsURL + '/' + request_id + '/cancel'
+ url = self.key_requests_url + '/' + request_id + '/cancel'
self.connection.post(url, self.headers)
- def generate_pki_archive_options(self, trans_wrapped_session_key, session_wrapped_secret):
- ''' Return a PKIArchiveOptions structure for archiving a secret
-
- Takes in a session key wrapped by the DRM transport certificate,
- and a secret wrapped with the session key and creates a PKIArchiveOptions
- structure to be used when archiving a secret
- '''
- pass
-
- def generate_archive_options(self, secret):
- ''' Return a PKIArchiveOptions structure for archiving a secret.
-
- This method uses NSS calls to do the following:
- 1) generate a session key
- 2) wrap the session key with the transport key
- 3) wrap the secret with the session key
- 4) create the PKIArchiveOptions structure using the results of
- (2) and (3)
-
- This method expects initialize_nss() to have been called previously.
- '''
- if secret is None:
- raise ValueError("secret must be specified")
-
- session_key = self.crypto.generate_session_key()
- trans_wrapped_session_key = self.crypto.asymmetric_wrap(session_key, self.transport_cert)
- wrapped_secret = self.crypto.symmetric_wrap(secret, session_key)
-
- return self.generate_pki_archive_options(trans_wrapped_session_key, wrapped_secret)
-
@pki.handle_exceptions()
def create_request(self, request):
''' Submit an archival, recovery or key generation request
@@ -452,7 +454,7 @@ class KeyClient(object):
if request is None:
raise ValueError("request must be specified")
- url = self.keyRequestsURL
+ url = self.key_requests_url
key_request = json.dumps(request, cls=encoder.CustomTypeEncoder, sort_keys=True)
response = self.connection.post(url, key_request, self.headers)
return KeyRequestResponse.from_json(response.json())
@@ -489,7 +491,9 @@ class KeyClient(object):
@pki.handle_exceptions()
def archive_key(self, client_key_id, data_type, private_data=None,
- wrapped_private_data=None,
+ wrapped_private_data=None, trans_wrapped_session_key=None,
+ algorithm_oid=None, symkey_params=None,
+ pki_archive_options=None,
key_algorithm=None, key_size=None):
''' Archive a secret (symmetric key or passphrase) on the DRM.
@@ -505,16 +509,22 @@ class KeyClient(object):
key_algorithm and key_size are applicable to symmetric keys only.
If a symmetric key is being archived, these parameters are required.
- wrapped_private_data consists of a PKIArchiveOptions structure, which
- can be constructed using either generate_archive_options() or
- generate_pki_archive_options() below.
+ Callers can invoke this method in one of three ways:
- private_data is the secret that is to be archived.
+ 1. Provide the private_data. This is the secret to be archived.
+ It will be wrapped and sent to the DRM.
+
+ 2. Provide the following pieces:
+ - wrapped_private_data - which is the secret wrapped by a session
+ key (168 bit 3DES symmetric key)
+ - trans_wrapped_session_key - the above session key wrapped by the
+ DRM transport certificate public key.
+ - the algorithm_oid string for the symmetric key wrap
+ - the symkey_params for the symmetric key wrap
+
+ 3. wrapped_private_data which consists of a PKIArchiveOptions structure,
- Callers must specify EITHER wrapped_private_data OR private_data.
- If wrapped_private_data is specified, then this data is forwarded to the
- DRM unchanged. Otherwise, the private_data is converted to a
- PKIArchiveOptions structure using the functions below.
+ private_data is the secret that is to be archived.
The function returns a KeyRequestResponse object containing a KeyRequestInfo
object with details about the archival request and key archived.
@@ -527,16 +537,50 @@ class KeyClient(object):
raise ValueError(
"For symmetric keys, key algorithm and key_size must be specified")
- if wrapped_private_data is None:
- if private_data is None:
- raise ValueError("No data provided to be archived")
- wrapped_private_data = self.generate_archive_options(private_data)
-
- request = KeyArchivalRequest(client_key_id=client_key_id,
+ if private_data is None:
+ if wrapped_private_data is None:
+ if pki_archive_options is None:
+ raise ValueError("No data provided to be archived")
+ else:
+ data = base64.encodestring(pki_archive_options)
+ request = KeyArchivalRequest(client_key_id=client_key_id,
data_type=data_type,
- wrapped_private_data=wrapped_private_data,
+ pki_archive_options=data,
key_algorithm=key_algorithm,
key_size=key_size)
+ if trans_wrapped_session_key is None:
+ raise ValueError("Session Key not provided")
+ else:
+ twsk = base64.encodestring(trans_wrapped_session_key)
+ data = base64.encodestring(wrapped_private_data)
+ request = KeyArchivalRequest(client_key_id=client_key_id,
+ data_type=data_type,
+ wrapped_private_data=data,
+ trans_wrapped_session_key=twsk,
+ algorithm_oid=algorithm_oid,
+ symkey_params=symkey_params,
+ key_algorithm=key_algorithm,
+ key_size=key_size)
+ else:
+ session_key = self.crypto.generate_session_key()
+ trans_wrapped_session_key = \
+ self.crypto.asymmetric_wrap(session_key, self.transport_cert)
+ wrapped_private_data = self.crypto.symmetric_wrap(private_data, session_key)
+
+ twsk = base64.encodestring(trans_wrapped_session_key)
+ data = base64.encodestring(wrapped_private_data)
+
+ # TODO - generate_algorithm_oid here
+ # generate symkey_params here
+
+ request = KeyArchivalRequest(client_key_id=client_key_id,
+ data_type=data_type,
+ wrapped_private_data=data,
+ trans_wrapped_session_key=twsk,
+ algorithm_oid=algorithm_oid,
+ symkey_params=symkey_params,
+ key_algorithm=key_algorithm,
+ key_size=key_size)
return self.create_request(request)
@pki.handle_exceptions()
@@ -577,9 +621,9 @@ class KeyClient(object):
if data is None:
raise ValueError("KeyRecoveryRequest must be specified")
- url = self.keyURL + '/retrieve'
- keyRequest = json.dumps(data, cls=encoder.CustomTypeEncoder, sort_keys=True)
- response = self.connection.post(url, keyRequest, self.headers)
+ url = self.key_url + '/retrieve'
+ key_request = json.dumps(data, cls=encoder.CustomTypeEncoder, sort_keys=True)
+ response = self.connection.post(url, key_request, self.headers)
return KeyData.from_json(response.json())
@pki.handle_exceptions()
diff --git a/base/common/src/com/netscape/certsrv/key/KeyArchivalRequest.java b/base/common/src/com/netscape/certsrv/key/KeyArchivalRequest.java
index 3c7628af9..03bbfb53a 100644
--- a/base/common/src/com/netscape/certsrv/key/KeyArchivalRequest.java
+++ b/base/common/src/com/netscape/certsrv/key/KeyArchivalRequest.java
@@ -38,7 +38,17 @@ public class KeyArchivalRequest extends ResourceMessage {
private static final String CLIENT_KEY_ID = "clientKeyID";
private static final String DATA_TYPE = "dataType";
+
+ // exploded pkiArchiveOptions parameters
private static final String WRAPPED_PRIVATE_DATA = "wrappedPrivateData";
+ private static final String TRANS_WRAPPED_SESSION_KEY = "transWrappedSessionKey";
+ private static final String ALGORITHM_OID = "algorithmOID";
+ private static final String SYMMETRIC_ALGORITHM_PARAMS = "symmetricAlgorithmParams";
+
+ // parameter for un-exploded pkiArchiveOptions
+ private static final String PKI_ARCHIVE_OPTIONS = "pkiArchiveOptions";
+
+ // parameters for symmetric keys
private static final String KEY_ALGORITHM = "keyAlgorithm";
private static final String KEY_SIZE = "keySize";
@@ -53,6 +63,8 @@ public class KeyArchivalRequest extends ResourceMessage {
attributes.put(WRAPPED_PRIVATE_DATA, form.getFirst(WRAPPED_PRIVATE_DATA));
attributes.put(KEY_ALGORITHM, form.getFirst(KEY_ALGORITHM));
attributes.put(KEY_SIZE, form.getFirst(KEY_SIZE));
+ attributes.put(PKI_ARCHIVE_OPTIONS, form.getFirst(PKI_ARCHIVE_OPTIONS));
+ attributes.put(TRANS_WRAPPED_SESSION_KEY, form.getFirst(TRANS_WRAPPED_SESSION_KEY));
setClassName(getClass().getName());
}
@@ -90,7 +102,63 @@ public class KeyArchivalRequest extends ResourceMessage {
}
/**
- * @return the wrappedPrivateData
+ * @return the transWrappedSessionKey
+ */
+ public String getTransWrappedSessionKey() {
+ return attributes.get(TRANS_WRAPPED_SESSION_KEY);
+ }
+
+ /**
+ * @param transWrappedSessionKey the trans wrapped session key to set
+ */
+ public void setTransWrappedSessionKey(String twsk) {
+ attributes.put(TRANS_WRAPPED_SESSION_KEY, twsk);
+ }
+
+ /**
+ * @return the PKIArchiveOptions structure
+ */
+ public String getPKIArchiveOptions() {
+ return attributes.get(PKI_ARCHIVE_OPTIONS);
+ }
+
+ /**
+ * @param pkiArchiveIOptions the archive options structure to set
+ */
+ public void setPKIArchiveOptions(String pkiArchiveOptions) {
+ attributes.put(PKI_ARCHIVE_OPTIONS, pkiArchiveOptions);
+ }
+
+ /**
+ * @return the algorithm OID structure
+ */
+ public String getAlgorithmOID() {
+ return attributes.get(ALGORITHM_OID);
+ }
+
+ /**
+ * @param algorithmOID the symmetric algorithm OID to set
+ */
+ public void setAlgorithmOID(String algOID) {
+ attributes.put(ALGORITHM_OID, algOID);
+ }
+
+ /**
+ * @return the algorithm params structure
+ */
+ public String getSymmetricAlgorithmParams() {
+ return attributes.get(SYMMETRIC_ALGORITHM_PARAMS);
+ }
+
+ /**
+ * @param params the algorithm params to set
+ */
+ public void setSymmetricAlgorithmParams(String params) {
+ attributes.put(SYMMETRIC_ALGORITHM_PARAMS, params);
+ }
+
+ /**
+ * @return the pkiArchiveOptions structure
*/
public String getWrappedPrivateData() {
return attributes.get(WRAPPED_PRIVATE_DATA);
diff --git a/base/common/src/com/netscape/certsrv/key/KeyClient.java b/base/common/src/com/netscape/certsrv/key/KeyClient.java
index 3c27dbb6c..0fa1f264e 100644
--- a/base/common/src/com/netscape/certsrv/key/KeyClient.java
+++ b/base/common/src/com/netscape/certsrv/key/KeyClient.java
@@ -118,11 +118,28 @@ public class KeyClient extends Client {
return client.getEntity(response, KeyRequestInfo.class);
}
- public KeyRequestResponse archiveSecurityData(byte[] encoded, String clientKeyId, String dataType, String algorithm, int strength) {
+ public KeyRequestResponse archiveSecurityData(String clientKeyId, String dataType,
+ String algorithm, int strength, byte[] pkiArchiveOptions) {
// create archival request
KeyArchivalRequest data = new KeyArchivalRequest();
- String req1 = Utils.base64encode(encoded);
- data.setWrappedPrivateData(req1);
+ data.setPKIArchiveOptions(Utils.base64encode(pkiArchiveOptions));
+ data.setClientKeyId(clientKeyId);
+ data.setDataType(dataType);
+ data.setKeyAlgorithm(algorithm);
+ data.setKeySize(strength);
+
+ return createRequest(data);
+ }
+
+ public KeyRequestResponse archiveSecurityData(String clientKeyId, String dataType,
+ String algorithm, int strength, byte[] wrappedPrivateData,
+ byte[] wrappedSessionKey, String algorithmOID, byte[] algParams) {
+ // create archival request
+ KeyArchivalRequest data = new KeyArchivalRequest();
+ data.setTransWrappedSessionKey(Utils.base64encode(wrappedSessionKey));
+ data.setWrappedPrivateData(Utils.base64encode(wrappedPrivateData));
+ data.setAlgorithmOID(algorithmOID);
+ data.setSymmetricAlgorithmParams(Utils.base64encode(algParams));
data.setClientKeyId(clientKeyId);
data.setDataType(dataType);
data.setKeyAlgorithm(algorithm);
diff --git a/base/common/src/com/netscape/certsrv/profile/IEnrollProfile.java b/base/common/src/com/netscape/certsrv/profile/IEnrollProfile.java
index a2767ee53..69a39d7e2 100644
--- a/base/common/src/com/netscape/certsrv/profile/IEnrollProfile.java
+++ b/base/common/src/com/netscape/certsrv/profile/IEnrollProfile.java
@@ -155,6 +155,26 @@ public interface IEnrollProfile extends IProfile {
public static final String REQUEST_TRANSPORT_CERT = "req_transport_cert";
/**
+ * Session wrapped security data passed in to the DRM archival service
+ */
+ public static final String REQUEST_SECURITY_DATA = "req_security_data";
+
+ /**
+ * Transport Key wrapped session key passed into DRM archival service.
+ */
+ public static final String REQUEST_SESSION_KEY = "req_session_key";
+
+ /**
+ * Symmetric Key algorithm OID passed into DRM archival service
+ */
+ public static final String REQUEST_ALGORITHM_OID = "req_algorithm_oid";
+
+ /**
+ * Symmetric key algorithm params passed into DRM archival service
+ */
+ public static final String REQUEST_ALGORITHM_PARAMS = "req_algorithm_params";
+
+ /**
* Set Default X509CertInfo in the request.
*
* @param request profile-based certificate request.
diff --git a/base/kra/functional/drmtest.py b/base/kra/functional/drmtest.py
index dd7abbf53..08baf5011 100644
--- a/base/kra/functional/drmtest.py
+++ b/base/kra/functional/drmtest.py
@@ -106,7 +106,7 @@ def main():
# Test 4: generate symkey -- same as barbican_encode()
print "Now generating symkey on KRA"
#client_key_id = "Vek #1" + time.strftime('%X %x %Z')
- client_key_id = "veka6"
+ client_key_id = "veka9"
algorithm = "AES"
key_size = 128
usages = [key.SymKeyGenerationRequest.DECRYPT_USAGE, key.SymKeyGenerationRequest.ENCRYPT_USAGE]
@@ -132,6 +132,7 @@ def main():
# Test 6: Barbican_decode() - Retrieve while providing trans_wrapped_session_key
session_key = crypto.generate_session_key()
wrapped_session_key = crypto.asymmetric_wrap(session_key, keyclient.transport_cert)
+ print "My key id is " + str(key_id)
key_data, _unwrapped_key = keyclient.retrieve_key(key_id, trans_wrapped_session_key=wrapped_session_key)
print_key_data(key_data)
unwrapped_key = crypto.symmetric_unwrap(base64.decodestring(key_data.wrappedPrivateData),
@@ -211,5 +212,17 @@ def main():
response = keyclient.generate_symmetric_key(client_key_id)
print_key_request(response.requestInfo)
+ # Test 19: Try to archive key
+ print "try to archive key"
+ print "key to archive: " + key1
+ client_key_id = "Vek #4" + time.strftime('%X %x %Z')
+
+ # this test is not quite working yet
+ #response = keyclient.archive_key(client_key_id, keyclient.SYMMETRIC_KEY_TYPE,
+ # private_data=base64.decodestring(key1),
+ # key_algorithm=keyclient.AES_ALGORITHM,
+ # key_size=128)
+ #print_key_request(response.requestInfo)
+
if __name__ == "__main__":
main()
diff --git a/base/kra/functional/src/com/netscape/cms/servlet/test/DRMTest.java b/base/kra/functional/src/com/netscape/cms/servlet/test/DRMTest.java
index 5681c1114..899c78a66 100644
--- a/base/kra/functional/src/com/netscape/cms/servlet/test/DRMTest.java
+++ b/base/kra/functional/src/com/netscape/cms/servlet/test/DRMTest.java
@@ -263,8 +263,8 @@ public class DRMTest {
byte[] encoded = CryptoUtil.createPKIArchiveOptions(manager, token, transportCert, vek, null,
KeyGenAlgorithm.DES3, ivps);
- KeyRequestResponse info = keyClient.archiveSecurityData(encoded, clientKeyId,
- KeyRequestResource.SYMMETRIC_KEY_TYPE, KeyRequestResource.DES3_ALGORITHM, 0);
+ KeyRequestResponse info = keyClient.archiveSecurityData(clientKeyId, KeyRequestResource.SYMMETRIC_KEY_TYPE,
+ KeyRequestResource.DES3_ALGORITHM, 0, encoded);
log("Archival Results:");
printRequestInfo(info.getRequestInfo());
keyId = info.getRequestInfo().getKeyId();
@@ -375,8 +375,8 @@ public class DRMTest {
try {
byte[] encoded = CryptoUtil.createPKIArchiveOptions(manager, token, transportCert, null, passphrase,
KeyGenAlgorithm.DES3, ivps);
- requestResponse = keyClient.archiveSecurityData(encoded, clientKeyId,
- KeyRequestResource.PASS_PHRASE_TYPE, null, 0);
+ requestResponse = keyClient.archiveSecurityData(clientKeyId, KeyRequestResource.PASS_PHRASE_TYPE,
+ null, 0, encoded);
log("Archival Results:");
printRequestInfo(requestResponse.getRequestInfo());
keyId = requestResponse.getRequestInfo().getKeyId();
@@ -661,8 +661,8 @@ public class DRMTest {
byte[] encoded = CryptoUtil.createPKIArchiveOptions(manager, token, transportCert, vek, null,
KeyGenAlgorithm.DES3, ivps);
- KeyRequestResponse response = keyClient.archiveSecurityData(encoded, clientKeyId,
- KeyRequestResource.SYMMETRIC_KEY_TYPE, KeyRequestResource.AES_ALGORITHM, 128);
+ KeyRequestResponse response = keyClient.archiveSecurityData(clientKeyId, KeyRequestResource.SYMMETRIC_KEY_TYPE,
+ KeyRequestResource.AES_ALGORITHM, 128, encoded);
log("Archival Results:");
printRequestInfo(response.getRequestInfo());
keyId = response.getRequestInfo().getKeyId();
diff --git a/base/kra/src/com/netscape/kra/SecurityDataService.java b/base/kra/src/com/netscape/kra/SecurityDataService.java
index 388079f32..37229f09a 100644
--- a/base/kra/src/com/netscape/kra/SecurityDataService.java
+++ b/base/kra/src/com/netscape/kra/SecurityDataService.java
@@ -84,7 +84,17 @@ public class SecurityDataService implements IService {
throws EBaseException {
String id = request.getRequestId().toString();
String clientKeyId = request.getExtDataInString(IRequest.SECURITY_DATA_CLIENT_KEY_ID);
- String wrappedSecurityData = request.getExtDataInString(IEnrollProfile.REQUEST_ARCHIVE_OPTIONS);
+
+ // one way to get data - unexploded pkiArchiveOptions
+ String pkiArchiveOptions = request.getExtDataInString(IEnrollProfile.REQUEST_ARCHIVE_OPTIONS);
+
+ // another way - exploded pkiArchiveOptions
+ String transWrappedSessionKey = request.getExtDataInString(IEnrollProfile.REQUEST_SESSION_KEY);
+ String wrappedSecurityData = request.getExtDataInString(IEnrollProfile.REQUEST_SECURITY_DATA);
+ String algParams = request.getExtDataInString(IEnrollProfile.REQUEST_ALGORITHM_PARAMS);
+ String algStr = request.getExtDataInString(IEnrollProfile.REQUEST_ALGORITHM_OID);
+
+ // prameters if the secret is a symkey
String dataType = request.getExtDataInString(IRequest.SECURITY_DATA_TYPE);
String algorithm = request.getExtDataInString(IRequest.SECURITY_DATA_ALGORITHM);
int strength = request.getExtDataInInteger(IRequest.SECURITY_DATA_STRENGTH);
@@ -96,25 +106,50 @@ public class SecurityDataService implements IService {
String subjectID = auditSubjectID();
//Check here even though restful layer checks for this.
- if(wrappedSecurityData == null || clientKeyId == null || dataType == null) {
+ if (clientKeyId == null || dataType == null) {
auditArchivalRequestProcessed(subjectID, ILogger.FAILURE, request.getRequestId(),
clientKeyId, null, "Bad data in request");
throw new EBaseException("Bad data in SecurityDataService.serviceRequest");
}
- //We need some info from the PKIArchiveOptions wrapped security data
- byte[] encoded = Utils.base64decode(wrappedSecurityData);
+ if (wrappedSecurityData != null) {
+ if (transWrappedSessionKey == null || algStr == null || algParams == null) {
+ throw new EBaseException(
+ "Bad data in SecurityDataService.serviceRequest, no session key");
- ArchiveOptions options = ArchiveOptions.toArchiveOptions(encoded);
-
- //Check here just in case a null ArchiveOptions makes it this far
- if(options == null) {
- auditArchivalRequestProcessed(subjectID, ILogger.FAILURE, request.getRequestId(),
- clientKeyId, null, "Problem decoding PKIArchiveOptions");
- throw new EBaseException("Problem decoding PKIArchiveOptions.");
+ }
+ } else if (pkiArchiveOptions == null) {
+ throw new EBaseException("No data to archive in SecurityDataService.serviceRequest");
}
- String algStr = options.getSymmAlgOID();
+ byte[] wrappedSessionKey = null;
+ byte[] secdata = null;
+ byte[] sparams = null;
+
+ if (wrappedSecurityData == null) {
+ // We have PKIArchiveOptions data
+
+ //We need some info from the PKIArchiveOptions wrapped security data
+ byte[] encoded = Utils.base64decode(pkiArchiveOptions);
+
+ ArchiveOptions options = ArchiveOptions.toArchiveOptions(encoded);
+
+ //Check here just in case a null ArchiveOptions makes it this far
+ if (options == null) {
+ auditArchivalRequestProcessed(subjectID, ILogger.FAILURE, request.getRequestId(),
+ clientKeyId, null, "Problem decoding PKIArchiveOptions");
+ throw new EBaseException("Problem decoding PKIArchiveOptions.");
+ }
+ algStr = options.getSymmAlgOID();
+ wrappedSessionKey = options.getEncSymmKey();
+ secdata = options.getEncValue();
+ sparams = options.getSymmAlgParams();
+
+ } else {
+ wrappedSessionKey = Utils.base64decode(transWrappedSessionKey);
+ secdata = Utils.base64decode(wrappedSecurityData);
+ sparams = Utils.base64decode(algParams);
+ }
SymmetricKey securitySymKey = null;
byte[] securityData = null;
@@ -123,19 +158,21 @@ public class SecurityDataService implements IService {
if (dataType.equals(KeyRequestResource.SYMMETRIC_KEY_TYPE)) {
// Symmetric Key
keyType = KeyRequestResource.SYMMETRIC_KEY_TYPE;
- securitySymKey = mTransportUnit.unwrap_symmetric(options.getEncSymmKey(),
- options.getSymmAlgOID(),
- options.getSymmAlgParams(),
- options.getEncValue(),
- KeyRequestService.SYMKEY_TYPES.get(algorithm),
- strength);
+ securitySymKey = mTransportUnit.unwrap_symmetric(
+ wrappedSessionKey,
+ algStr,
+ sparams,
+ secdata,
+ KeyRequestService.SYMKEY_TYPES.get(algorithm),
+ strength);
} else if (dataType.equals(KeyRequestResource.PASS_PHRASE_TYPE)) {
keyType = KeyRequestResource.PASS_PHRASE_TYPE;
- securityData = mTransportUnit.decryptExternalPrivate(options.getEncSymmKey(),
- options.getSymmAlgOID(),
- options.getSymmAlgParams(),
- options.getEncValue());
+ securityData = mTransportUnit.decryptExternalPrivate(
+ wrappedSessionKey,
+ algStr,
+ sparams,
+ secdata);
}
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 d84bbd013..93e0018c4 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
@@ -63,6 +63,11 @@ import com.netscape.cms.servlet.request.KeyRequestService;
public class KeyRequestDAO extends CMSRequestDAO {
private static String REQUEST_ARCHIVE_OPTIONS = IEnrollProfile.REQUEST_ARCHIVE_OPTIONS;
+ private static String REQUEST_SECURITY_DATA = IEnrollProfile.REQUEST_SECURITY_DATA;
+ private static String REQUEST_SESSION_KEY = IEnrollProfile.REQUEST_SESSION_KEY;
+ private static String REQUEST_ALGORITHM_OID = IEnrollProfile.REQUEST_ALGORITHM_OID;
+ private static String REQUEST_ALGORITHM_PARAMS = IEnrollProfile.REQUEST_ALGORITHM_PARAMS;
+
public static final String ATTR_SERIALNO = "serialNumber";
private IKeyRepository repo;
@@ -140,6 +145,10 @@ public class KeyRequestDAO extends CMSRequestDAO {
public KeyRequestResponse submitRequest(KeyArchivalRequest data, UriInfo uriInfo) throws EBaseException {
String clientKeyId = data.getClientKeyId();
String wrappedSecurityData = data.getWrappedPrivateData();
+ String transWrappedSessionKey = data.getTransWrappedSessionKey();
+ String algorithmOID = data.getAlgorithmOID();
+ String symkeyParams = data.getSymmetricAlgorithmParams();
+ String pkiArchiveOptions = data.getPKIArchiveOptions();
String dataType = data.getDataType();
String keyAlgorithm = data.getKeyAlgorithm();
int keyStrength = data.getKeySize();
@@ -152,7 +161,14 @@ public class KeyRequestDAO extends CMSRequestDAO {
IRequest request = queue.newRequest(IRequest.SECURITY_DATA_ENROLLMENT_REQUEST);
- request.setExtData(REQUEST_ARCHIVE_OPTIONS, wrappedSecurityData);
+ if (pkiArchiveOptions != null) {
+ request.setExtData(REQUEST_ARCHIVE_OPTIONS, pkiArchiveOptions);
+ } else {
+ request.setExtData(REQUEST_SECURITY_DATA, wrappedSecurityData);
+ request.setExtData(REQUEST_SESSION_KEY, transWrappedSessionKey);
+ request.setExtData(REQUEST_ALGORITHM_PARAMS, symkeyParams);
+ request.setExtData(REQUEST_ALGORITHM_OID, algorithmOID);
+ }
request.setExtData(IRequest.SECURITY_DATA_CLIENT_KEY_ID, clientKeyId);
request.setExtData(IRequest.SECURITY_DATA_TYPE, dataType);
request.setExtData(IRequest.SECURITY_DATA_STRENGTH,
diff --git a/base/server/cms/src/com/netscape/cms/servlet/request/KeyRequestService.java b/base/server/cms/src/com/netscape/cms/servlet/request/KeyRequestService.java
index dd27c2ac7..e2253b6e8 100644
--- a/base/server/cms/src/com/netscape/cms/servlet/request/KeyRequestService.java
+++ b/base/server/cms/src/com/netscape/cms/servlet/request/KeyRequestService.java
@@ -162,12 +162,23 @@ public class KeyRequestService extends PKIService implements KeyRequestResource
// auth and authz
// Catch this before internal server processing has to deal with it
- if (data == null || data.getClientKeyId() == null
- || data.getWrappedPrivateData() == null
- || data.getDataType() == null) {
+ if (data == null || data.getClientKeyId() == null || data.getDataType() == null) {
throw new BadRequestException("Invalid key archival request.");
}
+ if (data.getWrappedPrivateData() != null) {
+ if (data.getTransWrappedSessionKey() == null ||
+ data.getAlgorithmOID() == null ||
+ data.getSymmetricAlgorithmParams() == null) {
+ throw new BadRequestException(
+ "Invalid key archival request. " +
+ "Missing wrapped session key, algoriithmOIS or symmetric key parameters");
+ }
+ } else if (data.getPKIArchiveOptions() == null) {
+ throw new BadRequestException(
+ "Invalid key archival request. No data to archive");
+ }
+
if (data.getDataType().equals(KeyRequestResource.SYMMETRIC_KEY_TYPE)) {
if ((data.getKeyAlgorithm() == null) ||
(! SYMKEY_TYPES.containsKey(data.getKeyAlgorithm()))) {