Пример #1
0
    def __init__(self,
                 hashing_algorithm=None,
                 digest_value=None,
                 key_format_type=None):
        """
        Construct a Digest object.

        Args:
            hashing_algorithm (HashingAlgorithm): The hash algorithm used to
                compute the value of the digest. Optional, defaults to None.
            digest_value (DigestValue): The byte string representing the
                value of the hash digest. Optional, defaults to None.
            key_format_type (KeyFormatType): The format type of the key the
                hash was computed for, if the object in question is a key.
                Optional, defaults to None.
        """
        super(Digest, self).__init__(Tags.DIGEST)

        if hashing_algorithm is None:
            self.hashing_algorithm = HashingAlgorithm()
        else:
            self.hashing_algorithm = hashing_algorithm

        if digest_value is None:
            self.digest_value = DigestValue()
        else:
            self.digest_value = digest_value

        if key_format_type is None:
            self.key_format_type = KeyFormatType()
        else:
            self.key_format_type = key_format_type

        self.validate()
Пример #2
0
    def read(self, istream):
        super(KeyBlock, self).read(istream)
        tstream = BytearrayStream(istream.read(self.length))

        self.key_format_type = KeyFormatType()
        self.key_format_type.read(tstream)

        if self.is_tag_next(Tags.KEY_COMPRESSION_TYPE, tstream):
            self.key_compression_type = KeyBlock.KeyCompressionType()
            self.key_compression_type.read(tstream)

        self.key_value = KeyValue()
        self.key_value.read(tstream)

        if self.is_tag_next(Tags.CRYPTOGRAPHIC_ALGORITHM, tstream):
            self.cryptographic_algorithm = attributes.CryptographicAlgorithm()
            self.cryptographic_algorithm.read(tstream)

        if self.is_tag_next(Tags.CRYPTOGRAPHIC_LENGTH, tstream):
            self.cryptographic_length = attributes.CryptographicLength()
            self.cryptographic_length.read(tstream)

        if self.is_tag_next(Tags.KEY_WRAPPING_DATA, tstream):
            self.key_wrapping_data = KeyWrappingData()
            self.key_wrapping_data.read(tstream)

        self.is_oversized(tstream)
        self.validate()
Пример #3
0
    def __init__(self,
                 hashing_algorithm=None,
                 digest_value=None,
                 key_format_type=None):
        """
        Construct a Digest object.

        Args:
            hashing_algorithm (HashingAlgorithm): The hash algorithm used to
                compute the value of the digest. Optional, defaults to None.
            digest_value (DigestValue): The byte string representing the
                value of the hash digest. Optional, defaults to None.
            key_format_type (KeyFormatType): The format type of the key the
                hash was computed for, if the object in question is a key.
                Optional, defaults to None.
        """
        super(Digest, self).__init__(Tags.DIGEST)

        if hashing_algorithm is None:
            self.hashing_algorithm = HashingAlgorithm()
        else:
            self.hashing_algorithm = hashing_algorithm

        if digest_value is None:
            self.digest_value = DigestValue()
        else:
            self.digest_value = digest_value

        if key_format_type is None:
            self.key_format_type = KeyFormatType()
        else:
            self.key_format_type = key_format_type

        self.validate()
Пример #4
0
    def _build_key_block(self, value):
        key_type = value.get('key_format_type')
        key_compression_type = value.get('key_compression_type')
        key_value = value.get('key_value')
        cryptographic_algorithm = value.get('cryptographic_algorithm')
        cryptographic_length = value.get('cryptographic_length')
        key_wrapping_data = value.get('key_wrapping_data')

        key_format_type = KeyFormatType(key_type)

        key_comp_type = None
        if key_compression_type is not None:
            key_comp_type = KeyBlock.KeyCompressionType(key_compression_type)

        key_material = KeyMaterial(key_value)
        key_value = KeyValue(key_material)

        crypto_algorithm = None
        if cryptographic_algorithm is not None:
            crypto_algorithm = CryptographicAlgorithm(cryptographic_algorithm)

        crypto_length = None
        if cryptographic_length is not None:
            crypto_length = CryptographicLength(cryptographic_length)

        key_wrap_data = None
        if key_wrapping_data:
            # TODO (peter-hamilton) This currently isn't used in the tests
            # TODO (peter-hamilton) but needs to be updated to properly
            # TODO (peter-hamilton) create a KeyWrappingData object.
            key_wrap_data = KeyWrappingData(**key_wrapping_data)

        key_block = KeyBlock(key_format_type, key_comp_type, key_value,
                             crypto_algorithm, crypto_length, key_wrap_data)
        return key_block
