From e31373169241c783f57e337fa18bb2f272e93f1f Mon Sep 17 00:00:00 2001 From: Peter Hamilton Date: Fri, 22 Nov 2019 13:53:48 -0500 Subject: [PATCH] Add support for the Sensitive attribute This change adds support for the Sensitive attribute, adding it to the attribute factory, the SQLAlchemy object hierarchy, and to the server attribute handling methods. The intent is to use this new attribute to test the new SetAttribute and ModifyAttribute operations coming in future commits. Unit tests have been added and modified to support the new additions. --- kmip/core/enums.py | 1 + kmip/core/factories/attribute_values.py | 4 ++++ kmip/pie/objects.py | 2 ++ kmip/services/server/engine.py | 4 ++++ kmip/services/server/policy.py | 24 +++++++++++++++++++ .../core/factories/test_attribute_values.py | 20 ++++++++++++++++ .../tests/unit/services/server/test_engine.py | 12 ++++++++++ .../tests/unit/services/server/test_policy.py | 3 ++- 8 files changed, 69 insertions(+), 1 deletion(-) diff --git a/kmip/core/enums.py b/kmip/core/enums.py index 5eb81db..4195d2b 100644 --- a/kmip/core/enums.py +++ b/kmip/core/enums.py @@ -126,6 +126,7 @@ class AttributeType(enum.Enum): KEY_VALUE_PRESENT = 'Key Value Present' KEY_VALUE_LOCATION = 'Key Value Location' ORIGINAL_CREATION_DATE = 'Original Creation Date' + SENSITIVE = "Sensitive" class AuthenticationSuite(enum.Enum): diff --git a/kmip/core/factories/attribute_values.py b/kmip/core/factories/attribute_values.py index 9f5efc3..4a1c4a5 100644 --- a/kmip/core/factories/attribute_values.py +++ b/kmip/core/factories/attribute_values.py @@ -104,6 +104,8 @@ class AttributeValueFactory(object): return self._create_contact_information(value) elif name is enums.AttributeType.LAST_CHANGE_DATE: return primitives.DateTime(value, enums.Tags.LAST_CHANGE_DATE) + elif name is enums.AttributeType.SENSITIVE: + return primitives.Boolean(value, enums.Tags.SENSITIVE) elif name is enums.AttributeType.CUSTOM_ATTRIBUTE: return attributes.CustomAttribute(value) else: @@ -194,6 +196,8 @@ class AttributeValueFactory(object): return self._create_contact_information(value) elif enum is enums.Tags.LAST_CHANGE_DATE: return primitives.DateTime(value, enums.Tags.LAST_CHANGE_DATE) + elif enum is enums.Tags.SENSITIVE: + return primitives.Boolean(value, enums.Tags.SENSITIVE) elif enum is enums.Tags.CUSTOM_ATTRIBUTE: return attributes.CustomAttribute(value) else: diff --git a/kmip/pie/objects.py b/kmip/pie/objects.py index f71615f..7f20b2c 100644 --- a/kmip/pie/objects.py +++ b/kmip/pie/objects.py @@ -106,6 +106,7 @@ class ManagedObject(sql.Base): String(50), default='default' ) + sensitive = Column("sensitive", Boolean, default=False) initial_date = Column(Integer, default=0) _owner = Column('owner', String(50), default=None) @@ -144,6 +145,7 @@ class ManagedObject(sql.Base): self.names = list() self.operation_policy_name = None self.initial_date = 0 + self.sensitive = False self._object_type = None self._owner = None diff --git a/kmip/services/server/engine.py b/kmip/services/server/engine.py index a4654ba..db0cc5c 100644 --- a/kmip/services/server/engine.py +++ b/kmip/services/server/engine.py @@ -744,6 +744,8 @@ class KmipEngine(object): return None elif attr_name == 'Last Change Date': return None + elif attr_name == "Sensitive": + return managed_object.sensitive else: # Since custom attribute names are possible, just return None # for unrecognized attributes. This satisfies the spec. @@ -825,6 +827,8 @@ class KmipEngine(object): value.append(e) elif attribute_name == 'Operation Policy Name': field = 'operation_policy_name' + elif attribute_name == "Sensitive": + field = "sensitive" if field: existing_value = getattr(managed_object, field) diff --git a/kmip/services/server/policy.py b/kmip/services/server/policy.py index 08f58b1..9601f89 100644 --- a/kmip/services/server/policy.py +++ b/kmip/services/server/policy.py @@ -1078,6 +1078,30 @@ class AttributePolicy(object): ), contents.ProtocolVersion(1, 0) ), + "Sensitive": AttributeRuleSet( + True, + ("server", "client"), + True, + True, + False, + False, + ( + enums.Operation.CREATE, + enums.Operation.CREATE_KEY_PAIR, + enums.Operation.REGISTER + ), + ( + enums.ObjectType.CERTIFICATE, + enums.ObjectType.SYMMETRIC_KEY, + enums.ObjectType.PUBLIC_KEY, + enums.ObjectType.PRIVATE_KEY, + enums.ObjectType.SPLIT_KEY, + enums.ObjectType.TEMPLATE, + enums.ObjectType.SECRET_DATA, + enums.ObjectType.OPAQUE_DATA + ), + contents.ProtocolVersion(1, 4) + ) } def is_attribute_supported(self, attribute): diff --git a/kmip/tests/unit/core/factories/test_attribute_values.py b/kmip/tests/unit/core/factories/test_attribute_values.py index 608ed82..6edc448 100644 --- a/kmip/tests/unit/core/factories/test_attribute_values.py +++ b/kmip/tests/unit/core/factories/test_attribute_values.py @@ -505,3 +505,23 @@ class TestAttributeValueFactory(testtools.TestCase): custom = self.factory.create_attribute_value( enums.AttributeType.CUSTOM_ATTRIBUTE, None) self.assertIsInstance(custom, attributes.CustomAttribute) + + def test_create_sensitive(self): + """ + Test that a Sensitive attribute can be created. + """ + sensitive = self.factory.create_attribute_value( + enums.AttributeType.SENSITIVE, + True + ) + self.assertIsInstance(sensitive, primitives.Boolean) + self.assertTrue(sensitive.value) + self.assertEqual(enums.Tags.SENSITIVE, sensitive.tag) + + sensitive = self.factory.create_attribute_value_by_enum( + enums.Tags.SENSITIVE, + False + ) + self.assertIsInstance(sensitive, primitives.Boolean) + self.assertFalse(sensitive.value) + self.assertEqual(enums.Tags.SENSITIVE, sensitive.tag) diff --git a/kmip/tests/unit/services/server/test_engine.py b/kmip/tests/unit/services/server/test_engine.py index 57ed296..1582e6f 100644 --- a/kmip/tests/unit/services/server/test_engine.py +++ b/kmip/tests/unit/services/server/test_engine.py @@ -1757,6 +1757,10 @@ class TestKmipEngine(testtools.TestCase): enums.CryptographicUsageMask.DECRYPT ] ) + sensitive = attribute_factory.create_attribute( + enums.AttributeType.SENSITIVE, + True + ) managed_object = pie_objects.SymmetricKey( enums.CryptographicAlgorithm.AES, 0, @@ -1771,6 +1775,7 @@ class TestKmipEngine(testtools.TestCase): ) self.assertEqual(0, managed_object.cryptographic_length) self.assertEqual([], managed_object.cryptographic_usage_masks) + self.assertFalse(managed_object.sensitive) e._set_attribute_on_managed_object( managed_object, @@ -1809,6 +1814,13 @@ class TestKmipEngine(testtools.TestCase): managed_object.cryptographic_usage_masks ) + e._set_attribute_on_managed_object( + managed_object, + ("Sensitive", sensitive.attribute_value) + ) + + self.assertTrue(managed_object.sensitive) + def test_set_attribute_on_managed_object_unsupported_features(self): """ Test that the right errors are generated when unsupported features diff --git a/kmip/tests/unit/services/server/test_policy.py b/kmip/tests/unit/services/server/test_policy.py index 3778430..838c0da 100644 --- a/kmip/tests/unit/services/server/test_policy.py +++ b/kmip/tests/unit/services/server/test_policy.py @@ -172,7 +172,8 @@ class TestAttributePolicy(testtools.TestCase): 'Application Specific Information', 'Contact Information', 'Last Change Date', - 'Custom Attribute' + 'Custom Attribute', + "Sensitive" ] result = rules.get_all_attribute_names()