def test_not_equal_on_not_equal(self): """ Test that the inequality operator returns True when comparing two ProtocolVersion structs with different data. """ a = contents.ProtocolVersion(1, 0) b = contents.ProtocolVersion(0, 1) self.assertTrue(a != b)
def test_not_equal_on_equal(self): """ Test that the inequality operator returns False when comparing two ProtocolVersion structs with the same data. """ a = contents.ProtocolVersion(1, 0) b = contents.ProtocolVersion(1, 0) self.assertFalse(a != b)
def test_str(self): """ Test that str can be applied to a ProtocolVersion struct. """ struct = contents.ProtocolVersion(1, 0) self.assertEqual("1.0", str(struct))
def test_protocol_version_to_kmip_version_kmip_1_4(self): """ Test the conversion from ProtocolVersion(1, 4) to KMIPVersion.KMIP_1_4. """ result = contents.protocol_version_to_kmip_version( contents.ProtocolVersion(1, 4)) self.assertEqual(result, enums.KMIPVersion.KMIP_1_4)
def test_protocol_version_to_kmip_version_invalid_major(self): """ Test the conversion from invalid ProtocolVersion major value to None. """ result = contents.protocol_version_to_kmip_version( contents.ProtocolVersion(9, 5)) self.assertIsNone(result)
def test_get_all_attribute_names(self): """ Test that get_all_attribute_names returns a complete list of the names of all spec-defined attributes. """ rules = policy.AttributePolicy(contents.ProtocolVersion(1, 0)) attribute_names = [ 'Unique Identifier', 'Name', 'Object Type', 'Cryptographic Algorithm', 'Cryptographic Length', 'Cryptographic Parameters', 'Cryptographic Domain Parameters', 'Certificate Type', 'Certificate Length', 'X.509 Certificate Identifier', 'X.509 Certificate Subject', 'X.509 Certificate Issuer', 'Certificate Identifier', 'Certificate Subject', 'Certificate Issuer', 'Digital Signature Algorithm', 'Digest', 'Operation Policy Name', 'Cryptographic Usage Mask', 'Lease Time', 'Usage Limits', 'State', 'Initial Date', 'Activation Date', 'Process Start Date', 'Protect Stop Date', 'Deactivation Date', 'Destroy Date', 'Compromise Occurrence Date', 'Compromise Date', 'Revocation Reason', 'Archive Date', 'Object Group', 'Fresh', 'Link', 'Application Specific Information', 'Contact Information', 'Last Change Date', 'Custom Attribute', "Sensitive" ] result = rules.get_all_attribute_names() self.assertEqual(len(attribute_names), len(result)) for attribute_name in attribute_names: self.assertIn(attribute_name, result)
def read(self, istream, kmip_version=enums.KMIPVersion.KMIP_1_0): super(ResponseHeader, self).read( istream, kmip_version=kmip_version ) tstream = BytearrayStream(istream.read(self.length)) self.protocol_version = contents.ProtocolVersion() self.protocol_version.read(tstream, kmip_version=kmip_version) kmip_version = contents.protocol_version_to_kmip_version( self.protocol_version ) self.time_stamp = contents.TimeStamp() self.time_stamp.read(tstream, kmip_version=kmip_version) if kmip_version >= enums.KMIPVersion.KMIP_2_0: if self.is_tag_next(enums.Tags.SERVER_HASHED_PASSWORD, tstream): server_hashed_password = primitives.ByteString( tag=enums.Tags.SERVER_HASHED_PASSWORD ) server_hashed_password.read(tstream, kmip_version=kmip_version) self._server_hashed_password = server_hashed_password self.batch_count = contents.BatchCount() self.batch_count.read(tstream, kmip_version=kmip_version) self.is_oversized(tstream) self.validate()
def test_repr(self): """ Test that repr can be applied to a ProtocolVersion struct. """ struct = contents.ProtocolVersion(1, 0) self.assertEqual("ProtocolVersion(major=1, minor=0)", "{}".format(repr(struct)))
def test_init(self): """ Test that a ProtocolVersion struct can be constructed with no arguments. """ struct = contents.ProtocolVersion() self.assertEqual(None, struct.major) self.assertEqual(None, struct.minor)
def test_init_with_args(self): """ Test that a ProtocolVersion struct can be constructed with valid values. """ struct = contents.ProtocolVersion(1, 1) self.assertEqual(1, struct.major) self.assertEqual(1, struct.minor)
def test_not_equal_on_type_mismatch(self): """ Test that the inequality operator returns True when comparing two ProtocolVersion structs with different types. """ a = contents.ProtocolVersion(1, 0) b = "invalid" self.assertTrue(a != b)
def test_write(self): """ Test that a ProtocolVersion struct can be written to a data stream. """ struct = contents.ProtocolVersion(1, 1) stream = utils.BytearrayStream() struct.write(stream) self.assertEqual(len(self.full_encoding), len(stream)) self.assertEqual(str(self.full_encoding), str(stream))
def test_is_attribute_modifiable_by_client(self): """ Test that is_attribute_modifiable_by_client returns the expected results in all cases. """ rules = policy.AttributePolicy(contents.ProtocolVersion(1, 0)) self.assertFalse( rules.is_attribute_modifiable_by_client("Unique Identifier")) self.assertTrue(rules.is_attribute_modifiable_by_client("Name"))
def test_is_attribute_deprecated(self): """ Test that is_attribute_deprecated returns the expected results in all cases. """ rules = policy.AttributePolicy(contents.ProtocolVersion(1, 0)) attribute_a = 'Name' attribute_b = 'Certificate Subject' result = rules.is_attribute_deprecated(attribute_a) self.assertFalse(result) result = rules.is_attribute_deprecated(attribute_b) self.assertFalse(result) rules = policy.AttributePolicy(contents.ProtocolVersion(1, 1)) result = rules.is_attribute_deprecated(attribute_b) self.assertTrue(result)
def test_invalid_protocol_version_minor(self): """ Test that a TypeError is raised when an invalid value is used to set the minor protocol version number of a ProtocolVersion struct. """ struct = contents.ProtocolVersion() args = (struct, 'minor', 'invalid') self.assertRaisesRegex( TypeError, "Minor protocol version number must be an integer.", setattr, *args)
def test_handle_message_loop_with_authentication_failure( self, request_mock, cert_mock): """ Test that the correct logging and error handling occurs when an authentication error is generated while processing a request. """ data = utils.BytearrayStream(()) cert_mock.return_value = 'test_certificate' kmip_engine = engine.KmipEngine() kmip_engine._logger = mock.MagicMock() kmip_session = session.KmipSession(kmip_engine, None, None, name='name', enable_tls_client_auth=False) kmip_session.authenticate = mock.MagicMock() kmip_session.authenticate.side_effect = exceptions.PermissionDenied( "Authentication failed.") kmip_session._engine = mock.MagicMock() kmip_session._engine.default_protocol_version = \ kmip_engine.default_protocol_version kmip_session._logger = mock.MagicMock() kmip_session._connection = mock.MagicMock() kmip_session._receive_request = mock.MagicMock(return_value=data) kmip_session._send_response = mock.MagicMock() fake_version = contents.ProtocolVersion(1, 2) fake_credential = objects.Credential( credential_type=enums.CredentialType.USERNAME_AND_PASSWORD, credential_value=objects.UsernamePasswordCredential( username="******", password="******")) fake_header = messages.RequestHeader( protocol_version=fake_version, authentication=contents.Authentication( credentials=[fake_credential])) fake_request = messages.RequestMessage() fake_request.request_header = fake_header fake_request.read = mock.MagicMock() request_mock.return_value = fake_request kmip_session._handle_message_loop() kmip_session._receive_request.assert_called_once_with() fake_request.read.assert_called_once_with( data, kmip_version=enums.KMIPVersion.KMIP_1_2) kmip_session.authenticate.assert_called_once_with( "test_certificate", fake_request) kmip_session._logger.warning.assert_called_once_with( "Authentication failed.") kmip_session._engine.build_error_response.assert_called_once_with( fake_version, enums.ResultReason.AUTHENTICATION_NOT_SUCCESSFUL, "An error occurred during client authentication. " "See server logs for more information.") kmip_session._logger.exception.assert_not_called() self.assertTrue(kmip_session._send_response.called)
def test_handle_message_loop(self, request_mock): """ Test that the correct logging and error handling occurs during the message handling loop. """ data = utils.BytearrayStream() # Build a response and use it as a dummy processing result. batch_item = messages.ResponseBatchItem( result_status=contents.ResultStatus(enums.ResultStatus.SUCCESS), result_reason=contents.ResultReason( enums.ResultReason.OBJECT_ARCHIVED), result_message=contents.ResultMessage("Test message.")) batch_items = [batch_item] header = messages.ResponseHeader( protocol_version=contents.ProtocolVersion(1, 0), time_stamp=contents.TimeStamp(int(time.time())), batch_count=contents.BatchCount(len(batch_items))) message = messages.ResponseMessage(response_header=header, batch_items=batch_items) kmip_engine = engine.KmipEngine() kmip_engine._logger = mock.MagicMock() kmip_session = session.KmipSession(kmip_engine, None, 'name') kmip_session._engine = mock.MagicMock() kmip_session._get_client_identity = mock.MagicMock() kmip_session._get_client_identity.return_value = 'test' kmip_session._engine.process_request = mock.MagicMock( return_value=(message, kmip_session._max_response_size)) kmip_session._logger = mock.MagicMock() kmip_session._connection = mock.MagicMock() kmip_session._connection.shared_ciphers = mock.MagicMock( return_value=[('AES128-SHA256', 'TLSv1/SSLv3', 128), ('AES256-SHA256', 'TLSv1/SSLv3', 256)]) kmip_session._connection.cipher = mock.MagicMock( return_value=('AES128-SHA256', 'TLSv1/SSLv3', 128)) kmip_session._receive_request = mock.MagicMock(return_value=data) kmip_session._send_response = mock.MagicMock() kmip_session._handle_message_loop() kmip_session._receive_request.assert_called_once_with() kmip_session._logger.info.assert_not_called() kmip_session._logger.debug.assert_any_call( "Possible session ciphers: 2") kmip_session._logger.debug.assert_any_call( ('AES128-SHA256', 'TLSv1/SSLv3', 128)) kmip_session._logger.debug.assert_any_call( ('AES256-SHA256', 'TLSv1/SSLv3', 256)) kmip_session._logger.debug.assert_any_call( "Session cipher selected: {0}".format( ('AES128-SHA256', 'TLSv1/SSLv3', 128))) kmip_session._logger.warning.assert_not_called() kmip_session._logger.exception.assert_not_called() self.assertTrue(kmip_session._send_response.called)
def test_is_attribute_deletable_by_client(self): """ Test that is_attribute_deletable_by_client returns the expected results in all cases. """ rules = policy.AttributePolicy(contents.ProtocolVersion(1, 0)) self.assertFalse( rules.is_attribute_deletable_by_client("Cryptographic Algorithm")) self.assertTrue( rules.is_attribute_deletable_by_client("Contact Information"))
def read(self, istream, kmip_version=enums.KMIPVersion.KMIP_1_0): super(RequestHeader, self).read( istream, kmip_version=kmip_version ) tstream = BytearrayStream(istream.read(self.length)) self.protocol_version = contents.ProtocolVersion() self.protocol_version.read(tstream, kmip_version=kmip_version) kmip_version = contents.protocol_version_to_kmip_version( self.protocol_version ) # Read the maximum response size if it is present if self.is_tag_next(Tags.MAXIMUM_RESPONSE_SIZE, tstream): self.maximum_response_size = contents.MaximumResponseSize() self.maximum_response_size.read(tstream, kmip_version=kmip_version) # Read the asynchronous indicator if it is present if self.is_tag_next(Tags.ASYNCHRONOUS_INDICATOR, tstream): self.asynchronous_indicator = contents.AsynchronousIndicator() self.asynchronous_indicator.read( tstream, kmip_version=kmip_version ) # Read the authentication if it is present if self.is_tag_next(Tags.AUTHENTICATION, tstream): self.authentication = contents.Authentication() self.authentication.read(tstream, kmip_version=kmip_version) # Read the batch error continuation option if it is present if self.is_tag_next(Tags.BATCH_ERROR_CONTINUATION_OPTION, tstream): self.batch_error_cont_option = BatchErrorContinuationOption() self.batch_error_cont_option.read( tstream, kmip_version=kmip_version ) # Read the batch order option if it is present if self.is_tag_next(Tags.BATCH_ORDER_OPTION, tstream): self.batch_order_option = contents.BatchOrderOption() self.batch_order_option.read(tstream, kmip_version=kmip_version) # Read the time stamp if it is present if self.is_tag_next(Tags.TIME_STAMP, tstream): self.time_stamp = contents.TimeStamp() self.time_stamp.read(tstream, kmip_version=kmip_version) self.batch_count = contents.BatchCount() self.batch_count.read(tstream, kmip_version=kmip_version) self.is_oversized(tstream)
def test_read_missing_minor_number(self): """ Test that a ValueError gets raised when a required ProtocolVersion struct attribute is missing from the struct encoding. """ struct = contents.ProtocolVersion() args = (self.encoding_no_minor_number, ) self.assertRaisesRegex( ValueError, "Invalid encoding missing the minor protocol version number.", struct.read, *args)
def test_write_missing_minor_number(self): """ Test that a ValueError gets raised when a required ProtocolVersion struct attribute is missing when encoding the struct. """ struct = contents.ProtocolVersion(1, None) stream = utils.BytearrayStream() args = (stream, ) self.assertRaisesRegex( ValueError, "Invalid struct missing the minor protocol version number.", struct.write, *args)
def test_greater_than_or_equal(self): """ Test that the greater than or equal operator correctly returns True/False when comparing two different ProtocolVersions. """ a = contents.ProtocolVersion(1, 0) b = contents.ProtocolVersion(1, 1) c = contents.ProtocolVersion(2, 0) d = contents.ProtocolVersion(0, 2) self.assertFalse(a >= b) self.assertTrue(b >= a) self.assertTrue(a >= a) self.assertFalse(a >= c) self.assertTrue(c >= a) self.assertTrue(c >= d) self.assertFalse(d >= c) # A direct call to __ge__ is required here due to differences in how # Python 2 and Python 3 treat comparison operators. self.assertEqual(NotImplemented, a.__ge__('invalid'))
def test_less_than(self): """ Test that the less than operator correctly returns True/False when comparing two different ProtocolVersions. """ a = contents.ProtocolVersion(1, 0) b = contents.ProtocolVersion(1, 1) c = contents.ProtocolVersion(2, 0) d = contents.ProtocolVersion(0, 2) self.assertTrue(a < b) self.assertFalse(b < a) self.assertFalse(a < a) self.assertTrue(a < c) self.assertFalse(c < a) self.assertFalse(c < d) self.assertTrue(d < c) # A direct call to __lt__ is required here due to differences in how # Python 2 and Python 3 treat comparison operators. self.assertEqual(NotImplemented, a.__lt__('invalid'))
def test_read(self): """ Test that a ProtocolVersion struct can be read from a data stream. """ struct = contents.ProtocolVersion() self.assertEqual(None, struct.major) self.assertEqual(None, struct.minor) struct.read(self.full_encoding) self.assertEqual(1, struct.major) self.assertEqual(1, struct.minor)
def test_is_attribute_multivalued(self): """ Test that is_attribute_multivalued returns the expected results in all cases. """ rules = policy.AttributePolicy(contents.ProtocolVersion(1, 0)) attribute_a = 'Object Type' attribute_b = 'Link' result = rules.is_attribute_multivalued(attribute_a) self.assertFalse(result) result = rules.is_attribute_multivalued(attribute_b) self.assertTrue(result)
def read(self, istream, kmip_version=enums.KMIPVersion.KMIP_1_0): super(ResponseHeader, self).read(istream, kmip_version=kmip_version) tstream = BytearrayStream(istream.read(self.length)) self.protocol_version = contents.ProtocolVersion() self.protocol_version.read(tstream, kmip_version=kmip_version) self.time_stamp = contents.TimeStamp() self.time_stamp.read(tstream, kmip_version=kmip_version) self.batch_count = contents.BatchCount() self.batch_count.read(tstream, kmip_version=kmip_version) self.is_oversized(tstream) self.validate()
def test_handle_message_loop_invalid_certificate_extension(self, request_mock, cert_mock, ext_mock): """ Test that the correct logging and error handling occurs when an invalid certificate is encountered while processing a request. """ data = utils.BytearrayStream(()) cert_mock.return_value = 'test_certificate' ext_mock.return_value = [] kmip_engine = engine.KmipEngine() kmip_engine._logger = mock.MagicMock() kmip_session = session.KmipSession( kmip_engine, None, None, name='name', enable_tls_client_auth=True ) kmip_session.authenticate = mock.MagicMock() kmip_session._engine = mock.MagicMock() kmip_session._logger = mock.MagicMock() kmip_session._connection = mock.MagicMock() kmip_session._receive_request = mock.MagicMock(return_value=data) kmip_session._send_response = mock.MagicMock() kmip_session._handle_message_loop() kmip_session._receive_request.assert_called_once_with() kmip_session._logger.warning( "Failure verifying the client certificate." ) kmip_session._logger.exception.assert_called_once_with( exceptions.PermissionDenied( "The extended key usage extension is not marked for client " "authentication in the client certificate." ) ) kmip_session._engine.build_error_response.assert_called_once_with( contents.ProtocolVersion(1, 0), enums.ResultReason.AUTHENTICATION_NOT_SUCCESSFUL, "Error verifying the client certificate. " "See server logs for more information." ) self.assertTrue(kmip_session._send_response.called)
def test_is_attribute_applicable_to_object_type(self): """ Test that is_attribute_applicable_to_object_type returns the expected results in all cases. """ rules = policy.AttributePolicy(contents.ProtocolVersion(1, 0)) attribute = 'Cryptographic Algorithm' object_type_a = enums.ObjectType.SYMMETRIC_KEY object_type_b = enums.ObjectType.OPAQUE_DATA result = rules.is_attribute_applicable_to_object_type( attribute, object_type_a) self.assertTrue(result) result = rules.is_attribute_applicable_to_object_type( attribute, object_type_b) self.assertFalse(result)
def test_is_attribute_supported(self): """ Test that is_attribute_supported returns the expected results in all cases. """ rules = policy.AttributePolicy(contents.ProtocolVersion(1, 0)) attribute_a = 'Unique Identifier' attribute_b = 'Certificate Length' attribute_c = 'invalid' result = rules.is_attribute_supported(attribute_a) self.assertTrue(result) result = rules.is_attribute_supported(attribute_b) self.assertFalse(result) result = rules.is_attribute_supported(attribute_c) self.assertFalse(result)
def __init__(self, version): """ Create an AttributePolicy. Args: version (ProtocolVersion): The KMIP protocol version under which this set of attribute policies should be evaluated. Required. """ self._version = version self._attribute_rule_sets = { 'Unique Identifier': AttributeRuleSet( True, ('server', ), False, False, False, False, ( enums.Operation.CREATE, enums.Operation.CREATE_KEY_PAIR, enums.Operation.REGISTER, enums.Operation.DERIVE_KEY, enums.Operation.CERTIFY, enums.Operation.RECERTIFY, enums.Operation.REKEY, enums.Operation.REKEY_KEY_PAIR ), ( 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, 0) ), 'Name': AttributeRuleSet( False, ('client', ), True, True, True, True, ( enums.Operation.RECERTIFY, enums.Operation.REKEY, enums.Operation.REKEY_KEY_PAIR ), ( 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, 0) ), 'Object Type': AttributeRuleSet( True, ('server', ), False, False, False, False, ( enums.Operation.CREATE, enums.Operation.CREATE_KEY_PAIR, enums.Operation.REGISTER, enums.Operation.DERIVE_KEY, enums.Operation.CERTIFY, enums.Operation.RECERTIFY, enums.Operation.REKEY, enums.Operation.REKEY_KEY_PAIR ), ( 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, 0) ), 'Cryptographic Algorithm': AttributeRuleSet( True, ('server', ), False, False, False, False, ( enums.Operation.CREATE, enums.Operation.CREATE_KEY_PAIR, enums.Operation.REGISTER, enums.Operation.DERIVE_KEY, enums.Operation.CERTIFY, enums.Operation.RECERTIFY, enums.Operation.REKEY, enums.Operation.REKEY_KEY_PAIR ), ( enums.ObjectType.CERTIFICATE, enums.ObjectType.SYMMETRIC_KEY, enums.ObjectType.PUBLIC_KEY, enums.ObjectType.PRIVATE_KEY, enums.ObjectType.SPLIT_KEY, enums.ObjectType.TEMPLATE ), contents.ProtocolVersion(1, 0) ), 'Cryptographic Length': AttributeRuleSet( True, ('server', ), False, False, False, False, ( enums.Operation.CREATE, enums.Operation.CREATE_KEY_PAIR, enums.Operation.REGISTER, enums.Operation.DERIVE_KEY, enums.Operation.CERTIFY, enums.Operation.RECERTIFY, enums.Operation.REKEY, enums.Operation.REKEY_KEY_PAIR ), ( enums.ObjectType.CERTIFICATE, enums.ObjectType.SYMMETRIC_KEY, enums.ObjectType.PUBLIC_KEY, enums.ObjectType.PRIVATE_KEY, enums.ObjectType.SPLIT_KEY, enums.ObjectType.TEMPLATE ), contents.ProtocolVersion(1, 0) ), 'Cryptographic Parameters': AttributeRuleSet( False, ('client', ), False, True, True, True, ( enums.Operation.RECERTIFY, enums.Operation.REKEY, enums.Operation.REKEY_KEY_PAIR ), ( enums.ObjectType.CERTIFICATE, enums.ObjectType.SYMMETRIC_KEY, enums.ObjectType.PUBLIC_KEY, enums.ObjectType.PRIVATE_KEY, enums.ObjectType.SPLIT_KEY, enums.ObjectType.TEMPLATE ), contents.ProtocolVersion(1, 0) ), 'Cryptographic Domain Parameters': AttributeRuleSet( False, ('client', ), False, False, False, False, ( enums.Operation.REKEY, enums.Operation.REKEY_KEY_PAIR ), ( enums.ObjectType.PUBLIC_KEY, enums.ObjectType.PRIVATE_KEY, enums.ObjectType.TEMPLATE ), contents.ProtocolVersion(1, 0) ), 'Certificate Type': AttributeRuleSet( True, ('server', ), False, False, False, False, ( enums.Operation.REGISTER, enums.Operation.CERTIFY, enums.Operation.RECERTIFY ), ( enums.ObjectType.CERTIFICATE, ), contents.ProtocolVersion(1, 0) ), 'Certificate Length': AttributeRuleSet( True, ('server', ), False, False, False, False, ( enums.Operation.REGISTER, enums.Operation.CERTIFY, enums.Operation.RECERTIFY ), ( enums.ObjectType.CERTIFICATE, ), contents.ProtocolVersion(1, 1) ), 'X.509 Certificate Identifier': AttributeRuleSet( True, ('server', ), False, False, False, False, ( enums.Operation.REGISTER, enums.Operation.CERTIFY, enums.Operation.RECERTIFY ), ( # TODO (peterhamilton) Enforce only on X.509 certificates enums.ObjectType.CERTIFICATE, ), contents.ProtocolVersion(1, 1) ), 'X.509 Certificate Subject': AttributeRuleSet( True, ('server', ), False, False, False, False, ( enums.Operation.REGISTER, enums.Operation.CERTIFY, enums.Operation.RECERTIFY ), ( # TODO (peterhamilton) Enforce only on X.509 certificates enums.ObjectType.CERTIFICATE, ), contents.ProtocolVersion(1, 1) ), 'X.509 Certificate Issuer': AttributeRuleSet( True, ('server', ), False, False, False, False, ( enums.Operation.REGISTER, enums.Operation.CERTIFY, enums.Operation.RECERTIFY ), ( # TODO (peterhamilton) Enforce only on X.509 certificates enums.ObjectType.CERTIFICATE, ), contents.ProtocolVersion(1, 1) ), 'Certificate Identifier': AttributeRuleSet( True, ('server', ), False, False, False, False, ( enums.Operation.REGISTER, enums.Operation.CERTIFY, enums.Operation.RECERTIFY ), ( enums.ObjectType.CERTIFICATE, ), contents.ProtocolVersion(1, 0), contents.ProtocolVersion(1, 1) ), 'Certificate Subject': AttributeRuleSet( True, ('server', ), False, False, False, False, ( enums.Operation.REGISTER, enums.Operation.CERTIFY, enums.Operation.RECERTIFY ), ( enums.ObjectType.CERTIFICATE, ), contents.ProtocolVersion(1, 0), contents.ProtocolVersion(1, 1) ), 'Certificate Issuer': AttributeRuleSet( True, ('server', ), False, False, False, False, ( enums.Operation.REGISTER, enums.Operation.CERTIFY, enums.Operation.RECERTIFY ), ( enums.ObjectType.CERTIFICATE, ), contents.ProtocolVersion(1, 0), contents.ProtocolVersion(1, 1) ), 'Digital Signature Algorithm': AttributeRuleSet( True, ('server', ), False, False, False, # TODO (peterhamilton) Enforce only for X.509 certificates False, # True for PGP certificates ( enums.Operation.REGISTER, enums.Operation.CERTIFY, enums.Operation.RECERTIFY ), ( enums.ObjectType.CERTIFICATE, ), contents.ProtocolVersion(1, 1) ), 'Digest': AttributeRuleSet( True, # If the server has access to the data ('server', ), False, False, False, True, ( enums.Operation.CREATE, enums.Operation.CREATE_KEY_PAIR, enums.Operation.REGISTER, enums.Operation.DERIVE_KEY, enums.Operation.CERTIFY, enums.Operation.RECERTIFY, enums.Operation.REKEY, enums.Operation.REKEY_KEY_PAIR ), ( enums.ObjectType.CERTIFICATE, enums.ObjectType.SYMMETRIC_KEY, enums.ObjectType.PUBLIC_KEY, enums.ObjectType.PRIVATE_KEY, enums.ObjectType.SPLIT_KEY, enums.ObjectType.SECRET_DATA, enums.ObjectType.OPAQUE_DATA ), contents.ProtocolVersion(1, 0) ), 'Operation Policy Name': AttributeRuleSet( False, ('server', 'client'), True, False, False, False, ( enums.Operation.CREATE, enums.Operation.CREATE_KEY_PAIR, enums.Operation.REGISTER, enums.Operation.DERIVE_KEY, enums.Operation.CERTIFY, enums.Operation.RECERTIFY, enums.Operation.REKEY, enums.Operation.REKEY_KEY_PAIR ), ( 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, 0), contents.ProtocolVersion(2, 0) ), 'Cryptographic Usage Mask': AttributeRuleSet( True, ('server', 'client'), True, False, False, False, ( enums.Operation.CREATE, enums.Operation.CREATE_KEY_PAIR, enums.Operation.REGISTER, enums.Operation.DERIVE_KEY, enums.Operation.CERTIFY, enums.Operation.RECERTIFY, enums.Operation.REKEY, enums.Operation.REKEY_KEY_PAIR ), ( 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 ), contents.ProtocolVersion(1, 0) ), 'Lease Time': AttributeRuleSet( False, ('server', ), True, False, False, False, ( enums.Operation.CREATE, enums.Operation.CREATE_KEY_PAIR, enums.Operation.REGISTER, enums.Operation.DERIVE_KEY, enums.Operation.CERTIFY, enums.Operation.RECERTIFY, enums.Operation.REKEY, enums.Operation.REKEY_KEY_PAIR ), ( enums.ObjectType.CERTIFICATE, enums.ObjectType.SYMMETRIC_KEY, enums.ObjectType.PUBLIC_KEY, enums.ObjectType.PRIVATE_KEY, enums.ObjectType.SPLIT_KEY, enums.ObjectType.SECRET_DATA ), contents.ProtocolVersion(1, 0) ), 'Usage Limits': AttributeRuleSet( False, ('server', 'client'), # Values differ based on source True, True, # Conditional on values and operations used True, # Conditional on operations used False, ( enums.Operation.CREATE, enums.Operation.CREATE_KEY_PAIR, enums.Operation.REGISTER, enums.Operation.DERIVE_KEY, enums.Operation.REKEY, enums.Operation.REKEY_KEY_PAIR, enums.Operation.GET_USAGE_ALLOCATION ), ( enums.ObjectType.SYMMETRIC_KEY, enums.ObjectType.PUBLIC_KEY, enums.ObjectType.PRIVATE_KEY, enums.ObjectType.SPLIT_KEY, enums.ObjectType.TEMPLATE ), contents.ProtocolVersion(1, 0) ), 'State': AttributeRuleSet( True, ('server', ), True, False, # Only modifiable by server for certain requests False, False, ( enums.Operation.CREATE, enums.Operation.CREATE_KEY_PAIR, enums.Operation.REGISTER, enums.Operation.DERIVE_KEY, enums.Operation.ACTIVATE, enums.Operation.REVOKE, enums.Operation.DESTROY, enums.Operation.CERTIFY, enums.Operation.RECERTIFY, enums.Operation.REKEY, enums.Operation.REKEY_KEY_PAIR ), ( enums.ObjectType.CERTIFICATE, enums.ObjectType.SYMMETRIC_KEY, enums.ObjectType.PUBLIC_KEY, enums.ObjectType.PRIVATE_KEY, enums.ObjectType.SPLIT_KEY, enums.ObjectType.SECRET_DATA ), contents.ProtocolVersion(1, 0) ), 'Initial Date': AttributeRuleSet( True, ('server', ), False, False, False, False, ( enums.Operation.CREATE, enums.Operation.CREATE_KEY_PAIR, enums.Operation.REGISTER, enums.Operation.DERIVE_KEY, enums.Operation.CERTIFY, enums.Operation.RECERTIFY, enums.Operation.REKEY, enums.Operation.REKEY_KEY_PAIR ), ( 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, 0) ), 'Activation Date': AttributeRuleSet( False, ('server', 'client'), True, # Only while in Pre-Active state True, # Only while in Pre-Active state False, False, ( enums.Operation.CREATE, enums.Operation.CREATE_KEY_PAIR, enums.Operation.REGISTER, enums.Operation.DERIVE_KEY, enums.Operation.ACTIVATE, enums.Operation.CERTIFY, enums.Operation.RECERTIFY, enums.Operation.REKEY, enums.Operation.REKEY_KEY_PAIR ), ( 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 ), contents.ProtocolVersion(1, 0) ), 'Process Start Date': AttributeRuleSet( False, ('server', 'client'), True, # Only while in Pre-Active / Active state and more True, # Only while in Pre-Active / Active state and more False, False, ( enums.Operation.CREATE, enums.Operation.REGISTER, enums.Operation.DERIVE_KEY, enums.Operation.REKEY ), ( enums.ObjectType.SYMMETRIC_KEY, # Only SplitKeys of SymmetricKeys enums.ObjectType.SPLIT_KEY, enums.ObjectType.TEMPLATE ), contents.ProtocolVersion(1, 0) ), 'Protect Stop Date': AttributeRuleSet( False, ('server', 'client'), True, # Only while in Pre-Active / Active state and more True, # Only while in Pre-Active / Active state and more False, False, ( enums.Operation.CREATE, enums.Operation.REGISTER, enums.Operation.DERIVE_KEY, enums.Operation.REKEY ), ( enums.ObjectType.SYMMETRIC_KEY, # Only SplitKeys of SymmetricKeys enums.ObjectType.SPLIT_KEY, enums.ObjectType.TEMPLATE ), contents.ProtocolVersion(1, 0) ), 'Deactivation Date': AttributeRuleSet( False, ('server', 'client'), True, # Only while in Pre-Active / Active state True, # Only while in Pre-Active / Active state False, False, ( enums.Operation.CREATE, enums.Operation.CREATE_KEY_PAIR, enums.Operation.REGISTER, enums.Operation.DERIVE_KEY, enums.Operation.REVOKE, enums.Operation.CERTIFY, enums.Operation.RECERTIFY, enums.Operation.REKEY, enums.Operation.REKEY_KEY_PAIR ), ( 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 ), contents.ProtocolVersion(1, 0) ), 'Destroy Date': AttributeRuleSet( False, ('server', ), False, False, False, False, ( enums.Operation.DESTROY, ), ( enums.ObjectType.CERTIFICATE, enums.ObjectType.SYMMETRIC_KEY, enums.ObjectType.PUBLIC_KEY, enums.ObjectType.PRIVATE_KEY, enums.ObjectType.SPLIT_KEY, enums.ObjectType.SECRET_DATA, enums.ObjectType.OPAQUE_DATA ), contents.ProtocolVersion(1, 0) ), 'Compromise Occurrence Date': AttributeRuleSet( False, ('server', ), False, False, False, False, ( enums.Operation.REVOKE, ), ( enums.ObjectType.CERTIFICATE, enums.ObjectType.SYMMETRIC_KEY, enums.ObjectType.PUBLIC_KEY, enums.ObjectType.PRIVATE_KEY, enums.ObjectType.SPLIT_KEY, enums.ObjectType.SECRET_DATA, enums.ObjectType.OPAQUE_DATA ), contents.ProtocolVersion(1, 0) ), 'Compromise Date': AttributeRuleSet( False, ('server', ), False, False, False, False, ( enums.Operation.REVOKE, ), ( enums.ObjectType.CERTIFICATE, enums.ObjectType.SYMMETRIC_KEY, enums.ObjectType.PUBLIC_KEY, enums.ObjectType.PRIVATE_KEY, enums.ObjectType.SPLIT_KEY, enums.ObjectType.SECRET_DATA, enums.ObjectType.OPAQUE_DATA ), contents.ProtocolVersion(1, 0) ), 'Revocation Reason': AttributeRuleSet( False, ('server', ), True, False, False, False, ( enums.Operation.REVOKE, ), ( enums.ObjectType.CERTIFICATE, enums.ObjectType.SYMMETRIC_KEY, enums.ObjectType.PUBLIC_KEY, enums.ObjectType.PRIVATE_KEY, enums.ObjectType.SPLIT_KEY, enums.ObjectType.SECRET_DATA, enums.ObjectType.OPAQUE_DATA ), contents.ProtocolVersion(1, 0) ), 'Archive Date': AttributeRuleSet( False, ('server', ), False, False, False, False, ( enums.Operation.ARCHIVE, ), ( 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, 0) ), 'Object Group': AttributeRuleSet( False, ('server', 'client'), False, False, False, False, ( enums.Operation.CREATE, enums.Operation.CREATE_KEY_PAIR, enums.Operation.REGISTER, enums.Operation.DERIVE_KEY, enums.Operation.CERTIFY, enums.Operation.RECERTIFY, enums.Operation.REKEY, enums.Operation.REKEY_KEY_PAIR ), ( 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, 0) ), 'Fresh': AttributeRuleSet( False, ('server', 'client'), True, False, False, False, ( enums.Operation.CREATE, enums.Operation.CREATE_KEY_PAIR, enums.Operation.REGISTER, enums.Operation.DERIVE_KEY, enums.Operation.CERTIFY, enums.Operation.RECERTIFY, enums.Operation.REKEY, enums.Operation.REKEY_KEY_PAIR ), ( 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, 1) ), 'Link': AttributeRuleSet( False, ('server', ), True, True, True, True, ( enums.Operation.CREATE_KEY_PAIR, enums.Operation.DERIVE_KEY, enums.Operation.CERTIFY, enums.Operation.RECERTIFY, enums.Operation.REKEY, enums.Operation.REKEY_KEY_PAIR ), ( 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, 0) ), 'Application Specific Information': AttributeRuleSet( False, ('server', 'client'), # Only if omitted in client request True, # Only if attribute omitted in client request True, True, True, ( enums.Operation.RECERTIFY, enums.Operation.REKEY, enums.Operation.REKEY_KEY_PAIR ), ( 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, 0) ), 'Contact Information': AttributeRuleSet( False, ('server', 'client'), True, True, True, False, ( enums.Operation.CREATE, enums.Operation.CREATE_KEY_PAIR, enums.Operation.REGISTER, enums.Operation.DERIVE_KEY, enums.Operation.CERTIFY, enums.Operation.RECERTIFY, enums.Operation.REKEY, enums.Operation.REKEY_KEY_PAIR ), ( 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, 0) ), 'Last Change Date': AttributeRuleSet( True, ('server', ), True, False, False, False, ( enums.Operation.CREATE, enums.Operation.CREATE_KEY_PAIR, enums.Operation.REGISTER, enums.Operation.DERIVE_KEY, enums.Operation.ACTIVATE, enums.Operation.REVOKE, enums.Operation.DESTROY, enums.Operation.ARCHIVE, enums.Operation.RECOVER, enums.Operation.CERTIFY, enums.Operation.RECERTIFY, enums.Operation.REKEY, enums.Operation.REKEY_KEY_PAIR, enums.Operation.ADD_ATTRIBUTE, enums.Operation.MODIFY_ATTRIBUTE, enums.Operation.DELETE_ATTRIBUTE, enums.Operation.GET_USAGE_ALLOCATION ), ( 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, 0) ), 'Custom Attribute': AttributeRuleSet( False, ('server', 'client'), True, # Only for server-created attributes True, # Only for client-created attributes True, # Only for client-created attributes True, ( enums.Operation.CREATE, enums.Operation.CREATE_KEY_PAIR, enums.Operation.REGISTER, enums.Operation.DERIVE_KEY, enums.Operation.ACTIVATE, enums.Operation.REVOKE, enums.Operation.DESTROY, enums.Operation.CERTIFY, enums.Operation.RECERTIFY, enums.Operation.REKEY, enums.Operation.REKEY_KEY_PAIR ), ( 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, 0) ), }