Пример #5
0
    def read(self, istream):
        super(self.__class__, self).read(istream)
        tstream = BytearrayStream(istream.read(self.length))

        self.key_format_type = KeyFormatType()
        self.key_format_type.read(tstream)

        if self.is_tag_next(Tags.KEY_COMPRESSION_TYPE, tstream):
            self.key_compression_type = KeyBlock.KeyCompressionType()
            self.key_compression_type.read(tstream)

        self.key_value = KeyValue()
        self.key_value.read(tstream)

        if self.is_tag_next(Tags.CRYPTOGRAPHIC_ALGORITHM, tstream):
            self.cryptographic_algorithm = attributes.CryptographicAlgorithm()
            self.cryptographic_algorithm.read(tstream)

        if self.is_tag_next(Tags.CRYPTOGRAPHIC_LENGTH, tstream):
            self.cryptographic_length = attributes.CryptographicLength()
            self.cryptographic_length.read(tstream)

        if self.is_tag_next(Tags.KEY_WRAPPING_DATA, tstream):
            self.key_wrapping_data = KeyWrappingData()
            self.key_wrapping_data.read(tstream)

        self.is_oversized(tstream)
        self.validate()
Пример #6
0
 def test_get_no_uuid(self):
     self._create()
     key_format_type = KeyFormatType(KeyFormatTypeEnum.RAW)
     res = self.kmip.get(None, key_format_type)
     self.assertEqual(ResultStatus.OPERATION_FAILED,
                      res.result_status.value,
                      'result status did not return failed')
Пример #7
0
 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)
Пример #8
0
    def _test_init(self, value):
        if (isinstance(value, KeyFormatTypeEnum)) or (value is None):
            key_format_type = KeyFormatType(value)

            msg = "expected {0}, observed {1}".format(value,
                                                      key_format_type.value)
            self.assertEqual(value, key_format_type.value, msg)
        else:
            self.assertRaises(TypeError, KeyFormatType, value)
Пример #9
0
 def test_get_unknown(self):
     uuids = ('some random string', UniqueIdentifier('no key here'))
     for uuid in uuids:
         key_format_type = KeyFormatType(KeyFormatTypeEnum.RAW)
         res = self.kmip.get(uuid, key_format_type)
         self.assertEqual(ResultStatus.OPERATION_FAILED,
                          res.result_status.value,
                          'result status did not return failed')
         self.assertEqual(ResultReason.ITEM_NOT_FOUND,
                          res.result_reason.value,
                          'result reason did not match')
Пример #10
0
def build_key_block(key_format_type, key_value, cryptographic_algorithm,
                    cryptographic_length):
    key_material = KeyMaterial(key_value)
    key_value = KeyValue(key_material)

    return KeyBlock(key_format_type=KeyFormatType(key_format_type),
                    key_compression_type=None,
                    key_value=key_value,
                    cryptographic_algorithm=cryptographic_algorithm,
                    cryptographic_length=cryptographic_length,
                    key_wrapping_data=None)
Пример #11
0
 def _get_symmetric_key(self):
     # only need usage attribute
     attrs = [self._get_attrs()[1]]
     key_format_type = KeyFormatType(KeyFormatTypeEnum.RAW)
     key_material = KeyMaterial(self.key)
     key_value = KeyValue(key_material, attrs)
     crypto_alg = CryptographicAlgorithm(self.algorithm_name)
     crypto_length = CryptographicLength(self.key_length)
     usage = CryptographicUsageMask(self.usage_mask)
     key_block = KeyBlock(key_format_type, None, key_value, crypto_alg,
                          crypto_length, usage)
     return SymmetricKey(key_block)
Пример #12
0
 def test_get_with_key_compression(self):
     uuid = self._create()
     key_format_type = KeyFormatType(KeyFormatTypeEnum.RAW)
     key_compression = KeyCompressionType(KeyCompressionTypeEnum.
                                          EC_PUBLIC_KEY_TYPE_UNCOMPRESSED)
     res = self.kmip.get(uuid, key_format_type, key_compression)
     self.assertEqual(ResultStatus.OPERATION_FAILED,
                      res.result_status.value,
                      'result status did not return failed')
     self.assertEqual(ResultReason.KEY_COMPRESSION_TYPE_NOT_SUPPORTED,
                      res.result_reason.value,
                      'result reason did not match')
