summaryrefslogtreecommitdiffstats
path: root/base/common
diff options
context:
space:
mode:
authorAde Lee <alee@redhat.com>2014-02-21 21:24:39 -0500
committerAde Lee <alee@redhat.com>2014-02-26 01:18:25 -0500
commitee472461f594706b40cedb39e55f167a034c13ee (patch)
tree4b0a800571713e6f6e9ebc88d978d9bab780fb92 /base/common
parent7add259c1220ca4f6fa55ae64447812fdbf83132 (diff)
downloadpki-ee472461f594706b40cedb39e55f167a034c13ee.tar.gz
pki-ee472461f594706b40cedb39e55f167a034c13ee.tar.xz
pki-ee472461f594706b40cedb39e55f167a034c13ee.zip
Added error checking in python client calls
1) Added error checking in python client calls. 2) Allow symmetric key generation with default params. Fix bug for when usages is not defined. 3) Fix bug when requesting key recovery - must check if key exists. 4) Extend key gen to allow for providing trans_wrapped_session_key 5) added constants to python client for key status
Diffstat (limited to 'base/common')
-rw-r--r--base/common/python/pki/key.py102
-rw-r--r--base/common/src/com/netscape/certsrv/key/SymKeyGenerationRequest.java22
-rw-r--r--base/common/src/com/netscape/certsrv/request/IRequest.java1
3 files changed, 108 insertions, 17 deletions
diff --git a/base/common/python/pki/key.py b/base/common/python/pki/key.py
index 7d93e783a..3fa5952db 100644
--- a/base/common/python/pki/key.py
+++ b/base/common/python/pki/key.py
@@ -94,7 +94,7 @@ class KeyInfo(object):
def get_key_id(self):
''' Return the key ID as parsed from key URL '''
- if self.keyURL != None:
+ if self.keyURL is not None:
indx = str(self.keyURL).rfind("/") + 1
return str(self.keyURL)[indx:]
return None
@@ -146,14 +146,14 @@ class KeyRequestInfo(object):
def get_request_id(self):
''' Return the request ID by parsing the request URL. '''
- if self.requestURL != None:
+ if self.requestURL is not None:
indx = str(self.requestURL).rfind("/") + 1
return str(self.requestURL)[indx:]
return None
def get_key_id(self):
''' Return the ID of the secret referred to by this request. '''
- if self.keyURL != None:
+ if self.keyURL is not None:
indx = str(self.keyURL).rfind("/") + 1
return str(self.keyURL)[indx:]
return None
@@ -268,7 +268,7 @@ class SymKeyGenerationRequest(pki.ResourceMessage):
ENCRYPT_USAGE = "encrypt"
def __init__(self, client_key_id=None, key_size=None, key_algorithm=None,
- key_usages=None):
+ key_usages=None, trans_wrapped_session_key=None):
''' Constructor '''
pki.ResourceMessage.__init__(self,
"com.netscape.certsrv.key.SymKeyGenerationRequest")
@@ -277,6 +277,7 @@ class SymKeyGenerationRequest(pki.ResourceMessage):
self.add_attribute("keySize", key_size)
self.add_attribute("keyAlgorithm", key_algorithm)
self.add_attribute("keyUsage", ','.join(key_usages))
+ self.add_attribute("transWrappedSessionKey", trans_wrapped_session_key)
class KeyClient(object):
'''
@@ -288,6 +289,9 @@ class KeyClient(object):
PASS_PHRASE_TYPE = "passPhrase"
ASYMMETRIC_KEY_TYPE = "asymmetricKey"
+ KEY_STATUS_ACTIVE = "active"
+ KEY_STATUS_INACTIVE = "inactive"
+
def __init__(self, connection, crypto, transport_cert_nick=None):
''' Constructor '''
self.connection = connection
@@ -297,7 +301,7 @@ class KeyClient(object):
self.keyRequestsURL = '/rest/agent/keyrequests'
self.crypto = crypto
- if transport_cert_nick != None:
+ if transport_cert_nick is not None:
self.crypto.initialize()
self.transport_cert = crypto.get_cert(transport_cert_nick)
else:
@@ -305,6 +309,8 @@ class KeyClient(object):
def set_transport_cert(self, transport_cert_nick):
''' Set the transport certificate for crypto operations '''
+ if transport_cert_nick is None:
+ raise ValueError("Transport cert nickname must be specified.")
self.transport_cert = self.crypto.get_cert(transport_cert_nick)
@pki.handle_exceptions()
@@ -339,6 +345,9 @@ class KeyClient(object):
@pki.handle_exceptions()
def get_request_info(self, request_id):
''' Return a KeyRequestInfo object for a specific request. '''
+ if request_id is None:
+ raise ValueError("request_id must be specified")
+
url = self.keyRequestsURL + '/' + request_id
response = self.connection.get(url, self.headers)
return KeyRequestInfo.from_json(response.json())
@@ -346,6 +355,9 @@ class KeyClient(object):
@pki.handle_exceptions()
def get_key_info(self, key_id):
''' Get the info in the KeyRecord for a specific secret in the DRM. '''
+ if key_id is None:
+ raise ValueError("key_id must be specified")
+
url = self.keyURL + '/' + key_id
response = self.connection.get(url, headers=self.headers)
return KeyInfo.from_json(response.json())
@@ -353,6 +365,9 @@ class KeyClient(object):
@pki.handle_exceptions()
def get_active_key_info(self, client_key_id):
''' Get the info in the KeyRecord for the active secret in the DRM. '''
+ if client_key_id is None:
+ raise ValueError("client_key_id must be specified")
+
url = self.keyURL + '/active/' + urllib.quote_plus(client_key_id)
response = self.connection.get(url, headers=self.headers)
return KeyInfo.from_json(response.json())
@@ -360,6 +375,9 @@ class KeyClient(object):
@pki.handle_exceptions()
def modify_key_status(self, key_id, status):
''' Modify the status of a key '''
+ if (key_id is None) or (status is None):
+ raise ValueError("key_id and status must be specified")
+
url = self.keyURL + '/' + key_id
params = {'status':status}
self.connection.post(url, None, headers=self.headers, params=params)
@@ -367,18 +385,27 @@ class KeyClient(object):
@pki.handle_exceptions()
def approve_request(self, request_id):
''' Approve a secret recovery request '''
+ if request_id is None:
+ raise ValueError("request_id must be specified")
+
url = self.keyRequestsURL + '/' + request_id + '/approve'
self.connection.post(url, self.headers)
@pki.handle_exceptions()
def reject_request(self, request_id):
''' Reject a secret recovery request. '''
+ if request_id is None:
+ raise ValueError("request_id must be specified")
+
url = self.keyRequestsURL + '/' + request_id + '/reject'
self.connection.post(url, self.headers)
@pki.handle_exceptions()
def cancel_request(self, request_id):
''' Cancel a secret recovery request '''
+ if request_id is None:
+ raise ValueError("request_id must be specified")
+
url = self.keyRequestsURL + '/' + request_id + '/cancel'
self.connection.post(url, self.headers)
@@ -403,6 +430,9 @@ class KeyClient(object):
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_symmetric_key()
trans_wrapped_session_key = self.crypto.asymmetric_wrap(session_key, self.transport_cert)
wrapped_secret = self.crypto.symmetric_wrap(secret, session_key)
@@ -419,22 +449,42 @@ class KeyClient(object):
returns a KeyRequestResponse object.
'''
+ if request is None:
+ raise ValueError("request must be specified")
+
url = self.keyRequestsURL
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())
@pki.handle_exceptions()
- def generate_symmetric_key(self, client_key_id, algorithm, size, usages):
+ def generate_symmetric_key(self, client_key_id, algorithm=None, size=None, usages=None,
+ trans_wrapped_session_key=None):
''' Generate and archive a symmetric key on the DRM.
Return a KeyRequestResponse which contains a KeyRequestInfo
object that describes the URL for the request and generated key.
+
'''
- request = SymKeyGenerationRequest(client_key_id=client_key_id,
- key_size=size,
- key_algorithm=algorithm,
- key_usages=usages)
+ if client_key_id is None:
+ raise ValueError("Must specify client_key_id")
+
+ if trans_wrapped_session_key is not None:
+ twsk = base64.encodestring(trans_wrapped_session_key)
+ request = SymKeyGenerationRequest(
+ client_key_id=client_key_id,
+ key_size=size,
+ key_algorithm=algorithm,
+ key_usages=usages,
+ trans_wrapped_session_key=twsk)
+ raise NotImplementedError(
+ "Returning the symmetric key in the same call is not yet implemented.")
+ else:
+ request = SymKeyGenerationRequest(
+ client_key_id=client_key_id,
+ key_size=size,
+ key_algorithm=algorithm,
+ key_usages=usages)
return self.create_request(request)
@pki.handle_exceptions()
@@ -448,9 +498,9 @@ class KeyClient(object):
key exists, a BadRequestException is thrown.
data_type can be one of the following:
- KeyRequestResource.SYMMETRIC_KEY_TYPE,
- KeyRequestResource.ASYMMETRIC_KEY_TYPE,
- KeyRequestResource.PASS_PHRASE_TYPE
+ KeyClient.SYMMETRIC_KEY_TYPE,
+ KeyClient.ASYMMETRIC_KEY_TYPE,
+ KeyClient.PASS_PHRASE_TYPE
key_algorithm and key_size are applicable to symmetric keys only.
If a symmetric key is being archived, these parameters are required.
@@ -469,8 +519,16 @@ class KeyClient(object):
The function returns a KeyRequestResponse object containing a KeyRequestInfo
object with details about the archival request and key archived.
'''
- if wrapped_private_data == None:
- if private_data == None:
+ if (client_key_id is None) or (data_type is None):
+ raise ValueError("client_key_id and data_type must be specified")
+
+ if data_type == KeyClient.SYMMETRIC_KEY_TYPE:
+ if (key_algorithm is None) or (key_size is None):
+ 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)
@@ -494,6 +552,9 @@ class KeyClient(object):
To retrieve an asymmetric key, the keyId and the the base-64 encoded certificate
is required.
'''
+ if key_id is None:
+ raise ValueError("key_id must be defined")
+
request = KeyRecoveryRequest(key_id=key_id,
request_id=request_id,
trans_wrapped_session_key=trans_wrapped_session_key,
@@ -513,6 +574,9 @@ class KeyClient(object):
Returns a KeyData object containing the wrapped secret.
'''
+ 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)
@@ -546,8 +610,11 @@ class KeyClient(object):
The function will return the tuple (KeyData, None), 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 ValueError("key_id must be specified")
+
key_provided = True
- if (trans_wrapped_session_key == None):
+ if trans_wrapped_session_key is None:
key_provided = False
session_key = self.crypto.generate_symmetric_key()
trans_wrapped_session_key = self.crypto.asymmetric_wrap(session_key,
@@ -629,6 +696,9 @@ class KeyClient(object):
The function returns a KeyData object.
'''
+ if (key_id is None) or (certificate is None) or (passphrase is None):
+ raise ValueError("key_id, certificate and passphrase must all be specified")
+
response = self.recover_key(key_id, b64certificate=certificate)
request_id = response.get_request_id()
self.approve_request(request_id)
diff --git a/base/common/src/com/netscape/certsrv/key/SymKeyGenerationRequest.java b/base/common/src/com/netscape/certsrv/key/SymKeyGenerationRequest.java
index 01326442f..27dc69fd5 100644
--- a/base/common/src/com/netscape/certsrv/key/SymKeyGenerationRequest.java
+++ b/base/common/src/com/netscape/certsrv/key/SymKeyGenerationRequest.java
@@ -25,6 +25,7 @@ public class SymKeyGenerationRequest extends ResourceMessage {
private static final String KEY_SIZE = "keySize";
private static final String KEY_ALGORITHM = "keyAlgorithm";
private static final String KEY_USAGE = "keyUsage";
+ private static final String TRANS_WRAPPED_SESSION_KEY = "transWrappedSessionKey";
/* Symmetric Key usages */
public static final String UWRAP_USAGE = "unwrap";
@@ -65,6 +66,7 @@ public class SymKeyGenerationRequest extends ResourceMessage {
attributes.put(KEY_SIZE, form.getFirst(KEY_SIZE));
attributes.put(KEY_ALGORITHM, form.getFirst(KEY_ALGORITHM));
attributes.put(KEY_USAGE, form.getFirst(KEY_USAGE));
+ attributes.put(TRANS_WRAPPED_SESSION_KEY, form.getFirst(TRANS_WRAPPED_SESSION_KEY));
String usageString = attributes.get(KEY_USAGE);
if (! StringUtils.isBlank(usageString)) {
@@ -96,7 +98,11 @@ public class SymKeyGenerationRequest extends ResourceMessage {
* @return the keySize
*/
public Integer getKeySize() {
- return new Integer(attributes.get(KEY_SIZE));
+ try {
+ return new Integer(attributes.get(KEY_SIZE));
+ } catch (NumberFormatException e) {
+ return null;
+ }
}
/**
@@ -120,6 +126,20 @@ public class SymKeyGenerationRequest extends ResourceMessage {
attributes.put(KEY_ALGORITHM, keyAlgorithm);
}
+ /**
+ * @return the transWrappedSessionKey
+ */
+ public String getTransWrappedSessionKey() {
+ return attributes.get(TRANS_WRAPPED_SESSION_KEY);
+ }
+
+ /**
+ * @param transWrappedSessionKey the wrapped seesion key to set
+ */
+ public void setTransWrappedSessionKey(String transWrappedSessionKey) {
+ attributes.put(TRANS_WRAPPED_SESSION_KEY, transWrappedSessionKey);
+ }
+
public String toString() {
try {
return ResourceMessage.marshal(this, SymKeyGenerationRequest.class);
diff --git a/base/common/src/com/netscape/certsrv/request/IRequest.java b/base/common/src/com/netscape/certsrv/request/IRequest.java
index e77a2e2b8..f9c442754 100644
--- a/base/common/src/com/netscape/certsrv/request/IRequest.java
+++ b/base/common/src/com/netscape/certsrv/request/IRequest.java
@@ -174,6 +174,7 @@ public interface IRequest extends Serializable {
public static final String SYMKEY_GEN_ALGORITHM = "symkeyGenAlgorithm";
public static final String SYMKEY_GEN_SIZE = "symkeyGenSize";
public static final String SYMKEY_GEN_USAGES = "symkeyGenUsages";
+ public static final String SYMKEY_TRANS_WRAPPED_SESSION_KEY = "transWrappedSessionKey";
// requestor type values.
public static final String REQUESTOR_EE = "EE";