From 751ae8e3b00eeeb997d060fce399fbe784011bc1 Mon Sep 17 00:00:00 2001 From: Tim Kelsey Date: Wed, 8 Apr 2015 14:16:49 +0100 Subject: [PATCH] Adding handling for SecretData and OpaqueData objects Secret Data (2.2.7) can now be registered Opaque Object (2.2.8) can now be registered This required the adding of a NONE type to the OpaqueDataType enum with the value of 0. This is not indicated by the standard but we needed some value to satisfy response decoding. Also fixed get demo This has been tested vs a HP Atalla ESKM HSM --- kmip/core/enums.py | 5 ++- kmip/core/factories/secrets.py | 82 ++++++++++++++++++++-------------- kmip/demos/get.py | 2 +- kmip/demos/utils.py | 20 ++++++--- 4 files changed, 67 insertions(+), 42 deletions(-) diff --git a/kmip/core/enums.py b/kmip/core/enums.py index f01b069..ec3f0db 100644 --- a/kmip/core/enums.py +++ b/kmip/core/enums.py @@ -330,10 +330,11 @@ class SecretDataType(Enum): PASSWORD = 0x00000001 SEED = 0x00000002 - # 9.1.3.2.10 class OpaqueDataType(Enum): - pass + NONE = 0x80000000 # Not defined by the standard, but we need something. + # The standard does say that values starting 0x8xxxxxx + # are considered extensions # 9.1.3.2.11 diff --git a/kmip/core/factories/secrets.py b/kmip/core/factories/secrets.py index 0fda6ad..dec818e 100644 --- a/kmip/core/factories/secrets.py +++ b/kmip/core/factories/secrets.py @@ -28,8 +28,10 @@ from kmip.core.objects import KeyMaterial from kmip.core.objects import KeyWrappingData from kmip.core.objects import KeyValue +from kmip.core.secrets import OpaqueObject from kmip.core.secrets import PrivateKey from kmip.core.secrets import PublicKey +from kmip.core.secrets import SecretData from kmip.core.secrets import SymmetricKey from kmip.core.secrets import Template @@ -70,6 +72,51 @@ class SecretFactory(object): if value is None: return SymmetricKey() else: + key_block = self._build_key_block(value) + return SymmetricKey(key_block) + + def _create_public_key(self): + return PublicKey() + + def _create_private_key(self): + return PrivateKey() + + def _create_split_key(self, value): + raise NotImplementedError() + + def _create_template(self, value): + if value is None: + return Template() + else: + if not isinstance(value, list): + msg = utils.build_er_error(Template, + 'constructor argument type', list, + type(value)) + raise TypeError(msg) + else: + for val in value: + if not isinstance(val, Attribute): + msg = utils.build_er_error(Template, + 'constructor argument type', + Attribute, type(val)) + raise TypeError(msg) + return Template(value) + + def _create_secret_data(self, value): + if value: + kind = SecretData.SecretDataType(value.get("secret_data_type")) + key_block = self._build_key_block(value) + return SecretData(kind, key_block) + return SecretData() + + def _create_opaque_data(self, value): + if value: + kind = OpaqueObject.OpaqueDataType(value.get("opaque_data_type")) + data = OpaqueObject.OpaqueDataValue(value.get("opaque_data_value")) + return OpaqueObject(kind, data) + return OpaqueObject() + + def _build_key_block(self, value): key_type = value.get('key_format_type') key_compression_type = value.get('key_compression_type') key_value = value.get('key_value') @@ -102,37 +149,4 @@ class SecretFactory(object): crypto_algorithm, crypto_length, key_wrap_data) - return SymmetricKey(key_block) - - def _create_public_key(self): - return PublicKey() - - def _create_private_key(self): - return PrivateKey() - - def _create_split_key(self, value): - raise NotImplementedError() - - def _create_template(self, value): - if value is None: - return Template() - else: - if not isinstance(value, list): - msg = utils.build_er_error(Template, - 'constructor argument type', list, - type(value)) - raise TypeError(msg) - else: - for val in value: - if not isinstance(val, Attribute): - msg = utils.build_er_error(Template, - 'constructor argument type', - Attribute, type(val)) - raise TypeError(msg) - return Template(value) - - def _create_secret_data(self, value): - raise NotImplementedError() - - def _create_opaque_data(self, value): - raise NotImplementedError() + return key_block diff --git a/kmip/demos/get.py b/kmip/demos/get.py index 97940ca..a3c02e7 100644 --- a/kmip/demos/get.py +++ b/kmip/demos/get.py @@ -60,7 +60,7 @@ if __name__ == '__main__': credential) uuid = result.uuid.value - result = client.get(uuid, credential) + result = client.get(uuid=uuid, credential=credential) client.close() logger.debug('get() result status: {0}'.format(result.result_status.enum)) diff --git a/kmip/demos/utils.py b/kmip/demos/utils.py index 6d5a724..b781bae 100644 --- a/kmip/demos/utils.py +++ b/kmip/demos/utils.py @@ -21,6 +21,7 @@ from kmip.core.enums import CryptographicAlgorithm as CryptoAlgorithmEnum from kmip.core.enums import CryptographicUsageMask from kmip.core.enums import ObjectType from kmip.core.enums import Operation +from kmip.core.enums import SecretDataType from kmip.core.factories.attributes import AttributeFactory @@ -33,6 +34,7 @@ from kmip.core.objects import KeyValue from kmip.core.secrets import PrivateKey from kmip.core.secrets import PublicKey from kmip.core.secrets import SymmetricKey +from kmip.core.secrets import SecretData import optparse import sys @@ -165,7 +167,7 @@ def build_cli_parser(operation): default="SYMMETRIC_KEY", dest="type", help=("Type of the object to register. Supported types include: " - "PRIVATE_KEY, PUBLIC_KEY, SYMMETRIC_KEY")) + "PRIVATE_KEY, PUBLIC_KEY, SYMMETRIC_KEY, SECRET_DATA")) elif operation is Operation.QUERY: pass elif operation is Operation.DISCOVER_VERSIONS: @@ -177,7 +179,8 @@ def build_cli_parser(operation): def build_cryptographic_usage_mask(logger, object_type): - if object_type == ObjectType.SYMMETRIC_KEY: + if (object_type == ObjectType.SYMMETRIC_KEY or + object_type == ObjectType.SECRET_DATA): flags = [CryptographicUsageMask.ENCRYPT, CryptographicUsageMask.DECRYPT] elif object_type == ObjectType.PUBLIC_KEY: @@ -215,13 +218,18 @@ def build_object(logger, object_type, key_format_type): return PublicKey(key_block) elif object_type == ObjectType.PRIVATE_KEY: return PrivateKey(key_block) + elif object_type == ObjectType.SECRET_DATA: + kind = SecretData.SecretDataType(SecretDataType.PASSWORD) + return SecretData(secret_data_type=kind, + key_block=key_block) else: logger.error("Unrecognized object type, could not build object") sys.exit() def build_cryptographic_length(logger, object_type): - if object_type == ObjectType.SYMMETRIC_KEY: + if (object_type == ObjectType.SYMMETRIC_KEY or + object_type == ObjectType.SECRET_DATA): return CryptographicLength(128) elif object_type == ObjectType.PUBLIC_KEY: return CryptographicLength(1024) @@ -234,7 +242,8 @@ def build_cryptographic_length(logger, object_type): def build_cryptographic_algorithm(logger, object_type): - if object_type == ObjectType.SYMMETRIC_KEY: + if (object_type == ObjectType.SYMMETRIC_KEY or + object_type == ObjectType.SECRET_DATA): return CryptographicAlgorithm(CryptoAlgorithmEnum.AES) elif object_type == ObjectType.PUBLIC_KEY: return CryptographicAlgorithm(CryptoAlgorithmEnum.RSA) @@ -247,7 +256,8 @@ def build_cryptographic_algorithm(logger, object_type): def build_key_value(logger, object_type): - if object_type == ObjectType.SYMMETRIC_KEY: + if (object_type == ObjectType.SYMMETRIC_KEY + or object_type == ObjectType.SECRET_DATA): return ( b'\x30\x82\x02\x76\x02\x01\x00\x30\x0D\x06\x09\x2A\x86\x48\x86\xF7' b'\x0D\x01\x01\x01\x05\x00\x04\x82\x02\x60\x30\x82\x02\x5C\x02\x01'