Пример #13
0
    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)
Пример #14
0
 def test_destroy(self):
     uuid = self._create()
     key_format_type = KeyFormatType(KeyFormatTypeEnum.RAW)
     res = self.kmip.get(uuid, key_format_type)
     self.assertEqual(ResultStatus.SUCCESS, res.result_status.value,
                      'result status did not return success')
     res = self.kmip.destroy(uuid)
     self.assertEqual(ResultStatus.SUCCESS, res.result_status.value,
                      'result status did not return success')
     res = self.kmip.destroy(uuid)
     self.assertEqual(ResultStatus.OPERATION_FAILED,
                      res.result_status.value,
                      'result status did not return failed')
     self.assertEqual(ResultReason.ITEM_NOT_FOUND,
                      res.result_reason.value,
                      'result reason did not match')
Пример #15
0
    def create(cls,
               hashing_algorithm=HashingAlgorithmEnum.SHA_256,
               digest_value=b'',
               key_format_type=KeyFormatTypeEnum.RAW):
        """
        Construct a Digest object from provided digest values.

        Args:
            hashing_algorithm (HashingAlgorithm): An enumeration representing
                the hash algorithm used to compute the digest. Optional,
                defaults to HashingAlgorithm.SHA_256.
            digest_value (byte string): The bytes of the digest hash. Optional,
                defaults to the empty byte string.
            key_format_type (KeyFormatType): An enumeration representing the
                format of the key corresponding to the digest. Optional,
                defaults to KeyFormatType.RAW.

        Returns:
            Digest: The newly created Digest.

        Example:
            >>> x = Digest.create(HashingAlgorithm.MD5, b'\x00',
            ... KeyFormatType.RAW)
            >>> x.hashing_algorithm
            HashingAlgorithm(value=HashingAlgorithm.MD5)
            >>> x.digest_value
            DigestValue(value=bytearray(b'\x00'))
            >>> x.key_format_type
            KeyFormatType(value=KeyFormatType.RAW)
        """
        algorithm = HashingAlgorithm(hashing_algorithm)
        value = DigestValue(bytearray(digest_value))
        format_type = KeyFormatType(key_format_type)

        return Digest(hashing_algorithm=algorithm,
                      digest_value=value,
                      key_format_type=format_type)
Пример #16
0
    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)
Пример #17
0
    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)
Пример #18
0
    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)
Пример #19
0
    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)
Пример #20
0
    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)
Пример #21
0
 def test_get(self):
     uuid = self._create()
     key_format_type = KeyFormatType(KeyFormatTypeEnum.RAW)
     res = self.kmip.get(uuid, key_format_type)
     self.assertEqual(ResultStatus.SUCCESS, res.result_status.value,
                      'result status did not return success')
