diff --git a/kmip/core/attributes.py b/kmip/core/attributes.py index 8722a58..ac53fce 100644 --- a/kmip/core/attributes.py +++ b/kmip/core/attributes.py @@ -206,7 +206,6 @@ class CryptographicParameters(Struct): enums.BlockCipherMode, value, Tags.BLOCK_CIPHER_MODE) class PaddingMethod(Enumeration): - def __init__(self, value=None): super(CryptographicParameters.PaddingMethod, self).__init__( enums.PaddingMethod, value, Tags.PADDING_METHOD) @@ -274,8 +273,49 @@ class CryptographicParameters(Struct): self.__validate() def __validate(self): - # TODO (peter-hamilton) Finish implementation. - pass + if self.block_cipher_mode is not None: + if not isinstance(self.block_cipher_mode, self.BlockCipherMode): + msg = "Invalid block cipher mode" + msg += "; expected {0}, received {1}".format( + self.BlockCipherMode, self.block_cipher_mode) + raise TypeError(msg) + if self.padding_method is not None: + if not isinstance(self.padding_method, self.PaddingMethod): + msg = "Invalid padding method" + msg += "; expected {0}, received {1}".format( + self.PaddingMethod, self.padding_method) + raise TypeError(msg) + if self.hashing_algorithm is not None: + 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 self.key_role_type is not None: + if not isinstance(self.key_role_type, self.KeyRoleType): + msg = "Invalid key role type" + msg += "; expected {0}, received {1}".format( + self.KeyRoleType, self.key_role_type) + raise TypeError(msg) + + def __eq__(self, other): + if isinstance(other, CryptographicParameters): + if self.block_cipher_mode != other.block_cipher_mode: + return False + elif self.key_role_type != other.key_role_type: + return False + elif self.hashing_algorithm != other.hashing_algorithm: + return False + elif self.padding_method != other.padding_method: + return False + else: + return True + + def __ne__(self, other): + if isinstance(other, CryptographicParameters): + return not self == other + else: + return NotImplemented class CertificateType(Enumeration): diff --git a/kmip/core/factories/attribute_values.py b/kmip/core/factories/attribute_values.py index 20afe4b..d066b17 100644 --- a/kmip/core/factories/attribute_values.py +++ b/kmip/core/factories/attribute_values.py @@ -130,24 +130,30 @@ class AttributeValueFactory(object): def _create_cryptographic_parameters(self, params): bcm = None - if 'block_cipher_mode' in params: - bcm = attributes.CryptographicParameters.BlockCipherMode( - params.get('block_cipher_mode')) - padding_method = None - if 'padding_method' in params: - padding_method = attributes.CryptographicParameters.PaddingMethod( - params.get('padding_method')) - - key_role_type = None - if 'key_role_type' in params: - key_role_type = attributes.CryptographicParameters.KeyRoleType( - params.get('key_role_type')) - hashing_algorithm = None - if 'hashing_algorithm' in params: - hashing_algorithm = attributes.HashingAlgorithm( - params.get("hashing_algorithm")) + key_role_type = None + + if params is not None: + + if 'block_cipher_mode' in params: + bcm = attributes.CryptographicParameters.BlockCipherMode( + params.get('block_cipher_mode')) + + padding_method = None + if 'padding_method' in params: + padding_method = attributes.CryptographicParameters. \ + PaddingMethod(params.get('padding_method')) + + key_role_type = None + if 'key_role_type' in params: + key_role_type = attributes.CryptographicParameters.KeyRoleType( + params.get('key_role_type')) + + hashing_algorithm = None + if 'hashing_algorithm' in params: + hashing_algorithm = attributes.HashingAlgorithm( + params.get("hashing_algorithm")) return attributes.CryptographicParameters( block_cipher_mode=bcm, diff --git a/kmip/core/objects.py b/kmip/core/objects.py index 159f360..43fce3c 100644 --- a/kmip/core/objects.py +++ b/kmip/core/objects.py @@ -49,6 +49,21 @@ class Attribute(Struct): super(Attribute.AttributeName, self).__init__( value, Tags.ATTRIBUTE_NAME) + def __eq__(self, other): + if isinstance(other, Attribute.AttributeName): + if self.value != other.value: + return False + else: + return True + else: + NotImplemented + + def __ne__(self, other): + if isinstance(other, Attribute.AttributeName): + return not (self == other) + else: + return NotImplemented + class AttributeIndex(Integer): def __init__(self, value=None): diff --git a/kmip/tests/unit/core/attributes/test_attributes.py b/kmip/tests/unit/core/attributes/test_attributes.py index 11972cf..5969f1c 100644 --- a/kmip/tests/unit/core/attributes/test_attributes.py +++ b/kmip/tests/unit/core/attributes/test_attributes.py @@ -379,6 +379,7 @@ class TestCryptographicParameters(TestCase): def setUp(self): super(TestCryptographicParameters, self).setUp() + self.bad_enum_code = 8535937 self.factory = AttributeValueFactory() self.cp = self.factory.create_attribute_value( @@ -433,3 +434,54 @@ class TestCryptographicParameters(TestCase): self.cp.hashing_algorithm.tag.value) self.assertEqual(HashingAlgorithmEnum.SHA_1.value, self.cp.hashing_algorithm.value.value) + + def test_bad_cipher_mode(self): + self.cp.block_cipher_mode = self.bad_enum_code + cp_valid = self.factory.create_attribute_value( + AttributeType.CRYPTOGRAPHIC_PARAMETERS, + {'block_cipher_mode': BlockCipherMode.CBC, + 'padding_method': PaddingMethod.PKCS5, + 'hashing_algorithm': HashingAlgorithmEnum.SHA_1, + 'key_role_type': KeyRoleType.BDK}) + self.assertFalse(self.cp == cp_valid) + self.assertRaises(TypeError, self.cp.validate) + + def test_bad_padding_method(self): + self.cp.padding_method = self.bad_enum_code + cp_valid = self.factory.create_attribute_value( + AttributeType.CRYPTOGRAPHIC_PARAMETERS, + {'block_cipher_mode': BlockCipherMode.CBC, + 'padding_method': PaddingMethod.PKCS5, + 'hashing_algorithm': HashingAlgorithmEnum.SHA_1, + 'key_role_type': KeyRoleType.BDK}) + self.assertFalse(self.cp == cp_valid) + self.assertRaises(TypeError, self.cp.validate) + + def test_bad_hash_algorithm(self): + self.cp.hashing_algorithm = self.bad_enum_code + cp_valid = self.factory.create_attribute_value( + AttributeType.CRYPTOGRAPHIC_PARAMETERS, + {'block_cipher_mode': BlockCipherMode.CBC, + 'padding_method': PaddingMethod.PKCS5, + 'hashing_algorithm': HashingAlgorithmEnum.SHA_1, + 'key_role_type': KeyRoleType.BDK}) + self.assertFalse(self.cp == cp_valid) + self.assertRaises(TypeError, self.cp.validate) + + def test_bad_key_role_type(self): + self.cp.key_role_type = self.bad_enum_code + cp_valid = self.factory.create_attribute_value( + AttributeType.CRYPTOGRAPHIC_PARAMETERS, + {'block_cipher_mode': BlockCipherMode.CBC, + 'padding_method': PaddingMethod.PKCS5, + 'hashing_algorithm': HashingAlgorithmEnum.SHA_1, + 'key_role_type': KeyRoleType.BDK}) + self.assertFalse(self.cp == cp_valid) + self.assertRaises(TypeError, self.cp.validate) + + def test_bad_object(self): + name_value = 'puppies' + name_type = NameType.UNINTERPRETED_TEXT_STRING + bad_obj = Name.create(name_value, name_type) + + self.assertNotEqual(NotImplemented, bad_obj) diff --git a/kmip/tests/unit/core/objects/test_objects.py b/kmip/tests/unit/core/objects/test_objects.py index 908f848..fae5f97 100644 --- a/kmip/tests/unit/core/objects/test_objects.py +++ b/kmip/tests/unit/core/objects/test_objects.py @@ -16,13 +16,116 @@ from six import string_types from testtools import TestCase +from kmip.core.enums import AttributeType +from kmip.core.enums import BlockCipherMode +from kmip.core.enums import HashingAlgorithm as HashingAlgorithmEnum +from kmip.core.enums import KeyRoleType +from kmip.core.enums import PaddingMethod from kmip.core.enums import Tags +from kmip.core.factories.attributes import AttributeValueFactory + +from kmip.core.objects import Attribute from kmip.core.objects import ExtensionName from kmip.core.objects import ExtensionTag from kmip.core.objects import ExtensionType from kmip.core.objects import KeyMaterialStruct +from kmip.core.utils import BytearrayStream + + +class TestAttributeClass(TestCase): + """ + A test suite for the Attribute class + """ + + def setUp(self): + super(TestAttributeClass, self).setUp() + + name_a = 'CRYPTOGRAPHIC PARAMETERS' + name_b = 'CRYPTOGRAPHIC ALGORITHM' + + self.attribute_name_a = Attribute.AttributeName(name_a) + self.attribute_name_b = Attribute.AttributeName(name_b) + + self.factory = AttributeValueFactory() + + self.attribute_value_a = self.factory.create_attribute_value( + AttributeType.CRYPTOGRAPHIC_PARAMETERS, + {'block_cipher_mode': BlockCipherMode.CBC, + 'padding_method': PaddingMethod.PKCS5, + 'hashing_algorithm': HashingAlgorithmEnum.SHA_1, + 'key_role_type': KeyRoleType.BDK}) + + self.attribute_value_b = self.factory.create_attribute_value( + AttributeType.CRYPTOGRAPHIC_PARAMETERS, + {'block_cipher_mode': BlockCipherMode.CCM, + 'padding_method': PaddingMethod.PKCS5, + 'hashing_algorithm': HashingAlgorithmEnum.SHA_1, + 'key_role_type': KeyRoleType.BDK}) + + index_a = 2 + index_b = 3 + + self.attribute_index_a = Attribute.AttributeIndex(index_a) + self.attribute_index_b = Attribute.AttributeIndex(index_b) + + self.attributeObj_a = Attribute( + attribute_name=self.attribute_name_a, + attribute_value=self.attribute_value_a, + attribute_index=self.attribute_index_a) + + self.attributeObj_b = Attribute( + attribute_name=self.attribute_name_b, + attribute_value=self.attribute_value_a, + attribute_index=self.attribute_index_a) + + self.attributeObj_c = Attribute( + attribute_name=self.attribute_name_a, + attribute_value=self.attribute_value_b, + attribute_index=self.attribute_index_a) + + self.attributeObj_d = Attribute( + attribute_name=self.attribute_name_a, + attribute_value=self.attribute_value_a, + attribute_index=self.attribute_index_b) + + self.key_req_with_crypt_params = BytearrayStream(( + b'\x42\x00\x08\x01\x00\x00\x00\x78\x42\x00\x0a\x07\x00\x00\x00\x18' + b'\x43\x52\x59\x50\x54\x4f\x47\x52\x41\x50\x48\x49\x43\x20\x50\x41' + b'\x52\x41\x4d\x45\x54\x45\x52\x53' + b'\x42\x00\x09\x02\x00\x00\x00\x04\x00\x00\x00\x02\x00\x00\x00\x00' + b'\x42\x00\x0b\x01\x00\x00\x00\x40' + b'\x42\x00\x11\x05\x00\x00\x00\x04\x00\x00\x00\x01\x00\x00\x00\x00' + b'\x42\x00\x5f\x05\x00\x00\x00\x04\x00\x00\x00\x03\x00\x00\x00\x00' + b'\x42\x00\x38\x05\x00\x00\x00\x04\x00\x00\x00\x04\x00\x00\x00\x00' + b'\x42\x00\x83\x05\x00\x00\x00\x04\x00\x00\x00\x01\x00\x00\x00\x00' + )) + + def tearDown(self): + super(TestAttributeClass, self).tearDown() + + def test_read(self): + attrObj = Attribute() + attrObj.read(self.key_req_with_crypt_params) + self.assertEqual(self.attributeObj_a, attrObj) + + def test_write(self): + attrObj = Attribute(self.attribute_name_a, self.attribute_index_a, + self.attribute_value_a) + ostream = BytearrayStream() + attrObj.write(ostream) + + self.assertEqual(self.key_req_with_crypt_params, ostream) + + def test_equal_on_equal(self): + self.assertFalse(self.attributeObj_a == self.attributeObj_b) + self.assertFalse(self.attributeObj_a == self.attributeObj_c) + self.assertFalse(self.attributeObj_a == self.attributeObj_d) + + def test_not_equal_on_not_equal(self): + self.assertTrue(self.attributeObj_a != self.attributeObj_b) + class TestKeyMaterialStruct(TestCase): """