def test_symmetric_key_register_get_destroy(self): """ Test that the ProxyKmipClient can register, retrieve, and destroy a symmetric key. """ # Key encoding obtained from Section 14.2 of the KMIP 1.1 test # documentation. key = objects.SymmetricKey( enums.CryptographicAlgorithm.AES, 128, (b'\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0A\x0B\x0C\x0D\x0E' b'\x0F')) uid = self.client.register(key) self.assertIsInstance(uid, six.string_types) try: result = self.client.get(uid) self.assertIsInstance(result, objects.SymmetricKey) self.assertEqual(result, key, "expected {0}\nobserved {1}".format(result, key)) finally: self.client.destroy(uid) self.assertRaises(exceptions.KmipOperationFailure, self.client.get, uid) self.assertRaises(exceptions.KmipOperationFailure, self.client.destroy, uid)
def test_derive_key_using_encryption(self): """ Test that the ProxyKmipClient can derive a new key using encryption. """ key_id = self.client.register( objects.SymmetricKey( enums.CryptographicAlgorithm.BLOWFISH, 128, (b'\x01\x23\x45\x67\x89\xAB\xCD\xEF' b'\xF0\xE1\xD2\xC3\xB4\xA5\x96\x87'), masks=[enums.CryptographicUsageMask.DERIVE_KEY])) secret_id = self.client.derive_key( enums.ObjectType.SECRET_DATA, [key_id], enums.DerivationMethod.ENCRYPT, { 'cryptographic_parameters': { 'block_cipher_mode': enums.BlockCipherMode.CBC, 'padding_method': enums.PaddingMethod.PKCS5, 'cryptographic_algorithm': enums.CryptographicAlgorithm.BLOWFISH }, 'initialization_vector': b'\xFE\xDC\xBA\x98\x76\x54\x32\x10', 'derivation_data': (b'\x37\x36\x35\x34\x33\x32\x31\x20' b'\x4E\x6F\x77\x20\x69\x73\x20\x74' b'\x68\x65\x20\x74\x69\x6D\x65\x20' b'\x66\x6F\x72\x20\x00') }, cryptographic_length=256) secret = self.client.get(secret_id) self.assertEqual((b'\x6B\x77\xB4\xD6\x30\x06\xDE\xE6' b'\x05\xB1\x56\xE2\x74\x03\x97\x93' b'\x58\xDE\xB9\xE7\x15\x46\x16\xD9' b'\x74\x9D\xEC\xBE\xC0\x5D\x26\x4B'), secret.value)
def test_register_on_operation_failure(self): """ Test that a KmipOperationFailure exception is raised when the backend fails to register a key. """ status = enums.ResultStatus.OPERATION_FAILED reason = enums.ResultReason.GENERAL_FAILURE message = "Test failure message" result = results.OperationResult(contents.ResultStatus(status), contents.ResultReason(reason), contents.ResultMessage(message)) error_msg = str(KmipOperationFailure(status, reason, message)) # Key encoding obtained from Section 14.2 of the KMIP 1.1 test # documentation. key_value = ( b'\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0A\x0B\x0C\x0D\x0E' b'\x0F') key = objects.SymmetricKey(enums.CryptographicAlgorithm.AES, 128, key_value) client = ProxyKmipClient() client.open() client.proxy.register.return_value = result args = [key] self.assertRaisesRegexp(KmipOperationFailure, error_msg, client.register, *args)
def test_get(self): """ Test that a secret can be retrieved with proper input. """ # Key encoding obtained from Section 14.2 of the KMIP 1.1 test # documentation. secret = objects.SymmetricKey( enums.CryptographicAlgorithm.AES, 128, (b'\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0A\x0B\x0C\x0D\x0E' b'\x0F')) fact = factory.ObjectFactory() result = results.GetResult(contents.ResultStatus( enums.ResultStatus.SUCCESS), uuid=attr.PublicKeyUniqueIdentifier( 'aaaaaaaa-1111-2222-3333-ffffffffffff'), secret=fact.convert(secret)) with ProxyKmipClient() as client: client.proxy.get.return_value = result result = client.get('aaaaaaaa-1111-2222-3333-ffffffffffff') client.proxy.get.assert_called_with( 'aaaaaaaa-1111-2222-3333-ffffffffffff') self.assertIsInstance(result, objects.SymmetricKey) self.assertEqual(result, secret)
def get_sample_symmetric_key(key_b64=utils.get_symmetric_key(), key_length=128, algorithm=enums.CryptographicAlgorithm.AES): return objects.SymmetricKey( algorithm, key_length, base64.b64decode(key_b64))
def test_build_core_key(self): """ Test that a Pie key object can be converted into a core key object. """ pie_key = pobjects.SymmetricKey(enums.CryptographicAlgorithm.AES, 128, self.symmetric_bytes) core_key = self.factory._build_core_key(pie_key, secrets.SymmetricKey) self.assertIsInstance(core_key, secrets.SymmetricKey) self._test_core_key(core_key, enums.CryptographicAlgorithm.AES, 128, self.symmetric_bytes, enums.KeyFormatType.RAW)
def test_register_on_closed(self): """ Test that a ClientConnectionNotOpen exception is raised when trying to register a key on an unopened client connection. """ key = objects.SymmetricKey( enums.CryptographicAlgorithm.AES, 128, (b'\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0A\x0B\x0C\x0D\x0E' b'\x0F')) client = ProxyKmipClient() args = [key] self.assertRaises(ClientConnectionNotOpen, client.register, *args)
def test_store_symmetric_secret_assert_called(self): key_spec = secret_store.KeySpec(secret_store.KeyAlgorithm.AES, 128, 'mode') sym_key = utils.get_symmetric_key() secret_dto = secret_store.SecretDTO(secret_store.SecretType.SYMMETRIC, sym_key, key_spec, 'content_type', transport_key=None) self.secret_store.store_secret(secret_dto) self.secret_store.client.register.assert_called_once_with( objects.SymmetricKey(enums.CryptographicAlgorithm.AES, 128, base64.b64decode(utils.get_symmetric_key())))
def _get_kmip_secret(self, secret_dto): """Builds a KMIP object from a SecretDTO This is needed for register calls. The Barbican object needs to be converted to KMIP object before it can be stored :param secret_dto: SecretDTO of secret to be stored :returns: KMIP object """ secret_type = secret_dto.type key_spec = secret_dto.key_spec object_type, key_format_type = ( self._map_type_ss_to_kmip(secret_type)) normalized_secret = self._normalize_secret(secret_dto.secret, secret_type) kmip_object = None if object_type == enums.ObjectType.CERTIFICATE: kmip_object = objects.X509Certificate(normalized_secret) elif object_type == enums.ObjectType.OPAQUE_DATA: opaque_type = enums.OpaqueDataType.NONE kmip_object = objects.OpaqueObject(normalized_secret, opaque_type) elif object_type == enums.ObjectType.PRIVATE_KEY: algorithm = self._get_kmip_algorithm(key_spec.alg) length = key_spec.bit_length format_type = enums.KeyFormatType.PKCS_8 kmip_object = objects.PrivateKey( algorithm, length, normalized_secret, format_type) elif object_type == enums.ObjectType.PUBLIC_KEY: algorithm = self._get_kmip_algorithm(key_spec.alg) length = key_spec.bit_length format_type = enums.KeyFormatType.X_509 kmip_object = objects.PublicKey( algorithm, length, normalized_secret, format_type) elif object_type == enums.ObjectType.SYMMETRIC_KEY: algorithm = self._get_kmip_algorithm(key_spec.alg) length = key_spec.bit_length kmip_object = objects.SymmetricKey(algorithm, length, normalized_secret) elif object_type == enums.ObjectType.SECRET_DATA: data_type = enums.SecretDataType.PASSWORD kmip_object = objects.SecretData(normalized_secret, data_type) return kmip_object
def test_register_wrapped_get_destroy(self): """ Test that a wrapped key can be registered with the server and that its metadata is retrieved with the get operation. """ key = objects.SymmetricKey( enums.CryptographicAlgorithm.AES, 128, (b'\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0A\x0B\x0C\x0D\x0E' b'\x0F'), key_wrapping_data={ 'wrapping_method': enums.WrappingMethod.ENCRYPT, 'encryption_key_information': { 'unique_identifier': '42', 'cryptographic_parameters': { 'block_cipher_mode': enums.BlockCipherMode.NIST_KEY_WRAP } }, 'encoding_option': enums.EncodingOption.NO_ENCODING } ) key_id = self.client.register(key) result = self.client.get(key_id) key_wrapping_data = result.key_wrapping_data self.assertIsInstance(key_wrapping_data, dict) self.assertEqual( enums.WrappingMethod.ENCRYPT, key_wrapping_data.get('wrapping_method') ) eki = key_wrapping_data.get('encryption_key_information') self.assertIsInstance(eki, dict) self.assertEqual('42', eki.get('unique_identifier')) cp = eki.get('cryptographic_parameters') self.assertIsInstance(cp, dict) self.assertEqual( enums.BlockCipherMode.NIST_KEY_WRAP, cp.get('block_cipher_mode') ) self.assertEqual( enums.EncodingOption.NO_ENCODING, key_wrapping_data.get('encoding_option') )
def test_register(self): """ Test that the client can register a key. """ key = objects.SymmetricKey( enums.CryptographicAlgorithm.AES, 128, (b'\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0A\x0B\x0C\x0D\x0E' b'\x0F')) result = results.RegisterResult( contents.ResultStatus(enums.ResultStatus.SUCCESS), uuid=attr.PublicKeyUniqueIdentifier( 'aaaaaaaa-1111-2222-3333-ffffffffffff')) with ProxyKmipClient() as client: client.proxy.register.return_value = result uid = client.register(key) self.assertTrue(client.proxy.register.called) self.assertIsInstance(uid, six.string_types)
from kmip.pie import objects if __name__ == '__main__': logger = utils.build_console_logger(logging.INFO) parser = utils.build_cli_parser() opts, args = parser.parse_args(sys.argv[1:]) config = opts.config algorithm = enums.CryptographicAlgorithm.AES length = 128 value = (b'\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0A\x0B\x0C\x0D\x0E' b'\x0F') usage_mask = [ enums.CryptographicUsageMask.ENCRYPT, enums.CryptographicUsageMask.DECRYPT ] name = 'Demo Symmetric Key' key = objects.SymmetricKey(algorithm, length, value, usage_mask, name) # Build the client and connect to the server with client.ProxyKmipClient(config=config) as client: try: uid = client.register(key) logger.info("Successfully registered symmetric key with ID: " "{0}".format(uid)) except Exception as e: logger.error(e)
def test_derive_key_using_nist_800_108c(self): """ Test that the ProxyKmipClient can derive a new key using NIST 800 108-C. """ base_id = self.client.register( objects.SymmetricKey( enums.CryptographicAlgorithm.AES, 512, ( b'\xdd\x5d\xbd\x45\x59\x3e\xe2\xac' b'\x13\x97\x48\xe7\x64\x5b\x45\x0f' b'\x22\x3d\x2f\xf2\x97\xb7\x3f\xd7' b'\x1c\xbc\xeb\xe7\x1d\x41\x65\x3c' b'\x95\x0b\x88\x50\x0d\xe5\x32\x2d' b'\x99\xef\x18\xdf\xdd\x30\x42\x82' b'\x94\xc4\xb3\x09\x4f\x4c\x95\x43' b'\x34\xe5\x93\xbd\x98\x2e\xc6\x14' ), masks=[enums.CryptographicUsageMask.DERIVE_KEY] ) ) key_id = self.client.derive_key( enums.ObjectType.SYMMETRIC_KEY, [base_id], enums.DerivationMethod.NIST800_108_C, { 'cryptographic_parameters': { 'hashing_algorithm': enums.HashingAlgorithm.SHA_512 }, 'derivation_data': ( b'\xb5\x0b\x0c\x96\x3c\x6b\x30\x34' b'\xb8\xcf\x19\xcd\x3f\x5c\x4e\xbe' b'\x4f\x49\x85\xaf\x0c\x03\xe5\x75' b'\xdb\x62\xe6\xfd\xf1\xec\xfe\x4f' b'\x28\xb9\x5d\x7c\xe1\x6d\xf8\x58' b'\x43\x24\x6e\x15\x57\xce\x95\xbb' b'\x26\xcc\x9a\x21\x97\x4b\xbd\x2e' b'\xb6\x9e\x83\x55' ) }, cryptographic_length=128, cryptographic_algorithm=enums.CryptographicAlgorithm.AES ) key = self.client.get(key_id) self.assertEqual( ( b'\xe5\x99\x3b\xf9\xbd\x2a\xa1\xc4' b'\x57\x46\x04\x2e\x12\x59\x81\x55' ), key.value ) attribute_list = self.client.get_attribute_list(key_id) self.assertIn('Cryptographic Algorithm', attribute_list) self.assertIn('Cryptographic Length', attribute_list) result_id, attribute_list = self.client.get_attributes( uid=key_id, attribute_names=['Cryptographic Algorithm', 'Cryptographic Length'] ) self.assertEqual(key_id, result_id) self.assertEqual(2, len(attribute_list)) attribute = attribute_list[0] self.assertEqual( 'Cryptographic Algorithm', attribute.attribute_name.value ) self.assertEqual( enums.CryptographicAlgorithm.AES, attribute.attribute_value.value ) attribute = attribute_list[1] self.assertEqual( 'Cryptographic Length', attribute.attribute_name.value ) self.assertEqual(128, attribute.attribute_value.value)
# Register keys with the pykmip server #Import modules from kmip import enums from kmip.pie import client from kmip.pie import objects c = client.ProxyKmipClient() symmetric_key = objects.SymmetricKey(enums.CryptographicAlgorithm.AES, 256, (b'\x00\x01\x02\x03\x04\x05\x06\x07' b'\x08\x09\x0A\x0B\x0C\x0D\x0E\x0F' b'\x00\x01\x02\x03\x04\x05\x06\x07' b'\x08\x09\x0A\x0B\x0C\x0D\x0E\x0F')) with c: for i in range(10): key_id = c.register(symmetric_key) print(f'Registered new key with ID {key_id}')
def _process_create(self, payload): self._logger.info("Processing operation: Create") object_type = payload.object_type.value template_attribute = payload.template_attribute if object_type != enums.ObjectType.SYMMETRIC_KEY: name = object_type.name raise exceptions.InvalidField( "Cannot create a {0} object with the Create operation.".format( ''.join([x.capitalize() for x in name.split('_')]))) object_attributes = {} if template_attribute: object_attributes = self._process_template_attribute( template_attribute) algorithm = object_attributes.get('Cryptographic Algorithm') if algorithm: algorithm = algorithm.value else: raise exceptions.InvalidField( "The cryptographic algorithm must be specified as an " "attribute.") length = object_attributes.get('Cryptographic Length') if length: length = length.value else: # TODO (peterhamilton) The cryptographic length is technically not # required per the spec. Update the CryptographyEngine to accept a # None length, allowing it to pick the length dynamically. Default # to the strongest key size allowed for the algorithm type. raise exceptions.InvalidField( "The cryptographic length must be specified as an attribute.") usage_mask = object_attributes.get('Cryptographic Usage Mask') if usage_mask is None: raise exceptions.InvalidField( "The cryptographic usage mask must be specified as an " "attribute.") result = self._cryptography_engine.create_symmetric_key( algorithm, length) managed_object = objects.SymmetricKey(algorithm, length, result.get('value')) managed_object.names = [] self._set_attributes_on_managed_object(managed_object, object_attributes) # TODO (peterhamilton) Set additional server-only attributes. managed_object._owner = self._client_identity self._data_session.add(managed_object) # NOTE (peterhamilton) SQLAlchemy will *not* assign an ID until # commit is called. This makes future support for UNDO problematic. self._data_session.commit() self._logger.info("Created a SymmetricKey with ID: {0}".format( managed_object.unique_identifier)) response_payload = create.CreateResponsePayload( object_type=payload.object_type, unique_identifier=attributes.UniqueIdentifier( str(managed_object.unique_identifier)), template_attribute=None) self._id_placeholder = str(managed_object.unique_identifier) return response_payload