Пример #22
0
class KeyBlock(Struct):

    class KeyCompressionType(Enumeration):

        def __init__(self, value=None):
            super(KeyBlock.KeyCompressionType, self).__init__(
                enums.KeyCompressionType, value, Tags.KEY_COMPRESSION_TYPE)

    def __init__(self,
                 key_format_type=None,
                 key_compression_type=None,
                 key_value=None,
                 cryptographic_algorithm=None,
                 cryptographic_length=None,
                 key_wrapping_data=None):
        super(KeyBlock, self).__init__(Tags.KEY_BLOCK)
        self.key_format_type = key_format_type
        self.key_compression_type = key_compression_type
        self.key_value = key_value
        self.cryptographic_algorithm = cryptographic_algorithm
        self.cryptographic_length = cryptographic_length
        self.key_wrapping_data = key_wrapping_data
        self.validate()

    def read(self, istream):
        super(KeyBlock, self).read(istream)
        tstream = BytearrayStream(istream.read(self.length))

        self.key_format_type = KeyFormatType()
        self.key_format_type.read(tstream)

        if self.is_tag_next(Tags.KEY_COMPRESSION_TYPE, tstream):
            self.key_compression_type = KeyBlock.KeyCompressionType()
            self.key_compression_type.read(tstream)

        self.key_value = KeyValue()
        self.key_value.read(tstream)

        if self.is_tag_next(Tags.CRYPTOGRAPHIC_ALGORITHM, tstream):
            self.cryptographic_algorithm = attributes.CryptographicAlgorithm()
            self.cryptographic_algorithm.read(tstream)

        if self.is_tag_next(Tags.CRYPTOGRAPHIC_LENGTH, tstream):
            self.cryptographic_length = attributes.CryptographicLength()
            self.cryptographic_length.read(tstream)

        if self.is_tag_next(Tags.KEY_WRAPPING_DATA, tstream):
            self.key_wrapping_data = KeyWrappingData()
            self.key_wrapping_data.read(tstream)

        self.is_oversized(tstream)
        self.validate()

    def write(self, ostream):
        tstream = BytearrayStream()

        self.key_format_type.write(tstream)

        if self.key_compression_type is not None:
            self.key_compression_type.write(tstream)

        self.key_value.write(tstream)

        if self.cryptographic_algorithm is not None:
            self.cryptographic_algorithm.write(tstream)
        if self.cryptographic_length is not None:
            self.cryptographic_length.write(tstream)
        if self.key_wrapping_data is not None:
            self.key_wrapping_data.write(tstream)

        # Write the length and value of the credential
        self.length = tstream.length()
        super(KeyBlock, self).write(ostream)
        ostream.write(tstream.buffer)

    def validate(self):
        self.__validate()

    def __validate(self):
        if self.key_format_type is not None:
            if type(self.key_format_type) is not KeyFormatType:
                member = 'KeyBlock.key_format_type'
                exp_type = KeyFormatType
                rcv_type = type(self.key_format_type)
                msg = ErrorStrings.BAD_EXP_RECV.format(member, 'type',
                                                       exp_type, rcv_type)
                raise TypeError(msg)
Пример #23
0
    attribute_factory = AttributeFactory()
    credential_factory = CredentialFactory()

    # Build the KMIP server account credentials
    # TODO (peter-hamilton) Move up into KMIPProxy
    if (username is None) and (password is None):
        credential = None
    else:
        credential_type = CredentialType.USERNAME_AND_PASSWORD
        credential_value = {'Username': username, 'Password': password}
        credential = credential_factory.create_credential(
            credential_type, credential_value)

    key_format_type = None
    if format_type_enum is not None:
        key_format_type = KeyFormatType(format_type_enum)

    # Build the client and connect to the server
    client = KMIPProxy(config=config, config_file=opts.config_file)
    client.open()

    # Retrieve the SYMMETRIC_KEY object
    result = client.get(uuid=uuid,
                        key_format_type=key_format_type,
                        credential=credential)
    client.close()

    # Display operation results
    logger.info('get() result status: {0}'.format(result.result_status.value))

    if result.result_status.value == ResultStatus.SUCCESS:
