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 5eb81dbd..4195d2be 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 9f5efc3a..4a1c4a59 100644 --- a/kmip/core/factories/attribute_values.py +++ b/kmip/core/factories/attribute_values.py @@ -104,6 +104,8 @@ def create_attribute_value(self, name, value): 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 @@ def create_attribute_value_by_enum(self, enum, value): 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 f71615f0..7f20b2c8 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 @@ def __init__(self): 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 a4654ba0..db0cc5ca 100644 --- a/kmip/services/server/engine.py +++ b/kmip/services/server/engine.py @@ -744,6 +744,8 @@ def _get_attribute_from_managed_object(self, managed_object, attr_name): 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 @@ def _set_attribute_on_managed_object(self, managed_object, attribute): 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 08f58b16..9601f896 100644 --- a/kmip/services/server/policy.py +++ b/kmip/services/server/policy.py @@ -1078,6 +1078,30 @@ def __init__(self, version): ), 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 608ed822..6edc4482 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 @@ def test_create_custom_attribute(self): 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 57ed2964..1582e6f2 100644 --- a/kmip/tests/unit/services/server/test_engine.py +++ b/kmip/tests/unit/services/server/test_engine.py @@ -1757,6 +1757,10 @@ def test_set_attribute_on_managed_object(self): 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 @@ def test_set_attribute_on_managed_object(self): ) 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 @@ def test_set_attribute_on_managed_object(self): 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 3778430e..838c0da5 100644 --- a/kmip/tests/unit/services/server/test_policy.py +++ b/kmip/tests/unit/services/server/test_policy.py @@ -172,7 +172,8 @@ def test_get_all_attribute_names(self): 'Application Specific Information', 'Contact Information', 'Last Change Date', - 'Custom Attribute' + 'Custom Attribute', + "Sensitive" ] result = rules.get_all_attribute_names()