From 950e98569e1076908e7fdbb4dc27c6ab3c6b6c1a Mon Sep 17 00:00:00 2001 From: Peter Hamilton Date: Wed, 11 Apr 2018 21:43:07 -0400 Subject: [PATCH] Fix cryptographic usage mask handling for CreateKeyPair This change fixes how the ProxyKmipClient handles cryptographic usage mask values for the CreateKeyPair operation. Originally, both Encrypt and Decrypt were set by default for both public and private keys. This is incorrect behavior for certain algorithms. Now, only the masks specified by the caller are set on the key pair. Fixes #412 --- kmip/core/objects.py | 2 ++ kmip/pie/client.py | 25 +++++++++---- .../services/test_proxykmipclient.py | 6 +++- kmip/tests/unit/pie/test_client.py | 35 ++++++------------- 4 files changed, 35 insertions(+), 33 deletions(-) diff --git a/kmip/core/objects.py b/kmip/core/objects.py index 614f35e..195ccb3 100644 --- a/kmip/core/objects.py +++ b/kmip/core/objects.py @@ -2453,6 +2453,8 @@ class TemplateAttribute(Struct): if len(self.attributes) != len(other.attributes): return False + # TODO (peter-hamilton) Allow order independence? + for i in xrange(len(self.names)): a = self.names[i] b = other.names[i] diff --git a/kmip/pie/client.py b/kmip/pie/client.py index c4296cc..6b6aff6 100644 --- a/kmip/pie/client.py +++ b/kmip/pie/client.py @@ -227,13 +227,13 @@ class ProxyKmipClient(object): length (int): The length in bits for the key pair. operation_policy_name (string): The name of the operation policy to use for the new key pair. Optional, defaults to None. - public_name (string): The name to give the public key. - Optional, defaults to None. + public_name (string): The name to give the public key. Optional, + defaults to None. public_usage_mask (list): A list of CryptographicUsageMask enumerations indicating how the public key should be used. Optional, defaults to None. - private_name (string): The name to give the public key. - Optional, defaults to None. + private_name (string): The name to give the public key. Optional, + defaults to None. private_usage_mask (list): A list of CryptographicUsageMask enumerations indicating how the private key should be used. Optional, defaults to None. @@ -258,9 +258,20 @@ class ProxyKmipClient(object): common_attributes = self._build_common_attributes( operation_policy_name ) - key_attributes = self._build_key_attributes(algorithm, length) - key_attributes.extend(common_attributes) - template = cobjects.CommonTemplateAttribute(attributes=key_attributes) + + algorithm_attribute = self.attribute_factory.create_attribute( + enums.AttributeType.CRYPTOGRAPHIC_ALGORITHM, + algorithm + ) + length_attribute = self.attribute_factory.create_attribute( + enums.AttributeType.CRYPTOGRAPHIC_LENGTH, + length + ) + + common_attributes.extend([algorithm_attribute, length_attribute]) + template = cobjects.CommonTemplateAttribute( + attributes=common_attributes + ) # Create public / private specific attributes public_template = None diff --git a/kmip/tests/integration/services/test_proxykmipclient.py b/kmip/tests/integration/services/test_proxykmipclient.py index 3c195af..652af68 100644 --- a/kmip/tests/integration/services/test_proxykmipclient.py +++ b/kmip/tests/integration/services/test_proxykmipclient.py @@ -181,7 +181,11 @@ class TestProxyKmipClientIntegration(testtools.TestCase): asymmetric key pair. """ public_uid, private_uid = self.client.create_key_pair( - enums.CryptographicAlgorithm.RSA, 2048) + enums.CryptographicAlgorithm.RSA, + 2048, + public_usage_mask=[enums.CryptographicUsageMask.ENCRYPT], + private_usage_mask=[enums.CryptographicUsageMask.DECRYPT] + ) self.assertIsInstance(public_uid, six.string_types) self.assertIsInstance(private_uid, six.string_types) diff --git a/kmip/tests/unit/pie/test_client.py b/kmip/tests/unit/pie/test_client.py index e3fb6fc..bb2cfcc 100644 --- a/kmip/tests/unit/pie/test_client.py +++ b/kmip/tests/unit/pie/test_client.py @@ -450,12 +450,8 @@ class TestProxyKmipClient(testtools.TestCase): enums.AttributeType.CRYPTOGRAPHIC_ALGORITHM, algorithm) length_attribute = self.attribute_factory.create_attribute( enums.AttributeType.CRYPTOGRAPHIC_LENGTH, length) - mask_attribute = self.attribute_factory.create_attribute( - enums.AttributeType.CRYPTOGRAPHIC_USAGE_MASK, - [enums.CryptographicUsageMask.ENCRYPT, - enums.CryptographicUsageMask.DECRYPT]) - attributes = [algorithm_attribute, length_attribute, mask_attribute] + attributes = [algorithm_attribute, length_attribute] template = obj.CommonTemplateAttribute(attributes=attributes) status = enums.ResultStatus.SUCCESS @@ -470,7 +466,9 @@ class TestProxyKmipClient(testtools.TestCase): client.proxy.create_key_pair.return_value = result public_uid, private_uid = client.create_key_pair( - enums.CryptographicAlgorithm.RSA, 2048) + enums.CryptographicAlgorithm.RSA, + 2048 + ) kwargs = {'common_template_attribute': template, 'private_key_template_attribute': None, @@ -494,20 +492,15 @@ class TestProxyKmipClient(testtools.TestCase): enums.AttributeType.CRYPTOGRAPHIC_ALGORITHM, algorithm) length_attribute = self.attribute_factory.create_attribute( enums.AttributeType.CRYPTOGRAPHIC_LENGTH, length) - mask_attribute = self.attribute_factory.create_attribute( - enums.AttributeType.CRYPTOGRAPHIC_USAGE_MASK, - [enums.CryptographicUsageMask.ENCRYPT, - enums.CryptographicUsageMask.DECRYPT]) opn_attribute = self.attribute_factory.create_attribute( enums.AttributeType.OPERATION_POLICY_NAME, 'test' ) pair_attributes = [ + opn_attribute, algorithm_attribute, - length_attribute, - mask_attribute, - opn_attribute + length_attribute ] template = obj.CommonTemplateAttribute(attributes=pair_attributes) @@ -548,10 +541,6 @@ class TestProxyKmipClient(testtools.TestCase): enums.AttributeType.CRYPTOGRAPHIC_ALGORITHM, algorithm) length_attribute = self.attribute_factory.create_attribute( enums.AttributeType.CRYPTOGRAPHIC_LENGTH, length) - mask_attribute = self.attribute_factory.create_attribute( - enums.AttributeType.CRYPTOGRAPHIC_USAGE_MASK, - [enums.CryptographicUsageMask.ENCRYPT, - enums.CryptographicUsageMask.DECRYPT]) private_name_attribute = self.attribute_factory.create_attribute( enums.AttributeType.NAME, "private") @@ -560,8 +549,8 @@ class TestProxyKmipClient(testtools.TestCase): pair_attributes = [ algorithm_attribute, - length_attribute, - mask_attribute] + length_attribute + ] template = obj.CommonTemplateAttribute(attributes=pair_attributes) private_template = obj.PrivateKeyTemplateAttribute( @@ -607,10 +596,6 @@ class TestProxyKmipClient(testtools.TestCase): enums.AttributeType.CRYPTOGRAPHIC_ALGORITHM, algorithm) length_attribute = self.attribute_factory.create_attribute( enums.AttributeType.CRYPTOGRAPHIC_LENGTH, length) - mask_attribute = self.attribute_factory.create_attribute( - enums.AttributeType.CRYPTOGRAPHIC_USAGE_MASK, - [enums.CryptographicUsageMask.ENCRYPT, - enums.CryptographicUsageMask.DECRYPT]) private_usage_mask = self.attribute_factory.create_attribute( enums.AttributeType.CRYPTOGRAPHIC_USAGE_MASK, @@ -623,8 +608,8 @@ class TestProxyKmipClient(testtools.TestCase): pair_attributes = [ algorithm_attribute, - length_attribute, - mask_attribute] + length_attribute + ] template = obj.CommonTemplateAttribute(attributes=pair_attributes) private_template = obj.PrivateKeyTemplateAttribute(