Пример #24
0
class KeyBlock(Struct):

    class KeyCompressionType(Enumeration):
        ENUM_TYPE = enums.KeyCompressionType

        def __init__(self, value=None):
            super(self.__class__, self).__init__(value,
                                                 Tags.KEY_COMPRESSION_TYPE)

    def __init__(self,
                 key_format_type=None,
                 key_compression_type=None,
                 key_value=None,
                 cryptographic_algorithm=None,
                 cryptographic_length=None,
                 key_wrapping_data=None):
        super(self.__class__, self).__init__(Tags.KEY_BLOCK)
        self.key_format_type = key_format_type
        self.key_compression_type = key_compression_type
        self.key_value = key_value
        self.cryptographic_algorithm = cryptographic_algorithm
        self.cryptographic_length = cryptographic_length
        self.key_wrapping_data = key_wrapping_data
        self.validate()

    def read(self, istream):
        super(self.__class__, self).read(istream)
        tstream = BytearrayStream(istream.read(self.length))

        self.key_format_type = KeyFormatType()
        self.key_format_type.read(tstream)

        if self.is_tag_next(Tags.KEY_COMPRESSION_TYPE, tstream):
            self.key_compression_type = KeyBlock.KeyCompressionType()
            self.key_compression_type.read(tstream)

        self.key_value = KeyValue()
        self.key_value.read(tstream)

        if self.is_tag_next(Tags.CRYPTOGRAPHIC_ALGORITHM, tstream):
            self.cryptographic_algorithm = attributes.CryptographicAlgorithm()
            self.cryptographic_algorithm.read(tstream)

        if self.is_tag_next(Tags.CRYPTOGRAPHIC_LENGTH, tstream):
            self.cryptographic_length = attributes.CryptographicLength()
            self.cryptographic_length.read(tstream)

        if self.is_tag_next(Tags.KEY_WRAPPING_DATA, tstream):
            self.key_wrapping_data = KeyWrappingData()
            self.key_wrapping_data.read(tstream)

        self.is_oversized(tstream)
        self.validate()

    def write(self, ostream):
        tstream = BytearrayStream()

        self.key_format_type.write(tstream)

        if self.key_compression_type is not None:
            self.key_compression_type.write(tstream)

        self.key_value.write(tstream)

        if self.cryptographic_algorithm is not None:
            self.cryptographic_algorithm.write(tstream)
        if self.cryptographic_length is not None:
            self.cryptographic_length.write(tstream)
        if self.key_wrapping_data is not None:
            self.key_wrapping_data.write(tstream)

        # Write the length and value of the credential
        self.length = tstream.length()
        super(self.__class__, self).write(ostream)
        ostream.write(tstream.buffer)

    def validate(self):
        self.__validate()

    def __validate(self):
        if self.key_format_type is not None:
            if type(self.key_format_type) is not KeyFormatType:
                member = 'KeyBlock.key_format_type'
                exp_type = KeyFormatType
                rcv_type = type(self.key_format_type)
                msg = ErrorStrings.BAD_EXP_RECV.format(member, 'type',
                                                       exp_type, rcv_type)
                raise TypeError(msg)
