def setUp(self): super(TestKMIPClientIntegration, self).setUp() self.attr_factory = AttributeFactory() self.cred_factory = CredentialFactory() self.secret_factory = SecretFactory() # Set up the KMIP server process path = os.path.join(os.path.dirname(__file__), os.path.pardir, 'utils', 'server.py') self.server = Popen( ['python', '{0}'.format(path), '-p', '{0}'.format(self.KMIP_PORT)], stderr=sys.stdout) time.sleep(self.STARTUP_TIME) if self.server.poll() is not None: raise KMIPServerSuicideError(self.server.pid) # Set up and open the client proxy; shutdown the server if open fails try: self.client = KMIPProxy(port=self.KMIP_PORT, ca_certs=self.CA_CERTS_PATH) self.client.open() except Exception as e: self._shutdown_server() raise e
def setUp(self): super(TestIntegration, self).setUp() self.logger = logging.getLogger(__name__) self.attr_factory = AttributeFactory() self.cred_factory = CredentialFactory() self.secret_factory = SecretFactory()
def __init__(self): super(KMIPImpl, self).__init__() self.logger = logging.getLogger(__name__) self.key_factory = KeyFactory() self.secret_factory = SecretFactory() self.attribute_factory = AttributeFactory() self.repo = MemRepo() self.protocol_versions = [ ProtocolVersion.create(1, 1), ProtocolVersion.create(1, 0) ]
def test_locate(self): self._create() name_value = Name.NameValue(value='TESTNAME') name_type = Name.NameType(value=NameType.UNINTERPRETED_TEXT_STRING) value = Name.create(name_value, name_type) attr_factory = AttributeFactory() nameattr = attr_factory.create_attribute(AttributeType.NAME, value) attrs = [nameattr] res = self.kmip.locate(attributes=attrs) self.assertEqual(ResultStatus.OPERATION_FAILED, res.result_status.enum, 'locate result status did not return success')
def _get_attrs(self): attr_factory = AttributeFactory() algorithm = self._get_alg_attr(self.algorithm_name) length = self._get_length_attr(self.key_length) attribute_type = AttributeType.CRYPTOGRAPHIC_USAGE_MASK mask_flags = [CryptoUsageMaskEnum.ENCRYPT, CryptoUsageMaskEnum.DECRYPT] usage_mask = attr_factory.create_attribute(attribute_type, mask_flags) name_value = Name.NameValue(value='TESTNAME') name_type = Name.NameType(value=NameType.UNINTERPRETED_TEXT_STRING) value = Name.create(name_value, name_type) nameattr = attr_factory.create_attribute(AttributeType.NAME, value) return [algorithm, usage_mask, length, nameattr]
def test_locate(self): self._create() name_value = Name.NameValue(value='TESTNAME') name_type = Name.NameType(value=NameType.UNINTERPRETED_TEXT_STRING) value = Name.create(name_value, name_type) attr_factory = AttributeFactory() nameattr = attr_factory.create_attribute(AttributeType.NAME, value) attrs = [nameattr] res = self.kmip.locate(attributes=attrs) self.assertEqual( ResultStatus.OPERATION_FAILED, res.result_status.value, 'locate result status did not return success')
def setUp(self): super(TestKMIPClientIntegration, self).setUp() self.attr_factory = AttributeFactory() self.cred_factory = CredentialFactory() self.secret_factory = SecretFactory() # Set up the KMIP server process path = os.path.join(os.path.dirname(__file__), os.path.pardir, 'utils', 'server.py') self.server = Popen(['python', '{0}'.format(path), '-p', '{0}'.format(self.KMIP_PORT)], stderr=sys.stdout) time.sleep(self.STARTUP_TIME) if self.server.poll() is not None: raise KMIPServerSuicideError(self.server.pid) # Set up and open the client proxy; shutdown the server if open fails try: self.client = KMIPProxy(port=self.KMIP_PORT, ca_certs=self.CA_CERTS_PATH) self.client.open() except Exception as e: self._shutdown_server() raise e
def __init__(self): super(self.__class__, self).__init__() self.logger = logging.getLogger(__name__) self.key_factory = KeyFactory() self.secret_factory = SecretFactory() self.attribute_factory = AttributeFactory() self.repo = MemRepo()
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 setUp(self): super(TestKMIPClient, self).setUp() self.attr_factory = AttributeFactory() self.cred_factory = CredentialFactory() self.secret_factory = SecretFactory() self.client = KMIPProxy() KMIP_PORT = 9090 CA_CERTS_PATH = os.path.normpath(os.path.join(os.path.dirname( os.path.abspath(__file__)), '../utils/certs/server.crt')) self.mock_client = KMIPProxy(host="IP_ADDR_1, IP_ADDR_2", port=KMIP_PORT, ca_certs=CA_CERTS_PATH) self.mock_client.socket = mock.MagicMock() self.mock_client.socket.connect = mock.MagicMock() self.mock_client.socket.close = mock.MagicMock()
def proccess_attributes(self, attributes): list_attributes = [] attribute_factory = AttributeFactory() for attribute in attributes: attribute_type = AttributeType(attribute['AttributeName']['value']) attribute_value = None if attribute_type == AttributeType.OBJECT_TYPE: if attribute['AttributeValue']['value'] == 'SymmetricKey': attribute_value = ObjectType.SYMMETRIC_KEY if attribute_type == AttributeType.ORIGINAL_CREATION_DATE: attribute_value = time.time() if attribute['AttributeValue']['value'] == '$NOW-60': attribute_value = attribute_value - 60 if attribute['AttributeValue']['value'] == '$NOW+60': attribute_value = attribute_value + 60 attribute_obj = attribute_factory.create_attribute( attribute_type, attribute_value) list_attributes.append(attribute_obj) return list_attributes
def build_cryptographic_usage_mask(logger, object_type): if object_type == ObjectType.CERTIFICATE: flags = [CryptographicUsageMask.ENCRYPT, CryptographicUsageMask.VERIFY] elif (object_type == ObjectType.SYMMETRIC_KEY or object_type == ObjectType.SECRET_DATA): 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 proccess_template_attributes(self, attributes): template_attributes = [] attribute_factory = AttributeFactory() for attribute in attributes: attribute_type = AttributeType(attribute['AttributeName']['value']) attribute_value = None if attribute_type == AttributeType.X_ID: name = Attribute.AttributeName('Name') attribute_value = Name.NameValue( attribute['AttributeValue']['value']) attribute_type = Name.NameType( NameType.UNINTERPRETED_TEXT_STRING) value = Name(name_value=attribute_value, name_type=attribute_type) name = Attribute(attribute_name=name, attribute_value=value) template_attributes.append(name) continue if attribute_type == AttributeType.CRYPTOGRAPHIC_ALGORITHM: attribute_value = getattr(CryptographicAlgorithm, attribute['AttributeValue']['value'], None) if attribute_type == AttributeType.CRYPTOGRAPHIC_LENGTH: attribute_value = attribute['AttributeValue']['value'] if attribute_type == AttributeType.CRYPTOGRAPHIC_USAGE_MASK: usage_mask = attribute['AttributeValue']['value'].split(' ') for idx, val in enumerate(usage_mask): usage_mask[idx] = getattr(CryptographicUsageMask, val.upper(), None) attribute_value = usage_mask attribute_obj = attribute_factory.create_attribute( attribute_type, attribute_value) template_attributes.append(attribute_obj) template_attributes = TemplateAttribute(attributes=template_attributes) return template_attributes
class TestIntegration(TestCase): def setUp(self): super(TestIntegration, self).setUp() self.logger = logging.getLogger(__name__) self.attr_factory = AttributeFactory() self.cred_factory = CredentialFactory() self.secret_factory = SecretFactory() def tearDown(self): super(TestIntegration, self).tearDown() def _create_symmetric_key(self, key_name=None): """ Helper function for creating symmetric keys. Used any time a key needs to be created. :param key_name: name of the key to be created :return: returns the result of the "create key" operation as provided by the KMIP appliance """ object_type = ObjectType.SYMMETRIC_KEY attribute_type = AttributeType.CRYPTOGRAPHIC_ALGORITHM algorithm = self.attr_factory.create_attribute(attribute_type, 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) key_length = 128 attribute_type = AttributeType.CRYPTOGRAPHIC_LENGTH key_length_obj = self.attr_factory.create_attribute(attribute_type, key_length) name = Attribute.AttributeName('Name') if key_name is None: key_name = 'Integration Test - 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 = [algorithm, usage_mask, key_length_obj, name] template_attribute = TemplateAttribute(attributes=attributes) return self.client.create(object_type, template_attribute, credential=None) def _create_key_pair(self, key_name=None): """ Helper function for creating private and public keys. Used any time a key pair needs to be created. :param key_name: name of the key to be created :return: returns the result of the "create key" operation as provided by the KMIP appliance """ attribute_type = AttributeType.CRYPTOGRAPHIC_ALGORITHM algorithm = self.attr_factory.create_attribute(attribute_type, CryptoAlgorithmEnum.RSA) mask_flags = [CryptographicUsageMask.ENCRYPT, CryptographicUsageMask.DECRYPT] attribute_type = AttributeType.CRYPTOGRAPHIC_USAGE_MASK usage_mask = self.attr_factory.create_attribute(attribute_type, mask_flags) key_length = 2048 attribute_type = AttributeType.CRYPTOGRAPHIC_LENGTH key_length_obj = self.attr_factory.create_attribute(attribute_type, key_length) name = Attribute.AttributeName('Name') if key_name is None: key_name = 'Integration Test - Key' priv_name_value = Name.NameValue(key_name + " Private") pub_name_value = Name.NameValue(key_name + " Public") name_type = Name.NameType(NameType.UNINTERPRETED_TEXT_STRING) priv_value = Name(name_value=priv_name_value, name_type=name_type) pub_value = Name(name_value=pub_name_value, name_type=name_type) priv_name = Attribute(attribute_name=name, attribute_value=priv_value) pub_name = Attribute(attribute_name=name, attribute_value=pub_value) common_attributes = [algorithm, usage_mask, key_length_obj] private_key_attributes = [priv_name] public_key_attributes = [pub_name] common = CommonTemplateAttribute(attributes=common_attributes) priv_templ_attr = PrivateKeyTemplateAttribute( attributes=private_key_attributes) pub_templ_attr = PublicKeyTemplateAttribute( attributes=public_key_attributes) return self.client.\ create_key_pair(common_template_attribute=common, private_key_template_attribute=priv_templ_attr, public_key_template_attribute=pub_templ_attr) def _check_result_status(self, result, result_status_type, result_status_value): """ Helper function for checking the status of KMIP appliance actions. Verifies the result status type and value. :param result: result object :param result_status_type: type of result status received :param result_status_value: value of the result status """ result_status = result.result_status.enum # Error check the result status type and value expected = result_status_type self.assertIsInstance(result_status, expected) expected = result_status_value if result_status is ResultStatus.OPERATION_FAILED: self.logger.error(result) self.logger.error(result.result_reason) self.logger.error(result.result_message) self.assertEqual(expected, result_status) def _check_uuid(self, uuid, uuid_type): """ Helper function for checking UUID type and value for errors :param uuid: UUID of a created key :param uuid_type: UUID type :return: """ # Error check the UUID type and value not_expected = None self.assertNotEqual(not_expected, uuid) expected = uuid_type self.assertEqual(expected, type(uuid)) def _check_object_type(self, object_type, object_type_type, object_type_value): """ Checks the type and value of a given object type. :param object_type: :param object_type_type: :param object_type_value: """ # Error check the object type type and value expected = object_type_type self.assertIsInstance(object_type, expected) expected = object_type_value self.assertEqual(expected, object_type) def _check_template_attribute(self, template_attribute, template_attribute_type, num_attributes, attribute_features): """ Checks the value and type of a given template attribute :param template_attribute: :param template_attribute_type: :param num_attributes: :param attribute_features: """ # Error check the template attribute type expected = template_attribute_type self.assertIsInstance(template_attribute, expected) attributes = template_attribute.attributes for i in range(num_attributes): features = attribute_features[i] self._check_attribute(attributes[i], features[0], features[1], features[2], features[3]) def _check_attribute(self, attribute, attribute_name_type, attribute_name_value, attribute_value_type, attribute_value_value): """ Checks the value and type of a given attribute :param attribute: :param attribute_name_type: :param attribute_name_value: :param attribute_value_type: :param attribute_value_value: """ # Error check the attribute name and value type and value attribute_name = attribute.attribute_name attribute_value = attribute.attribute_value self._check_attribute_name(attribute_name, attribute_name_type, attribute_name_value) if attribute_name_value == 'Unique Identifier': self._check_uuid(attribute_value.value, attribute_value_type) else: self._check_attribute_value(attribute_value, attribute_value_type, attribute_value_value) def _check_attribute_name(self, attribute_name, attribute_name_type, attribute_name_value): """ Checks the attribute name for a given attribute :param attribute_name: :param attribute_name_type: :param attribute_name_value: """ # Error check the attribute name type and value expected = attribute_name_type observed = type(attribute_name.value) self.assertEqual(expected, observed) expected = attribute_name_value observed = attribute_name.value self.assertEqual(expected, observed) def _check_attribute_value(self, attribute_value, attribute_value_type, attribute_value_value): """ Checks the attribute value for a given attribute :param attribute_value: :param attribute_value_type: :param attribute_value_value: """ expected = attribute_value_type observed = type(attribute_value.value) self.assertEqual(expected, observed) expected = attribute_value_value observed = attribute_value.value self.assertEqual(expected, observed) def test_discover_versions(self): result = self.client.discover_versions() expected = ResultStatus.SUCCESS observed = result.result_status.enum self.assertEqual(expected, observed) def test_query(self): # Build query function list, asking for all server data. query_functions = list() query_functions.append( QueryFunction(QueryFunctionEnum.QUERY_OPERATIONS)) query_functions.append( QueryFunction(QueryFunctionEnum.QUERY_OBJECTS)) query_functions.append( QueryFunction(QueryFunctionEnum.QUERY_SERVER_INFORMATION)) query_functions.append( QueryFunction(QueryFunctionEnum.QUERY_APPLICATION_NAMESPACES)) query_functions.append( QueryFunction(QueryFunctionEnum.QUERY_EXTENSION_LIST)) query_functions.append( QueryFunction(QueryFunctionEnum.QUERY_EXTENSION_MAP)) result = self.client.query(query_functions=query_functions) expected = ResultStatus.SUCCESS observed = result.result_status.enum self.assertEqual(expected, observed) def test_symmetric_key_create_get_destroy(self): """ Test that symmetric keys are properly created """ key_name = 'Integration Test - Create-Get-Destroy Key' result = self._create_symmetric_key(key_name=key_name) self._check_result_status(result, ResultStatus, ResultStatus.SUCCESS) self._check_object_type(result.object_type.enum, ObjectType, ObjectType.SYMMETRIC_KEY) self._check_uuid(result.uuid.value, str) result = self.client.get(uuid=result.uuid.value, credential=None) self._check_result_status(result, ResultStatus, ResultStatus.SUCCESS) self._check_object_type(result.object_type.enum, ObjectType, ObjectType.SYMMETRIC_KEY) self._check_uuid(result.uuid.value, str) # Check the secret type secret = result.secret expected = SymmetricKey self.assertIsInstance(secret, expected) self.logger.debug('Destroying key: ' + key_name + '\n With 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=result.uuid.value, credential=None) self._check_result_status(result, ResultStatus, ResultStatus.OPERATION_FAILED) expected = ResultReason observed = type(result.result_reason.enum) self.assertEqual(expected, observed) expected = ResultReason.ITEM_NOT_FOUND observed = result.result_reason.enum self.assertEqual(expected, 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.enum, 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.enum) self.assertEqual(expected, observed) expected = ResultReason.ITEM_NOT_FOUND observed = result.result_reason.enum self.assertEqual(expected, observed) def test_key_pair_create_get_destroy(self): """ Test that key pairs are properly created, retrieved, and destroyed. """ key_name = 'Integration Test - Create-Get-Destroy Key Pair -' result = self._create_key_pair(key_name=key_name) self._check_result_status(result, ResultStatus, ResultStatus.SUCCESS) # Check UUID value for Private key self._check_uuid(result.private_key_uuid.value, str) # Check UUID value for Public key self._check_uuid(result.public_key_uuid.value, str) priv_key_uuid = result.private_key_uuid.value pub_key_uuid = result.public_key_uuid.value priv_key_result = self.client.get(uuid=priv_key_uuid, credential=None) pub_key_result = self.client.get(uuid=pub_key_uuid, credential=None) self._check_result_status(priv_key_result, ResultStatus, ResultStatus.SUCCESS) self._check_object_type(priv_key_result.object_type.enum, ObjectType, ObjectType.PRIVATE_KEY) self._check_uuid(priv_key_result.uuid.value, str) self._check_result_status(pub_key_result, ResultStatus, ResultStatus.SUCCESS) self._check_object_type(pub_key_result.object_type.enum, ObjectType, ObjectType.PUBLIC_KEY) self._check_uuid(pub_key_result.uuid.value, str) # Check the secret type priv_secret = priv_key_result.secret pub_secret = pub_key_result.secret priv_expected = PrivateKey pub_expected = PublicKey self.assertIsInstance(priv_secret, priv_expected) self.assertIsInstance(pub_secret, pub_expected) self.logger.debug('Destroying key: ' + key_name + ' Private' + '\n With UUID: ' + result.private_key_uuid.value) destroy_priv_key_result = self.client.destroy( result.private_key_uuid.value) self._check_result_status(destroy_priv_key_result, ResultStatus, ResultStatus.SUCCESS) self.logger.debug('Destroying key: ' + key_name + ' Public' + '\n With UUID: ' + result.public_key_uuid.value) destroy_pub_key_result = self.client.destroy( result.public_key_uuid.value) self._check_result_status(destroy_pub_key_result, ResultStatus, ResultStatus.SUCCESS) priv_key_uuid = destroy_priv_key_result.uuid.value pub_key_uuid = destroy_pub_key_result.uuid.value self._check_uuid(priv_key_uuid, str) self._check_uuid(pub_key_uuid, str) # Verify the secret was destroyed priv_key_destroyed_result = self.client.get(uuid=priv_key_uuid) pub_key_destroyed_result = self.client.get(uuid=pub_key_uuid) self._check_result_status(priv_key_destroyed_result, ResultStatus, ResultStatus.OPERATION_FAILED) self._check_result_status(pub_key_destroyed_result, ResultStatus, ResultStatus.OPERATION_FAILED) expected = ResultReason observed_priv = type(priv_key_destroyed_result.result_reason.enum) observed_pub = type(pub_key_destroyed_result.result_reason.enum) self.assertEqual(expected, observed_priv) self.assertEqual(expected, observed_pub) 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.enum, 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.enum) self.assertEqual(expected, priv_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.enum, 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.enum) self.assertEqual(expected, pub_observed) def test_cert_register_get_destroy(self): """ Tests that certificates are 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#_Toc333488807 cert_obj_type = ObjectType.CERTIFICATE mask_flags = [CryptographicUsageMask.SIGN, CryptographicUsageMask.VERIFY] attribute_type = AttributeType.CRYPTOGRAPHIC_USAGE_MASK usage_mask = self.attr_factory.create_attribute(attribute_type, mask_flags) name = Attribute.AttributeName('Name') cert_name = 'Integration Test - Register-Get-Destroy Certificate' cert_name_value = Name.NameValue(cert_name) name_type = Name.NameType(NameType.UNINTERPRETED_TEXT_STRING) cert_value = Name(name_value=cert_name_value, name_type=name_type) cert_name_attr = Attribute(attribute_name=name, attribute_value=cert_value) cert_attributes = [usage_mask, cert_name_attr] cert_template_attribute = TemplateAttribute( attributes=cert_attributes) cert_format_type = CertificateTypeEnum.X_509 cert_data = ( b'\x30\x82\x03\x12\x30\x82\x01\xFA\xA0\x03\x02\x01\x02\x02\x01\x01' b'\x30\x0D\x06\x09\x2A\x86\x48\x86\xF7\x0D\x01\x01\x05\x05\x00\x30' b'\x3B\x31\x0B\x30\x09\x06\x03\x55\x04\x06\x13\x02\x55\x53\x31\x0D' b'\x30\x0B\x06\x03\x55\x04\x0A\x13\x04\x54\x45\x53\x54\x31\x0E\x30' b'\x0C\x06\x03\x55\x04\x0B\x13\x05\x4F\x41\x53\x49\x53\x31\x0D\x30' b'\x0B\x06\x03\x55\x04\x03\x13\x04\x4B\x4D\x49\x50\x30\x1E\x17\x0D' b'\x31\x30\x31\x31\x30\x31\x32\x33\x35\x39\x35\x39\x5A\x17\x0D\x32' b'\x30\x31\x31\x30\x31\x32\x33\x35\x39\x35\x39\x5A\x30\x3B\x31\x0B' b'\x30\x09\x06\x03\x55\x04\x06\x13\x02\x55\x53\x31\x0D\x30\x0B\x06' b'\x03\x55\x04\x0A\x13\x04\x54\x45\x53\x54\x31\x0E\x30\x0C\x06\x03' b'\x55\x04\x0B\x13\x05\x4F\x41\x53\x49\x53\x31\x0D\x30\x0B\x06\x03' b'\x55\x04\x03\x13\x04\x4B\x4D\x49\x50\x30\x82\x01\x22\x30\x0D\x06' b'\x09\x2A\x86\x48\x86\xF7\x0D\x01\x01\x01\x05\x00\x03\x82\x01\x0F' b'\x00\x30\x82\x01\x0A\x02\x82\x01\x01\x00\xAB\x7F\x16\x1C\x00\x42' b'\x49\x6C\xCD\x6C\x6D\x4D\xAD\xB9\x19\x97\x34\x35\x35\x77\x76\x00' b'\x3A\xCF\x54\xB7\xAF\x1E\x44\x0A\xFB\x80\xB6\x4A\x87\x55\xF8\x00' b'\x2C\xFE\xBA\x6B\x18\x45\x40\xA2\xD6\x60\x86\xD7\x46\x48\x34\x6D' b'\x75\xB8\xD7\x18\x12\xB2\x05\x38\x7C\x0F\x65\x83\xBC\x4D\x7D\xC7' b'\xEC\x11\x4F\x3B\x17\x6B\x79\x57\xC4\x22\xE7\xD0\x3F\xC6\x26\x7F' b'\xA2\xA6\xF8\x9B\x9B\xEE\x9E\x60\xA1\xD7\xC2\xD8\x33\xE5\xA5\xF4' b'\xBB\x0B\x14\x34\xF4\xE7\x95\xA4\x11\x00\xF8\xAA\x21\x49\x00\xDF' b'\x8B\x65\x08\x9F\x98\x13\x5B\x1C\x67\xB7\x01\x67\x5A\xBD\xBC\x7D' b'\x57\x21\xAA\xC9\xD1\x4A\x7F\x08\x1F\xCE\xC8\x0B\x64\xE8\xA0\xEC' b'\xC8\x29\x53\x53\xC7\x95\x32\x8A\xBF\x70\xE1\xB4\x2E\x7B\xB8\xB7' b'\xF4\xE8\xAC\x8C\x81\x0C\xDB\x66\xE3\xD2\x11\x26\xEB\xA8\xDA\x7D' b'\x0C\xA3\x41\x42\xCB\x76\xF9\x1F\x01\x3D\xA8\x09\xE9\xC1\xB7\xAE' b'\x64\xC5\x41\x30\xFB\xC2\x1D\x80\xE9\xC2\xCB\x06\xC5\xC8\xD7\xCC' b'\xE8\x94\x6A\x9A\xC9\x9B\x1C\x28\x15\xC3\x61\x2A\x29\xA8\x2D\x73' b'\xA1\xF9\x93\x74\xFE\x30\xE5\x49\x51\x66\x2A\x6E\xDA\x29\xC6\xFC' b'\x41\x13\x35\xD5\xDC\x74\x26\xB0\xF6\x05\x02\x03\x01\x00\x01\xA3' b'\x21\x30\x1F\x30\x1D\x06\x03\x55\x1D\x0E\x04\x16\x04\x14\x04\xE5' b'\x7B\xD2\xC4\x31\xB2\xE8\x16\xE1\x80\xA1\x98\x23\xFA\xC8\x58\x27' b'\x3F\x6B\x30\x0D\x06\x09\x2A\x86\x48\x86\xF7\x0D\x01\x01\x05\x05' b'\x00\x03\x82\x01\x01\x00\xA8\x76\xAD\xBC\x6C\x8E\x0F\xF0\x17\x21' b'\x6E\x19\x5F\xEA\x76\xBF\xF6\x1A\x56\x7C\x9A\x13\xDC\x50\xD1\x3F' b'\xEC\x12\xA4\x27\x3C\x44\x15\x47\xCF\xAB\xCB\x5D\x61\xD9\x91\xE9' b'\x66\x31\x9D\xF7\x2C\x0D\x41\xBA\x82\x6A\x45\x11\x2F\xF2\x60\x89' b'\xA2\x34\x4F\x4D\x71\xCF\x7C\x92\x1B\x4B\xDF\xAE\xF1\x60\x0D\x1B' b'\xAA\xA1\x53\x36\x05\x7E\x01\x4B\x8B\x49\x6D\x4F\xAE\x9E\x8A\x6C' b'\x1D\xA9\xAE\xB6\xCB\xC9\x60\xCB\xF2\xFA\xE7\x7F\x58\x7E\xC4\xBB' b'\x28\x20\x45\x33\x88\x45\xB8\x8D\xD9\xAE\xEA\x53\xE4\x82\xA3\x6E' b'\x73\x4E\x4F\x5F\x03\xB9\xD0\xDF\xC4\xCA\xFC\x6B\xB3\x4E\xA9\x05' b'\x3E\x52\xBD\x60\x9E\xE0\x1E\x86\xD9\xB0\x9F\xB5\x11\x20\xC1\x98' b'\x34\xA9\x97\xB0\x9C\xE0\x8D\x79\xE8\x13\x11\x76\x2F\x97\x4B\xB1' b'\xC8\xC0\x91\x86\xC4\xD7\x89\x33\xE0\xDB\x38\xE9\x05\x08\x48\x77' b'\xE1\x47\xC7\x8A\xF5\x2F\xAE\x07\x19\x2F\xF1\x66\xD1\x9F\xA9\x4A' b'\x11\xCC\x11\xB2\x7E\xD0\x50\xF7\xA2\x7F\xAE\x13\xB2\x05\xA5\x74' b'\xC4\xEE\x00\xAA\x8B\xD6\x5D\x0D\x70\x57\xC9\x85\xC8\x39\xEF\x33' b'\x6A\x44\x1E\xD5\x3A\x53\xC6\xB6\xB6\x96\xF1\xBD\xEB\x5F\x7E\xA8' b'\x11\xEB\xB2\x5A\x7F\x86') cert_obj = Certificate(cert_format_type, cert_data) cert_result = self.client.register(cert_obj_type, cert_template_attribute, cert_obj, credential=None) self._check_result_status(cert_result, ResultStatus, ResultStatus.SUCCESS) self._check_uuid(cert_result.uuid.value, str) # Check that the returned key bytes match what was provided cert_uuid = cert_result.uuid.value cert_result = self.client.get(uuid=cert_uuid, credential=None) self._check_result_status(cert_result, ResultStatus, ResultStatus.SUCCESS) self._check_object_type(cert_result.object_type.enum, ObjectType, ObjectType.CERTIFICATE) self._check_uuid(cert_result.uuid.value, str) # Check the secret type cert_secret = cert_result.secret cert_secret_expected = Certificate self.assertIsInstance(cert_secret, cert_secret_expected) cert_material = cert_result.secret.certificate_value.value expected = cert_data self.assertEqual(expected, cert_material) self.logger.debug('Destroying cert: ' + cert_name + '\nWith " "UUID: ' + cert_result.uuid.value) cert_result = self.client.destroy(cert_result.uuid.value) self._check_result_status(cert_result, ResultStatus, ResultStatus.SUCCESS) self._check_uuid(cert_result.uuid.value, str) # Verify the secret was destroyed cert_result_destroyed_result = self.client.get(uuid=cert_uuid, credential=None) self._check_result_status(cert_result_destroyed_result, ResultStatus, ResultStatus.OPERATION_FAILED) expected = ResultReason cert_observed = type(cert_result_destroyed_result.result_reason.enum) self.assertEqual(expected, cert_observed) 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.enum, 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.enum) self.assertEqual(expected, pass_observed) def test_opaque_data_register_get_destroy(self): """ Tests that opaque objects can be properly registered, retrieved, and destroyed """ opaque_obj_type = ObjectType.OPAQUE_DATA opaque_obj_data_type = OpaqueObject.OpaqueDataType(OpaqueDataType.NONE) name = Attribute.AttributeName('Name') opaque_obj_name = 'Integration Test - Register-Get-Destroy Opaque Data' opaque_obj_name_value = Name.NameValue(opaque_obj_name) name_type = Name.NameType(NameType.UNINTERPRETED_TEXT_STRING) opaque_obj_value = Name(name_value=opaque_obj_name_value, name_type=name_type) opaque_obj_name_attr = Attribute(attribute_name=name, attribute_value=opaque_obj_value) opaque_obj_attributes = [opaque_obj_name_attr] opaque_obj_template_attribute = TemplateAttribute( attributes=opaque_obj_attributes) opaque_obj_data = OpaqueObject.OpaqueDataValue(( b'\x30\x82\x03\x12\x30\x82\x01\xFA\xA0\x03\x02\x01\x02\x02\x01\x01' b'\x30\x0D\x06\x09\x2A\x86\x48\x86\xF7\x0D\x01\x01\x05\x05\x00\x30' b'\x3B\x31\x0B\x30\x09\x06\x03\x55\x04\x06\x13\x02\x55\x53\x31\x0D' b'\x30\x0B\x06\x03\x55\x04\x0A\x13\x04\x54\x45\x53\x54\x31\x0E\x30' )) opaque_obj = OpaqueObject(opaque_data_type=opaque_obj_data_type, opaque_data_value=opaque_obj_data) opaque_obj_result = self.client.register(opaque_obj_type, opaque_obj_template_attribute, opaque_obj, credential=None) self._check_result_status(opaque_obj_result, ResultStatus, ResultStatus.SUCCESS) self._check_uuid(opaque_obj_result.uuid.value, str) # Check that the returned key bytes match what was provided opaque_obj_uuid = opaque_obj_result.uuid.value opaque_obj_result = self.client.get(uuid=opaque_obj_uuid, credential=None) self._check_result_status(opaque_obj_result, ResultStatus, ResultStatus.SUCCESS) self._check_object_type(opaque_obj_result.object_type.enum, ObjectType, ObjectType.OPAQUE_DATA) self._check_uuid(opaque_obj_result.uuid.value, str) # Check the secret type opaque_obj_secret = opaque_obj_result.secret opaque_obj_secret_expected = OpaqueObject self.assertIsInstance(opaque_obj_secret, opaque_obj_secret_expected) opaque_obj_material = opaque_obj_result.secret.opaque_data_value.value expected = opaque_obj_data.value self.assertEqual(expected, opaque_obj_material) self.logger.debug('Destroying opaque object: ' + opaque_obj_name + '\nWith " "UUID: ' + opaque_obj_result.uuid.value) opaque_obj_result = self.client.destroy(opaque_obj_result.uuid.value) self._check_result_status(opaque_obj_result, ResultStatus, ResultStatus.SUCCESS) self._check_uuid(opaque_obj_result.uuid.value, str) # Verify the secret was destroyed opaque_obj_result_destroyed_result = self.client.get( uuid=opaque_obj_uuid, credential=None) self._check_result_status(opaque_obj_result_destroyed_result, ResultStatus, ResultStatus.OPERATION_FAILED) expected = ResultReason opaque_obj_observed = \ type(opaque_obj_result_destroyed_result.result_reason.enum) self.assertEqual(expected, opaque_obj_observed)
class TestKMIPClient(TestCase): def setUp(self): super(TestKMIPClient, self).setUp() self.attr_factory = AttributeFactory() self.cred_factory = CredentialFactory() self.secret_factory = SecretFactory() self.client = KMIPProxy() KMIP_PORT = 9090 CA_CERTS_PATH = os.path.normpath(os.path.join(os.path.dirname( os.path.abspath(__file__)), '../utils/certs/server.crt')) self.mock_client = KMIPProxy(host="IP_ADDR_1, IP_ADDR_2", port=KMIP_PORT, ca_certs=CA_CERTS_PATH) self.mock_client.socket = mock.MagicMock() self.mock_client.socket.connect = mock.MagicMock() self.mock_client.socket.close = mock.MagicMock() def tearDown(self): super(TestKMIPClient, self).tearDown() def test_close(self): """ Test that calling close on the client works as expected. """ c = KMIPProxy( host="IP_ADDR_1, IP_ADDR_2", port=9090, ca_certs=None ) c.socket = mock.MagicMock() c_socket = c.socket c.socket.shutdown.assert_not_called() c.socket.close.assert_not_called() c.close() self.assertEqual(None, c.socket) c_socket.shutdown.assert_called_once_with(socket.SHUT_RDWR) c_socket.close.assert_called_once() def test_close_with_shutdown_error(self): """ Test that calling close on an unconnected client does not trigger an exception. """ c = KMIPProxy( host="IP_ADDR_1, IP_ADDR_2", port=9090, ca_certs=None ) c.socket = mock.MagicMock() c_socket = c.socket c.socket.shutdown.side_effect = OSError c.socket.shutdown.assert_not_called() c.socket.close.assert_not_called() c.close() self.assertEqual(None, c.socket) c_socket.shutdown.assert_called_once_with(socket.SHUT_RDWR) c_socket.close.assert_not_called() # TODO (peter-hamilton) Modify for credential type and/or add new test def test_build_credential(self): username = '******' password = '******' cred_type = CredentialType.USERNAME_AND_PASSWORD self.client.username = username self.client.password = password credential = self.client._build_credential() message = utils.build_er_error(credential.__class__, 'type', cred_type, credential.credential_type.value, 'value') self.assertEqual(CredentialType.USERNAME_AND_PASSWORD, credential.credential_type.value, message) message = utils.build_er_error( credential.__class__, 'type', username, credential.credential_value.username.value, 'value') self.assertEqual(username, credential.credential_value.username.value, message) message = utils.build_er_error( credential.__class__, 'type', password, credential.credential_value.password.value, 'value') self.assertEqual(password, credential.credential_value.password.value, message) def test_build_credential_no_username(self): username = None password = '******' self.client.username = username self.client.password = password exception = self.assertRaises(ValueError, self.client._build_credential) self.assertEqual('cannot build credential, username is None', str(exception)) def test_build_credential_no_password(self): username = '******' password = None self.client.username = username self.client.password = password exception = self.assertRaises(ValueError, self.client._build_credential) self.assertEqual('cannot build credential, password is None', str(exception)) def test_build_credential_no_creds(self): self.client.username = None self.client.password = None credential = self.client._build_credential() self.assertEqual(None, credential) def _test_build_create_key_pair_batch_item(self, common, private, public): batch_item = self.client._build_create_key_pair_batch_item( common_template_attribute=common, private_key_template_attribute=private, public_key_template_attribute=public) base = "expected {0}, received {1}" msg = base.format(RequestBatchItem, batch_item) self.assertIsInstance(batch_item, RequestBatchItem, msg) operation = batch_item.operation msg = base.format(Operation, operation) self.assertIsInstance(operation, Operation, msg) operation_enum = operation.value msg = base.format(OperationEnum.CREATE_KEY_PAIR, operation_enum) self.assertEqual(OperationEnum.CREATE_KEY_PAIR, operation_enum, msg) payload = batch_item.request_payload msg = base.format(payloads.CreateKeyPairRequestPayload, payload) self.assertIsInstance( payload, payloads.CreateKeyPairRequestPayload, msg ) common_observed = payload.common_template_attribute private_observed = payload.private_key_template_attribute public_observed = payload.public_key_template_attribute msg = base.format(common, common_observed) self.assertEqual(common, common_observed, msg) msg = base.format(private, private_observed) self.assertEqual(private, private_observed, msg) msg = base.format(public, public_observed) self.assertEqual(public, public_observed) def test_build_create_key_pair_batch_item_with_input(self): self._test_build_create_key_pair_batch_item( CommonTemplateAttribute(), PrivateKeyTemplateAttribute(), PublicKeyTemplateAttribute()) def test_build_create_key_pair_batch_item_no_input(self): self._test_build_create_key_pair_batch_item(None, None, None) def _test_build_rekey_key_pair_batch_item(self, uuid, offset, common, private, public): batch_item = self.client._build_rekey_key_pair_batch_item( private_key_uuid=uuid, offset=offset, common_template_attribute=common, private_key_template_attribute=private, public_key_template_attribute=public) base = "expected {0}, received {1}" msg = base.format(RequestBatchItem, batch_item) self.assertIsInstance(batch_item, RequestBatchItem, msg) operation = batch_item.operation msg = base.format(Operation, operation) self.assertIsInstance(operation, Operation, msg) operation_enum = operation.value msg = base.format(OperationEnum.REKEY_KEY_PAIR, operation_enum) self.assertEqual(OperationEnum.REKEY_KEY_PAIR, operation_enum, msg) payload = batch_item.request_payload msg = base.format(payloads.RekeyKeyPairRequestPayload, payload) self.assertIsInstance( payload, payloads.RekeyKeyPairRequestPayload, msg ) private_key_uuid_observed = payload.private_key_uuid offset_observed = payload.offset common_observed = payload.common_template_attribute private_observed = payload.private_key_template_attribute public_observed = payload.public_key_template_attribute msg = base.format(uuid, private_key_uuid_observed) self.assertEqual(uuid, private_key_uuid_observed, msg) msg = base.format(offset, offset_observed) self.assertEqual(offset, offset_observed, msg) msg = base.format(common, common_observed) self.assertEqual(common, common_observed, msg) msg = base.format(private, private_observed) self.assertEqual(private, private_observed, msg) msg = base.format(public, public_observed) self.assertEqual(public, public_observed) def test_build_rekey_key_pair_batch_item_with_input(self): self._test_build_rekey_key_pair_batch_item( PrivateKeyUniqueIdentifier(), Offset(), CommonTemplateAttribute(), PrivateKeyTemplateAttribute(), PublicKeyTemplateAttribute()) def test_build_rekey_key_pair_batch_item_no_input(self): self._test_build_rekey_key_pair_batch_item( None, None, None, None, None) def _test_build_query_batch_item(self, query_functions): batch_item = self.client._build_query_batch_item(query_functions) base = "expected {0}, received {1}" msg = base.format(RequestBatchItem, batch_item) self.assertIsInstance(batch_item, RequestBatchItem, msg) operation = batch_item.operation msg = base.format(Operation, operation) self.assertIsInstance(operation, Operation, msg) operation_enum = operation.value msg = base.format(OperationEnum.QUERY, operation_enum) self.assertEqual(OperationEnum.QUERY, operation_enum, msg) payload = batch_item.request_payload if query_functions is None: query_functions = list() msg = base.format(payloads.QueryRequestPayload, payload) self.assertIsInstance(payload, payloads.QueryRequestPayload, msg) query_functions_observed = payload.query_functions self.assertEqual(query_functions, query_functions_observed) def test_build_query_batch_item_with_input(self): self._test_build_query_batch_item( [QueryFunction(QueryFunctionEnum.QUERY_OBJECTS)]) def test_build_query_batch_item_without_input(self): self._test_build_query_batch_item(None) def _test_build_discover_versions_batch_item(self, protocol_versions): batch_item = self.client._build_discover_versions_batch_item( protocol_versions) base = "expected {0}, received {1}" msg = base.format(RequestBatchItem, batch_item) self.assertIsInstance(batch_item, RequestBatchItem, msg) operation = batch_item.operation msg = base.format(Operation, operation) self.assertIsInstance(operation, Operation, msg) operation_enum = operation.value msg = base.format(OperationEnum.DISCOVER_VERSIONS, operation_enum) self.assertEqual(OperationEnum.DISCOVER_VERSIONS, operation_enum, msg) payload = batch_item.request_payload if protocol_versions is None: protocol_versions = list() msg = base.format(payloads.DiscoverVersionsRequestPayload, payload) self.assertIsInstance( payload, payloads.DiscoverVersionsRequestPayload, msg ) observed = payload.protocol_versions msg = base.format(protocol_versions, observed) self.assertEqual(protocol_versions, observed, msg) def test_build_discover_versions_batch_item_with_input(self): protocol_versions = [ProtocolVersion.create(1, 0)] self._test_build_discover_versions_batch_item(protocol_versions) def test_build_discover_versions_batch_item_no_input(self): protocol_versions = None self._test_build_discover_versions_batch_item(protocol_versions) def test_build_get_attributes_batch_item(self): uuid = '00000000-1111-2222-3333-444444444444' attribute_names = [ 'Name', 'Object Type' ] batch_item = self.client._build_get_attributes_batch_item( uuid, attribute_names ) self.assertIsInstance(batch_item, RequestBatchItem) self.assertIsInstance(batch_item.operation, Operation) self.assertEqual( OperationEnum.GET_ATTRIBUTES, batch_item.operation.value ) self.assertIsInstance( batch_item.request_payload, payloads.GetAttributesRequestPayload ) self.assertEqual(uuid, batch_item.request_payload.unique_identifier) self.assertEqual( attribute_names, batch_item.request_payload.attribute_names ) def test_build_get_attribute_list_batch_item(self): uid = '00000000-1111-2222-3333-444444444444' batch_item = self.client._build_get_attribute_list_batch_item(uid) self.assertIsInstance(batch_item, RequestBatchItem) self.assertIsInstance(batch_item.operation, Operation) self.assertEqual( OperationEnum.GET_ATTRIBUTE_LIST, batch_item.operation.value) self.assertIsInstance( batch_item.request_payload, payloads.GetAttributeListRequestPayload) self.assertEqual(uid, batch_item.request_payload.unique_identifier) def test_process_batch_items(self): batch_item = ResponseBatchItem( operation=Operation(OperationEnum.CREATE_KEY_PAIR), response_payload=payloads.CreateKeyPairResponsePayload()) response = ResponseMessage(batch_items=[batch_item, batch_item]) results = self.client._process_batch_items(response) base = "expected {0}, received {1}" msg = base.format(list, results) self.assertIsInstance(results, list, msg) msg = "number of results " + base.format(2, len(results)) self.assertEqual(2, len(results), msg) for result in results: msg = base.format(CreateKeyPairResult, result) self.assertIsInstance(result, CreateKeyPairResult, msg) def test_process_batch_items_no_batch_items(self): response = ResponseMessage(batch_items=[]) results = self.client._process_batch_items(response) base = "expected {0}, received {1}" msg = base.format(list, results) self.assertIsInstance(results, list, msg) msg = "number of results " + base.format(0, len(results)) self.assertEqual(0, len(results), msg) def test_process_batch_item_with_error(self): result_status = ResultStatus(ResultStatusEnum.OPERATION_FAILED) result_reason = ResultReason(ResultReasonEnum.INVALID_MESSAGE) result_message = ResultMessage("message") batch_item = ResponseBatchItem( result_status=result_status, result_reason=result_reason, result_message=result_message) response = ResponseMessage(batch_items=[batch_item]) results = self.client._process_batch_items(response) base = "expected {0}, received {1}" msg = "number of results " + base.format(1, len(results)) self.assertEqual(1, len(results), msg) result = results[0] self.assertIsInstance(result, OperationResult) self.assertEqual(result.result_status, result_status) self.assertEqual(result.result_reason, result_reason) self.assertEqual(result.result_message.value, "message") def test_get_batch_item_processor(self): base = "expected {0}, received {1}" expected = self.client._process_create_key_pair_batch_item observed = self.client._get_batch_item_processor( OperationEnum.CREATE_KEY_PAIR) msg = base.format(expected, observed) self.assertEqual(expected, observed, msg) expected = self.client._process_rekey_key_pair_batch_item observed = self.client._get_batch_item_processor( OperationEnum.REKEY_KEY_PAIR) msg = base.format(expected, observed) self.assertEqual(expected, observed, msg) self.assertRaisesRegexp(ValueError, "no processor for operation", self.client._get_batch_item_processor, 0xA5A5A5A5) expected = self.client._process_get_attributes_batch_item observed = self.client._get_batch_item_processor( OperationEnum.GET_ATTRIBUTES ) self.assertEqual(expected, observed) expected = self.client._process_get_attribute_list_batch_item observed = self.client._get_batch_item_processor( OperationEnum.GET_ATTRIBUTE_LIST) self.assertEqual(expected, observed) def _test_equality(self, expected, observed): msg = "expected {0}, observed {1}".format(expected, observed) self.assertEqual(expected, observed, msg) def test_process_create_key_pair_batch_item(self): batch_item = ResponseBatchItem( operation=Operation(OperationEnum.CREATE_KEY_PAIR), response_payload=payloads.CreateKeyPairResponsePayload()) result = self.client._process_create_key_pair_batch_item(batch_item) msg = "expected {0}, received {1}".format(CreateKeyPairResult, result) self.assertIsInstance(result, CreateKeyPairResult, msg) def test_process_rekey_key_pair_batch_item(self): batch_item = ResponseBatchItem( operation=Operation(OperationEnum.REKEY_KEY_PAIR), response_payload=payloads.RekeyKeyPairResponsePayload()) result = self.client._process_rekey_key_pair_batch_item(batch_item) msg = "expected {0}, received {1}".format(RekeyKeyPairResult, result) self.assertIsInstance(result, RekeyKeyPairResult, msg) def _test_process_query_batch_item( self, operations, object_types, vendor_identification, server_information, application_namespaces, extension_information): payload = payloads.QueryResponsePayload( operations, object_types, vendor_identification, server_information, application_namespaces, extension_information) batch_item = ResponseBatchItem( operation=Operation(OperationEnum.QUERY), response_payload=payload) result = self.client._process_query_batch_item(batch_item) base = "expected {0}, observed {1}" msg = base.format(QueryResult, result) self.assertIsInstance(result, QueryResult, msg) # The payload maps the following inputs to empty lists on None. if operations is None: operations = list() if object_types is None: object_types = list() if application_namespaces is None: application_namespaces = list() if extension_information is None: extension_information = list() self._test_equality(operations, result.operations) self._test_equality(object_types, result.object_types) self._test_equality( vendor_identification, result.vendor_identification) self._test_equality(server_information, result.server_information) self._test_equality( application_namespaces, result.application_namespaces) self._test_equality( extension_information, result.extension_information) def test_process_query_batch_item_with_results(self): self._test_process_query_batch_item( list(), list(), VendorIdentification(), ServerInformation(), list(), list()) def test_process_query_batch_item_without_results(self): self._test_process_query_batch_item(None, None, None, None, None, None) def _test_process_discover_versions_batch_item(self, protocol_versions): batch_item = ResponseBatchItem( operation=Operation(OperationEnum.DISCOVER_VERSIONS), response_payload=payloads.DiscoverVersionsResponsePayload( protocol_versions)) result = self.client._process_discover_versions_batch_item(batch_item) base = "expected {0}, received {1}" msg = base.format(DiscoverVersionsResult, result) self.assertIsInstance(result, DiscoverVersionsResult, msg) # The payload maps protocol_versions to an empty list on None if protocol_versions is None: protocol_versions = list() msg = base.format(protocol_versions, result.protocol_versions) self.assertEqual(protocol_versions, result.protocol_versions, msg) def test_process_discover_versions_batch_item_with_results(self): protocol_versions = [ProtocolVersion.create(1, 0)] self._test_process_discover_versions_batch_item(protocol_versions) def test_process_discover_versions_batch_item_no_results(self): protocol_versions = None self._test_process_discover_versions_batch_item(protocol_versions) def test_process_get_attributes_batch_item(self): uuid = '00000000-1111-2222-3333-444444444444' attributes = [] payload = payloads.GetAttributesResponsePayload( unique_identifier=uuid, attributes=attributes ) batch_item = ResponseBatchItem( operation=Operation(OperationEnum.GET_ATTRIBUTES), response_payload=payload ) result = self.client._process_get_attributes_batch_item(batch_item) self.assertIsInstance(result, GetAttributesResult) self.assertEqual(uuid, result.uuid) self.assertEqual(attributes, result.attributes) def test_process_get_attribute_list_batch_item(self): uid = '00000000-1111-2222-3333-444444444444' names = ['Cryptographic Algorithm', 'Cryptographic Length'] payload = payloads.GetAttributeListResponsePayload( unique_identifier=uid, attribute_names=names) batch_item = ResponseBatchItem( operation=Operation(OperationEnum.GET_ATTRIBUTE_LIST), response_payload=payload) result = self.client._process_get_attribute_list_batch_item(batch_item) self.assertIsInstance(result, GetAttributeListResult) self.assertEqual(uid, result.uid) self.assertEqual(names, result.names) def test_host_list_import_string(self): """ This test verifies that the client can process a string with multiple IP addresses specified in it. It also tests that unnecessary spaces are ignored. """ host_list_string = '127.0.0.1,127.0.0.3, 127.0.0.5' host_list_expected = ['127.0.0.1', '127.0.0.3', '127.0.0.5'] self.client._set_variables(host=host_list_string, port=None, keyfile=None, certfile=None, cert_reqs=None, ssl_version=None, ca_certs=None, do_handshake_on_connect=False, suppress_ragged_eofs=None, username=None, password=None, timeout=None) self.assertEqual(host_list_expected, self.client.host_list) def test_host_is_invalid_input(self): """ This test verifies that invalid values are not processed when setting the client object parameters """ host = 1337 expected_error = TypeError kwargs = {'host': host, 'port': None, 'keyfile': None, 'certfile': None, 'cert_reqs': None, 'ssl_version': None, 'ca_certs': None, 'do_handshake_on_connect': False, 'suppress_ragged_eofs': None, 'username': None, 'password': None, 'timeout': None} self.assertRaises(expected_error, self.client._set_variables, **kwargs) @mock.patch.object(KMIPProxy, '_create_socket') def test_open_server_conn_failover_fail(self, mock_create_socket): """ This test verifies that the KMIP client throws an exception if no servers are available for connection """ mock_create_socket.return_value = mock.MagicMock() # Assumes both IP addresses fail connection attempts self.mock_client.socket.connect.side_effect = [Exception, Exception] self.assertRaises(Exception, self.mock_client.open) @mock.patch.object(KMIPProxy, '_create_socket') def test_open_server_conn_failover_succeed(self, mock_create_socket): """ This test verifies that the KMIP client can setup a connection if at least one connection is established """ mock_create_socket.return_value = mock.MagicMock() # Assumes IP_ADDR_1 is a bad address and IP_ADDR_2 is a good address self.mock_client.socket.connect.side_effect = [Exception, None] self.mock_client.open() self.assertEqual('IP_ADDR_2', self.mock_client.host) def test_socket_ssl_wrap(self): """ This test tests that the KMIP socket is successfully wrapped into an ssl socket """ sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) self.client._create_socket(sock) self.assertEqual(ssl.SSLSocket, type(self.client.socket)) @mock.patch( 'kmip.services.kmip_client.KMIPProxy._build_request_message' ) @mock.patch( 'kmip.services.kmip_client.KMIPProxy._send_and_receive_message' ) def test_derive_key(self, send_mock, build_mock): """ Test that the client can derive a key. """ payload = payloads.DeriveKeyResponsePayload( unique_identifier='1', ) batch_item = ResponseBatchItem( operation=Operation(OperationEnum.DERIVE_KEY), result_status=ResultStatus(ResultStatusEnum.SUCCESS), response_payload=payload ) response = ResponseMessage(batch_items=[batch_item]) build_mock.return_value = None send_mock.return_value = response result = self.client.derive_key( object_type=enums.ObjectType.SYMMETRIC_KEY, unique_identifiers=['2', '3'], derivation_method=enums.DerivationMethod.ENCRYPT, derivation_parameters=DerivationParameters( cryptographic_parameters=CryptographicParameters( block_cipher_mode=enums.BlockCipherMode.CBC, padding_method=enums.PaddingMethod.PKCS1v15, cryptographic_algorithm=enums.CryptographicAlgorithm.AES ), initialization_vector=b'\x01\x02\x03\x04', derivation_data=b'\xF1\xF2\xF3\xF4\xF5\xF6\xF7\xF8' ), template_attribute=TemplateAttribute( attributes=[ self.attr_factory.create_attribute( 'Cryptographic Length', 128 ), self.attr_factory.create_attribute( 'Cryptographic Algorithm', enums.CryptographicAlgorithm.AES ) ] ), ) self.assertEqual('1', result.get('unique_identifier')) self.assertEqual( ResultStatusEnum.SUCCESS, result.get('result_status') ) self.assertEqual(None, result.get('result_reason')) self.assertEqual(None, result.get('result_message')) @mock.patch( 'kmip.services.kmip_client.KMIPProxy._build_request_message' ) @mock.patch( 'kmip.services.kmip_client.KMIPProxy._send_and_receive_message' ) def test_encrypt(self, send_mock, build_mock): """ Test that the client can encrypt data. """ payload = payloads.EncryptResponsePayload( unique_identifier='1', data=( 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' ) ) batch_item = ResponseBatchItem( operation=Operation(OperationEnum.ENCRYPT), result_status=ResultStatus(ResultStatusEnum.SUCCESS), response_payload=payload ) response = ResponseMessage(batch_items=[batch_item]) build_mock.return_value = None send_mock.return_value = response result = self.client.encrypt( ( 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' ), unique_identifier='1', cryptographic_parameters=CryptographicParameters( block_cipher_mode=enums.BlockCipherMode.CBC, padding_method=enums.PaddingMethod.PKCS5, cryptographic_algorithm=enums.CryptographicAlgorithm.BLOWFISH ), iv_counter_nonce=b'\xFE\xDC\xBA\x98\x76\x54\x32\x10' ) self.assertEqual('1', result.get('unique_identifier')) 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' ), result.get('data') ) self.assertEqual(None, result.get('iv_counter_nonce')) self.assertEqual( ResultStatusEnum.SUCCESS, result.get('result_status') ) self.assertEqual(None, result.get('result_reason')) self.assertEqual(None, result.get('result_message')) @mock.patch( 'kmip.services.kmip_client.KMIPProxy._build_request_message' ) @mock.patch( 'kmip.services.kmip_client.KMIPProxy._send_and_receive_message' ) def test_decrypt(self, send_mock, build_mock): """ Test that the client can decrypt data. """ payload = payloads.DecryptResponsePayload( unique_identifier='1', 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' ) ) batch_item = ResponseBatchItem( operation=Operation(OperationEnum.DECRYPT), result_status=ResultStatus(ResultStatusEnum.SUCCESS), response_payload=payload ) response = ResponseMessage(batch_items=[batch_item]) build_mock.return_value = None send_mock.return_value = response result = self.client.decrypt( ( 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' ), unique_identifier='1', cryptographic_parameters=CryptographicParameters( block_cipher_mode=enums.BlockCipherMode.CBC, padding_method=enums.PaddingMethod.PKCS5, cryptographic_algorithm=enums.CryptographicAlgorithm.BLOWFISH ), iv_counter_nonce=b'\xFE\xDC\xBA\x98\x76\x54\x32\x10' ) self.assertEqual('1', result.get('unique_identifier')) self.assertEqual( ( 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' ), result.get('data') ) self.assertEqual( ResultStatusEnum.SUCCESS, result.get('result_status') ) self.assertEqual(None, result.get('result_reason')) self.assertEqual(None, result.get('result_message')) @mock.patch( 'kmip.services.kmip_client.KMIPProxy._build_request_message' ) @mock.patch( 'kmip.services.kmip_client.KMIPProxy._send_and_receive_message' ) def test_signature_verify(self, send_mock, build_mock): """ Test that the client can verify a signature. """ payload = payloads.SignatureVerifyResponsePayload( unique_identifier='1', validity_indicator=enums.ValidityIndicator.INVALID ) batch_item = ResponseBatchItem( operation=Operation(OperationEnum.SIGNATURE_VERIFY), result_status=ResultStatus(ResultStatusEnum.SUCCESS), response_payload=payload ) response = ResponseMessage(batch_items=[batch_item]) build_mock.return_value = None send_mock.return_value = response result = self.client.signature_verify( ( 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' ), ( b'\x11\x11\x11\x11\x11\x11\x11\x11' ), unique_identifier='1', cryptographic_parameters=CryptographicParameters( padding_method=enums.PaddingMethod.PKCS1v15, cryptographic_algorithm=enums.CryptographicAlgorithm.RSA, hashing_algorithm=enums.HashingAlgorithm.SHA_224 ) ) self.assertEqual('1', result.get('unique_identifier')) self.assertEqual( enums.ValidityIndicator.INVALID, result.get('validity_indicator') ) self.assertEqual( ResultStatusEnum.SUCCESS, result.get('result_status') ) self.assertEqual(None, result.get('result_reason')) self.assertEqual(None, result.get('result_message')) @mock.patch( 'kmip.services.kmip_client.KMIPProxy._build_request_message' ) @mock.patch( 'kmip.services.kmip_client.KMIPProxy._send_and_receive_message' ) def test_sign(self, send_mock, build_mock): """ Test that the client can sign data """ payload = payloads.SignResponsePayload( unique_identifier='1', signature_data=b'aaaaaaaaaaaaaaaa' ) batch_item = ResponseBatchItem( operation=Operation(OperationEnum.SIGN), result_status=ResultStatus(ResultStatusEnum.SUCCESS), response_payload=payload ) response = ResponseMessage(batch_items=[batch_item]) build_mock.return_value = None send_mock.return_value = response result = self.client.sign( b'\x11\x11\x11\x11\x11\x11\x11\x11', unique_identifier='1', cryptographic_parameters=CryptographicParameters( padding_method=enums.PaddingMethod.PKCS1v15, cryptographic_algorithm=enums.CryptographicAlgorithm.RSA, hashing_algorithm=enums.HashingAlgorithm.SHA_224 ) ) self.assertEqual('1', result.get('unique_identifier')) self.assertEqual( b'aaaaaaaaaaaaaaaa', result.get('signature') ) self.assertEqual( ResultStatusEnum.SUCCESS, result.get('result_status') ) self.assertEqual(None, result.get('result_reason')) self.assertEqual(None, result.get('result_message')) @mock.patch('kmip.services.kmip_client.KMIPProxy._send_message', mock.MagicMock()) @mock.patch('kmip.services.kmip_client.KMIPProxy._receive_message', mock.MagicMock()) def test_mac(self): from kmip.core.utils import BytearrayStream request_expected = ( b'\x42\x00\x78\x01\x00\x00\x00\xa0\x42\x00\x77\x01\x00\x00\x00\x38' b'\x42\x00\x69\x01\x00\x00\x00\x20\x42\x00\x6a\x02\x00\x00\x00\x04' b'\x00\x00\x00\x01\x00\x00\x00\x00\x42\x00\x6b\x02\x00\x00\x00\x04' b'\x00\x00\x00\x02\x00\x00\x00\x00\x42\x00\x0d\x02\x00\x00\x00\x04' b'\x00\x00\x00\x01\x00\x00\x00\x00\x42\x00\x0f\x01\x00\x00\x00\x58' b'\x42\x00\x5c\x05\x00\x00\x00\x04\x00\x00\x00\x23\x00\x00\x00\x00' b'\x42\x00\x79\x01\x00\x00\x00\x40\x42\x00\x94\x07\x00\x00\x00\x01' b'\x31\x00\x00\x00\x00\x00\x00\x00\x42\x00\x2b\x01\x00\x00\x00\x10' b'\x42\x00\x28\x05\x00\x00\x00\x04\x00\x00\x00\x0b\x00\x00\x00\x00' b'\x42\x00\xc2\x08\x00\x00\x00\x10\x00\x01\x02\x03\x04\x05\x06\x07' b'\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f') response = ( b'\x42\x00\x7b\x01\x00\x00\x00\xd8\x42\x00\x7a\x01\x00\x00\x00\x48' b'\x42\x00\x69\x01\x00\x00\x00\x20\x42\x00\x6a\x02\x00\x00\x00\x04' b'\x00\x00\x00\x01\x00\x00\x00\x00\x42\x00\x6b\x02\x00\x00\x00\x04' b'\x00\x00\x00\x02\x00\x00\x00\x00\x42\x00\x92\x09\x00\x00\x00\x08' b'\x00\x00\x00\x00\x58\x8a\x3f\x23\x42\x00\x0d\x02\x00\x00\x00\x04' b'\x00\x00\x00\x01\x00\x00\x00\x00\x42\x00\x0f\x01\x00\x00\x00\x80' b'\x42\x00\x5c\x05\x00\x00\x00\x04\x00\x00\x00\x23\x00\x00\x00\x00' b'\x42\x00\x7f\x05\x00\x00\x00\x04\x00\x00\x00\x00\x00\x00\x00\x00' b'\x42\x00\x7c\x01\x00\x00\x00\x58\x42\x00\x94\x07\x00\x00\x00\x01' b'\x31\x00\x00\x00\x00\x00\x00\x00\x42\x00\xc6\x08\x00\x00\x00\x40' b'\x99\x8b\x55\x59\x90\x9b\x85\x87\x5b\x90\x63\x13\x12\xbb\x32\x9f' b'\x6a\xc4\xed\x97\x6e\xac\x99\xe5\x21\x53\xc4\x19\x28\xf2\x2a\x5b' b'\xef\x79\xa4\xbe\x05\x3b\x31\x49\x19\xe0\x75\x23\xb9\xbe\xc8\x23' b'\x35\x60\x7e\x49\xba\xa9\x7e\xe0\x9e\x6b\x3d\x55\xf4\x51\xff\x7c' ) response_no_payload = ( b'\x42\x00\x7b\x01\x00\x00\x00\x78\x42\x00\x7a\x01\x00\x00\x00\x48' b'\x42\x00\x69\x01\x00\x00\x00\x20\x42\x00\x6a\x02\x00\x00\x00\x04' b'\x00\x00\x00\x01\x00\x00\x00\x00\x42\x00\x6b\x02\x00\x00\x00\x04' b'\x00\x00\x00\x02\x00\x00\x00\x00\x42\x00\x92\x09\x00\x00\x00\x08' b'\x00\x00\x00\x00\x58\x8a\x3f\x23\x42\x00\x0d\x02\x00\x00\x00\x04' b'\x00\x00\x00\x01\x00\x00\x00\x00\x42\x00\x0f\x01\x00\x00\x00\x80' b'\x42\x00\x5c\x05\x00\x00\x00\x04\x00\x00\x00\x23\x00\x00\x00\x00' b'\x42\x00\x7f\x05\x00\x00\x00\x04\x00\x00\x00\x00\x00\x00\x00\x00' ) data = (b'\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0A\x0B' b'\x0C\x0D\x0E\x0F') mdata = (b'\x99\x8b\x55\x59\x90\x9b\x85\x87\x5b\x90\x63\x13' b'\x12\xbb\x32\x9f' b'\x6a\xc4\xed\x97\x6e\xac\x99\xe5\x21\x53\xc4\x19' b'\x28\xf2\x2a\x5b' b'\xef\x79\xa4\xbe\x05\x3b\x31\x49\x19\xe0\x75\x23' b'\xb9\xbe\xc8\x23' b'\x35\x60\x7e\x49\xba\xa9\x7e\xe0\x9e\x6b\x3d\x55' b'\xf4\x51\xff\x7c') def verify_request(message): stream = BytearrayStream() message.write(stream) self.assertEqual(stream.buffer, request_expected) uuid = '1' cryptographic_parameters = CryptographicParameters( cryptographic_algorithm=CryptographicAlgorithmEnum.HMAC_SHA512 ) self.client._send_message.side_effect = verify_request self.client._receive_message.return_value = BytearrayStream(response) result = self.client.mac(data, uuid, cryptographic_parameters) self.assertEqual(result.uuid.value, uuid) self.assertEqual(result.mac_data.value, mdata) self.client._receive_message.return_value = \ BytearrayStream(response_no_payload) result = self.client.mac(data, uuid, cryptographic_parameters) self.assertEqual(result.uuid, None) self.assertEqual(result.mac_data, None)
username = opts.username password = opts.password config = opts.config algorithm = opts.algorithm length = opts.length # Exit early if the arguments are not specified if algorithm is None: logger.error('No algorithm provided, exiting early from demo') sys.exit() if length is None: logger.error("No key length provided, exiting early from demo") sys.exit() 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) # Build the client and connect to the server client = KMIPProxy(config=config, config_file=opts.config_file) client.open()
config = opts.config object_type = opts.type format_type = opts.format # Exit early if the arguments are not specified object_type = getattr(ObjectType, object_type, None) if object_type is None: logger.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: logger.error( "Invalid key format type specified; exiting early from demo") attribute_factory = AttributeFactory() # 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] if opts.operation_policy_name is not None: opn = attribute_factory.create_attribute( enums.AttributeType.OPERATION_POLICY_NAME, opts.operation_policy_name) attributes.append(opn) template_attribute = TemplateAttribute(attributes=attributes) secret = utils.build_object(logger, object_type, key_format_type)
def create_key_pair_proxy(app_name, algorithm, length): kmip_result_dir = {} res_obj = CreateKeyResponse() attribute_factory = AttributeFactory() attribute_type = AttributeType.CRYPTOGRAPHIC_ALGORITHM algorithm_enum = getattr(CryptographicAlgorithm, algorithm, None) if algorithm_enum is None: logger.error("Invalid algorithm specified; exiting early from demo") return res_obj( KmisResponseCodes.FAIL, KmisResponseStatus.FAIL, KmisResponseDescriptions.KEY_CREATION_ERROR) algorithm_obj = attribute_factory.create_attribute(attribute_type, algorithm_enum) key_name = get_key_name(app_name) name_value = Name.NameValue(key_name) name = Attribute.AttributeName('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) name = Attribute.AttributeName('Cryptographic Usage Mask') value = CryptographicUsageMask( CryptographicUsageMask.ENCRYPT.value | CryptographicUsageMask.DECRYPT.value) usage_mask = Attribute(attribute_name=name, attribute_value=value) attribute_type = AttributeType.CRYPTOGRAPHIC_LENGTH length_obj = attribute_factory.create_attribute(attribute_type, length) attributes = [algorithm_obj, length_obj, name, usage_mask] common = CommonTemplateAttribute(attributes=attributes) private = PrivateKeyTemplateAttribute(attributes=attributes) public = PublicKeyTemplateAttribute(attributes=attributes) (client, credential) = get_kmip_client() # Create the SYMMETRIC_KEY object result = client.create_key_pair(common_template_attribute=common, private_key_template_attribute=private, public_key_template_attribute=public) # Display operation results key_out_type = KmisKeyFormatType.PKCS_1 cert_out_type = KmisKeyFormatType.X_509 logger.info('create_key_pair() result status: {0}'.format( result.result_status.enum)) if result.result_status.enum == ResultStatus.SUCCESS: logger.info("KeyPair Creation Successful") logger.info('Created Private key UUID: {0}'.format( result.private_key_uuid)) logger.info('Created public key UUID: {0}'.format( result.public_key_uuid)) if result.private_key_uuid: kmip_result_dir["kmip_private_key_result"] = client.get( uuid=result.private_key_uuid, credential=credential, key_format_type=get_key_format_type(key_out_type)) if result.public_key_uuid: kmip_result_dir["kmip_cert_result"] = client.get( uuid=result.public_key_uuid, credential=credential, key_format_type=get_key_format_type(cert_out_type)) if result.private_key_template_attribute is not None: logger.info('Private Key Template Attribute:') utils.log_template_attribute( logger, result.private_key_template_attribute) if result.public_key_template_attribute is not None: logger.info('Public Key Template Attribute:') utils.log_template_attribute( logger, result.public_key_template_attribute) close_kmip_proxy(client) res_obj.process_kmip_response(kmip_result_dir) return res_obj( KmisResponseCodes.SUCCESS, KmisResponseStatus.SUCCESS, KmisResponseDescriptions.SUCCESS) else: close_kmip_proxy(client) logger.info('key pair creation failed, reason: {0}'.format( result.result_reason.enum)) logger.info('key pair creation failed, result message: {0}'.format( result.result_message.value)) return res_obj( KmisResponseCodes.FAIL, KmisResponseStatus.FAIL, KmisResponseDescriptions.KEY_CREATION_ERROR)
username = opts.username password = opts.password config = opts.config algorithm = opts.algorithm length = opts.length # Exit early if the arguments are not specified if algorithm is None: logger.error('No algorithm provided, exiting early from demo') sys.exit() if length is None: logger.error("No key length provided, exiting early from demo") sys.exit() 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) # Build the client and connect to the server client = KMIPProxy(config=config) client.open()
def _get_alg_attr(self, alg=None): if alg is None: alg = self.algorithm_name attr_factory = AttributeFactory() attribute_type = AttributeType.CRYPTOGRAPHIC_ALGORITHM return attr_factory.create_attribute(attribute_type, alg)
from kmip.core.factories.attributes import AttributeFactory from kmip.core.factories.credentials import CredentialFactory from kmip.core.objects import TemplateAttribute, Attribute from kmip.services.kmip_client import KMIPProxy import logging import os if __name__ == '__main__': f_log = os.path.join(os.path.dirname(__file__), '..', 'logconfig.ini') logging.config.fileConfig(f_log) logger = logging.getLogger(__name__) attribute_factory = AttributeFactory() credential_factory = CredentialFactory() credential_type = CredentialType.USERNAME_AND_PASSWORD credential_value = {'Username': '******', 'Password': '******'} credential = credential_factory.create_credential(credential_type, credential_value) client = KMIPProxy() client.open() object_type = ObjectType.SYMMETRIC_KEY attribute_type = AttributeType.CRYPTOGRAPHIC_ALGORITHM algorithm = attribute_factory.create_attribute(attribute_type, CryptographicAlgorithm.AES) mask_flags = [CryptographicUsageMask.ENCRYPT, CryptographicUsageMask.DECRYPT]
# Exit early if the UUID is not specified if uuid is None: logger.error('No UUID provided, exiting early from demo') sys.exit() format_type_enum = None if format_type is not None: format_type_enum = getattr(KeyFormatTypeEnum, format_type, None) if format_type_enum is None: logger.error( "Invalid key format type specified; exiting early from demo") sys.exit() 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)
sys.exit() attribute_type = AttributeType.CRYPTOGRAPHIC_ALGORITHM algorithm_enum = getattr(CryptographicAlgorithm, algorithm, None) if algorithm_enum is None: logging.error("Invalid algorithm specified; exiting early from demo") sys.exit() # 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() # 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()
parser = utils.build_cli_parser(enums.Operation.LOCATE) opts, args = parser.parse_args(sys.argv[1:]) username = opts.username password = opts.password config = opts.config name = opts.name initial_dates = opts.initial_dates state = opts.state object_type = opts.object_type cryptographic_algorithm = opts.cryptographic_algorithm cryptographic_length = opts.cryptographic_length unique_identifier = opts.unique_identifier operation_policy_name = opts.operation_policy_name 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 = enums.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 = kmip_client.KMIPProxy(config=config, config_file=opts.config_file) client.open()
class KMIPImpl(KMIP): def __init__(self): super(self.__class__, self).__init__() self.logger = logging.getLogger(__name__) self.key_factory = KeyFactory() self.secret_factory = SecretFactory() self.attribute_factory = AttributeFactory() self.repo = MemRepo() def create(self, object_type, template_attribute, credential=None): self.logger.debug('create() called') self.logger.debug('object type = %s' % object_type) bit_length = 256 attributes = template_attribute.attributes ret_attributes = [] if object_type.enum != OT.SYMMETRIC_KEY: self.logger.debug('invalid object type') return self._get_invalid_field_result('invalid object type') try: alg_attr =\ self._validate_req_field(attributes, AT.CRYPTOGRAPHIC_ALGORITHM.value, (CA.AES.value,), 'unsupported algorithm') len_attr = self._validate_req_field(attributes, AT.CRYPTOGRAPHIC_LENGTH.value, (128, 256, 512), 'unsupported key length', False) self._validate_req_field(attributes, AT.CRYPTOGRAPHIC_USAGE_MASK.value, (), '') except InvalidFieldException as e: self.logger.debug('InvalidFieldException raised') return e.result crypto_alg = CryptographicAlgorithm(CA(alg_attr.attribute_value.value)) if len_attr is None: self.logger.debug('cryptographic length not supplied') attribute_type = AT.CRYPTOGRAPHIC_LENGTH length_attribute = self.attribute_factory.\ create_attribute(attribute_type, bit_length) attributes.append(length_attribute) ret_attributes.append(length_attribute) else: bit_length = len_attr.attribute_value.value key = self._gen_symmetric_key(bit_length, crypto_alg) s_uuid, uuid_attribute = self._save(key, attributes) ret_attributes.append(uuid_attribute) template_attribute = TemplateAttribute(attributes=ret_attributes) return CreateResult(ResultStatus(RS.SUCCESS), object_type=object_type, uuid=UniqueIdentifier(s_uuid), template_attribute=template_attribute) def register(self, object_type, template_attribute, secret, credential=None): self.logger.debug('register() called') self.logger.debug('object type = %s' % object_type) attributes = template_attribute.attributes ret_attributes = [] if object_type is None: self.logger.debug('invalid object type') return self._get_missing_field_result('object type') if object_type.enum != OT.SYMMETRIC_KEY: self.logger.debug('invalid object type') return self._get_invalid_field_result('invalid object type') if secret is None or not isinstance(secret, SymmetricKey): msg = 'object type does not match that of secret' self.logger.debug(msg) return self._get_invalid_field_result(msg) self.logger.debug('Collecting all attributes') if attributes is None: attributes = [] attributes.extend(self._get_key_block_attributes(secret.key_block)) self.logger.debug('Verifying all attributes are valid and set') try: self._validate_req_field(attributes, AT.CRYPTOGRAPHIC_ALGORITHM.value, (CA.AES.value,), 'unsupported algorithm') self._validate_req_field(attributes, AT.CRYPTOGRAPHIC_LENGTH.value, (128, 256, 512), 'unsupported key length') self._validate_req_field(attributes, AT.CRYPTOGRAPHIC_USAGE_MASK.value, (), '') except InvalidFieldException as e: self.logger.debug('InvalidFieldException raised') return RegisterResult(e.result.result_status, e.result.result_reason, e.result.result_message) s_uuid, uuid_attribute = self._save(secret, attributes) ret_attributes.append(uuid_attribute) template_attribute = TemplateAttribute(attributes=ret_attributes) return RegisterResult(ResultStatus(RS.SUCCESS), uuid=UniqueIdentifier(s_uuid), template_attribute=template_attribute) 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.enum != 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 destroy(self, uuid): self.logger.debug('destroy() 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 DestroyResult(ResultStatus(ret_value), reason, message) msg = 'deleting object from repo: {0}'.format(uuid) self.logger.debug(msg) if not self.repo.delete(uuid.value): self.logger.debug('repo did not find and delete managed object') reason = ResultReason(ResultReasonEnum.ITEM_NOT_FOUND) message = ResultMessage('') return DestroyResult(ResultStatus(ret_value), reason, message) ret_value = RS.SUCCESS return DestroyResult(ResultStatus(ret_value), uuid=uuid) def locate(self, maximum_items=None, storage_status_mask=None, object_group_member=None, attributes=None, credential=None): self.logger.debug('locate() called') msg = 'locating object(s) from repo' self.logger.debug(msg) try: uuids = self.repo.locate(maximum_items, storage_status_mask, object_group_member, attributes) return LocateResult(ResultStatus(RS.SUCCESS), uuids=uuids) except NotImplementedError: msg = ResultMessage('Locate Operation Not Supported') reason = ResultReason(ResultReasonEnum.OPERATION_NOT_SUPPORTED) return LocateResult(ResultStatus(RS.OPERATION_FAILED), result_reason=reason, result_message=msg) def _validate_req_field(self, attrs, name, expected, msg, required=True): self.logger.debug('Validating attribute %s' % name) seen = False found_attr = None for attr in attrs: if self._validate_field(attr, name, expected, msg): if seen: # TODO check what spec says to do on this msg = 'duplicate attribute: %s' % name self.logger.debug(msg) result = self._get_duplicate_attribute_result(name) raise InvalidFieldException(result) seen = True found_attr = attr if required and not seen: result = self._get_missing_field_result(name) raise InvalidFieldException(result) return found_attr def _validate_field(self, attr, name, expected, msg): if attr.attribute_name.value == name: self.logger.debug('validating attribute %s' % name) if not expected or attr.attribute_value.value in expected: self.logger.debug('attribute validated') return True else: self.logger.debug('attribute not validated') result = self._get_invalid_field_result(msg) raise InvalidFieldException(result) else: return False def _get_invalid_field_result(self, msg): status = ResultStatus(RS.OPERATION_FAILED) reason = ResultReason(ResultReasonEnum.INVALID_FIELD) message = ResultMessage(msg) return OperationResult(status, reason, message) def _get_missing_field_result(self, name): msg = '%s not supplied' % name self.logger.debug(msg) status = ResultStatus(RS.OPERATION_FAILED) reason = ResultReason(ResultReasonEnum.ITEM_NOT_FOUND) message = ResultMessage(msg) return OperationResult(status, reason, message) def _get_duplicate_attribute_result(self, name): msg = '%s supplied multiple times' % name self.logger.debug(msg) status = ResultStatus(RS.OPERATION_FAILED) reason = ResultReason(ResultReasonEnum.INDEX_OUT_OF_BOUNDS) message = ResultMessage(msg) return OperationResult(status, reason, message) def _gen_symmetric_key(self, bit_length, crypto_alg): key_format_type = KeyBlock.KeyFormatType(KeyFormatTypeEnum.RAW) key_material = RawKey(bytearray(os.urandom(int(bit_length/8)))) key_value = KeyValueStruct(key_format_type, 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 _save(self, key, attributes): s_uuid = self.repo.save(key, attributes) self.logger.debug('creating object with uuid = %s' % s_uuid) attribute_type = AT.UNIQUE_IDENTIFIER attribute = self.attribute_factory.create_attribute(attribute_type, s_uuid) attributes.append(attribute) # Calling update to also store the UUID self.repo.update(s_uuid, key, attributes) return s_uuid, attribute def _get_key_block_attributes(self, key_block): self.logger.debug('getting all key attributes from key block') attributes = [] if key_block.cryptographic_algorithm is not None: self.logger.debug('crypto_alg set on key block') self.logger.debug('adding crypto algorithm attribute') at = AT.CRYPTOGRAPHIC_ALGORITHM alg = key_block.cryptographic_algorithm.enum attributes.append(self.attribute_factory.create_attribute(at, alg)) if key_block.cryptographic_length is not None: self.logger.debug('crypto_length set on key block') self.logger.debug('adding crypto length attribute') at = AT.CRYPTOGRAPHIC_LENGTH len = key_block.cryptographic_length.value attributes.append(self.attribute_factory.create_attribute(at, len)) self.logger.debug('getting key value attributes') if key_block.key_wrapping_data is not None: self.logger.debug('no wrapping data so key value is struct') 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) return attributes
def _get_length_attr(self, length=None): if length is None: length = self.key_length attr_factory = AttributeFactory() attribute_type = AttributeType.CRYPTOGRAPHIC_LENGTH return attr_factory.create_attribute(attribute_type, length)
sys.exit() if length is None: logger.error("No key length provided, exiting early from demo") sys.exit() if name is None: logger.error("No key name provided, exiting early from demo") sys.exit() attribute_type = AttributeType.CRYPTOGRAPHIC_ALGORITHM algorithm_enum = getattr(CryptographicAlgorithm, algorithm, None) if algorithm_enum is None: logger.error("Invalid algorithm specified; exiting early from demo") sys.exit() 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) # Build the client and connect to the server client = KMIPProxy(config=config) client.open()
from kmip.core.factories.credentials import CredentialFactory from kmip.core.factories.secrets import SecretFactory from kmip.core.objects import TemplateAttribute from kmip.services.kmip_client import KMIPProxy import logging import os if __name__ == '__main__': f_log = os.path.join(os.path.dirname(__file__), '..', 'logconfig.ini') logging.config.fileConfig(f_log) logger = logging.getLogger(__name__) attribute_factory = AttributeFactory() credential_factory = CredentialFactory() secret_factory = SecretFactory() credential_type = CredentialType.USERNAME_AND_PASSWORD credential_value = {'Username': '******', 'Password': '******'} credential = credential_factory.create_credential(credential_type, credential_value) client = KMIPProxy() client.open() object_type = ObjectType.SYMMETRIC_KEY algorithm_value = CryptographicAlgorithm.AES mask_flags = [CryptographicUsageMask.ENCRYPT, CryptographicUsageMask.DECRYPT]
class TestKMIPClientIntegration(TestCase): STARTUP_TIME = 1.0 SHUTDOWN_TIME = 0.1 KMIP_PORT = 9090 CA_CERTS_PATH = os.path.normpath(os.path.join(os.path.dirname( os.path.abspath(__file__)), '../../demos/certs/server.crt')) def setUp(self): super(TestKMIPClientIntegration, self).setUp() self.attr_factory = AttributeFactory() self.cred_factory = CredentialFactory() self.secret_factory = SecretFactory() # Set up the KMIP server process path = os.path.join(os.path.dirname(__file__), os.path.pardir, 'utils', 'server.py') self.server = Popen(['python', '{0}'.format(path), '-p', '{0}'.format(self.KMIP_PORT)], stderr=sys.stdout) time.sleep(self.STARTUP_TIME) if self.server.poll() is not None: raise KMIPServerSuicideError(self.server.pid) # Set up and open the client proxy; shutdown the server if open fails try: self.client = KMIPProxy(port=self.KMIP_PORT, ca_certs=self.CA_CERTS_PATH) self.client.open() except Exception as e: self._shutdown_server() raise e def tearDown(self): super(TestKMIPClientIntegration, self).tearDown() # Close the client proxy and shutdown the server self.client.close() self._shutdown_server() def test_create(self): result = self._create_symmetric_key() self._check_result_status(result.result_status.enum, ResultStatus, ResultStatus.SUCCESS) self._check_object_type(result.object_type.enum, ObjectType, ObjectType.SYMMETRIC_KEY) self._check_uuid(result.uuid.value, str) # Check the template attribute type self._check_template_attribute(result.template_attribute, TemplateAttribute, 2, [[str, 'Cryptographic Length', int, 256], [str, 'Unique Identifier', str, None]]) def test_get(self): credential_type = CredentialType.USERNAME_AND_PASSWORD credential_value = {'Username': '******', 'Password': '******'} credential = self.cred_factory.create_credential(credential_type, credential_value) result = self._create_symmetric_key() uuid = result.uuid.value result = self.client.get(uuid=uuid, credential=credential) self._check_result_status(result.result_status.enum, ResultStatus, ResultStatus.SUCCESS) self._check_object_type(result.object_type.enum, 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) def test_destroy(self): credential_type = CredentialType.USERNAME_AND_PASSWORD credential_value = {'Username': '******', 'Password': '******'} credential = self.cred_factory.create_credential(credential_type, credential_value) result = self._create_symmetric_key() uuid = result.uuid.value # Verify the secret was created result = self.client.get(uuid=uuid, credential=credential) self._check_result_status(result.result_status.enum, ResultStatus, ResultStatus.SUCCESS) self._check_object_type(result.object_type.enum, ObjectType, ObjectType.SYMMETRIC_KEY) self._check_uuid(result.uuid.value, str) secret = result.secret expected = SymmetricKey message = utils.build_er_error(result.__class__, 'type', expected, secret, 'secret') self.assertIsInstance(secret, expected, message) # Destroy the SYMMETRIC_KEY object result = self.client.destroy(uuid, credential) self._check_result_status(result.result_status.enum, ResultStatus, ResultStatus.SUCCESS) self._check_uuid(result.uuid.value, str) # Verify the secret was destroyed result = self.client.get(uuid=uuid, credential=credential) self._check_result_status(result.result_status.enum, ResultStatus, ResultStatus.OPERATION_FAILED) expected = ResultReason observed = type(result.result_reason.enum) message = utils.build_er_error(result.result_reason.__class__, 'type', expected, observed) self.assertEqual(expected, observed, message) expected = ResultReason.ITEM_NOT_FOUND observed = result.result_reason.enum message = utils.build_er_error(result.result_reason.__class__, 'value', expected, observed) self.assertEqual(expected, observed, message) 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.enum, 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.enum, ResultStatus, ResultStatus.SUCCESS) self._check_object_type(result.object_type.enum, 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 _shutdown_server(self): if self.server.poll() is not None: return else: # Terminate the server process. If it resists, kill it. pid = self.server.pid self.server.terminate() time.sleep(self.SHUTDOWN_TIME) if self.server.poll() is None: raise KMIPServerZombieError(pid) def _create_symmetric_key(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 attribute_type = AttributeType.CRYPTOGRAPHIC_ALGORITHM algorithm = self.attr_factory.create_attribute( attribute_type, 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 = [algorithm, usage_mask] template_attribute = TemplateAttribute(attributes=attributes) return self.client.create(object_type, template_attribute, credential) def _check_result_status(self, result_status, result_status_type, result_status_value): # Error check the result status type and value expected = result_status_type message = utils.build_er_error(result_status_type, 'type', expected, result_status) self.assertIsInstance(result_status, expected, message) expected = result_status_value message = utils.build_er_error(result_status_type, 'value', expected, result_status) self.assertEqual(expected, result_status, message) def _check_uuid(self, uuid, uuid_type): # Error check the UUID type and value not_expected = None message = utils.build_er_error(uuid_type, 'type', 'not {0}'.format(not_expected), uuid) self.assertNotEqual(not_expected, uuid, message) expected = uuid_type message = utils.build_er_error(uuid_type, 'type', expected, uuid) self.assertEqual(expected, type(uuid), message) def _check_object_type(self, object_type, object_type_type, object_type_value): # Error check the object type type and value expected = object_type_type message = utils.build_er_error(object_type_type, 'type', expected, object_type) self.assertIsInstance(object_type, expected, message) expected = object_type_value message = utils.build_er_error(object_type_type, 'value', expected, object_type) self.assertEqual(expected, object_type, message) def _check_template_attribute(self, template_attribute, template_attribute_type, num_attributes, attribute_features): # Error check the template attribute type expected = template_attribute_type message = utils.build_er_error(template_attribute.__class__, 'type', expected, template_attribute) self.assertIsInstance(template_attribute, expected, message) attributes = template_attribute.attributes expected = num_attributes observed = len(attributes) message = utils.build_er_error(TemplateAttribute.__class__, 'number', expected, observed, 'attributes') for i in range(num_attributes): features = attribute_features[i] self._check_attribute(attributes[i], features[0], features[1], features[2], features[3]) def _check_attribute(self, attribute, attribute_name_type, attribute_name_value, attribute_value_type, attribute_value_value): # Error check the attribute name and value type and value attribute_name = attribute.attribute_name attribute_value = attribute.attribute_value self._check_attribute_name(attribute_name, attribute_name_type, attribute_name_value) if attribute_name_value == 'Unique Identifier': self._check_uuid(attribute_value.value, attribute_value_type) else: self._check_attribute_value(attribute_value, attribute_value_type, attribute_value_value) def _check_attribute_name(self, attribute_name, attribute_name_type, attribute_name_value): # Error check the attribute name type and value expected = attribute_name_type observed = type(attribute_name.value) message = utils.build_er_error(attribute_name_type, 'type', expected, observed) self.assertEqual(expected, observed, message) expected = attribute_name_value observed = attribute_name.value message = utils.build_er_error(attribute_name_type, 'value', expected, observed) self.assertEqual(expected, observed, message) def _check_attribute_value(self, attribute_value, attribute_value_type, attribute_value_value): expected = attribute_value_type observed = type(attribute_value.value) message = utils.build_er_error(Attribute, 'type', expected, observed, 'attribute_value') self.assertEqual(expected, observed, message) expected = attribute_value_value observed = attribute_value.value message = utils.build_er_error(Attribute, 'value', expected, observed, 'attribute_value') self.assertEqual(expected, observed, message)
# 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") sys.exit() # 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() # 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()
class TestIntegration(TestCase): def setUp(self): super(TestIntegration, self).setUp() self.logger = logging.getLogger(__name__) self.attr_factory = AttributeFactory() self.cred_factory = CredentialFactory() self.secret_factory = SecretFactory() def tearDown(self): super(TestIntegration, self).tearDown() def _create_symmetric_key(self, key_name=None): """ Helper function for creating symmetric keys. Used any time a key needs to be created. :param key_name: name of the key to be created :return: returns the result of the "create key" operation as provided by the KMIP appliance """ object_type = ObjectType.SYMMETRIC_KEY attribute_type = AttributeType.CRYPTOGRAPHIC_ALGORITHM algorithm = self.attr_factory.create_attribute(attribute_type, 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) key_length = 128 attribute_type = AttributeType.CRYPTOGRAPHIC_LENGTH key_length_obj = self.attr_factory.create_attribute( attribute_type, key_length) name = Attribute.AttributeName('Name') if key_name is None: key_name = 'Integration Test - 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 = [algorithm, usage_mask, key_length_obj, name] template_attribute = TemplateAttribute(attributes=attributes) return self.client.create(object_type, template_attribute, credential=None) def _create_key_pair(self, key_name=None): """ Helper function for creating private and public keys. Used any time a key pair needs to be created. :param key_name: name of the key to be created :return: returns the result of the "create key" operation as provided by the KMIP appliance """ attribute_type = AttributeType.CRYPTOGRAPHIC_ALGORITHM algorithm = self.attr_factory.create_attribute(attribute_type, CryptoAlgorithmEnum.RSA) mask_flags = [ CryptographicUsageMask.ENCRYPT, CryptographicUsageMask.DECRYPT ] attribute_type = AttributeType.CRYPTOGRAPHIC_USAGE_MASK usage_mask = self.attr_factory.create_attribute( attribute_type, mask_flags) key_length = 2048 attribute_type = AttributeType.CRYPTOGRAPHIC_LENGTH key_length_obj = self.attr_factory.create_attribute( attribute_type, key_length) name = Attribute.AttributeName('Name') if key_name is None: key_name = 'Integration Test - Key' priv_name_value = Name.NameValue(key_name + " Private") pub_name_value = Name.NameValue(key_name + " Public") name_type = Name.NameType(NameType.UNINTERPRETED_TEXT_STRING) priv_value = Name(name_value=priv_name_value, name_type=name_type) pub_value = Name(name_value=pub_name_value, name_type=name_type) priv_name = Attribute(attribute_name=name, attribute_value=priv_value) pub_name = Attribute(attribute_name=name, attribute_value=pub_value) common_attributes = [algorithm, usage_mask, key_length_obj] private_key_attributes = [priv_name] public_key_attributes = [pub_name] common = CommonTemplateAttribute(attributes=common_attributes) priv_templ_attr = PrivateKeyTemplateAttribute( attributes=private_key_attributes) pub_templ_attr = PublicKeyTemplateAttribute( attributes=public_key_attributes) return self.client.\ create_key_pair(common_template_attribute=common, private_key_template_attribute=priv_templ_attr, public_key_template_attribute=pub_templ_attr) def _check_result_status(self, result, result_status_type, result_status_value): """ Helper function for checking the status of KMIP appliance actions. Verifies the result status type and value. :param result: result object :param result_status_type: type of result status received :param result_status_value: value of the result status """ result_status = result.result_status.value # Error check the result status type and value expected = result_status_type self.assertIsInstance(result_status, expected) expected = result_status_value if result_status is ResultStatus.OPERATION_FAILED: self.logger.error(result) self.logger.error(result.result_reason) self.logger.error(result.result_message) self.assertEqual(expected, result_status) def _check_uuid(self, uuid, uuid_type): """ Helper function for checking UUID type and value for errors :param uuid: UUID of a created key :param uuid_type: UUID type :return: """ # Error check the UUID type and value not_expected = None self.assertNotEqual(not_expected, uuid) expected = uuid_type self.assertEqual(expected, type(uuid)) def _check_object_type(self, object_type, object_type_type, object_type_value): """ Checks the type and value of a given object type. :param object_type: :param object_type_type: :param object_type_value: """ # Error check the object type type and value expected = object_type_type self.assertIsInstance(object_type, expected) expected = object_type_value self.assertEqual(expected, object_type) def _check_template_attribute(self, template_attribute, template_attribute_type, num_attributes, attribute_features): """ Checks the value and type of a given template attribute :param template_attribute: :param template_attribute_type: :param num_attributes: :param attribute_features: """ # Error check the template attribute type expected = template_attribute_type self.assertIsInstance(template_attribute, expected) attributes = template_attribute.attributes for i in range(num_attributes): features = attribute_features[i] self._check_attribute(attributes[i], features[0], features[1], features[2], features[3]) def _check_attribute(self, attribute, attribute_name_type, attribute_name_value, attribute_value_type, attribute_value_value): """ Checks the value and type of a given attribute :param attribute: :param attribute_name_type: :param attribute_name_value: :param attribute_value_type: :param attribute_value_value: """ # Error check the attribute name and value type and value attribute_name = attribute.attribute_name attribute_value = attribute.attribute_value self._check_attribute_name(attribute_name, attribute_name_type, attribute_name_value) if attribute_name_value == 'Unique Identifier': self._check_uuid(attribute_value.value, attribute_value_type) else: self._check_attribute_value(attribute_value, attribute_value_type, attribute_value_value) def _check_attribute_name(self, attribute_name, attribute_name_type, attribute_name_value): """ Checks the attribute name for a given attribute :param attribute_name: :param attribute_name_type: :param attribute_name_value: """ # Error check the attribute name type and value expected = attribute_name_type observed = type(attribute_name.value) self.assertEqual(expected, observed) expected = attribute_name_value observed = attribute_name.value self.assertEqual(expected, observed) def _check_attribute_value(self, attribute_value, attribute_value_type, attribute_value_value): """ Checks the attribute value for a given attribute :param attribute_value: :param attribute_value_type: :param attribute_value_value: """ expected = attribute_value_type observed = type(attribute_value.value) self.assertEqual(expected, observed) expected = attribute_value_value observed = attribute_value.value self.assertEqual(expected, observed) def test_discover_versions(self): result = self.client.discover_versions() expected = ResultStatus.SUCCESS observed = result.result_status.value self.assertEqual(expected, observed) def test_query(self): # Build query function list, asking for all server data. query_functions = list() query_functions.append( QueryFunction(QueryFunctionEnum.QUERY_OPERATIONS)) query_functions.append(QueryFunction(QueryFunctionEnum.QUERY_OBJECTS)) query_functions.append( QueryFunction(QueryFunctionEnum.QUERY_SERVER_INFORMATION)) query_functions.append( QueryFunction(QueryFunctionEnum.QUERY_APPLICATION_NAMESPACES)) query_functions.append( QueryFunction(QueryFunctionEnum.QUERY_EXTENSION_LIST)) query_functions.append( QueryFunction(QueryFunctionEnum.QUERY_EXTENSION_MAP)) result = self.client.query(query_functions=query_functions) expected = ResultStatus.SUCCESS observed = result.result_status.value self.assertEqual(expected, observed) def test_symmetric_key_create_get_destroy(self): """ Test that symmetric keys are properly created """ key_name = 'Integration Test - Create-Get-Destroy Key' result = self._create_symmetric_key(key_name=key_name) 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) result = self.client.get(uuid=result.uuid.value, 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) self.logger.debug('Destroying key: ' + key_name + '\n With 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=result.uuid.value, 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_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_key_pair_create_get_destroy(self): """ Test that key pairs are properly created, retrieved, and destroyed. """ key_name = 'Integration Test - Create-Get-Destroy Key Pair -' result = self._create_key_pair(key_name=key_name) self._check_result_status(result, ResultStatus, ResultStatus.SUCCESS) # Check UUID value for Private key self._check_uuid(result.private_key_uuid.value, str) # Check UUID value for Public key self._check_uuid(result.public_key_uuid.value, str) priv_key_uuid = result.private_key_uuid.value pub_key_uuid = result.public_key_uuid.value priv_key_result = self.client.get(uuid=priv_key_uuid, credential=None) pub_key_result = self.client.get(uuid=pub_key_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) 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 priv_secret = priv_key_result.secret pub_secret = pub_key_result.secret priv_expected = PrivateKey pub_expected = PublicKey self.assertIsInstance(priv_secret, priv_expected) self.assertIsInstance(pub_secret, pub_expected) self.logger.debug('Destroying key: ' + key_name + ' Private' + '\n With UUID: ' + result.private_key_uuid.value) destroy_priv_key_result = self.client.destroy( result.private_key_uuid.value) self._check_result_status(destroy_priv_key_result, ResultStatus, ResultStatus.SUCCESS) self.logger.debug('Destroying key: ' + key_name + ' Public' + '\n With UUID: ' + result.public_key_uuid.value) destroy_pub_key_result = self.client.destroy( result.public_key_uuid.value) self._check_result_status(destroy_pub_key_result, ResultStatus, ResultStatus.SUCCESS) priv_key_uuid = destroy_priv_key_result.uuid.value pub_key_uuid = destroy_pub_key_result.uuid.value self._check_uuid(priv_key_uuid, str) self._check_uuid(pub_key_uuid, str) # Verify the secret was destroyed priv_key_destroyed_result = self.client.get(uuid=priv_key_uuid) pub_key_destroyed_result = self.client.get(uuid=pub_key_uuid) self._check_result_status(priv_key_destroyed_result, ResultStatus, ResultStatus.OPERATION_FAILED) self._check_result_status(pub_key_destroyed_result, ResultStatus, ResultStatus.OPERATION_FAILED) expected = ResultReason observed_priv = type(priv_key_destroyed_result.result_reason.value) observed_pub = type(pub_key_destroyed_result.result_reason.value) self.assertEqual(expected, observed_priv) self.assertEqual(expected, observed_pub) 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_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_cert_register_get_destroy(self): """ Tests that certificates are 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#_Toc333488807 cert_obj_type = ObjectType.CERTIFICATE mask_flags = [ CryptographicUsageMask.SIGN, CryptographicUsageMask.VERIFY ] attribute_type = AttributeType.CRYPTOGRAPHIC_USAGE_MASK usage_mask = self.attr_factory.create_attribute( attribute_type, mask_flags) name = Attribute.AttributeName('Name') cert_name = 'Integration Test - Register-Get-Destroy Certificate' cert_name_value = Name.NameValue(cert_name) name_type = Name.NameType(NameType.UNINTERPRETED_TEXT_STRING) cert_value = Name(name_value=cert_name_value, name_type=name_type) cert_name_attr = Attribute(attribute_name=name, attribute_value=cert_value) cert_attributes = [usage_mask, cert_name_attr] cert_template_attribute = TemplateAttribute(attributes=cert_attributes) cert_format_type = CertificateTypeEnum.X_509 cert_data = ( b'\x30\x82\x03\x12\x30\x82\x01\xFA\xA0\x03\x02\x01\x02\x02\x01\x01' b'\x30\x0D\x06\x09\x2A\x86\x48\x86\xF7\x0D\x01\x01\x05\x05\x00\x30' b'\x3B\x31\x0B\x30\x09\x06\x03\x55\x04\x06\x13\x02\x55\x53\x31\x0D' b'\x30\x0B\x06\x03\x55\x04\x0A\x13\x04\x54\x45\x53\x54\x31\x0E\x30' b'\x0C\x06\x03\x55\x04\x0B\x13\x05\x4F\x41\x53\x49\x53\x31\x0D\x30' b'\x0B\x06\x03\x55\x04\x03\x13\x04\x4B\x4D\x49\x50\x30\x1E\x17\x0D' b'\x31\x30\x31\x31\x30\x31\x32\x33\x35\x39\x35\x39\x5A\x17\x0D\x32' b'\x30\x31\x31\x30\x31\x32\x33\x35\x39\x35\x39\x5A\x30\x3B\x31\x0B' b'\x30\x09\x06\x03\x55\x04\x06\x13\x02\x55\x53\x31\x0D\x30\x0B\x06' b'\x03\x55\x04\x0A\x13\x04\x54\x45\x53\x54\x31\x0E\x30\x0C\x06\x03' b'\x55\x04\x0B\x13\x05\x4F\x41\x53\x49\x53\x31\x0D\x30\x0B\x06\x03' b'\x55\x04\x03\x13\x04\x4B\x4D\x49\x50\x30\x82\x01\x22\x30\x0D\x06' b'\x09\x2A\x86\x48\x86\xF7\x0D\x01\x01\x01\x05\x00\x03\x82\x01\x0F' b'\x00\x30\x82\x01\x0A\x02\x82\x01\x01\x00\xAB\x7F\x16\x1C\x00\x42' b'\x49\x6C\xCD\x6C\x6D\x4D\xAD\xB9\x19\x97\x34\x35\x35\x77\x76\x00' b'\x3A\xCF\x54\xB7\xAF\x1E\x44\x0A\xFB\x80\xB6\x4A\x87\x55\xF8\x00' b'\x2C\xFE\xBA\x6B\x18\x45\x40\xA2\xD6\x60\x86\xD7\x46\x48\x34\x6D' b'\x75\xB8\xD7\x18\x12\xB2\x05\x38\x7C\x0F\x65\x83\xBC\x4D\x7D\xC7' b'\xEC\x11\x4F\x3B\x17\x6B\x79\x57\xC4\x22\xE7\xD0\x3F\xC6\x26\x7F' b'\xA2\xA6\xF8\x9B\x9B\xEE\x9E\x60\xA1\xD7\xC2\xD8\x33\xE5\xA5\xF4' b'\xBB\x0B\x14\x34\xF4\xE7\x95\xA4\x11\x00\xF8\xAA\x21\x49\x00\xDF' b'\x8B\x65\x08\x9F\x98\x13\x5B\x1C\x67\xB7\x01\x67\x5A\xBD\xBC\x7D' b'\x57\x21\xAA\xC9\xD1\x4A\x7F\x08\x1F\xCE\xC8\x0B\x64\xE8\xA0\xEC' b'\xC8\x29\x53\x53\xC7\x95\x32\x8A\xBF\x70\xE1\xB4\x2E\x7B\xB8\xB7' b'\xF4\xE8\xAC\x8C\x81\x0C\xDB\x66\xE3\xD2\x11\x26\xEB\xA8\xDA\x7D' b'\x0C\xA3\x41\x42\xCB\x76\xF9\x1F\x01\x3D\xA8\x09\xE9\xC1\xB7\xAE' b'\x64\xC5\x41\x30\xFB\xC2\x1D\x80\xE9\xC2\xCB\x06\xC5\xC8\xD7\xCC' b'\xE8\x94\x6A\x9A\xC9\x9B\x1C\x28\x15\xC3\x61\x2A\x29\xA8\x2D\x73' b'\xA1\xF9\x93\x74\xFE\x30\xE5\x49\x51\x66\x2A\x6E\xDA\x29\xC6\xFC' b'\x41\x13\x35\xD5\xDC\x74\x26\xB0\xF6\x05\x02\x03\x01\x00\x01\xA3' b'\x21\x30\x1F\x30\x1D\x06\x03\x55\x1D\x0E\x04\x16\x04\x14\x04\xE5' b'\x7B\xD2\xC4\x31\xB2\xE8\x16\xE1\x80\xA1\x98\x23\xFA\xC8\x58\x27' b'\x3F\x6B\x30\x0D\x06\x09\x2A\x86\x48\x86\xF7\x0D\x01\x01\x05\x05' b'\x00\x03\x82\x01\x01\x00\xA8\x76\xAD\xBC\x6C\x8E\x0F\xF0\x17\x21' b'\x6E\x19\x5F\xEA\x76\xBF\xF6\x1A\x56\x7C\x9A\x13\xDC\x50\xD1\x3F' b'\xEC\x12\xA4\x27\x3C\x44\x15\x47\xCF\xAB\xCB\x5D\x61\xD9\x91\xE9' b'\x66\x31\x9D\xF7\x2C\x0D\x41\xBA\x82\x6A\x45\x11\x2F\xF2\x60\x89' b'\xA2\x34\x4F\x4D\x71\xCF\x7C\x92\x1B\x4B\xDF\xAE\xF1\x60\x0D\x1B' b'\xAA\xA1\x53\x36\x05\x7E\x01\x4B\x8B\x49\x6D\x4F\xAE\x9E\x8A\x6C' b'\x1D\xA9\xAE\xB6\xCB\xC9\x60\xCB\xF2\xFA\xE7\x7F\x58\x7E\xC4\xBB' b'\x28\x20\x45\x33\x88\x45\xB8\x8D\xD9\xAE\xEA\x53\xE4\x82\xA3\x6E' b'\x73\x4E\x4F\x5F\x03\xB9\xD0\xDF\xC4\xCA\xFC\x6B\xB3\x4E\xA9\x05' b'\x3E\x52\xBD\x60\x9E\xE0\x1E\x86\xD9\xB0\x9F\xB5\x11\x20\xC1\x98' b'\x34\xA9\x97\xB0\x9C\xE0\x8D\x79\xE8\x13\x11\x76\x2F\x97\x4B\xB1' b'\xC8\xC0\x91\x86\xC4\xD7\x89\x33\xE0\xDB\x38\xE9\x05\x08\x48\x77' b'\xE1\x47\xC7\x8A\xF5\x2F\xAE\x07\x19\x2F\xF1\x66\xD1\x9F\xA9\x4A' b'\x11\xCC\x11\xB2\x7E\xD0\x50\xF7\xA2\x7F\xAE\x13\xB2\x05\xA5\x74' b'\xC4\xEE\x00\xAA\x8B\xD6\x5D\x0D\x70\x57\xC9\x85\xC8\x39\xEF\x33' b'\x6A\x44\x1E\xD5\x3A\x53\xC6\xB6\xB6\x96\xF1\xBD\xEB\x5F\x7E\xA8' b'\x11\xEB\xB2\x5A\x7F\x86') cert_obj = Certificate(cert_format_type, cert_data) cert_result = self.client.register(cert_obj_type, cert_template_attribute, cert_obj, credential=None) self._check_result_status(cert_result, ResultStatus, ResultStatus.SUCCESS) self._check_uuid(cert_result.uuid.value, str) # Check that the returned key bytes match what was provided cert_uuid = cert_result.uuid.value cert_result = self.client.get(uuid=cert_uuid, credential=None) self._check_result_status(cert_result, ResultStatus, ResultStatus.SUCCESS) self._check_object_type(cert_result.object_type.value, ObjectType, ObjectType.CERTIFICATE) self._check_uuid(cert_result.uuid.value, str) # Check the secret type cert_secret = cert_result.secret cert_secret_expected = Certificate self.assertIsInstance(cert_secret, cert_secret_expected) cert_material = cert_result.secret.certificate_value.value expected = cert_data self.assertEqual(expected, cert_material) self.logger.debug('Destroying cert: ' + cert_name + '\nWith " "UUID: ' + cert_result.uuid.value) cert_result = self.client.destroy(cert_result.uuid.value) self._check_result_status(cert_result, ResultStatus, ResultStatus.SUCCESS) self._check_uuid(cert_result.uuid.value, str) # Verify the secret was destroyed cert_result_destroyed_result = self.client.get(uuid=cert_uuid, credential=None) self._check_result_status(cert_result_destroyed_result, ResultStatus, ResultStatus.OPERATION_FAILED) expected = ResultReason cert_observed = type(cert_result_destroyed_result.result_reason.value) self.assertEqual(expected, cert_observed) 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_opaque_data_register_get_destroy(self): """ Tests that opaque objects can be properly registered, retrieved, and destroyed """ opaque_obj_type = ObjectType.OPAQUE_DATA opaque_obj_data_type = OpaqueObject.OpaqueDataType(OpaqueDataType.NONE) name = Attribute.AttributeName('Name') opaque_obj_name = 'Integration Test - Register-Get-Destroy Opaque Data' opaque_obj_name_value = Name.NameValue(opaque_obj_name) name_type = Name.NameType(NameType.UNINTERPRETED_TEXT_STRING) opaque_obj_value = Name(name_value=opaque_obj_name_value, name_type=name_type) opaque_obj_name_attr = Attribute(attribute_name=name, attribute_value=opaque_obj_value) opaque_obj_attributes = [opaque_obj_name_attr] opaque_obj_template_attribute = TemplateAttribute( attributes=opaque_obj_attributes) opaque_obj_data = OpaqueObject.OpaqueDataValue(( b'\x30\x82\x03\x12\x30\x82\x01\xFA\xA0\x03\x02\x01\x02\x02\x01\x01' b'\x30\x0D\x06\x09\x2A\x86\x48\x86\xF7\x0D\x01\x01\x05\x05\x00\x30' b'\x3B\x31\x0B\x30\x09\x06\x03\x55\x04\x06\x13\x02\x55\x53\x31\x0D' b'\x30\x0B\x06\x03\x55\x04\x0A\x13\x04\x54\x45\x53\x54\x31\x0E\x30' )) opaque_obj = OpaqueObject(opaque_data_type=opaque_obj_data_type, opaque_data_value=opaque_obj_data) opaque_obj_result = self.client.register(opaque_obj_type, opaque_obj_template_attribute, opaque_obj, credential=None) self._check_result_status(opaque_obj_result, ResultStatus, ResultStatus.SUCCESS) self._check_uuid(opaque_obj_result.uuid.value, str) # Check that the returned key bytes match what was provided opaque_obj_uuid = opaque_obj_result.uuid.value opaque_obj_result = self.client.get(uuid=opaque_obj_uuid, credential=None) self._check_result_status(opaque_obj_result, ResultStatus, ResultStatus.SUCCESS) self._check_object_type(opaque_obj_result.object_type.value, ObjectType, ObjectType.OPAQUE_DATA) self._check_uuid(opaque_obj_result.uuid.value, str) # Check the secret type opaque_obj_secret = opaque_obj_result.secret opaque_obj_secret_expected = OpaqueObject self.assertIsInstance(opaque_obj_secret, opaque_obj_secret_expected) opaque_obj_material = opaque_obj_result.secret.opaque_data_value.value expected = opaque_obj_data.value self.assertEqual(expected, opaque_obj_material) self.logger.debug('Destroying opaque object: ' + opaque_obj_name + '\nWith " "UUID: ' + opaque_obj_result.uuid.value) opaque_obj_result = self.client.destroy(opaque_obj_result.uuid.value) self._check_result_status(opaque_obj_result, ResultStatus, ResultStatus.SUCCESS) self._check_uuid(opaque_obj_result.uuid.value, str) # Verify the secret was destroyed opaque_obj_result_destroyed_result = self.client.get( uuid=opaque_obj_uuid, credential=None) self._check_result_status(opaque_obj_result_destroyed_result, ResultStatus, ResultStatus.OPERATION_FAILED) expected = ResultReason opaque_obj_observed = \ type(opaque_obj_result_destroyed_result.result_reason.value) self.assertEqual(expected, opaque_obj_observed) def test_symmetric_key_create_getattributelist_destroy(self): """ Test that the GetAttributeList operation works for a newly created key. """ key_name = 'Integration Test - Create-GetAttributeList-Destroy Key' result = self._create_symmetric_key(key_name=key_name) uid = result.uuid.value self.assertEqual(ResultStatus.SUCCESS, result.result_status.value) self.assertEqual(ObjectType.SYMMETRIC_KEY, result.object_type.value) self.assertIsInstance(uid, str) try: result = self.client.get_attribute_list(uid) self.assertEqual(ResultStatus.SUCCESS, result.result_status.value) self.assertIsInstance(result.uid, str) self.assertIsInstance(result.names, list) for name in result.names: self.assertIsInstance(name, str) expected = [ 'Cryptographic Algorithm', 'Cryptographic Length', 'Cryptographic Usage Mask', 'Unique Identifier', 'Object Type' ] for name in expected: self.assertIn(name, result.names) finally: result = self.client.destroy(uid) self.assertEqual(ResultStatus.SUCCESS, result.result_status.value) result = self.client.get(uuid=result.uuid.value, credential=None) self.assertEqual(ResultStatus.OPERATION_FAILED, result.result_status.value)
class TestKMIPClientIntegration(TestCase): STARTUP_TIME = 1.0 SHUTDOWN_TIME = 0.1 KMIP_PORT = 9090 CA_CERTS_PATH = os.path.normpath( os.path.join(os.path.dirname(os.path.abspath(__file__)), '../utils/certs/server.crt')) def setUp(self): super(TestKMIPClientIntegration, self).setUp() self.attr_factory = AttributeFactory() self.cred_factory = CredentialFactory() self.secret_factory = SecretFactory() # Set up the KMIP server process path = os.path.join(os.path.dirname(__file__), os.path.pardir, 'utils', 'server.py') self.server = Popen( ['python', '{0}'.format(path), '-p', '{0}'.format(self.KMIP_PORT)], stderr=sys.stdout) time.sleep(self.STARTUP_TIME) if self.server.poll() is not None: raise KMIPServerSuicideError(self.server.pid) # Set up and open the client proxy; shutdown the server if open fails try: self.client = KMIPProxy(port=self.KMIP_PORT, ca_certs=self.CA_CERTS_PATH) self.client.open() except Exception as e: self._shutdown_server() raise e def tearDown(self): super(TestKMIPClientIntegration, self).tearDown() # Close the client proxy and shutdown the server self.client.close() self._shutdown_server() def test_create(self): result = self._create_symmetric_key() 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 template attribute type self._check_template_attribute( result.template_attribute, TemplateAttribute, 2, [[str, 'Cryptographic Length', int, 256], [str, 'Unique Identifier', str, None]]) def test_get(self): credential_type = CredentialType.USERNAME_AND_PASSWORD credential_value = {'Username': '******', 'Password': '******'} credential = self.cred_factory.create_credential( credential_type, credential_value) result = self._create_symmetric_key() 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) def test_destroy(self): credential_type = CredentialType.USERNAME_AND_PASSWORD credential_value = {'Username': '******', 'Password': '******'} credential = self.cred_factory.create_credential( credential_type, credential_value) result = self._create_symmetric_key() uuid = result.uuid.value # Verify the secret was created 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) secret = result.secret expected = SymmetricKey message = utils.build_er_error(result.__class__, 'type', expected, secret, 'secret') self.assertIsInstance(secret, expected, message) # Destroy the SYMMETRIC_KEY object result = self.client.destroy(uuid, credential) self._check_result_status(result.result_status.value, ResultStatus, ResultStatus.SUCCESS) self._check_uuid(result.uuid.value, str) # Verify the secret was destroyed result = self.client.get(uuid=uuid, credential=credential) self._check_result_status(result.result_status.value, ResultStatus, ResultStatus.OPERATION_FAILED) expected = ResultReason observed = type(result.result_reason.value) message = utils.build_er_error(result.result_reason.__class__, 'type', expected, observed) self.assertEqual(expected, observed, message) expected = ResultReason.ITEM_NOT_FOUND observed = result.result_reason.value message = utils.build_er_error(result.result_reason.__class__, 'value', expected, observed) self.assertEqual(expected, observed, message) 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 _shutdown_server(self): if self.server.poll() is not None: return else: # Terminate the server process. If it resists, kill it. pid = self.server.pid self.server.terminate() time.sleep(self.SHUTDOWN_TIME) if self.server.poll() is None: raise KMIPServerZombieError(pid) def _create_symmetric_key(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 attribute_type = AttributeType.CRYPTOGRAPHIC_ALGORITHM algorithm = self.attr_factory.create_attribute(attribute_type, 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 = [algorithm, usage_mask] template_attribute = TemplateAttribute(attributes=attributes) return self.client.create(object_type, template_attribute, credential) def _check_result_status(self, result_status, result_status_type, result_status_value): # Error check the result status type and value expected = result_status_type message = utils.build_er_error(result_status_type, 'type', expected, result_status) self.assertIsInstance(result_status, expected, message) expected = result_status_value message = utils.build_er_error(result_status_type, 'value', expected, result_status) self.assertEqual(expected, result_status, message) def _check_uuid(self, uuid, uuid_type): # Error check the UUID type and value not_expected = None message = utils.build_er_error(uuid_type, 'type', 'not {0}'.format(not_expected), uuid) self.assertNotEqual(not_expected, uuid, message) expected = uuid_type message = utils.build_er_error(uuid_type, 'type', expected, uuid) self.assertEqual(expected, type(uuid), message) def _check_object_type(self, object_type, object_type_type, object_type_value): # Error check the object type type and value expected = object_type_type message = utils.build_er_error(object_type_type, 'type', expected, object_type) self.assertIsInstance(object_type, expected, message) expected = object_type_value message = utils.build_er_error(object_type_type, 'value', expected, object_type) self.assertEqual(expected, object_type, message) def _check_template_attribute(self, template_attribute, template_attribute_type, num_attributes, attribute_features): # Error check the template attribute type expected = template_attribute_type message = utils.build_er_error(template_attribute.__class__, 'type', expected, template_attribute) self.assertIsInstance(template_attribute, expected, message) attributes = template_attribute.attributes expected = num_attributes observed = len(attributes) message = utils.build_er_error(TemplateAttribute.__class__, 'number', expected, observed, 'attributes') for i in range(num_attributes): features = attribute_features[i] self._check_attribute(attributes[i], features[0], features[1], features[2], features[3]) def _check_attribute(self, attribute, attribute_name_type, attribute_name_value, attribute_value_type, attribute_value_value): # Error check the attribute name and value type and value attribute_name = attribute.attribute_name attribute_value = attribute.attribute_value self._check_attribute_name(attribute_name, attribute_name_type, attribute_name_value) if attribute_name_value == 'Unique Identifier': self._check_uuid(attribute_value.value, attribute_value_type) else: self._check_attribute_value(attribute_value, attribute_value_type, attribute_value_value) def _check_attribute_name(self, attribute_name, attribute_name_type, attribute_name_value): # Error check the attribute name type and value expected = attribute_name_type observed = type(attribute_name.value) message = utils.build_er_error(attribute_name_type, 'type', expected, observed) self.assertEqual(expected, observed, message) expected = attribute_name_value observed = attribute_name.value message = utils.build_er_error(attribute_name_type, 'value', expected, observed) self.assertEqual(expected, observed, message) def _check_attribute_value(self, attribute_value, attribute_value_type, attribute_value_value): expected = attribute_value_type observed = type(attribute_value.value) message = utils.build_er_error(Attribute, 'type', expected, observed, 'attribute_value') self.assertEqual(expected, observed, message) expected = attribute_value_value observed = attribute_value.value message = utils.build_er_error(Attribute, 'value', expected, observed, 'attribute_value') self.assertEqual(expected, observed, message)
def create_key_proxy(app_name, algorithm, length): ''' :Desc: Proxy for creating key with a given algorithm and length. :param app_name: :param algorithm: :param length: :return: key object created on KMS ''' res_obj = CreateKeyResponse() object_type = ObjectType.SYMMETRIC_KEY attribute_factory = AttributeFactory() attribute_type = AttributeType.CRYPTOGRAPHIC_ALGORITHM algorithm_enum = getattr(CryptographicAlgorithm, algorithm, None) if algorithm_enum is None: logger.info(KmisResponseDescriptions.INVALID_ALGORITHM) return res_obj( KmisResponseCodes.FAIL, KmisResponseStatus.FAIL, KmisResponseDescriptions.INVALID_ALGORITHM) (client, credential) = get_kmip_client() algorithm_obj = attribute_factory.create_attribute(attribute_type, algorithm_enum) mask_flags = [CryptographicUsageMask.ENCRYPT, CryptographicUsageMask.DECRYPT] attribute_type = AttributeType.CRYPTOGRAPHIC_USAGE_MASK usage_mask = attribute_factory.create_attribute(attribute_type, mask_flags) attribute_type = AttributeType.CRYPTOGRAPHIC_LENGTH length_obj = attribute_factory.create_attribute(attribute_type, length) name = Attribute.AttributeName('Name') key_name = get_key_name(app_name) 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 = [algorithm_obj, usage_mask, length_obj, name] template_attribute = TemplateAttribute(attributes=attributes) # Create the SYMMETRIC_KEY object kmip_result = client.create(object_type, template_attribute, credential) if kmip_result and kmip_result.result_status.enum == ResultStatus.SUCCESS: logger.info( 'Key : {0} creation successful. UUID : {1}'.format( key_name, kmip_result.uuid.value)) print "=============", CryptographicAlgorithm.AES, algorithm if algorithm == 'AES': key_out_type = KmisKeyFormatType.RAW if algorithm == 'RSA': key_out_type = KmisKeyFormatType.PKCS_1 key_format_type = get_key_format_type(key_out_type) kmip_result_content = get_key_with_id(client, credential, kmip_result.uuid.value, key_format_type) res_obj.process_kmip_response(kmip_result_content) if kmip_result_content and kmip_result_content.result_status.enum == ResultStatus.SUCCESS: logger.info( 'Key : {0} retrieval successful. UUID : {1}'.format( key_name, kmip_result.uuid.value)) close_kmip_proxy(client) return res_obj( KmisResponseCodes.SUCCESS, KmisResponseStatus.SUCCESS, KmisResponseDescriptions.SUCCESS) else: logger.info("Key : {0} retrieval failed. Reason: {1}".format(str(key_name),kmip_result_content.result_message.value)) close_kmip_proxy(client) return res_obj( KmisResponseCodes.FAIL, KmisResponseStatus.FAIL, KmisResponseDescriptions.KEY_CREATION_ERROR) else: close_kmip_proxy(client) logger.info("Key creation failed for app: {0}. Reason : {1} ".format(app_name,kmip_result.result_message.value)) return res_obj( KmisResponseCodes.FAIL, KmisResponseStatus.FAIL, KmisResponseDescriptions.KEY_CREATION_ERROR)
class TestIntegration(TestCase): def setUp(self): super(TestIntegration, self).setUp() self.logger = logging.getLogger(__name__) self.attr_factory = AttributeFactory() self.cred_factory = CredentialFactory() self.secret_factory = SecretFactory() def tearDown(self): super(TestIntegration, self).tearDown() def _create_symmetric_key(self, key_name=None): """ Helper function for creating symmetric keys. Used any time a key needs to be created. :param key_name: name of the key to be created :return: returns the result of the "create key" operation as provided by the KMIP appliance """ object_type = ObjectType.SYMMETRIC_KEY attribute_type = AttributeType.CRYPTOGRAPHIC_ALGORITHM algorithm = self.attr_factory.create_attribute(attribute_type, 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) key_length = 128 attribute_type = AttributeType.CRYPTOGRAPHIC_LENGTH key_length_obj = self.attr_factory.create_attribute(attribute_type, key_length) name = Attribute.AttributeName('Name') if key_name is None: key_name = 'Integration Test - 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 = [algorithm, usage_mask, key_length_obj, name] template_attribute = TemplateAttribute(attributes=attributes) return self.client.create(object_type, template_attribute, credential=None) def _check_result_status(self, result, result_status_type, result_status_value): """ Helper function for checking the status of KMIP appliance actions. Verifies the result status type and value. :param result: result object :param result_status_type: type of result status received :param result_status_value: value of the result status """ result_status = result.result_status.enum # Error check the result status type and value expected = result_status_type self.assertIsInstance(result_status, expected) expected = result_status_value if result_status is ResultStatus.OPERATION_FAILED: self.logger.debug(result) self.logger.debug(result.result_reason) self.logger.debug(result.result_message) self.assertEqual(expected, result_status) def _check_uuid(self, uuid, uuid_type): """ Helper function for checking UUID type and value for errors :param uuid: UUID of a created key :param uuid_type: UUID type :return: """ # Error check the UUID type and value not_expected = None self.assertNotEqual(not_expected, uuid) expected = uuid_type self.assertEqual(expected, type(uuid)) def _check_object_type(self, object_type, object_type_type, object_type_value): """ Checks the type and value of a given object type. :param object_type: :param object_type_type: :param object_type_value: """ # Error check the object type type and value expected = object_type_type self.assertIsInstance(object_type, expected) expected = object_type_value self.assertEqual(expected, object_type) def _check_template_attribute(self, template_attribute, template_attribute_type, num_attributes, attribute_features): """ Checks the value and type of a given template attribute :param template_attribute: :param template_attribute_type: :param num_attributes: :param attribute_features: """ # Error check the template attribute type expected = template_attribute_type self.assertIsInstance(template_attribute, expected) attributes = template_attribute.attributes for i in range(num_attributes): features = attribute_features[i] self._check_attribute(attributes[i], features[0], features[1], features[2], features[3]) def _check_attribute(self, attribute, attribute_name_type, attribute_name_value, attribute_value_type, attribute_value_value): """ Checks the value and type of a given attribute :param attribute: :param attribute_name_type: :param attribute_name_value: :param attribute_value_type: :param attribute_value_value: """ # Error check the attribute name and value type and value attribute_name = attribute.attribute_name attribute_value = attribute.attribute_value self._check_attribute_name(attribute_name, attribute_name_type, attribute_name_value) if attribute_name_value == 'Unique Identifier': self._check_uuid(attribute_value.value, attribute_value_type) else: self._check_attribute_value(attribute_value, attribute_value_type, attribute_value_value) def _check_attribute_name(self, attribute_name, attribute_name_type, attribute_name_value): """ Checks the attribute name for a given attribute :param attribute_name: :param attribute_name_type: :param attribute_name_value: """ # Error check the attribute name type and value expected = attribute_name_type observed = type(attribute_name.value) self.assertEqual(expected, observed) expected = attribute_name_value observed = attribute_name.value self.assertEqual(expected, observed) def _check_attribute_value(self, attribute_value, attribute_value_type, attribute_value_value): """ Checks the attribute value for a given attribute :param attribute_value: :param attribute_value_type: :param attribute_value_value: """ expected = attribute_value_type observed = type(attribute_value.value) self.assertEqual(expected, observed) expected = attribute_value_value observed = attribute_value.value self.assertEqual(expected, observed) def test_discover_versions(self): result = self.client.discover_versions() expected = ResultStatus.SUCCESS observed = result.result_status.enum self.assertEqual(expected, observed) def test_query(self): # Build query function list, asking for all server data. query_functions = list() query_functions.append( QueryFunction(QueryFunctionEnum.QUERY_OPERATIONS)) query_functions.append( QueryFunction(QueryFunctionEnum.QUERY_OBJECTS)) query_functions.append( QueryFunction(QueryFunctionEnum.QUERY_SERVER_INFORMATION)) query_functions.append( QueryFunction(QueryFunctionEnum.QUERY_APPLICATION_NAMESPACES)) query_functions.append( QueryFunction(QueryFunctionEnum.QUERY_EXTENSION_LIST)) query_functions.append( QueryFunction(QueryFunctionEnum.QUERY_EXTENSION_MAP)) result = self.client.query(query_functions=query_functions) expected = ResultStatus.SUCCESS observed = result.result_status.enum self.assertEqual(expected, observed) def test_symmetric_key_create_get_destroy(self): """ Test that symmetric keys are properly created """ key_name = 'Integration Test - Create-Get-Destroy Key' result = self._create_symmetric_key(key_name=key_name) self._check_result_status(result, ResultStatus, ResultStatus.SUCCESS) self._check_object_type(result.object_type.enum, ObjectType, ObjectType.SYMMETRIC_KEY) self._check_uuid(result.uuid.value, str) result = self.client.get(uuid=result.uuid.value, credential=None) self._check_result_status(result, ResultStatus, ResultStatus.SUCCESS) self._check_object_type(result.object_type.enum, ObjectType, ObjectType.SYMMETRIC_KEY) self._check_uuid(result.uuid.value, str) # Check the secret type secret = result.secret expected = SymmetricKey self.assertIsInstance(secret, expected) self.logger.debug('Destroying key: ' + key_name + '\n With 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=result.uuid.value, credential=None) self._check_result_status(result, ResultStatus, ResultStatus.OPERATION_FAILED) expected = ResultReason observed = type(result.result_reason.enum) self.assertEqual(expected, observed) expected = ResultReason.ITEM_NOT_FOUND observed = result.result_reason.enum self.assertEqual(expected, observed) def test_symmetric_key_register_get_destroy(self): """ Tests that symmetric keys are properly registered """ 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.enum, 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.enum) self.assertEqual(expected, observed) expected = ResultReason.ITEM_NOT_FOUND observed = result.result_reason.enum self.assertEqual(expected, observed)
class KMIPImpl(KMIP): def __init__(self): super(KMIPImpl, self).__init__() self.logger = logging.getLogger(__name__) self.key_factory = KeyFactory() self.secret_factory = SecretFactory() self.attribute_factory = AttributeFactory() self.repo = MemRepo() self.protocol_versions = [ ProtocolVersion.create(1, 1), ProtocolVersion.create(1, 0) ] def create(self, object_type, template_attribute, credential=None): self.logger.debug('create() called') self.logger.debug('object type = %s' % object_type) bit_length = 256 attributes = template_attribute.attributes ret_attributes = [] if object_type.value != OT.SYMMETRIC_KEY: self.logger.debug('invalid object type') return self._get_invalid_field_result('invalid object type') try: alg_attr = self._validate_req_field( attributes, AT.CRYPTOGRAPHIC_ALGORITHM.value, (CA.AES,), 'unsupported algorithm') len_attr = self._validate_req_field( attributes, AT.CRYPTOGRAPHIC_LENGTH.value, (128, 256, 512), 'unsupported key length', False) self._validate_req_field( attributes, AT.CRYPTOGRAPHIC_USAGE_MASK.value, (), '') except InvalidFieldException as e: self.logger.debug('InvalidFieldException raised') return e.result crypto_alg = CryptographicAlgorithm(CA(alg_attr.attribute_value.value)) if len_attr is None: self.logger.debug('cryptographic length not supplied') attribute_type = AT.CRYPTOGRAPHIC_LENGTH length_attribute = self.attribute_factory.\ create_attribute(attribute_type, bit_length) attributes.append(length_attribute) ret_attributes.append(length_attribute) else: bit_length = len_attr.attribute_value.value key = self._gen_symmetric_key(bit_length, crypto_alg) s_uuid, uuid_attribute = self._save(key, attributes) ret_attributes.append(uuid_attribute) template_attribute = TemplateAttribute(attributes=ret_attributes) return CreateResult(ResultStatus(RS.SUCCESS), object_type=object_type, uuid=UniqueIdentifier(s_uuid), template_attribute=template_attribute) def create_key_pair(self, common_template_attribute, private_key_template_attribute, public_key_template_attribute): raise NotImplementedError() def register(self, object_type, template_attribute, secret, credential=None): self.logger.debug('register() called') self.logger.debug('object type = %s' % object_type) attributes = template_attribute.attributes ret_attributes = [] if object_type is None: self.logger.debug('invalid object type') return self._get_missing_field_result('object type') if object_type.value != OT.SYMMETRIC_KEY: self.logger.debug('invalid object type') return self._get_invalid_field_result('invalid object type') if secret is None or not isinstance(secret, SymmetricKey): msg = 'object type does not match that of secret' self.logger.debug(msg) return self._get_invalid_field_result(msg) self.logger.debug('Collecting all attributes') if attributes is None: attributes = [] attributes.extend(self._get_key_block_attributes(secret.key_block)) self.logger.debug('Verifying all attributes are valid and set') try: self._validate_req_field( attributes, AT.CRYPTOGRAPHIC_ALGORITHM.value, (CA.AES,), 'unsupported algorithm') self._validate_req_field( attributes, AT.CRYPTOGRAPHIC_LENGTH.value, (128, 256, 512), 'unsupported key length') self._validate_req_field( attributes, AT.CRYPTOGRAPHIC_USAGE_MASK.value, (), '') except InvalidFieldException as e: self.logger.debug('InvalidFieldException raised') return RegisterResult(e.result.result_status, e.result.result_reason, e.result.result_message) s_uuid, uuid_attribute = self._save(secret, attributes) ret_attributes.append(uuid_attribute) template_attribute = TemplateAttribute(attributes=ret_attributes) return RegisterResult(ResultStatus(RS.SUCCESS), uuid=UniqueIdentifier(s_uuid), template_attribute=template_attribute) def rekey_key_pair(self, private_key_unique_identifier, offset, common_template_attribute, private_key_template_attribute, public_key_template_attribute): raise NotImplementedError() 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 destroy(self, uuid): self.logger.debug('destroy() 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 DestroyResult(ResultStatus(ret_value), reason, message) msg = 'deleting object from repo: {0}'.format(uuid) self.logger.debug(msg) if not self.repo.delete(uuid.value): self.logger.debug('repo did not find and delete managed object') reason = ResultReason(ResultReasonEnum.ITEM_NOT_FOUND) message = ResultMessage('') return DestroyResult(ResultStatus(ret_value), reason, message) ret_value = RS.SUCCESS return DestroyResult(ResultStatus(ret_value), uuid=uuid) def locate(self, maximum_items=None, storage_status_mask=None, object_group_member=None, attributes=None, credential=None): self.logger.debug('locate() called') msg = 'locating object(s) from repo' self.logger.debug(msg) try: uuids = self.repo.locate(maximum_items, storage_status_mask, object_group_member, attributes) return LocateResult(ResultStatus(RS.SUCCESS), uuids=uuids) except NotImplementedError: msg = ResultMessage('Locate Operation Not Supported') reason = ResultReason(ResultReasonEnum.OPERATION_NOT_SUPPORTED) return LocateResult(ResultStatus(RS.OPERATION_FAILED), result_reason=reason, result_message=msg) def discover_versions(self, protocol_versions=None): self.logger.debug( "discover_versions(protocol_versions={0}) called".format( protocol_versions)) msg = 'get protocol versions supported by server' result_versions = list() if protocol_versions: msg += " and client; client versions {0}".format(protocol_versions) for version in protocol_versions: if version in self.protocol_versions: result_versions.append(version) else: result_versions = self.protocol_versions self.logger.debug(msg) try: return DiscoverVersionsResult(ResultStatus(RS.SUCCESS), protocol_versions=result_versions) except Exception: msg = ResultMessage('DiscoverVersions Operation Failed') reason = ResultReason(ResultReasonEnum.GENERAL_FAILURE) return DiscoverVersionsResult(ResultStatus(RS.OPERATION_FAILED), result_reason=reason, result_message=msg) def _validate_req_field(self, attrs, name, expected, msg, required=True): self.logger.debug('Validating attribute %s' % name) seen = False found_attr = None for attr in attrs: if self._validate_field(attr, name, expected, msg): if seen: # TODO check what spec says to do on this msg = 'duplicate attribute: %s' % name self.logger.debug(msg) result = self._get_duplicate_attribute_result(name) raise InvalidFieldException(result) seen = True found_attr = attr if required and not seen: result = self._get_missing_field_result(name) raise InvalidFieldException(result) return found_attr def _validate_field(self, attr, name, expected, msg): if attr.attribute_name.value == name: self.logger.debug('validating attribute %s' % name) if not expected or attr.attribute_value.value in expected: self.logger.debug('attribute validated') return True else: self.logger.debug('attribute not validated') result = self._get_invalid_field_result(msg) raise InvalidFieldException(result) else: return False def _get_invalid_field_result(self, msg): status = ResultStatus(RS.OPERATION_FAILED) reason = ResultReason(ResultReasonEnum.INVALID_FIELD) message = ResultMessage(msg) return OperationResult(status, reason, message) def _get_missing_field_result(self, name): msg = '%s not supplied' % name self.logger.debug(msg) status = ResultStatus(RS.OPERATION_FAILED) reason = ResultReason(ResultReasonEnum.ITEM_NOT_FOUND) message = ResultMessage(msg) return OperationResult(status, reason, message) def _get_duplicate_attribute_result(self, name): msg = '%s supplied multiple times' % name self.logger.debug(msg) status = ResultStatus(RS.OPERATION_FAILED) reason = ResultReason(ResultReasonEnum.INDEX_OUT_OF_BOUNDS) message = ResultMessage(msg) return OperationResult(status, reason, message) 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 _save(self, key, attributes): s_uuid = self.repo.save(key, attributes) self.logger.debug('creating object with uuid = %s' % s_uuid) attribute_type = AT.UNIQUE_IDENTIFIER attribute = self.attribute_factory.create_attribute(attribute_type, s_uuid) attributes.append(attribute) # Calling update to also store the UUID self.repo.update(s_uuid, key, attributes) return s_uuid, attribute def _get_key_block_attributes(self, key_block): self.logger.debug('getting all key attributes from key block') attributes = [] if key_block.cryptographic_algorithm is not None: self.logger.debug('crypto_alg set on key block') self.logger.debug('adding crypto algorithm attribute') at = AT.CRYPTOGRAPHIC_ALGORITHM alg = key_block.cryptographic_algorithm.value attributes.append(self.attribute_factory.create_attribute(at, alg)) if key_block.cryptographic_length is not None: self.logger.debug('crypto_length set on key block') self.logger.debug('adding crypto length attribute') at = AT.CRYPTOGRAPHIC_LENGTH len = key_block.cryptographic_length.value attributes.append(self.attribute_factory.create_attribute(at, len)) self.logger.debug('getting key value attributes') if key_block.key_wrapping_data is not None: self.logger.debug('no wrapping data so key value is struct') kv = key_block.key_value if isinstance(kv, KeyValue): kv = key_block.key_value if kv.attributes is not None: self.logger.debug('adding the key value struct attributes') attributes.extend(kv.attributes) return attributes