summaryrefslogtreecommitdiffstats
path: root/base/common/python
diff options
context:
space:
mode:
authorAde Lee <alee@redhat.com>2014-02-21 11:48:54 -0500
committerAde Lee <alee@redhat.com>2014-02-26 01:18:08 -0500
commit7add259c1220ca4f6fa55ae64447812fdbf83132 (patch)
tree26f90c0c6f710760093965ff5b61a2772eaa2b5c /base/common/python
parente68dd1da3715d0b9d39bc6393a84732f15b7b7cd (diff)
downloadpki-7add259c1220ca4f6fa55ae64447812fdbf83132.tar.gz
pki-7add259c1220ca4f6fa55ae64447812fdbf83132.tar.xz
pki-7add259c1220ca4f6fa55ae64447812fdbf83132.zip
Moved key functions out of kraclient.py
Diffstat (limited to 'base/common/python')
-rw-r--r--base/common/python/pki/cryptoutil.py7
-rw-r--r--base/common/python/pki/key.py350
-rw-r--r--base/common/python/pki/kraclient.py199
3 files changed, 261 insertions, 295 deletions
diff --git a/base/common/python/pki/cryptoutil.py b/base/common/python/pki/cryptoutil.py
index b450e820c..b5d5fdc13 100644
--- a/base/common/python/pki/cryptoutil.py
+++ b/base/common/python/pki/cryptoutil.py
@@ -41,6 +41,11 @@ class CryptoUtil(object):
pass
@abc.abstractmethod
+ def initialize(self):
+ ''' Initialization code '''
+ pass
+
+ @abc.abstractmethod
def generate_symmetric_key(self, mechanism=None):
''' Generate and return a symmetric key '''
pass
@@ -112,7 +117,7 @@ class NSSCryptoUtil(CryptoUtil):
self.certdb_password = certdb_password
self.nonce_iv = "e4:bb:3b:d3:c3:71:2e:58"
- def initialize_db(self):
+ def initialize(self):
''' initialize the nss db. Must be done before any crypto operations '''
nss.nss_init(self.certdb_dir)
diff --git a/base/common/python/pki/key.py b/base/common/python/pki/key.py
index 0d1dd36f3..7d93e783a 100644
--- a/base/common/python/pki/key.py
+++ b/base/common/python/pki/key.py
@@ -23,6 +23,7 @@
Module containing the Python client classes for the KeyClient and
KeyRequestClient REST API on a DRM
'''
+import base64
import pki.encoder as encoder
import json
import pki
@@ -287,13 +288,24 @@ class KeyClient(object):
PASS_PHRASE_TYPE = "passPhrase"
ASYMMETRIC_KEY_TYPE = "asymmetricKey"
- def __init__(self, connection):
+ 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.crypto = crypto
+
+ if transport_cert_nick != None:
+ self.crypto.initialize()
+ self.transport_cert = crypto.get_cert(transport_cert_nick)
+ else:
+ self.transport_cert = None
+
+ def set_transport_cert(self, transport_cert_nick):
+ ''' Set the transport certificate for crypto operations '''
+ self.transport_cert = self.crypto.get_cert(transport_cert_nick)
@pki.handle_exceptions()
def list_keys(self, client_key_id=None, status=None, max_results=None,
@@ -310,55 +322,6 @@ class KeyClient(object):
return KeyInfoCollection.from_json(response.json())
@pki.handle_exceptions()
- def retrieve_key(self, data):
- ''' Retrieve a secret from the DRM.
-
- @param: data - a KeyRecoveryRequest containing the keyId of the
- secret being retrieved, the request_id of the approved recovery
- request and a wrapping mechanism. More details at
- KRAClient.retrieve_key.
-
- Returns a KeyData object containing the wrapped secret.
- '''
- url = self.keyURL + '/retrieve'
- keyRequest = json.dumps(data, cls=encoder.CustomTypeEncoder, sort_keys=True)
- response = self.connection.post(url, keyRequest, self.headers)
- return KeyData.from_json(response.json())
-
- @pki.handle_exceptions()
- def request_key_retrieval(self, key_id, request_id, trans_wrapped_session_key=None,
- session_wrapped_passphrase=None, passphrase=None, nonce_data=None):
- ''' Retrieve a secret from the DRM.
-
- The secret (which is referenced by key_id) can be retrieved only if the
- recovery request (referenced by request_id) is approved. key_id and request_id
- are required.
-
- Data must be provided to wrap the recovered secret. This can either be
- a) a 56-bit DES3 symmetric key, wrapped by the DRM transport key, and
- passed in trans_wrapped_session_key
- b) a passphrase. In this case, the passphrase must be wrapped by a 56-bit
- symmetric key ("the session key" and passed in session_wrapped_passphrase,
- and the session key must be wrapped by the DRM transport key and passed
- in trans_wrapped_session_key
- c) a passphrase for a p12 file. If the key being recovered is an asymmetric
- key, then it is possible to pass in the passphrase for the P12 file to
- be generated. This is passed in as passphrase
-
- nonce_data may also be passed as a salt.
-
- Returns a KeyData object containing the wrapped secret.
- '''
- request = KeyRecoveryRequest(key_id=key_id,
- request_id=request_id,
- trans_wrapped_session_key=trans_wrapped_session_key,
- session_wrapped_passphrase=session_wrapped_passphrase,
- nonce_data=nonce_data,
- passphrase=passphrase)
-
- return self.retrieve_key(request)
-
- @pki.handle_exceptions()
def list_requests(self, request_state=None, request_type=None, client_key_id=None,
start=None, page_size=None, max_results=None, max_time=None):
''' List/Search key requests in the DRM.
@@ -381,19 +344,25 @@ class KeyClient(object):
return KeyRequestInfo.from_json(response.json())
@pki.handle_exceptions()
- def create_request(self, request):
- ''' Submit an archival, recovery or key generation request
- to the DRM.
+ def get_key_info(self, key_id):
+ ''' Get the info in the KeyRecord for a specific secret in the DRM. '''
+ url = self.keyURL + '/' + key_id
+ response = self.connection.get(url, headers=self.headers)
+ return KeyInfo.from_json(response.json())
- @param request - is either a KeyArchivalRequest,
- KeyRecoverRequest or SymKeyGenerationRequest.
+ @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. '''
+ url = self.keyURL + '/active/' + urllib.quote_plus(client_key_id)
+ response = self.connection.get(url, headers=self.headers)
+ return KeyInfo.from_json(response.json())
- returns a KeyRequestResponse object.
- '''
- 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 modify_key_status(self, key_id, status):
+ ''' Modify the status of a key '''
+ url = self.keyURL + '/' + key_id
+ params = {'status':status}
+ self.connection.post(url, None, headers=self.headers, params=params)
@pki.handle_exceptions()
def approve_request(self, request_id):
@@ -413,45 +382,98 @@ class KeyClient(object):
url = self.keyRequestsURL + '/' + 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.
+ '''
+ 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)
+
+ return self.generate_pki_archive_options(trans_wrapped_session_key, wrapped_secret)
+
@pki.handle_exceptions()
- def request_recovery(self, key_id, request_id=None, session_wrapped_passphrase=None,
- trans_wrapped_session_key=None, b64certificate=None, nonce_data=None):
- ''' Create a request to recover a secret.
+ def create_request(self, request):
+ ''' Submit an archival, recovery or key generation request
+ to the DRM.
- To retrieve a symmetric key or passphrase, the only parameter that is required is
- the keyId. It is possible (but not required) to pass in the session keys/passphrase
- and nonceData for the retrieval at this time. Those parameters are documented
- in the docstring for retrieve_key below.
+ @param request - is either a KeyArchivalRequest,
+ KeyRecoverRequest or SymKeyGenerationRequest.
- To retrieve an asymmetric key, the keyId and the the base-64 encoded certificate
- is required.
+ returns a KeyRequestResponse object.
'''
- request = KeyRecoveryRequest(key_id=key_id,
- request_id=request_id,
- trans_wrapped_session_key=trans_wrapped_session_key,
- session_wrapped_passphrase=session_wrapped_passphrase,
- certificate=b64certificate,
- nonce_data=nonce_data)
+ 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):
+ ''' 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)
return self.create_request(request)
@pki.handle_exceptions()
- def request_archival(self, client_key_id, data_type, wrapped_private_data,
+ def archive_key(self, client_key_id, data_type, private_data=None,
+ wrapped_private_data=None,
key_algorithm=None, key_size=None):
''' Archive a secret (symmetric key or passphrase) on the DRM.
Requires a user-supplied client ID. There can be only one active
key with a specified client ID. If a record for a duplicate active
- key exists, an exception is thrown.
+ 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
+
+ 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.
- key_algorithm and key_size are applicable to symmetric keys only.
- If a symmetric key is being archived, these parameters are required.
+ private_data is the secret that is to be archived.
+
+ 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.
+
+ 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:
+ 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,
data_type=data_type,
wrapped_private_data=wrapped_private_data,
@@ -460,26 +482,162 @@ class KeyClient(object):
return self.create_request(request)
@pki.handle_exceptions()
- def get_key_info(self, key_id):
- ''' Get the info in the KeyRecord for a specific secret in the DRM. '''
- url = self.keyURL + '/' + key_id
- response = self.connection.get(url, headers=self.headers)
- return KeyInfo.from_json(response.json())
+ def recover_key(self, key_id, request_id=None, session_wrapped_passphrase=None,
+ trans_wrapped_session_key=None, b64certificate=None, nonce_data=None):
+ ''' Create a request to recover a secret.
+
+ To retrieve a symmetric key or passphrase, the only parameter that is required is
+ the keyId. It is possible (but not required) to pass in the session keys/passphrase
+ and nonceData for the retrieval at this time. Those parameters are documented
+ in the docstring for retrieve_key below.
+
+ To retrieve an asymmetric key, the keyId and the the base-64 encoded certificate
+ is required.
+ '''
+ request = KeyRecoveryRequest(key_id=key_id,
+ request_id=request_id,
+ trans_wrapped_session_key=trans_wrapped_session_key,
+ session_wrapped_passphrase=session_wrapped_passphrase,
+ certificate=b64certificate,
+ nonce_data=nonce_data)
+ return self.create_request(request)
@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. '''
- url = self.keyURL + '/active/' + urllib.quote_plus(client_key_id)
- response = self.connection.get(url, headers=self.headers)
- print response
- return KeyInfo.from_json(response.json())
+ def retrieve_key_data(self, data):
+ ''' Retrieve a secret from the DRM.
+
+ @param: data - a KeyRecoveryRequest containing the keyId of the
+ secret being retrieved, the request_id of the approved recovery
+ request and a wrapping mechanism. More details at
+ KRAClient.retrieve_key.
+
+ Returns a KeyData object containing the wrapped secret.
+ '''
+ url = self.keyURL + '/retrieve'
+ keyRequest = json.dumps(data, cls=encoder.CustomTypeEncoder, sort_keys=True)
+ response = self.connection.post(url, keyRequest, self.headers)
+ return KeyData.from_json(response.json())
@pki.handle_exceptions()
- def modify_key_status(self, key_id, status):
- ''' Modify the status of a key '''
- url = self.keyURL + '/' + key_id
- params = {'status':status}
- self.connection.post(url, None, headers=self.headers, params=params)
+ def retrieve_key(self, key_id, trans_wrapped_session_key=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.
+
+ To ensure data security in transit, the data will be returned encrypted by a session
+ key (56 bit DES3 symmetric key) - which is first wrapped (encrypted) by the public
+ key of the DRM transport certificate before 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 CryptoUtil methods to generate and wrap the
+ session key. The function will return the tuple (KeyData, unwrapped_secret)
+
+ 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 tuple (KeyData, None), where the KeyData structure includes the
+ wrapped secret and some nonce data to be used as a salt when unwrapping.
+ '''
+ key_provided = True
+ if (trans_wrapped_session_key == None):
+ key_provided = False
+ session_key = self.crypto.generate_symmetric_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,
+ trans_wrapped_session_key=base64.encodestring(trans_wrapped_session_key))
+
+ key_data = self.retrieve_key_data(request)
+ if key_provided:
+ return key_data, None
+
+ unwrapped_key = self.crypto.symmetric_unwrap(
+ base64.decodestring(key_data.wrappedPrivateData),
+ session_key,
+ nonce_iv=base64.decodestring(key_data.nonceData))
+ return key_data, unwrapped_key
+
+ @pki.handle_exceptions()
+ def retrieve_key_by_passphrase(self, key_id, passphrase=None,
+ trans_wrapped_session_key=None,
+ session_wrapped_passphrase=None,
+ nonce_data=None):
+ ''' Retrieve a secret (passphrase or symmetric key) from the DRM using a passphrase.
+
+ 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.
+
+ The secret is secured in transit by wrapping the secret with a passphrase using
+ PBE encryption.
+
+ There are two ways of using this function:
+
+ 1) A passphrase is provided by the caller.
+
+ In this case, CryptoUtil methods will be called to create the data to securely send the
+ passphrase to the DRM. Basically, three pieces of data will be sent:
+
+ - the passphrase wrapped by a 56 bit DES3 symmetric key (the session key). This
+ is referred to as the parameter session_wrapped_passphrase above.
+
+ - the session key wrapped with the public key in the DRM transport certificate. This
+ is referred to as the trans_wrapped_session_key above.
+
+ - ivps nonce data, referred to as nonce_data
+
+ The function will return the tuple (KeyData, unwrapped_secret)
+
+ 2) The caller provides the trans_wrapped_session_key, session_wrapped_passphrase
+ and nonce_data.
+
+ In this case, the data will simply be passed to the DRM. The function will return
+ the secret encrypted by the passphrase using PBE Encryption. The secret will still
+ need to be decrypted by the caller.
+
+ The function will return the tuple (KeyData, None)
+ '''
+ pass
+
+ @pki.handle_exceptions()
+ def retrieve_key_by_pkcs12(self, key_id, certificate, passphrase):
+ ''' Retrieve an asymmetric private key and return it as PKCS12 data.
+
+ This function generates a key recovery request, approves it, and retrieves
+ the secret referred to by key_id in a PKCS12 file. This assumes that only
+ one approval is required to authorize the recovery.
+
+ This function requires the following parameters:
+ - key_id : the ID of the key
+ - certificate: the certificate associated with the private key
+ - passphrase: A passphrase for the pkcs12 file.
+
+ The function returns a KeyData object.
+ '''
+ response = self.recover_key(key_id, b64certificate=certificate)
+ request_id = response.get_request_id()
+ self.approve_request(request_id)
+
+ request = KeyRecoveryRequest(key_id=key_id,
+ request_id=request_id,
+ passphrase=passphrase)
+
+ return self.retrieve_key_data(request)
encoder.NOTYPES['Attribute'] = pki.Attribute
encoder.NOTYPES['AttributeList'] = pki.AttributeList
diff --git a/base/common/python/pki/kraclient.py b/base/common/python/pki/kraclient.py
index 25c4dc9ca..4d62f38f9 100644
--- a/base/common/python/pki/kraclient.py
+++ b/base/common/python/pki/kraclient.py
@@ -25,7 +25,6 @@ to interact with the DRM to expose the functionality of the KeyClient and
KeyRequestResouce REST APIs.
'''
-import base64
import pki.key as key
from pki.systemcert import SystemCertClient
@@ -49,204 +48,8 @@ class KRAClient(object):
beforehand.
'''
self.connection = connection
- self.keys = key.KeyClient(connection)
+ self.keys = key.KeyClient(connection, crypto, transport_cert_nick)
self.system_certs = SystemCertClient(connection)
- self.crypto = crypto
- if transport_cert_nick != None:
- self.transport_cert = crypto.get_cert(transport_cert_nick)
- else:
- self.transport_cert = None
- def set_transport_cert(self, transport_cert_nick):
- ''' Set the transport certificate for crypto operations '''
- self.transport_cert = self.crypto.get_cert(transport_cert_nick)
- def retrieve_key(self, key_id, trans_wrapped_session_key=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.
-
- To ensure data security in transit, the data will be returned encrypted by a session
- key (56 bit DES3 symmetric key) - which is first wrapped (encrypted) by the public
- key of the DRM transport certificate before 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 CryptoUtil methods to generate and wrap the
- session key. The function will return the tuple (KeyData, unwrapped_secret)
-
- 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 tuple (KeyData, None), where the KeyData structure includes the
- wrapped secret and some nonce data to be used as a salt when unwrapping.
- '''
- key_provided = True
- if (trans_wrapped_session_key == None):
- key_provided = False
- session_key = self.crypto.generate_symmetric_key()
- trans_wrapped_session_key = self.crypto.asymmetric_wrap(session_key,
- self.transport_cert)
-
- response = self.keys.request_recovery(key_id)
- request_id = response.get_request_id()
- self.keys.approve_request(request_id)
-
- key_data = self.keys.request_key_retrieval(key_id, request_id,
- trans_wrapped_session_key=base64.encodestring(trans_wrapped_session_key))
- if key_provided:
- return key_data, None
-
- unwrapped_key = self.crypto.symmetric_unwrap(
- base64.decodestring(key_data.wrappedPrivateData),
- session_key,
- nonce_iv=base64.decodestring(key_data.nonceData))
- return key_data, unwrapped_key
-
- def retrieve_key_by_passphrase(self, key_id, passphrase=None,
- trans_wrapped_session_key=None,
- session_wrapped_passphrase=None,
- nonce_data=None):
- ''' Retrieve a secret (passphrase or symmetric key) from the DRM using a passphrase.
-
- 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.
-
- The secret is secured in transit by wrapping the secret with a passphrase using
- PBE encryption.
-
- There are two ways of using this function:
-
- 1) A passphrase is provided by the caller.
-
- In this case, CryptoUtil methods will be called to create the data to securely send the
- passphrase to the DRM. Basically, three pieces of data will be sent:
-
- - the passphrase wrapped by a 56 bit DES3 symmetric key (the session key). This
- is referred to as the parameter session_wrapped_passphrase above.
-
- - the session key wrapped with the public key in the DRM transport certificate. This
- is referred to as the trans_wrapped_session_key above.
-
- - ivps nonce data, referred to as nonce_data
-
- The function will return the tuple (KeyData, unwrapped_secret)
-
- 2) The caller provides the trans_wrapped_session_key, session_wrapped_passphrase
- and nonce_data.
-
- In this case, the data will simply be passed to the DRM. The function will return
- the secret encrypted by the passphrase using PBE Encryption. The secret will still
- need to be decrypted by the caller.
-
- The function will return the tuple (KeyData, None)
- '''
- pass
-
- def retrieve_key_by_pkcs12(self, key_id, certificate, passphrase):
- ''' Retrieve an asymmetric private key and return it as PKCS12 data.
-
- This function generates a key recovery request, approves it, and retrieves
- the secret referred to by key_id in a PKCS12 file. This assumes that only
- one approval is required to authorize the recovery.
-
- This function requires the following parameters:
- - key_id : the ID of the key
- - certificate: the certificate associated with the private key
- - passphrase: A passphrase for the pkcs12 file.
-
- The function returns a KeyData object.
- '''
- response = self.keys.request_recovery(key_id, b64certificate=certificate)
- request_id = response.get_request_id()
- self.keys.approve_request(request_id)
-
- return self.keys.request_key_retrieval(key_id, request_id, passphrase)
-
-
- def generate_symmetric_key(self, client_key_id, algorithm, size, usages):
- ''' 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 = key.SymKeyGenerationRequest(client_key_id=client_key_id,
- key_size=size,
- key_algorithm=algorithm,
- key_usages=usages)
- return self.keys.create_request(request)
-
- def archive_key(self, client_key_id, data_type, private_data=None,
- wrapped_private_data=None,
- key_algorithm=None, key_size=None):
- ''' Archive a secret (symmetric key or passphrase) on the DRM.
-
- Requires a user-supplied client ID. There can be only one active
- key with a specified client ID. If a record for a duplicate active
- 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
-
- 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.
-
- private_data is the secret that is to be archived.
-
- 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.
-
- 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:
- # raise BadRequestException - to be added in next patch
- return None
- wrapped_private_data = self.generate_archive_options(private_data)
- return self.keys.request_archival(client_key_id, data_type, wrapped_private_data,
- key_algorithm, key_size)
-
- 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.
- '''
- 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)
-
- return self.generate_pki_archive_options(trans_wrapped_session_key, wrapped_secret)