Пример #25
0
class Digest(Struct):
    """
    A structure storing a hash digest of a Managed Object.

    Digests may be calculated for keys, secret data objects, certificates, and
    opaque data objects and are generated when the object is created or
    registered with the KMIP server. See Section 3.17 of the KMIP 1.1
    specification for more information.

    Attributes:
        hashing_algorithm: The algorithm used to compute the hash digest.
        digest_value: The bytes representing the hash digest value.
        key_format_type: The type of the key the hash was generated for.
    """

    def __init__(self,
                 hashing_algorithm=None,
                 digest_value=None,
                 key_format_type=None):
        """
        Construct a Digest object.

        Args:
            hashing_algorithm (HashingAlgorithm): The hash algorithm used to
                compute the value of the digest. Optional, defaults to None.
            digest_value (DigestValue): The byte string representing the
                value of the hash digest. Optional, defaults to None.
            key_format_type (KeyFormatType): The format type of the key the
                hash was computed for, if the object in question is a key.
                Optional, defaults to None.
        """
        super(Digest, self).__init__(Tags.DIGEST)

        if hashing_algorithm is None:
            self.hashing_algorithm = HashingAlgorithm()
        else:
            self.hashing_algorithm = hashing_algorithm

        if digest_value is None:
            self.digest_value = DigestValue()
        else:
            self.digest_value = digest_value

        if key_format_type is None:
            self.key_format_type = KeyFormatType()
        else:
            self.key_format_type = key_format_type

        self.validate()

    def read(self, istream):
        """
        Read the data encoding the Digest object and decode it into its
        constituent parts.

        Args:
            istream (Stream): A data stream containing encoded object data,
                supporting a read method; usually a BytearrayStream object.
        """
        super(Digest, self).read(istream)
        tstream = BytearrayStream(istream.read(self.length))

        self.hashing_algorithm.read(tstream)
        self.digest_value.read(tstream)
        self.key_format_type.read(tstream)

        self.is_oversized(tstream)
        self.validate()

    def write(self, ostream):
        """
        Write the data encoding the Digest object to a stream.

        Args:
            ostream (Stream): A data stream in which to encode object data,
                supporting a write method; usually a BytearrayStream object.
        """
        tstream = BytearrayStream()

        self.hashing_algorithm.write(tstream)
        self.digest_value.write(tstream)
        self.key_format_type.write(tstream)

        self.length = tstream.length()
        super(Digest, self).write(ostream)
        ostream.write(tstream.buffer)

    def validate(self):
        """
        Error check the attributes of the Digest object.
        """
        self.__validate()

    def __validate(self):
        # TODO (peter-hamilton) Add checks comparing the length of the digest
        # value against the standard length for the stated hashing algorithm.
        if not isinstance(self.hashing_algorithm, HashingAlgorithm):
            msg = "invalid hashing algorithm"
            msg += "; expected {0}, received {1}".format(
                HashingAlgorithm, self.hashing_algorithm)
            raise TypeError(msg)

        if not isinstance(self.digest_value, DigestValue):
            msg = "invalid digest value"
            msg += "; expected {0}, received {1}".format(
                DigestValue, self.digest_value)
            raise TypeError(msg)

        if not isinstance(self.key_format_type, KeyFormatType):
            msg = "invalid key format type"
            msg += "; expected {0}, received {1}".format(
                KeyFormatType, self.key_format_type)
            raise TypeError(msg)

    def __eq__(self, other):
        if isinstance(other, Digest):
            if self.hashing_algorithm != other.hashing_algorithm:
                return False
            elif self.digest_value != other.digest_value:
                return False
            elif self.key_format_type != other.key_format_type:
                return False
            else:
                return True
        else:
            return NotImplemented

    def __ne__(self, other):
        if isinstance(other, Digest):
            return not (self == other)
        else:
            return NotImplemented

    def __repr__(self):
        hashing_algorithm = "hashing_algorithm={0}".format(
            repr(self.hashing_algorithm))
        digest_value = "digest_value={0}".format(
            repr(self.digest_value))
        key_format_type = "key_format_type={0}".format(
            repr(self.key_format_type))

        return "Digest({0}, {1}, {2})".format(
            hashing_algorithm, digest_value, key_format_type)

    def __str__(self):
        return str(self.digest_value)

    @classmethod
    def create(cls,
               hashing_algorithm=HashingAlgorithmEnum.SHA_256,
               digest_value=b'',
               key_format_type=KeyFormatTypeEnum.RAW):
        """
        Construct a Digest object from provided digest values.

        Args:
            hashing_algorithm (HashingAlgorithm): An enumeration representing
                the hash algorithm used to compute the digest. Optional,
                defaults to HashingAlgorithm.SHA_256.
            digest_value (byte string): The bytes of the digest hash. Optional,
                defaults to the empty byte string.
            key_format_type (KeyFormatType): An enumeration representing the
                format of the key corresponding to the digest. Optional,
                defaults to KeyFormatType.RAW.

        Returns:
            Digest: The newly created Digest.

        Example:
            >>> x = Digest.create(HashingAlgorithm.MD5, b'\x00',
            ... KeyFormatType.RAW)
            >>> x.hashing_algorithm
            HashingAlgorithm(value=HashingAlgorithm.MD5)
            >>> x.digest_value
            DigestValue(value=bytearray(b'\x00'))
            >>> x.key_format_type
            KeyFormatType(value=KeyFormatType.RAW)
        """
        algorithm = HashingAlgorithm(hashing_algorithm)
        value = DigestValue(bytearray(digest_value))
        format_type = KeyFormatType(key_format_type)

        return Digest(hashing_algorithm=algorithm,
                      digest_value=value,
                      key_format_type=format_type)
