diff --git a/kmip/core/factories/secrets.py b/kmip/core/factories/secrets.py index f09c891..0fda6ad 100644 --- a/kmip/core/factories/secrets.py +++ b/kmip/core/factories/secrets.py @@ -24,8 +24,8 @@ from kmip.core.misc import KeyFormatType from kmip.core.objects import Attribute from kmip.core.objects import KeyBlock +from kmip.core.objects import KeyMaterial from kmip.core.objects import KeyWrappingData -from kmip.core.objects import KeyValueStruct from kmip.core.objects import KeyValue from kmip.core.secrets import PrivateKey @@ -84,12 +84,8 @@ class SecretFactory(object): key_comp_type = KeyBlock.KeyCompressionType( key_compression_type) - key_material = self.key_factory.create_key(key_type, - key_value) - key_val_struc = KeyValueStruct(key_format_type=key_format_type, - key_material=key_material) - key_value = KeyValue(key_value=key_val_struc, - key_format_type=key_format_type) + key_material = KeyMaterial(key_value) + key_value = KeyValue(key_material) crypto_algorithm = CryptographicAlgorithm(cryptographic_algorithm) crypto_length = CryptographicLength(cryptographic_length) diff --git a/kmip/core/objects.py b/kmip/core/objects.py index 84746a8..f1b8964 100644 --- a/kmip/core/objects.py +++ b/kmip/core/objects.py @@ -19,7 +19,6 @@ from kmip.core import attributes from kmip.core.attributes import CryptographicParameters from kmip.core.factories.attribute_values import AttributeValueFactory -from kmip.core.factories.keys import KeyFactory from kmip.core import enums from kmip.core.enums import AttributeType @@ -373,13 +372,12 @@ class KeyBlock(Struct): self.key_format_type = KeyFormatType() self.key_format_type.read(tstream) - key_format_type = self.key_format_type.enum if self.is_tag_next(Tags.KEY_COMPRESSION_TYPE, tstream): self.key_compression_type = KeyBlock.KeyCompressionType() self.key_compression_type.read(tstream) - self.key_value = KeyValue(key_format_type=key_format_type) + self.key_value = KeyValue() self.key_value.read(tstream) if self.is_tag_next(Tags.CRYPTOGRAPHIC_ALGORITHM, tstream): @@ -434,35 +432,78 @@ class KeyBlock(Struct): # 2.1.4 -class KeyValueString(ByteString): +class KeyMaterial(ByteString): def __init__(self, value=None): - super(self.__class__, self).__init__(value, Tags.KEY_VALUE) + super(self.__class__, self).__init__(value, Tags.KEY_MATERIAL) -class KeyValueStruct(Struct): +# TODO (peter-hamilton) Get rid of this and replace with a KeyMaterial factory. +class KeyMaterialStruct(Struct): + + def __init__(self): + super(KeyMaterialStruct, self).__init__(Tags.SERVER_INFORMATION) + + self.data = BytearrayStream() + + self.validate() + + def read(self, istream): + super(KeyMaterialStruct, self).read(istream) + tstream = BytearrayStream(istream.read(self.length)) + + self.data = BytearrayStream(tstream.read()) + + self.is_oversized(tstream) + self.validate() + + def write(self, ostream): + tstream = BytearrayStream() + tstream.write(self.data.buffer) + + self.length = tstream.length() + super(KeyMaterialStruct, self).write(ostream) + ostream.write(tstream.buffer) + + def validate(self): + self.__validate() + + def __validate(self): + # NOTE (peter-hamilton): Intentional pass, no way to validate data. + pass + + +class KeyValue(Struct): def __init__(self, - key_format_type=None, key_material=None, attributes=None): super(self.__class__, self).__init__(Tags.KEY_VALUE) - self.key_format_type = key_format_type - self.key_material = key_material - self.attributes = attributes - self.key_factory = KeyFactory() + + if key_material is None: + self.key_material = KeyMaterial() + else: + self.key_material = key_material + + if attributes is None: + self.attributes = list() + else: + self.attributes = attributes + self.validate() def read(self, istream): super(self.__class__, self).read(istream) tstream = BytearrayStream(istream.read(self.length)) - self.key_material = self.key_factory.create_key(self.key_format_type) - self.key_material.read(tstream) + # TODO (peter-hamilton) Replace this with a KeyMaterial factory. + if self.is_type_next(Types.STRUCTURE, tstream): + self.key_material = KeyMaterialStruct() + self.key_material.read(tstream) + else: + self.key_material = KeyMaterial() + self.key_material.read(tstream) - self.attributes = list() - - # Read the attributes, 0 or more while self.is_tag_next(Tags.ATTRIBUTE, tstream): attribute = Attribute() attribute.read(tstream) @@ -476,11 +517,9 @@ class KeyValueStruct(Struct): self.key_material.write(tstream) - if self.attributes is not None: - for attribute in self.attributes: - attribute.write(tstream) + for attribute in self.attributes: + attribute.write(tstream) - # Write the length and value of the credential self.length = tstream.length() super(self.__class__, self).write(ostream) ostream.write(tstream.buffer) @@ -489,56 +528,26 @@ class KeyValueStruct(Struct): self.__validate() def __validate(self): - # TODO (peter-hamilton) Finish implementation. - pass + # TODO (peter-hamilton) Replace with check against KeyMaterial factory. + if not isinstance(self.key_material, KeyMaterial): + msg = "invalid key material" + msg += "; expected {0}, received {1}".format( + KeyMaterial, self.key_material) + raise TypeError(msg) - -class KeyValue(Struct): - ''' - KeyValue can be either a ByteString or a Struct. Therefore, this class - acts as a wrapper for two different KeyValue objects, KeyValueString, - which represents the ByteString format, and KeyValueStruct, which - represents the Struct format, both of which are defined above. This - KeyValue object does not read or write itself; instead, it reads and - writes its internal key_value attribute, which is either a KeyValueString - or a KeyValueStruct. - - When reading, the class determines what the format of its internal - structure should be by looking at the type of the object it will read - using KeyValue.is_type_next(). This is one of the only places in the - code where this approach is used. - ''' - - def __init__(self, - key_value=None, - key_format_type=None): - super(self.__class__, self).__init__(Tags.KEY_VALUE) - self.key_value = key_value - self.key_format_type = key_format_type - if self.key_value is not None: - self.type = key_value.type - self.validate() - - def read(self, istream): - if self.is_type_next(Types.BYTE_STRING, istream): - self.key_value = KeyValueString() - self.key_value.read(istream) - elif self.is_type_next(Types.STRUCTURE, istream): - kft = self.key_format_type - self.key_value = KeyValueStruct(key_format_type=kft) - self.key_value.read(istream) - - def write(self, ostream): - tstream = BytearrayStream() - self.key_value.write(tstream) - ostream.write(tstream.buffer) - - def validate(self): - self.__validate() - - def __validate(self): - # TODO (peter-hamilton) Finish implementation. - pass + if isinstance(self.attributes, list): + for i in xrange(len(self.attributes)): + attribute = self.attributes[i] + if not isinstance(attribute, Attribute): + msg = "invalid attribute ({0} in list)".format(i) + msg += "; expected {0}, received {1}".format( + Attribute, attribute) + raise TypeError(msg) + else: + msg = "invalid attributes list" + msg += "; expected {0}, received {1}".format( + list, self.attributes) + raise TypeError(msg) # 2.1.5 diff --git a/kmip/core/server.py b/kmip/core/server.py index 33b66de..ff9aa00 100644 --- a/kmip/core/server.py +++ b/kmip/core/server.py @@ -29,7 +29,6 @@ from kmip.core.enums import ResultStatus as RS from kmip.core.factories.attributes import AttributeFactory from kmip.core.factories.keys import KeyFactory from kmip.core.factories.secrets import SecretFactory -from kmip.core.keys import RawKey from kmip.core.messages.contents import ResultStatus from kmip.core.messages.contents import ResultReason @@ -38,8 +37,8 @@ from kmip.core.messages.contents import ResultMessage from kmip.core.misc import KeyFormatType from kmip.core.objects import KeyBlock +from kmip.core.objects import KeyMaterial from kmip.core.objects import KeyValue -from kmip.core.objects import KeyValueStruct from kmip.core.objects import TemplateAttribute from kmip.core.repo.mem_repo import MemRepo from kmip.core.secrets import SymmetricKey @@ -346,8 +345,8 @@ class KMIPImpl(KMIP): def _gen_symmetric_key(self, bit_length, crypto_alg): key_format_type = KeyFormatType(KeyFormatTypeEnum.RAW) - key_material = RawKey(bytearray(os.urandom(int(bit_length/8)))) - key_value = KeyValueStruct(key_format_type, key_material) + key_material = KeyMaterial(os.urandom(int(bit_length/8))) + key_value = KeyValue(key_material) crypto_length = CryptographicLength(bit_length) key_block = KeyBlock(key_format_type, None, key_value, crypto_alg, crypto_length, None) @@ -385,7 +384,6 @@ class KMIPImpl(KMIP): kv = key_block.key_value if isinstance(kv, KeyValue): kv = key_block.key_value - if isinstance(kv, KeyValueStruct): if kv.attributes is not None: self.logger.debug('adding the key value struct attributes') attributes.extend(kv.attributes) diff --git a/kmip/demos/units/register.py b/kmip/demos/units/register.py index c2b0919..7bc04e4 100644 --- a/kmip/demos/units/register.py +++ b/kmip/demos/units/register.py @@ -13,19 +13,11 @@ # License for the specific language governing permissions and limitations # under the License. -from kmip.core.enums import AttributeType -from kmip.core.enums import CredentialType -from kmip.core.enums import CryptographicAlgorithm -from kmip.core.enums import CryptographicUsageMask from kmip.core.enums import KeyFormatType from kmip.core.enums import ObjectType from kmip.core.enums import Operation from kmip.core.enums import ResultStatus -from kmip.core.factories.attributes import AttributeFactory -from kmip.core.factories.credentials import CredentialFactory -from kmip.core.factories.secrets import SecretFactory - from kmip.core.objects import TemplateAttribute from kmip.demos import utils @@ -38,87 +30,45 @@ import sys if __name__ == '__main__': - # Build and parse arguments parser = utils.build_cli_parser(Operation.REGISTER) opts, args = parser.parse_args(sys.argv[1:]) username = opts.username password = opts.password config = opts.config - algorithm = opts.algorithm - length = opts.length + object_type = opts.type + format_type = opts.format # Exit early if the arguments are not specified - if algorithm is None: - logging.debug('No algorithm provided, exiting early from demo') - sys.exit() - if length is None: - logging.debug("No key length provided, exiting early from demo") + object_type = getattr(ObjectType, object_type, None) + if object_type is None: + logging.error("Invalid object type specified; exiting early from demo") sys.exit() + key_format_type = getattr(KeyFormatType, format_type, None) + if key_format_type is None: + logging.error( + "Invalid key format type specified; exiting early from demo") + # Build and setup logging and needed factories f_log = os.path.join(os.path.dirname(__file__), os.pardir, os.pardir, 'logconfig.ini') logging.config.fileConfig(f_log) logger = logging.getLogger(__name__) - attribute_factory = AttributeFactory() - credential_factory = CredentialFactory() - secret_factory = SecretFactory() - - # Build the KMIP server account credentials - # TODO (peter-hamilton) Move up into KMIPProxy - if (username is None) and (password is None): - credential = None - else: - credential_type = CredentialType.USERNAME_AND_PASSWORD - credential_value = {'Username': username, - 'Password': password} - credential = credential_factory.create_credential(credential_type, - credential_value) - # Build the client and connect to the server - client = KMIPProxy(config=config) - client.open() - - # Build the different object attributes - object_type = ObjectType.SYMMETRIC_KEY - - attribute_type = AttributeType.CRYPTOGRAPHIC_ALGORITHM - algorithm_enum = getattr(CryptographicAlgorithm, algorithm, None) - - if algorithm_enum is None: - logging.debug("{0} not found".format(algorithm)) - logging.debug("Invalid algorithm specified, exiting early from demo") - - client.close() - sys.exit() - - mask_flags = [CryptographicUsageMask.ENCRYPT, - CryptographicUsageMask.DECRYPT] - attribute_type = AttributeType.CRYPTOGRAPHIC_USAGE_MASK - usage_mask = attribute_factory.create_attribute(attribute_type, - mask_flags) + # Create the template attribute for the secret and then build the secret + usage_mask = utils.build_cryptographic_usage_mask(logger, object_type) attributes = [usage_mask] template_attribute = TemplateAttribute(attributes=attributes) - secret_features = {} + secret = utils.build_object(logger, object_type, key_format_type) - key_format_type = KeyFormatType.RAW - secret_features.update([('key_format_type', key_format_type)]) + # Build the client, connect to the server, register the secret, and + # disconnect from the server + client = KMIPProxy(config=config) - # TODO (peter-hamilton) Replace with calls to crypto libraries - key_data = {'bytes': bytearray(b'\x00\x00\x00\x00\x00\x00\x00\x00' - b'\x00\x00\x00\x00\x00\x00\x00\x00')} - - secret_features.update([('key_value', key_data)]) - secret_features.update([('cryptographic_algorithm', algorithm_enum)]) - secret_features.update([('cryptographic_length', length)]) - - secret = secret_factory.create(object_type, secret_features) - - # Register the SYMMETRIC_KEY object - result = client.register(object_type, template_attribute, secret, - credential) + client.open() + result = client.register(object_type, template_attribute, secret) client.close() # Display operation results diff --git a/kmip/demos/utils.py b/kmip/demos/utils.py index a8b18c8..6d5a724 100644 --- a/kmip/demos/utils.py +++ b/kmip/demos/utils.py @@ -13,10 +13,29 @@ # License for the specific language governing permissions and limitations # under the License. +from kmip.core.attributes import CryptographicAlgorithm +from kmip.core.attributes import CryptographicLength + +from kmip.core.enums import AttributeType +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.factories.attributes import AttributeFactory + +from kmip.core.misc import KeyFormatType + +from kmip.core.objects import KeyBlock +from kmip.core.objects import KeyMaterial +from kmip.core.objects import KeyValue + +from kmip.core.secrets import PrivateKey +from kmip.core.secrets import PublicKey +from kmip.core.secrets import SymmetricKey + import optparse +import sys def build_cli_parser(operation): @@ -130,21 +149,23 @@ def build_cli_parser(operation): help="Name of secret to retrieve from the KMIP server") elif operation is Operation.REGISTER: parser.add_option( - "-a", - "--algorithm", + "-f", + "--format", action="store", type="str", - default=None, - dest="algorithm", - help="Encryption algorithm for the secret (e.g., AES)") + default="RAW", + dest="format", + help=("Format in which to store the secret. Supported formats " + "include: RAW, PKCS_1, PKCS_8, X_509")) parser.add_option( - "-l", - "--length", + "-t", + "--type", action="store", - type="int", - default=None, - dest="length", - help="Key length in bits (e.g., 128, 256)") + type="str", + default="SYMMETRIC_KEY", + dest="type", + help=("Type of the object to register. Supported types include: " + "PRIVATE_KEY, PUBLIC_KEY, SYMMETRIC_KEY")) elif operation is Operation.QUERY: pass elif operation is Operation.DISCOVER_VERSIONS: @@ -155,6 +176,162 @@ def build_cli_parser(operation): return parser +def build_cryptographic_usage_mask(logger, object_type): + if object_type == ObjectType.SYMMETRIC_KEY: + flags = [CryptographicUsageMask.ENCRYPT, + CryptographicUsageMask.DECRYPT] + elif object_type == ObjectType.PUBLIC_KEY: + flags = [CryptographicUsageMask.VERIFY] + elif object_type == ObjectType.PRIVATE_KEY: + flags = [CryptographicUsageMask.SIGN] + else: + logger.error("Unrecognized object type, could not build cryptographic " + "usage mask") + sys.exit() + + attribute_type = AttributeType.CRYPTOGRAPHIC_USAGE_MASK + attribute_factory = AttributeFactory() + usage_mask = attribute_factory.create_attribute(attribute_type, flags) + + return usage_mask + + +def build_object(logger, object_type, key_format_type): + + key_value = build_key_value(logger, object_type) + cryptographic_algorithm = build_cryptographic_algorithm( + logger, object_type) + cryptographic_length = build_cryptographic_length(logger, object_type) + + key_block = build_key_block( + key_format_type, + key_value, + cryptographic_algorithm, + cryptographic_length) + + if object_type == ObjectType.SYMMETRIC_KEY: + return SymmetricKey(key_block) + elif object_type == ObjectType.PUBLIC_KEY: + return PublicKey(key_block) + elif object_type == ObjectType.PRIVATE_KEY: + return PrivateKey(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: + return CryptographicLength(128) + elif object_type == ObjectType.PUBLIC_KEY: + return CryptographicLength(1024) + elif object_type == ObjectType.PRIVATE_KEY: + return CryptographicLength(1024) + else: + logger.error("Unrecognized object type, could not build cryptographic " + "length") + sys.exit() + + +def build_cryptographic_algorithm(logger, object_type): + if object_type == ObjectType.SYMMETRIC_KEY: + return CryptographicAlgorithm(CryptoAlgorithmEnum.AES) + elif object_type == ObjectType.PUBLIC_KEY: + return CryptographicAlgorithm(CryptoAlgorithmEnum.RSA) + elif object_type == ObjectType.PRIVATE_KEY: + return CryptographicAlgorithm(CryptoAlgorithmEnum.RSA) + else: + logger.error("Unrecognized object type, could not build cryptographic " + "algorithm") + sys.exit() + + +def build_key_value(logger, object_type): + if object_type == ObjectType.SYMMETRIC_KEY: + 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' + b'\x00\x02\x81\x81\x00\x93\x04\x51\xC9\xEC\xD9\x4F\x5B\xB9\xDA\x17' + b'\xDD\x09\x38\x1B\xD2\x3B\xE4\x3E\xCA\x8C\x75\x39\xF3\x01\xFC\x8A' + b'\x8C\xD5\xD5\x27\x4C\x3E\x76\x99\xDB\xDC\x71\x1C\x97\xA7\xAA\x91' + b'\xE2\xC5\x0A\x82\xBD\x0B\x10\x34\xF0\xDF\x49\x3D\xEC\x16\x36\x24' + b'\x27\xE5\x8A\xCC\xE7\xF6\xCE\x0F\x9B\xCC\x61\x7B\xBD\x8C\x90\xD0' + b'\x09\x4A\x27\x03\xBA\x0D\x09\xEB\x19\xD1\x00\x5F\x2F\xB2\x65' + b'\x52') + elif object_type == ObjectType.PUBLIC_KEY: + return ( + b'\x30\x81\x9F\x30\x0D\x06\x09\x2A\x86\x48\x86\xF7\x0D\x01\x01\x01' + b'\x05\x00\x03\x81\x8D\x00\x30\x81\x89\x02\x81\x81\x00\x93\x04\x51' + b'\xC9\xEC\xD9\x4F\x5B\xB9\xDA\x17\xDD\x09\x38\x1B\xD2\x3B\xE4\x3E' + b'\xCA\x8C\x75\x39\xF3\x01\xFC\x8A\x8C\xD5\xD5\x27\x4C\x3E\x76\x99' + b'\xDB\xDC\x71\x1C\x97\xA7\xAA\x91\xE2\xC5\x0A\x82\xBD\x0B\x10\x34' + b'\xF0\xDF\x49\x3D\xEC\x16\x36\x24\x27\xE5\x8A\xCC\xE7\xF6\xCE\x0F' + b'\x9B\xCC\x61\x7B\xBD\x8C\x90\xD0\x09\x4A\x27\x03\xBA\x0D\x09\xEB' + b'\x19\xD1\x00\x5F\x2F\xB2\x65\x52\x6A\xAC\x75\xAF\x32\xF8\xBC\x78' + b'\x2C\xDE\xD2\xA5\x7F\x81\x1E\x03\xEA\xF6\x7A\x94\x4D\xE5\xE7\x84' + b'\x13\xDC\xA8\xF2\x32\xD0\x74\xE6\xDC\xEA\x4C\xEC\x9F\x02\x03\x01' + b'\x00\x01') + elif object_type == ObjectType.PRIVATE_KEY: + 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' + b'\x00\x02\x81\x81\x00\x93\x04\x51\xC9\xEC\xD9\x4F\x5B\xB9\xDA\x17' + b'\xDD\x09\x38\x1B\xD2\x3B\xE4\x3E\xCA\x8C\x75\x39\xF3\x01\xFC\x8A' + b'\x8C\xD5\xD5\x27\x4C\x3E\x76\x99\xDB\xDC\x71\x1C\x97\xA7\xAA\x91' + b'\xE2\xC5\x0A\x82\xBD\x0B\x10\x34\xF0\xDF\x49\x3D\xEC\x16\x36\x24' + b'\x27\xE5\x8A\xCC\xE7\xF6\xCE\x0F\x9B\xCC\x61\x7B\xBD\x8C\x90\xD0' + b'\x09\x4A\x27\x03\xBA\x0D\x09\xEB\x19\xD1\x00\x5F\x2F\xB2\x65\x52' + b'\x6A\xAC\x75\xAF\x32\xF8\xBC\x78\x2C\xDE\xD2\xA5\x7F\x81\x1E\x03' + b'\xEA\xF6\x7A\x94\x4D\xE5\xE7\x84\x13\xDC\xA8\xF2\x32\xD0\x74\xE6' + b'\xDC\xEA\x4C\xEC\x9F\x02\x03\x01\x00\x01\x02\x81\x80\x0B\x6A\x7D' + b'\x73\x61\x99\xEA\x48\xA4\x20\xE4\x53\x7C\xA0\xC7\xC0\x46\x78\x4D' + b'\xCB\xEA\xA6\x3B\xAE\xBC\x0B\xC1\x32\x78\x74\x49\xCD\xE8\xD7\xCA' + b'\xD0\xC0\xC8\x63\xC0\xFE\xFB\x06\xC3\x06\x2B\xEF\xC5\x00\x33\xEC' + b'\xF8\x7B\x4E\x33\xA9\xBE\x7B\xCB\xC8\xF1\x51\x1A\xE2\x15\xE8\x0D' + b'\xEB\x5D\x8A\xF2\xBD\x31\x31\x9D\x78\x21\x19\x66\x40\x93\x5A\x0C' + b'\xD6\x7C\x94\x59\x95\x79\xF2\x10\x0D\x65\xE0\x38\x83\x1F\xDA\xFB' + b'\x0D\xBE\x2B\xBD\xAC\x00\xA6\x96\xE6\x7E\x75\x63\x50\xE1\xC9\x9A' + b'\xCE\x11\xA3\x6D\xAB\xAC\x3E\xD3\xE7\x30\x96\x00\x59\x02\x41\x00' + b'\xDD\xF6\x72\xFB\xCC\x5B\xDA\x3D\x73\xAF\xFC\x4E\x79\x1E\x0C\x03' + b'\x39\x02\x24\x40\x5D\x69\xCC\xAA\xBC\x74\x9F\xAA\x0D\xCD\x4C\x25' + b'\x83\xC7\x1D\xDE\x89\x41\xA7\xB9\xAA\x03\x0F\x52\xEF\x14\x51\x46' + b'\x6C\x07\x4D\x4D\x33\x8F\xE6\x77\x89\x2A\xCD\x9E\x10\xFD\x35\xBD' + b'\x02\x41\x00\xA9\x8F\xBC\x3E\xD6\xB4\xC6\xF8\x60\xF9\x71\x65\xAC' + b'\x2F\x7B\xB6\xF2\xE2\xCB\x19\x2A\x9A\xBD\x49\x79\x5B\xE5\xBC\xF3' + b'\x7D\x8E\xE6\x9A\x6E\x16\x9C\x24\xE5\xC3\x2E\x4E\x7F\xA3\x32\x65' + b'\x46\x14\x07\xF9\x52\xBA\x49\xE2\x04\x81\x8A\x2F\x78\x5F\x11\x3F' + b'\x92\x2B\x8B\x02\x40\x25\x3F\x94\x70\x39\x0D\x39\x04\x93\x03\x77' + b'\x7D\xDB\xC9\x75\x0E\x9D\x64\x84\x9C\xE0\x90\x3E\xAE\x70\x4D\xC9' + b'\xF5\x89\xB7\x68\x0D\xEB\x9D\x60\x9F\xD5\xBC\xD4\xDE\xCD\x6F\x12' + b'\x05\x42\xE5\xCF\xF5\xD7\x6F\x2A\x43\xC8\x61\x5F\xB5\xB3\xA9\x21' + b'\x34\x63\x79\x7A\xA9\x02\x41\x00\xA1\xDD\xF0\x23\xC0\xCD\x94\xC0' + b'\x19\xBB\x26\xD0\x9B\x9E\x3C\xA8\xFA\x97\x1C\xB1\x6A\xA5\x8B\x9B' + b'\xAF\x79\xD6\x08\x1A\x1D\xBB\xA4\x52\xBA\x53\x65\x3E\x28\x04\xBA' + b'\x98\xFF\x69\xE8\xBB\x1B\x3A\x16\x1E\xA2\x25\xEA\x50\x14\x63\x21' + b'\x6A\x8D\xAB\x9B\x88\xA7\x5E\x5F\x02\x40\x61\x78\x64\x6E\x11\x2C' + b'\xF7\x9D\x92\x1A\x8A\x84\x3F\x17\xF6\xE7\xFF\x97\x4F\x68\x81\x22' + b'\x36\x5B\xF6\x69\x0C\xDF\xC9\x96\xE1\x89\x09\x52\xEB\x38\x20\xDD' + b'\x18\x90\xEC\x1C\x86\x19\xE8\x7A\x2B\xD3\x8F\x9D\x03\xB3\x7F\xAC' + b'\x74\x2E\xFB\x74\x8C\x78\x85\x94\x2C\x39') + else: + logger.error("Unrecognized object type, could not build key value") + sys.exit() + + +def build_key_block(key_format_type, key_value, cryptographic_algorithm, + cryptographic_length): + key_material = KeyMaterial(key_value) + key_value = KeyValue(key_material) + + return KeyBlock( + key_format_type=KeyFormatType(key_format_type), + key_compression_type=None, + key_value=key_value, + cryptographic_algorithm=cryptographic_algorithm, + cryptographic_length=cryptographic_length, + key_wrapping_data=None) + + def log_template_attribute(logger, template_attribute): names = template_attribute.names attributes = template_attribute.attributes @@ -164,7 +341,7 @@ def log_template_attribute(logger, template_attribute): name = names[i] logger.info('name {0}: {1}'.format(i, name)) - log_attribute_list(attributes) + log_attribute_list(logger, attributes) def log_attribute_list(logger, attributes): @@ -230,22 +407,14 @@ def log_key_block(logger, key_block): def log_key_value(logger, key_value): if key_value is not None: - key_format_type = key_value.key_format_type - key_value = key_value.key_value + logger.info('key value:') - logger.info('key format type: {0}'.format(key_format_type)) + key_material = key_value.key_material + attributes = key_value.attributes - if key_value is not None: - logger.info('key value:') + logger.info('key material: {0}'.format(repr(key_material))) - key_material = key_value.key_material - attributes = key_value.attributes - - logger.info('key material: {0}'.format(repr(key_material))) - - log_attribute_list(logger, attributes) - else: - logger.info('key value: {0}'.format(key_value)) + log_attribute_list(logger, attributes) else: logger.info('key value: {0}'.format(key_value)) diff --git a/kmip/tests/core/messages/test_messages.py b/kmip/tests/core/messages/test_messages.py index f4e40e3..5145557 100644 --- a/kmip/tests/core/messages/test_messages.py +++ b/kmip/tests/core/messages/test_messages.py @@ -24,23 +24,22 @@ from kmip.core.attributes import ApplicationData from kmip.core.attributes import ApplicationNamespace from kmip.core.attributes import ApplicationSpecificInformation from kmip.core.attributes import ContactInformation +from kmip.core.attributes import CryptographicAlgorithm +from kmip.core.attributes import CryptographicLength from kmip.core.attributes import Name from kmip.core.attributes import ObjectGroup from kmip.core import enums from kmip.core.enums import AttributeType -from kmip.core.enums import CryptographicAlgorithm +from kmip.core.enums import CryptographicAlgorithm as CryptoAlgorithmEnum from kmip.core.enums import CryptographicUsageMask from kmip.core.enums import NameType -from kmip.core.enums import ObjectType from kmip.core import errors from kmip.core.errors import ErrorStrings from kmip.core import objects -from kmip.core.keys import RawKey - from kmip.core.messages import contents from kmip.core.messages import messages from kmip.core.messages.payloads import create @@ -357,7 +356,7 @@ class TestRequestMessage(TestCase): object_type = attr.ObjectType(enums.ObjectType.SYMMETRIC_KEY) name = AttributeType.CRYPTOGRAPHIC_ALGORITHM - value = CryptographicAlgorithm.AES + value = CryptoAlgorithmEnum.AES attr_a = self.attribute_factory.create_attribute(name, value) name = AttributeType.CRYPTOGRAPHIC_LENGTH @@ -1341,13 +1340,13 @@ class TestResponseMessage(TestCase): objects.KeyValue, type(key_value))) - key_material = key_value.key_value.key_material - value = bytearray(b'\x73\x67\x57\x80\x51\x01\x2A\x6D\x13\x4A\x85' - b'\x5E\x25\xC8\xCD\x5E\x4C\xA1\x31\x45\x57\x29' - b'\xD3\xC8') - self.assertIsInstance(key_material, RawKey, + key_material = key_value.key_material + value = ( + b'\x73\x67\x57\x80\x51\x01\x2A\x6D\x13\x4A\x85\x5E\x25\xC8\xCD' + b'\x5E\x4C\xA1\x31\x45\x57\x29\xD3\xC8') + self.assertIsInstance(key_material, objects.KeyMaterial, self.msg.format('key_material', 'type', - RawKey, + objects.KeyMaterial, type(key_material))) exp = utils.hexlify_bytearray(value) obs = utils.hexlify_bytearray(key_material.value) @@ -1395,17 +1394,29 @@ class TestResponseMessage(TestCase): uuid = '49a1ca88-6bea-4fb2-b450-7e58802c3038' uniq_id = attr.UniqueIdentifier(uuid) - key_type = enums.KeyFormatType.RAW - key = bytearray(b'\x73\x67\x57\x80\x51\x01\x2A\x6D\x13\x4A\x85\x5E\x25' - b'\xC8\xCD\x5E\x4C\xA1\x31\x45\x57\x29\xD3\xC8') + key = ( + b'\x73\x67\x57\x80\x51\x01\x2A\x6D\x13\x4A\x85\x5E\x25\xC8\xCD\x5E' + b'\x4C\xA1\x31\x45\x57\x29\xD3\xC8') crypto_algorithm = enums.CryptographicAlgorithm.TRIPLE_DES cryptographic_length = 168 - value = {'key_format_type': key_type, - 'key_value': {'bytes': key}, - 'cryptographic_algorithm': crypto_algorithm, - 'cryptographic_length': cryptographic_length} - secret = self.secret_factory.create(ObjectType.SYMMETRIC_KEY, value) + key_format_type = KeyFormatType(enums.KeyFormatType.RAW) + + key_material = objects.KeyMaterial(key) + key_value = objects.KeyValue(key_material) + cryptographic_algorithm = CryptographicAlgorithm(crypto_algorithm) + cryptographic_length = CryptographicLength(cryptographic_length) + + key_block = objects.KeyBlock( + key_format_type=key_format_type, + key_compression_type=None, + key_value=key_value, + cryptographic_algorithm=cryptographic_algorithm, + cryptographic_length=cryptographic_length, + key_wrapping_data=None) + + secret = SymmetricKey(key_block) + resp_pl = get.GetResponsePayload(object_type=object_type, unique_identifier=uniq_id, secret=secret) diff --git a/kmip/tests/core/test_server.py b/kmip/tests/core/test_server.py index 17d7e70..65c7d23 100644 --- a/kmip/tests/core/test_server.py +++ b/kmip/tests/core/test_server.py @@ -33,13 +33,13 @@ from kmip.core.enums import ResultStatus from kmip.core.enums import NameType from kmip.core.factories.attributes import AttributeFactory -from kmip.core.keys import RawKey from kmip.core.messages.contents import KeyCompressionType from kmip.core.misc import KeyFormatType from kmip.core.objects import KeyBlock -from kmip.core.objects import KeyValueStruct +from kmip.core.objects import KeyMaterial +from kmip.core.objects import KeyValue from kmip.core.objects import TemplateAttribute from kmip.core.secrets import SymmetricKey @@ -472,8 +472,8 @@ class TestKMIPServer(TestCase): # only need usage attribute attrs = [self._get_attrs()[1]] key_format_type = KeyFormatType(KeyFormatTypeEnum.RAW) - key_material = RawKey(self.key) - key_value = KeyValueStruct(key_format_type, key_material, attrs) + key_material = KeyMaterial(self.key) + key_value = KeyValue(key_material, attrs) crypto_alg = CryptographicAlgorithm(self.algorithm_name) crypto_length = CryptographicLength(self.key_length) usage = CryptographicUsageMask(self.usage_mask) diff --git a/kmip/tests/services/test_kmip_client.py b/kmip/tests/services/test_kmip_client.py index 33f3758..8592859 100644 --- a/kmip/tests/services/test_kmip_client.py +++ b/kmip/tests/services/test_kmip_client.py @@ -21,15 +21,17 @@ import os import sys import time +from kmip.core.attributes import CryptographicAlgorithm +from kmip.core.attributes import CryptographicLength from kmip.core.attributes import PrivateKeyUniqueIdentifier from kmip.core.enums import AttributeType from kmip.core.enums import CredentialType -from kmip.core.enums import CryptographicAlgorithm +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 as OperationEnum -from kmip.core.enums import KeyFormatType +from kmip.core.enums import KeyFormatType as KeyFormatTypeEnum from kmip.core.enums import QueryFunction as QueryFunctionEnum from kmip.core.enums import ResultStatus from kmip.core.enums import ResultReason @@ -44,10 +46,8 @@ from kmip.core.factories.secrets import SecretFactory from kmip.core.messages.messages import RequestBatchItem from kmip.core.messages.messages import ResponseBatchItem from kmip.core.messages.messages import ResponseMessage - from kmip.core.messages.contents import Operation from kmip.core.messages.contents import ProtocolVersion - from kmip.core.messages.payloads.create_key_pair import \ CreateKeyPairRequestPayload, CreateKeyPairResponsePayload from kmip.core.messages.payloads.discover_versions import \ @@ -57,6 +57,7 @@ from kmip.core.messages.payloads.query import \ from kmip.core.messages.payloads.rekey_key_pair import \ RekeyKeyPairRequestPayload, RekeyKeyPairResponsePayload +from kmip.core.misc import KeyFormatType from kmip.core.misc import Offset from kmip.core.misc import QueryFunction from kmip.core.misc import ServerInformation @@ -64,6 +65,9 @@ from kmip.core.misc import VendorIdentification from kmip.core.objects import Attribute from kmip.core.objects import CommonTemplateAttribute +from kmip.core.objects import KeyBlock +from kmip.core.objects import KeyMaterial +from kmip.core.objects import KeyValue from kmip.core.objects import PrivateKeyTemplateAttribute from kmip.core.objects import PublicKeyTemplateAttribute from kmip.core.objects import TemplateAttribute @@ -218,7 +222,7 @@ class TestKMIPClientIntegration(TestCase): credential_value) object_type = ObjectType.SYMMETRIC_KEY - algorithm_value = CryptographicAlgorithm.AES + algorithm_value = CryptoAlgorithmEnum.AES mask_flags = [CryptographicUsageMask.ENCRYPT, CryptographicUsageMask.DECRYPT] attribute_type = AttributeType.CRYPTOGRAPHIC_USAGE_MASK @@ -227,19 +231,26 @@ class TestKMIPClientIntegration(TestCase): attributes = [usage_mask] template_attribute = TemplateAttribute(attributes=attributes) - secret_features = {} + key_format_type = KeyFormatType(KeyFormatTypeEnum.RAW) - key_format_type = KeyFormatType.RAW - secret_features.update([('key_format_type', key_format_type)]) + key_data = ( + b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00' + b'\x00') - key_data = {'bytes': bytearray(b'\x00\x00\x00\x00\x00\x00\x00\x00' - b'\x00\x00\x00\x00\x00\x00\x00\x00')} + key_material = KeyMaterial(key_data) + key_value = KeyValue(key_material) + cryptographic_algorithm = CryptographicAlgorithm(algorithm_value) + cryptographic_length = CryptographicLength(128) - secret_features.update([('key_value', key_data)]) - secret_features.update([('cryptographic_algorithm', algorithm_value)]) - secret_features.update([('cryptographic_length', 128)]) + key_block = KeyBlock( + key_format_type=key_format_type, + key_compression_type=None, + key_value=key_value, + cryptographic_algorithm=cryptographic_algorithm, + cryptographic_length=cryptographic_length, + key_wrapping_data=None) - secret = self.secret_factory.create(object_type, secret_features) + secret = SymmetricKey(key_block) result = self.client.register(object_type, template_attribute, secret, credential) @@ -273,9 +284,9 @@ class TestKMIPClientIntegration(TestCase): key_block = result.secret.key_block key_value = key_block.key_value - key_material = key_value.key_value.key_material + key_material = key_value.key_material - expected = key_data.get('bytes') + expected = key_data observed = key_material.value message = utils.build_er_error(key_material.__class__, 'value', expected, observed, 'value') @@ -303,7 +314,7 @@ class TestKMIPClientIntegration(TestCase): attribute_type = AttributeType.CRYPTOGRAPHIC_ALGORITHM algorithm = self.attr_factory.create_attribute( attribute_type, - CryptographicAlgorithm.AES) + CryptoAlgorithmEnum.AES) mask_flags = [CryptographicUsageMask.ENCRYPT, CryptographicUsageMask.DECRYPT]