def __init__(self, hashing_algorithm=None, digest_value=None, key_format_type=None): """ Construct a Digest object. Args: hashing_algorithm (HashingAlgorithm): The hash algorithm used to compute the value of the digest. Optional, defaults to None. digest_value (DigestValue): The byte string representing the value of the hash digest. Optional, defaults to None. key_format_type (KeyFormatType): The format type of the key the hash was computed for, if the object in question is a key. Optional, defaults to None. """ super(Digest, self).__init__(Tags.DIGEST) if hashing_algorithm is None: self.hashing_algorithm = HashingAlgorithm() else: self.hashing_algorithm = hashing_algorithm if digest_value is None: self.digest_value = DigestValue() else: self.digest_value = digest_value if key_format_type is None: self.key_format_type = KeyFormatType() else: self.key_format_type = key_format_type self.validate()
def read(self, istream): super(KeyBlock, self).read(istream) tstream = BytearrayStream(istream.read(self.length)) self.key_format_type = KeyFormatType() self.key_format_type.read(tstream) 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() self.key_value.read(tstream) if self.is_tag_next(Tags.CRYPTOGRAPHIC_ALGORITHM, tstream): self.cryptographic_algorithm = attributes.CryptographicAlgorithm() self.cryptographic_algorithm.read(tstream) if self.is_tag_next(Tags.CRYPTOGRAPHIC_LENGTH, tstream): self.cryptographic_length = attributes.CryptographicLength() self.cryptographic_length.read(tstream) if self.is_tag_next(Tags.KEY_WRAPPING_DATA, tstream): self.key_wrapping_data = KeyWrappingData() self.key_wrapping_data.read(tstream) self.is_oversized(tstream) self.validate()
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') cryptographic_algorithm = value.get('cryptographic_algorithm') cryptographic_length = value.get('cryptographic_length') key_wrapping_data = value.get('key_wrapping_data') key_format_type = KeyFormatType(key_type) key_comp_type = None if key_compression_type is not None: key_comp_type = KeyBlock.KeyCompressionType(key_compression_type) key_material = KeyMaterial(key_value) key_value = KeyValue(key_material) crypto_algorithm = None if cryptographic_algorithm is not None: crypto_algorithm = CryptographicAlgorithm(cryptographic_algorithm) crypto_length = None if cryptographic_length is not None: crypto_length = CryptographicLength(cryptographic_length) key_wrap_data = None if key_wrapping_data: # TODO (peter-hamilton) This currently isn't used in the tests # TODO (peter-hamilton) but needs to be updated to properly # TODO (peter-hamilton) create a KeyWrappingData object. key_wrap_data = KeyWrappingData(**key_wrapping_data) key_block = KeyBlock(key_format_type, key_comp_type, key_value, crypto_algorithm, crypto_length, key_wrap_data) return key_block
def read(self, istream): super(self.__class__, self).read(istream) tstream = BytearrayStream(istream.read(self.length)) self.key_format_type = KeyFormatType() self.key_format_type.read(tstream) 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() self.key_value.read(tstream) if self.is_tag_next(Tags.CRYPTOGRAPHIC_ALGORITHM, tstream): self.cryptographic_algorithm = attributes.CryptographicAlgorithm() self.cryptographic_algorithm.read(tstream) if self.is_tag_next(Tags.CRYPTOGRAPHIC_LENGTH, tstream): self.cryptographic_length = attributes.CryptographicLength() self.cryptographic_length.read(tstream) if self.is_tag_next(Tags.KEY_WRAPPING_DATA, tstream): self.key_wrapping_data = KeyWrappingData() self.key_wrapping_data.read(tstream) self.is_oversized(tstream) self.validate()
def test_get_no_uuid(self): self._create() key_format_type = KeyFormatType(KeyFormatTypeEnum.RAW) res = self.kmip.get(None, key_format_type) self.assertEqual(ResultStatus.OPERATION_FAILED, res.result_status.value, 'result status did not return failed')
def _gen_symmetric_key(self, bit_length, crypto_alg): key_format_type = KeyFormatType(KeyFormatTypeEnum.RAW) 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) return SymmetricKey(key_block)
def _test_init(self, value): if (isinstance(value, KeyFormatTypeEnum)) or (value is None): key_format_type = KeyFormatType(value) msg = "expected {0}, observed {1}".format(value, key_format_type.value) self.assertEqual(value, key_format_type.value, msg) else: self.assertRaises(TypeError, KeyFormatType, value)
def test_get_unknown(self): uuids = ('some random string', UniqueIdentifier('no key here')) for uuid in uuids: key_format_type = KeyFormatType(KeyFormatTypeEnum.RAW) res = self.kmip.get(uuid, key_format_type) self.assertEqual(ResultStatus.OPERATION_FAILED, res.result_status.value, 'result status did not return failed') self.assertEqual(ResultReason.ITEM_NOT_FOUND, res.result_reason.value, 'result reason did not match')
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 _get_symmetric_key(self): # only need usage attribute attrs = [self._get_attrs()[1]] key_format_type = KeyFormatType(KeyFormatTypeEnum.RAW) 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) key_block = KeyBlock(key_format_type, None, key_value, crypto_alg, crypto_length, usage) return SymmetricKey(key_block)
def test_get_with_key_compression(self): uuid = self._create() key_format_type = KeyFormatType(KeyFormatTypeEnum.RAW) key_compression = KeyCompressionType(KeyCompressionTypeEnum. EC_PUBLIC_KEY_TYPE_UNCOMPRESSED) res = self.kmip.get(uuid, key_format_type, key_compression) self.assertEqual(ResultStatus.OPERATION_FAILED, res.result_status.value, 'result status did not return failed') self.assertEqual(ResultReason.KEY_COMPRESSION_TYPE_NOT_SUPPORTED, res.result_reason.value, 'result reason did not match')
def get(self, uuid=None, key_format_type=None, key_compression_type=None, key_wrapping_specification=None, credential=None): self.logger.debug('get() called') ret_value = RS.OPERATION_FAILED if uuid is None or not hasattr(uuid, 'value'): self.logger.debug('no uuid provided') reason = ResultReason(ResultReasonEnum.ITEM_NOT_FOUND) message = ResultMessage('') return GetResult(ResultStatus(ret_value), reason, message) if key_format_type is None: self.logger.debug('key format type is None, setting to raw') key_format_type = KeyFormatType(KeyFormatTypeEnum.RAW) if key_format_type.value != KeyFormatTypeEnum.RAW: self.logger.debug('key format type is not raw') reason = ResultReason(ResultReasonEnum. KEY_FORMAT_TYPE_NOT_SUPPORTED) message = ResultMessage('') return GetResult(ResultStatus(ret_value), reason, message) if key_compression_type is not None: self.logger.debug('key compression type is not None') reason = ResultReason(ResultReasonEnum. KEY_COMPRESSION_TYPE_NOT_SUPPORTED) message = ResultMessage('') return GetResult(ResultStatus(ret_value), reason, message) if key_wrapping_specification is not None: self.logger.debug('key wrapping specification is not None') reason = ResultReason(ResultReasonEnum.FEATURE_NOT_SUPPORTED) message = ResultMessage('key wrapping is not currently supported') return GetResult(ResultStatus(ret_value), reason, message) self.logger.debug('retrieving object from repo') managed_object, _ = self.repo.get(uuid.value) if managed_object is None: self.logger.debug('object not found in repo') reason = ResultReason(ResultReasonEnum.ITEM_NOT_FOUND) message = ResultMessage('') return GetResult(ResultStatus(ret_value), reason, message) # currently only symmetric keys are supported, fix this in future object_type = ObjectType(OT.SYMMETRIC_KEY) ret_value = RS.SUCCESS return GetResult(ResultStatus(ret_value), object_type=object_type, uuid=uuid, secret=managed_object)
def test_destroy(self): uuid = self._create() key_format_type = KeyFormatType(KeyFormatTypeEnum.RAW) res = self.kmip.get(uuid, key_format_type) self.assertEqual(ResultStatus.SUCCESS, res.result_status.value, 'result status did not return success') res = self.kmip.destroy(uuid) self.assertEqual(ResultStatus.SUCCESS, res.result_status.value, 'result status did not return success') res = self.kmip.destroy(uuid) self.assertEqual(ResultStatus.OPERATION_FAILED, res.result_status.value, 'result status did not return failed') self.assertEqual(ResultReason.ITEM_NOT_FOUND, res.result_reason.value, 'result reason did not match')
def create(cls, hashing_algorithm=HashingAlgorithmEnum.SHA_256, digest_value=b'', key_format_type=KeyFormatTypeEnum.RAW): """ Construct a Digest object from provided digest values. Args: hashing_algorithm (HashingAlgorithm): An enumeration representing the hash algorithm used to compute the digest. Optional, defaults to HashingAlgorithm.SHA_256. digest_value (byte string): The bytes of the digest hash. Optional, defaults to the empty byte string. key_format_type (KeyFormatType): An enumeration representing the format of the key corresponding to the digest. Optional, defaults to KeyFormatType.RAW. Returns: Digest: The newly created Digest. Example: >>> x = Digest.create(HashingAlgorithm.MD5, b'\x00', ... KeyFormatType.RAW) >>> x.hashing_algorithm HashingAlgorithm(value=HashingAlgorithm.MD5) >>> x.digest_value DigestValue(value=bytearray(b'\x00')) >>> x.key_format_type KeyFormatType(value=KeyFormatType.RAW) """ algorithm = HashingAlgorithm(hashing_algorithm) value = DigestValue(bytearray(digest_value)) format_type = KeyFormatType(key_format_type) return Digest(hashing_algorithm=algorithm, digest_value=value, key_format_type=format_type)
def test_register(self): credential_type = CredentialType.USERNAME_AND_PASSWORD credential_value = {'Username': '******', 'Password': '******'} credential = self.cred_factory.create_credential( credential_type, credential_value) object_type = ObjectType.SYMMETRIC_KEY algorithm_value = CryptoAlgorithmEnum.AES mask_flags = [ CryptographicUsageMask.ENCRYPT, CryptographicUsageMask.DECRYPT ] attribute_type = AttributeType.CRYPTOGRAPHIC_USAGE_MASK usage_mask = self.attr_factory.create_attribute( attribute_type, mask_flags) attributes = [usage_mask] template_attribute = TemplateAttribute(attributes=attributes) key_format_type = KeyFormatType(KeyFormatTypeEnum.RAW) key_data = ( b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00' b'\x00') key_material = KeyMaterial(key_data) key_value = KeyValue(key_material) cryptographic_algorithm = CryptographicAlgorithm(algorithm_value) cryptographic_length = CryptographicLength(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 = SymmetricKey(key_block) result = self.client.register(object_type, template_attribute, secret, credential) self._check_result_status(result.result_status.value, ResultStatus, ResultStatus.SUCCESS) self._check_uuid(result.uuid.value, str) # Check the template attribute type self._check_template_attribute(result.template_attribute, TemplateAttribute, 1, [[str, 'Unique Identifier', str, None]]) # Check that the returned key bytes match what was provided uuid = result.uuid.value result = self.client.get(uuid=uuid, credential=credential) self._check_result_status(result.result_status.value, ResultStatus, ResultStatus.SUCCESS) self._check_object_type(result.object_type.value, ObjectType, ObjectType.SYMMETRIC_KEY) self._check_uuid(result.uuid.value, str) # Check the secret type secret = result.secret expected = SymmetricKey message = utils.build_er_error(result.__class__, 'type', expected, secret, 'secret') self.assertIsInstance(secret, expected, message) key_block = result.secret.key_block key_value = key_block.key_value key_material = key_value.key_material expected = key_data observed = key_material.value message = utils.build_er_error(key_material.__class__, 'value', expected, observed, 'value') self.assertEqual(expected, observed, message)
def test_passphrase_register_get_destroy(self): """ Tests that passphrases can be properly registered, retrieved, and destroyed """ # properties copied from test case example : # http://docs.oasis-open.org/kmip/testcases/v1.1/cn01/kmip-testcases-v1.1-cn01.html#_Toc333488777 pass_obj_type = ObjectType.SECRET_DATA mask_flags = [CryptographicUsageMask.VERIFY] attribute_type = AttributeType.CRYPTOGRAPHIC_USAGE_MASK usage_mask = self.attr_factory.create_attribute( attribute_type, mask_flags) name = Attribute.AttributeName('Name') pass_name = 'Integration Test - Register-Get-Destroy Passphrase' pass_name_value = Name.NameValue(pass_name) name_type = Name.NameType(NameType.UNINTERPRETED_TEXT_STRING) pass_value = Name(name_value=pass_name_value, name_type=name_type) pass_name_attr = Attribute(attribute_name=name, attribute_value=pass_value) pass_attributes = [usage_mask, pass_name_attr] pass_template_attribute = TemplateAttribute(attributes=pass_attributes) pass_format_type = SecretData.SecretDataType(SecretDataType.PASSWORD) key_format_type = KeyFormatType(KeyFormatTypeEnum.OPAQUE) key_data = b'\x70\x65\x65\x6b\x2d\x61\x2d\x62\x6f\x6f\x21\x21' key_material = KeyMaterial(key_data) key_value = KeyValue(key_material) key_block = KeyBlock(key_format_type=key_format_type, key_compression_type=None, key_value=key_value, key_wrapping_data=None) pass_obj = SecretData(secret_data_type=pass_format_type, key_block=key_block) pass_result = self.client.register(pass_obj_type, pass_template_attribute, pass_obj, credential=None) self._check_result_status(pass_result, ResultStatus, ResultStatus.SUCCESS) self._check_uuid(pass_result.uuid.value, str) # Check that the returned key bytes match what was provided pass_uuid = pass_result.uuid.value pass_result = self.client.get(uuid=pass_uuid, credential=None) self._check_result_status(pass_result, ResultStatus, ResultStatus.SUCCESS) self._check_object_type(pass_result.object_type.value, ObjectType, ObjectType.SECRET_DATA) self._check_uuid(pass_result.uuid.value, str) # Check the secret type pass_secret = pass_result.secret pass_secret_expected = SecretData self.assertIsInstance(pass_secret, pass_secret_expected) pass_material = pass_result.secret.key_block.key_value.key_material\ .value expected = key_data self.assertEqual(expected, pass_material) self.logger.debug('Destroying cert: ' + pass_name + '\nWith " "UUID: ' + pass_result.uuid.value) pass_result = self.client.destroy(pass_result.uuid.value) self._check_result_status(pass_result, ResultStatus, ResultStatus.SUCCESS) self._check_uuid(pass_result.uuid.value, str) # Verify the secret was destroyed pass_result_destroyed_result = self.client.get(uuid=pass_uuid, credential=None) self._check_result_status(pass_result_destroyed_result, ResultStatus, ResultStatus.OPERATION_FAILED) expected = ResultReason pass_observed = type(pass_result_destroyed_result.result_reason.value) self.assertEqual(expected, pass_observed)
def test_public_key_register_get_destroy(self): """ Tests that public keys are properly registered, retrieved, and destroyed. """ pub_key_object_type = ObjectType.PUBLIC_KEY mask_flags = [ CryptographicUsageMask.ENCRYPT, CryptographicUsageMask.DECRYPT ] attribute_type = AttributeType.CRYPTOGRAPHIC_USAGE_MASK usage_mask = self.attr_factory.create_attribute( attribute_type, mask_flags) name = Attribute.AttributeName('Name') key_name = 'Integration Test - Register-Get-Destroy Key -' pub_name_value = Name.NameValue(key_name + " Public") name_type = Name.NameType(NameType.UNINTERPRETED_TEXT_STRING) pub_value = Name(name_value=pub_name_value, name_type=name_type) pub_name = Attribute(attribute_name=name, attribute_value=pub_value) pub_key_attributes = [usage_mask, pub_name] public_template_attribute = TemplateAttribute( attributes=pub_key_attributes) key_format_type = KeyFormatType(KeyFormatTypeEnum.RAW) key_data = ( 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') key_material = KeyMaterial(key_data) key_value = KeyValue(key_material) algorithm_value = CryptoAlgorithmEnum.RSA cryptographic_algorithm = CryptographicAlgorithm(algorithm_value) cryptographic_length = CryptographicLength(2048) 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) pub_secret = PublicKey(key_block) pub_key_result = self.client.register(pub_key_object_type, public_template_attribute, pub_secret, credential=None) self._check_result_status(pub_key_result, ResultStatus, ResultStatus.SUCCESS) # Check that the returned key bytes match what was provided pub_uuid = pub_key_result.uuid.value pub_key_result = self.client.get(uuid=pub_uuid, credential=None) self._check_result_status(pub_key_result, ResultStatus, ResultStatus.SUCCESS) self._check_object_type(pub_key_result.object_type.value, ObjectType, ObjectType.PUBLIC_KEY) self._check_uuid(pub_key_result.uuid.value, str) # Check the secret type pub_secret = pub_key_result.secret pub_expected = PublicKey self.assertIsInstance(pub_secret, pub_expected) pub_key_block = pub_key_result.secret.key_block pub_key_value = pub_key_block.key_value pub_key_material = pub_key_value.key_material expected = key_data pub_observed = pub_key_material.value self.assertEqual(expected, pub_observed) self.logger.debug('Destroying key: ' + key_name + " Public" + '\nWith " "UUID: ' + pub_key_result.uuid.value) pub_result = self.client.destroy(pub_key_result.uuid.value) self._check_result_status(pub_result, ResultStatus, ResultStatus.SUCCESS) self._check_uuid(pub_result.uuid.value, str) pub_key_destroyed_result = self.client.get(uuid=pub_uuid, credential=None) self._check_result_status(pub_key_destroyed_result, ResultStatus, ResultStatus.OPERATION_FAILED) expected = ResultReason pub_observed = type(pub_key_destroyed_result.result_reason.value) self.assertEqual(expected, pub_observed)
def test_private_key_register_get_destroy(self): """ Tests that private keys are properly registered, retrieved, and destroyed. """ priv_key_object_type = ObjectType.PRIVATE_KEY mask_flags = [ CryptographicUsageMask.ENCRYPT, CryptographicUsageMask.DECRYPT ] attribute_type = AttributeType.CRYPTOGRAPHIC_USAGE_MASK usage_mask = self.attr_factory.create_attribute( attribute_type, mask_flags) name = Attribute.AttributeName('Name') key_name = 'Integration Test - Register-Get-Destroy Key -' priv_name_value = Name.NameValue(key_name + " Private") name_type = Name.NameType(NameType.UNINTERPRETED_TEXT_STRING) priv_value = Name(name_value=priv_name_value, name_type=name_type) priv_name = Attribute(attribute_name=name, attribute_value=priv_value) priv_key_attributes = [usage_mask, priv_name] private_template_attribute = TemplateAttribute( attributes=priv_key_attributes) key_format_type = KeyFormatType(KeyFormatTypeEnum.RAW) key_data = ( 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') key_material = KeyMaterial(key_data) key_value = KeyValue(key_material) algorithm_value = CryptoAlgorithmEnum.RSA cryptographic_algorithm = CryptographicAlgorithm(algorithm_value) cryptographic_length = CryptographicLength(2048) 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) priv_secret = PrivateKey(key_block) priv_key_result = self.client.register(priv_key_object_type, private_template_attribute, priv_secret, credential=None) self._check_result_status(priv_key_result, ResultStatus, ResultStatus.SUCCESS) self._check_uuid(priv_key_result.uuid.value, str) # Check that the returned key bytes match what was provided priv_uuid = priv_key_result.uuid.value priv_key_result = self.client.get(uuid=priv_uuid, credential=None) self._check_result_status(priv_key_result, ResultStatus, ResultStatus.SUCCESS) self._check_object_type(priv_key_result.object_type.value, ObjectType, ObjectType.PRIVATE_KEY) self._check_uuid(priv_key_result.uuid.value, str) # Check the secret type priv_secret = priv_key_result.secret priv_expected = PrivateKey self.assertIsInstance(priv_secret, priv_expected) priv_key_block = priv_key_result.secret.key_block priv_key_value = priv_key_block.key_value priv_key_material = priv_key_value.key_material expected = key_data priv_observed = priv_key_material.value self.assertEqual(expected, priv_observed) self.logger.debug('Destroying key: ' + key_name + " Private" + '\nWith " "UUID: ' + priv_key_result.uuid.value) priv_result = self.client.destroy(priv_key_result.uuid.value) self._check_result_status(priv_result, ResultStatus, ResultStatus.SUCCESS) self._check_uuid(priv_result.uuid.value, str) # Verify the secret was destroyed priv_key_destroyed_result = self.client.get(uuid=priv_uuid, credential=None) self._check_result_status(priv_key_destroyed_result, ResultStatus, ResultStatus.OPERATION_FAILED) expected = ResultReason priv_observed = type(priv_key_destroyed_result.result_reason.value) self.assertEqual(expected, priv_observed)
def test_symmetric_key_register_get_destroy(self): """ Tests that symmetric keys are properly registered, retrieved, and destroyed. """ object_type = ObjectType.SYMMETRIC_KEY algorithm_value = CryptoAlgorithmEnum.AES mask_flags = [ CryptographicUsageMask.ENCRYPT, CryptographicUsageMask.DECRYPT ] attribute_type = AttributeType.CRYPTOGRAPHIC_USAGE_MASK usage_mask = self.attr_factory.create_attribute( attribute_type, mask_flags) name = Attribute.AttributeName('Name') key_name = 'Integration Test - Register-Get-Destroy Key' name_value = Name.NameValue(key_name) name_type = Name.NameType(NameType.UNINTERPRETED_TEXT_STRING) value = Name(name_value=name_value, name_type=name_type) name = Attribute(attribute_name=name, attribute_value=value) attributes = [usage_mask, name] template_attribute = TemplateAttribute(attributes=attributes) key_format_type = KeyFormatType(KeyFormatTypeEnum.RAW) key_data = ( b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00' b'\x00') key_material = KeyMaterial(key_data) key_value = KeyValue(key_material) cryptographic_algorithm = CryptographicAlgorithm(algorithm_value) cryptographic_length = CryptographicLength(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 = SymmetricKey(key_block) result = self.client.register(object_type, template_attribute, secret, credential=None) self._check_result_status(result, ResultStatus, ResultStatus.SUCCESS) self._check_uuid(result.uuid.value, str) # Check that the returned key bytes match what was provided uuid = result.uuid.value result = self.client.get(uuid=uuid, credential=None) self._check_result_status(result, ResultStatus, ResultStatus.SUCCESS) self._check_object_type(result.object_type.value, ObjectType, ObjectType.SYMMETRIC_KEY) self._check_uuid(result.uuid.value, str) # Check the secret type secret = result.secret expected = SymmetricKey self.assertIsInstance(secret, expected) key_block = result.secret.key_block key_value = key_block.key_value key_material = key_value.key_material expected = key_data observed = key_material.value self.assertEqual(expected, observed) self.logger.debug('Destroying key: ' + key_name + '\nWith UUID: ' + result.uuid.value) result = self.client.destroy(result.uuid.value) self._check_result_status(result, ResultStatus, ResultStatus.SUCCESS) self._check_uuid(result.uuid.value, str) # Verify the secret was destroyed result = self.client.get(uuid=uuid, credential=None) self._check_result_status(result, ResultStatus, ResultStatus.OPERATION_FAILED) expected = ResultReason observed = type(result.result_reason.value) self.assertEqual(expected, observed) expected = ResultReason.ITEM_NOT_FOUND observed = result.result_reason.value self.assertEqual(expected, observed)
def test_get(self): uuid = self._create() key_format_type = KeyFormatType(KeyFormatTypeEnum.RAW) res = self.kmip.get(uuid, key_format_type) self.assertEqual(ResultStatus.SUCCESS, res.result_status.value, 'result status did not return success')
class KeyBlock(Struct): class KeyCompressionType(Enumeration): def __init__(self, value=None): super(KeyBlock.KeyCompressionType, self).__init__( enums.KeyCompressionType, value, Tags.KEY_COMPRESSION_TYPE) def __init__(self, key_format_type=None, key_compression_type=None, key_value=None, cryptographic_algorithm=None, cryptographic_length=None, key_wrapping_data=None): super(KeyBlock, self).__init__(Tags.KEY_BLOCK) self.key_format_type = key_format_type self.key_compression_type = key_compression_type self.key_value = key_value self.cryptographic_algorithm = cryptographic_algorithm self.cryptographic_length = cryptographic_length self.key_wrapping_data = key_wrapping_data self.validate() def read(self, istream): super(KeyBlock, self).read(istream) tstream = BytearrayStream(istream.read(self.length)) self.key_format_type = KeyFormatType() self.key_format_type.read(tstream) 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() self.key_value.read(tstream) if self.is_tag_next(Tags.CRYPTOGRAPHIC_ALGORITHM, tstream): self.cryptographic_algorithm = attributes.CryptographicAlgorithm() self.cryptographic_algorithm.read(tstream) if self.is_tag_next(Tags.CRYPTOGRAPHIC_LENGTH, tstream): self.cryptographic_length = attributes.CryptographicLength() self.cryptographic_length.read(tstream) if self.is_tag_next(Tags.KEY_WRAPPING_DATA, tstream): self.key_wrapping_data = KeyWrappingData() self.key_wrapping_data.read(tstream) self.is_oversized(tstream) self.validate() def write(self, ostream): tstream = BytearrayStream() self.key_format_type.write(tstream) if self.key_compression_type is not None: self.key_compression_type.write(tstream) self.key_value.write(tstream) if self.cryptographic_algorithm is not None: self.cryptographic_algorithm.write(tstream) if self.cryptographic_length is not None: self.cryptographic_length.write(tstream) if self.key_wrapping_data is not None: self.key_wrapping_data.write(tstream) # Write the length and value of the credential self.length = tstream.length() super(KeyBlock, self).write(ostream) ostream.write(tstream.buffer) def validate(self): self.__validate() def __validate(self): if self.key_format_type is not None: if type(self.key_format_type) is not KeyFormatType: member = 'KeyBlock.key_format_type' exp_type = KeyFormatType rcv_type = type(self.key_format_type) msg = ErrorStrings.BAD_EXP_RECV.format(member, 'type', exp_type, rcv_type) raise TypeError(msg)
attribute_factory = AttributeFactory() credential_factory = CredentialFactory() # 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) key_format_type = None if format_type_enum is not None: key_format_type = KeyFormatType(format_type_enum) # Build the client and connect to the server client = KMIPProxy(config=config, config_file=opts.config_file) client.open() # Retrieve the SYMMETRIC_KEY object result = client.get(uuid=uuid, key_format_type=key_format_type, credential=credential) client.close() # Display operation results logger.info('get() result status: {0}'.format(result.result_status.value)) if result.result_status.value == ResultStatus.SUCCESS:
class KeyBlock(Struct): class KeyCompressionType(Enumeration): ENUM_TYPE = enums.KeyCompressionType def __init__(self, value=None): super(self.__class__, self).__init__(value, Tags.KEY_COMPRESSION_TYPE) def __init__(self, key_format_type=None, key_compression_type=None, key_value=None, cryptographic_algorithm=None, cryptographic_length=None, key_wrapping_data=None): super(self.__class__, self).__init__(Tags.KEY_BLOCK) self.key_format_type = key_format_type self.key_compression_type = key_compression_type self.key_value = key_value self.cryptographic_algorithm = cryptographic_algorithm self.cryptographic_length = cryptographic_length self.key_wrapping_data = key_wrapping_data self.validate() def read(self, istream): super(self.__class__, self).read(istream) tstream = BytearrayStream(istream.read(self.length)) self.key_format_type = KeyFormatType() self.key_format_type.read(tstream) 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() self.key_value.read(tstream) if self.is_tag_next(Tags.CRYPTOGRAPHIC_ALGORITHM, tstream): self.cryptographic_algorithm = attributes.CryptographicAlgorithm() self.cryptographic_algorithm.read(tstream) if self.is_tag_next(Tags.CRYPTOGRAPHIC_LENGTH, tstream): self.cryptographic_length = attributes.CryptographicLength() self.cryptographic_length.read(tstream) if self.is_tag_next(Tags.KEY_WRAPPING_DATA, tstream): self.key_wrapping_data = KeyWrappingData() self.key_wrapping_data.read(tstream) self.is_oversized(tstream) self.validate() def write(self, ostream): tstream = BytearrayStream() self.key_format_type.write(tstream) if self.key_compression_type is not None: self.key_compression_type.write(tstream) self.key_value.write(tstream) if self.cryptographic_algorithm is not None: self.cryptographic_algorithm.write(tstream) if self.cryptographic_length is not None: self.cryptographic_length.write(tstream) if self.key_wrapping_data is not None: self.key_wrapping_data.write(tstream) # Write the length and value of the credential self.length = tstream.length() super(self.__class__, self).write(ostream) ostream.write(tstream.buffer) def validate(self): self.__validate() def __validate(self): if self.key_format_type is not None: if type(self.key_format_type) is not KeyFormatType: member = 'KeyBlock.key_format_type' exp_type = KeyFormatType rcv_type = type(self.key_format_type) msg = ErrorStrings.BAD_EXP_RECV.format(member, 'type', exp_type, rcv_type) raise TypeError(msg)
class Digest(Struct): """ A structure storing a hash digest of a Managed Object. Digests may be calculated for keys, secret data objects, certificates, and opaque data objects and are generated when the object is created or registered with the KMIP server. See Section 3.17 of the KMIP 1.1 specification for more information. Attributes: hashing_algorithm: The algorithm used to compute the hash digest. digest_value: The bytes representing the hash digest value. key_format_type: The type of the key the hash was generated for. """ def __init__(self, hashing_algorithm=None, digest_value=None, key_format_type=None): """ Construct a Digest object. Args: hashing_algorithm (HashingAlgorithm): The hash algorithm used to compute the value of the digest. Optional, defaults to None. digest_value (DigestValue): The byte string representing the value of the hash digest. Optional, defaults to None. key_format_type (KeyFormatType): The format type of the key the hash was computed for, if the object in question is a key. Optional, defaults to None. """ super(Digest, self).__init__(Tags.DIGEST) if hashing_algorithm is None: self.hashing_algorithm = HashingAlgorithm() else: self.hashing_algorithm = hashing_algorithm if digest_value is None: self.digest_value = DigestValue() else: self.digest_value = digest_value if key_format_type is None: self.key_format_type = KeyFormatType() else: self.key_format_type = key_format_type self.validate() def read(self, istream): """ Read the data encoding the Digest object and decode it into its constituent parts. Args: istream (Stream): A data stream containing encoded object data, supporting a read method; usually a BytearrayStream object. """ super(Digest, self).read(istream) tstream = BytearrayStream(istream.read(self.length)) self.hashing_algorithm.read(tstream) self.digest_value.read(tstream) self.key_format_type.read(tstream) self.is_oversized(tstream) self.validate() def write(self, ostream): """ Write the data encoding the Digest object to a stream. Args: ostream (Stream): A data stream in which to encode object data, supporting a write method; usually a BytearrayStream object. """ tstream = BytearrayStream() self.hashing_algorithm.write(tstream) self.digest_value.write(tstream) self.key_format_type.write(tstream) self.length = tstream.length() super(Digest, self).write(ostream) ostream.write(tstream.buffer) def validate(self): """ Error check the attributes of the Digest object. """ self.__validate() def __validate(self): # TODO (peter-hamilton) Add checks comparing the length of the digest # value against the standard length for the stated hashing algorithm. if not isinstance(self.hashing_algorithm, HashingAlgorithm): msg = "invalid hashing algorithm" msg += "; expected {0}, received {1}".format( HashingAlgorithm, self.hashing_algorithm) raise TypeError(msg) if not isinstance(self.digest_value, DigestValue): msg = "invalid digest value" msg += "; expected {0}, received {1}".format( DigestValue, self.digest_value) raise TypeError(msg) if not isinstance(self.key_format_type, KeyFormatType): msg = "invalid key format type" msg += "; expected {0}, received {1}".format( KeyFormatType, self.key_format_type) raise TypeError(msg) def __eq__(self, other): if isinstance(other, Digest): if self.hashing_algorithm != other.hashing_algorithm: return False elif self.digest_value != other.digest_value: return False elif self.key_format_type != other.key_format_type: return False else: return True else: return NotImplemented def __ne__(self, other): if isinstance(other, Digest): return not (self == other) else: return NotImplemented def __repr__(self): hashing_algorithm = "hashing_algorithm={0}".format( repr(self.hashing_algorithm)) digest_value = "digest_value={0}".format( repr(self.digest_value)) key_format_type = "key_format_type={0}".format( repr(self.key_format_type)) return "Digest({0}, {1}, {2})".format( hashing_algorithm, digest_value, key_format_type) def __str__(self): return str(self.digest_value) @classmethod def create(cls, hashing_algorithm=HashingAlgorithmEnum.SHA_256, digest_value=b'', key_format_type=KeyFormatTypeEnum.RAW): """ Construct a Digest object from provided digest values. Args: hashing_algorithm (HashingAlgorithm): An enumeration representing the hash algorithm used to compute the digest. Optional, defaults to HashingAlgorithm.SHA_256. digest_value (byte string): The bytes of the digest hash. Optional, defaults to the empty byte string. key_format_type (KeyFormatType): An enumeration representing the format of the key corresponding to the digest. Optional, defaults to KeyFormatType.RAW. Returns: Digest: The newly created Digest. Example: >>> x = Digest.create(HashingAlgorithm.MD5, b'\x00', ... KeyFormatType.RAW) >>> x.hashing_algorithm HashingAlgorithm(value=HashingAlgorithm.MD5) >>> x.digest_value DigestValue(value=bytearray(b'\x00')) >>> x.key_format_type KeyFormatType(value=KeyFormatType.RAW) """ algorithm = HashingAlgorithm(hashing_algorithm) value = DigestValue(bytearray(digest_value)) format_type = KeyFormatType(key_format_type) return Digest(hashing_algorithm=algorithm, digest_value=value, key_format_type=format_type)