Пример #26
0
class Digest(Struct):
    """
    A structure storing a hash digest of a Managed Object.

    Digests may be calculated for keys, secret data objects, certificates, and
    opaque data objects and are generated when the object is created or
    registered with the KMIP server. See Section 3.17 of the KMIP 1.1
    specification for more information.

    Attributes:
        hashing_algorithm: The algorithm used to compute the hash digest.
        digest_value: The bytes representing the hash digest value.
        key_format_type: The type of the key the hash was generated for.
    """

    def __init__(self,
                 hashing_algorithm=None,
                 digest_value=None,
                 key_format_type=None):
        """
        Construct a Digest object.

        Args:
            hashing_algorithm (HashingAlgorithm): The hash algorithm used to
                compute the value of the digest. Optional, defaults to None.
            digest_value (DigestValue): The byte string representing the
                value of the hash digest. Optional, defaults to None.
            key_format_type (KeyFormatType): The format type of the key the
                hash was computed for, if the object in question is a key.
                Optional, defaults to None.
        """
        super(Digest, self).__init__(Tags.DIGEST)

        if hashing_algorithm is None:
            self.hashing_algorithm = HashingAlgorithm()
        else:
            self.hashing_algorithm = hashing_algorithm

        if digest_value is None:
            self.digest_value = DigestValue()
        else:
            self.digest_value = digest_value

        if key_format_type is None:
            self.key_format_type = KeyFormatType()
        else:
            self.key_format_type = key_format_type

        self.validate()

    def read(self, istream):
        """
        Read the data encoding the Digest object and decode it into its
        constituent parts.

        Args:
            istream (Stream): A data stream containing encoded object data,
                supporting a read method; usually a BytearrayStream object.
        """
        super(Digest, self).read(istream)
        tstream = BytearrayStream(istream.read(self.length))

        self.hashing_algorithm.read(tstream)
        self.digest_value.read(tstream)
        self.key_format_type.read(tstream)

        self.is_oversized(tstream)
        self.validate()

    def write(self, ostream):
        """
        Write the data encoding the Digest object to a stream.

        Args:
            ostream (Stream): A data stream in which to encode object data,
                supporting a write method; usually a BytearrayStream object.
        """
        tstream = BytearrayStream()

        self.hashing_algorithm.write(tstream)
        self.digest_value.write(tstream)
        self.key_format_type.write(tstream)

        self.length = tstream.length()
        super(Digest, self).write(ostream)
        ostream.write(tstream.buffer)

    def validate(self):
        """
        Error check the attributes of the Digest object.
        """
        self.__validate()

    def __validate(self):
        # TODO (peter-hamilton) Add checks comparing the length of the digest
        # value against the standard length for the stated hashing algorithm.
        if not isinstance(self.hashing_algorithm, HashingAlgorithm):
            msg = "invalid hashing algorithm"
            msg += "; expected {0}, received {1}".format(
                HashingAlgorithm, self.hashing_algorithm)
            raise TypeError(msg)

        if not isinstance(self.digest_value, DigestValue):
            msg = "invalid digest value"
            msg += "; expected {0}, received {1}".format(
                DigestValue, self.digest_value)
            raise TypeError(msg)

        if not isinstance(self.key_format_type, KeyFormatType):
            msg = "invalid key format type"
            msg += "; expected {0}, received {1}".format(
                KeyFormatType, self.key_format_type)
            raise TypeError(msg)

    def __eq__(self, other):
        if isinstance(other, Digest):
            if self.hashing_algorithm != other.hashing_algorithm:
                return False
            elif self.digest_value != other.digest_value:
                return False
            elif self.key_format_type != other.key_format_type:
                return False
            else:
                return True
        else:
            return NotImplemented

    def __ne__(self, other):
        if isinstance(other, Digest):
            return not (self == other)
        else:
            return NotImplemented

    def __repr__(self):
        hashing_algorithm = "hashing_algorithm={0}".format(
            repr(self.hashing_algorithm))
        digest_value = "digest_value={0}".format(
            repr(self.digest_value))
        key_format_type = "key_format_type={0}".format(
            repr(self.key_format_type))

        return "Digest({0}, {1}, {2})".format(
            hashing_algorithm, digest_value, key_format_type)

    def __str__(self):
        return str(self.digest_value)

    @classmethod
    def create(cls,
               hashing_algorithm=HashingAlgorithmEnum.SHA_256,
               digest_value=b'',
               key_format_type=KeyFormatTypeEnum.RAW):
        """
        Construct a Digest object from provided digest values.

        Args:
            hashing_algorithm (HashingAlgorithm): An enumeration representing
                the hash algorithm used to compute the digest. Optional,
                defaults to HashingAlgorithm.SHA_256.
            digest_value (byte string): The bytes of the digest hash. Optional,
                defaults to the empty byte string.
            key_format_type (KeyFormatType): An enumeration representing the
                format of the key corresponding to the digest. Optional,
                defaults to KeyFormatType.RAW.

        Returns:
            Digest: The newly created Digest.

        Example:
            >>> x = Digest.create(HashingAlgorithm.MD5, b'\x00',
            ... KeyFormatType.RAW)
            >>> x.hashing_algorithm
            HashingAlgorithm(value=HashingAlgorithm.MD5)
            >>> x.digest_value
            DigestValue(value=bytearray(b'\x00'))
            >>> x.key_format_type
            KeyFormatType(value=KeyFormatType.RAW)
        """
        algorithm = HashingAlgorithm(hashing_algorithm)
        value = DigestValue(bytearray(digest_value))
        format_type = KeyFormatType(key_format_type)

        return Digest(hashing_algorithm=algorithm,
                      digest_value=value,
                      key_format_type=format_type)