예제 #1
0
    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
예제 #2
0
    def setUp(self):
        super(TestIntegration, self).setUp()

        self.logger = logging.getLogger(__name__)

        self.attr_factory = AttributeFactory()
        self.cred_factory = CredentialFactory()
        self.secret_factory = SecretFactory()
예제 #3
0
파일: server.py 프로젝트: nausley/PyKMIP
 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)
     ]
예제 #4
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')
예제 #5
0
 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]
예제 #6
0
 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]
예제 #7
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.value,
            'locate result status did not return success')
예제 #8
0
    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
예제 #9
0
파일: server.py 프로젝트: wyllys66/PyKMIP
 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()
예제 #10
0
    def setUp(self):
        super(TestIntegration, self).setUp()

        self.logger = logging.getLogger(__name__)

        self.attr_factory = AttributeFactory()
        self.cred_factory = CredentialFactory()
        self.secret_factory = SecretFactory()
예제 #11
0
파일: utils.py 프로젝트: poldridge/PyKMIP
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
예제 #12
0
    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()
예제 #13
0
 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
예제 #14
0
파일: utils.py 프로젝트: nausley/PyKMIP
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
예제 #15
0
    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
예제 #16
0
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)
예제 #17
0
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)
예제 #18
0
    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()
예제 #19
0
파일: register.py 프로젝트: zmole945/PyKMIP
    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)
예제 #20
0
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)
예제 #21
0
파일: create.py 프로젝트: vbnmmnbv/PyKMIP
    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()
예제 #22
0
 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)
예제 #23
0
파일: locate.py 프로젝트: wyllys66/PyKMIP
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]
예제 #24
0
    # 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)
예제 #25
0
        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()
예제 #26
0
    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()
예제 #27
0
파일: server.py 프로젝트: wyllys66/PyKMIP
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
예제 #28
0
 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)
예제 #29
0
 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)
예제 #30
0
        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()
예제 #31
0
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]
예제 #32
0
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)
예제 #33
0
파일: create.py 프로젝트: poldridge/PyKMIP
    # 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()
예제 #34
0
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)
예제 #35
0
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)
예제 #36
0
 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)
예제 #37
0
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)
예제 #38
0
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)
예제 #39
0
파일: server.py 프로젝트: nausley/PyKMIP
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