diff --git a/kmip/core/messages/contents.py b/kmip/core/messages/contents.py index 661b1ee..9027f7a 100644 --- a/kmip/core/messages/contents.py +++ b/kmip/core/messages/contents.py @@ -118,6 +118,58 @@ class ProtocolVersion(Struct): else: return NotImplemented + def __lt__(self, other): + if isinstance(other, ProtocolVersion): + if self.protocol_version_major < other.protocol_version_major: + return True + elif self.protocol_version_major > other.protocol_version_major: + return False + elif self.protocol_version_minor < other.protocol_version_minor: + return True + else: + return False + else: + return NotImplemented + + def __gt__(self, other): + if isinstance(other, ProtocolVersion): + if self.protocol_version_major > other.protocol_version_major: + return True + elif self.protocol_version_major < other.protocol_version_major: + return False + elif self.protocol_version_minor > other.protocol_version_minor: + return True + else: + return False + else: + return NotImplemented + + def __le__(self, other): + if isinstance(other, ProtocolVersion): + if self.protocol_version_major < other.protocol_version_major: + return True + elif self.protocol_version_major > other.protocol_version_major: + return False + elif self.protocol_version_minor <= other.protocol_version_minor: + return True + else: + return False + else: + return NotImplemented + + def __ge__(self, other): + if isinstance(other, ProtocolVersion): + if self.protocol_version_major > other.protocol_version_major: + return True + elif self.protocol_version_major < other.protocol_version_major: + return False + elif self.protocol_version_minor >= other.protocol_version_minor: + return True + else: + return False + else: + return NotImplemented + def __repr__(self): major = self.protocol_version_major.value minor = self.protocol_version_minor.value diff --git a/kmip/core/primitives.py b/kmip/core/primitives.py index 59ff91e..5b46787 100644 --- a/kmip/core/primitives.py +++ b/kmip/core/primitives.py @@ -231,10 +231,10 @@ class Integer(Base): raise ValueError('integer value less than accepted min') def __repr__(self): - return "{0}(value={1})".format(type(self).__name__, repr(self.value)) + return "{0}(value={1})".format(type(self).__name__, self.value) def __str__(self): - return "{0}".format(repr(self.value)) + return str(self.value) def __eq__(self, other): if isinstance(other, Integer): @@ -248,6 +248,30 @@ class Integer(Base): else: return NotImplemented + def __lt__(self, other): + if isinstance(other, Integer): + return self.value < other.value + else: + return NotImplemented + + def __gt__(self, other): + if isinstance(other, Integer): + return self.value > other.value + else: + return NotImplemented + + def __le__(self, other): + if isinstance(other, Integer): + return self.__eq__(other) or self.__lt__(other) + else: + return NotImplemented + + def __ge__(self, other): + if isinstance(other, Integer): + return self.__eq__(other) or self.__gt__(other) + else: + return NotImplemented + class LongInteger(Base): """ diff --git a/kmip/services/server/policy.py b/kmip/services/server/policy.py new file mode 100644 index 0000000..5c40153 --- /dev/null +++ b/kmip/services/server/policy.py @@ -0,0 +1,1148 @@ +# Copyright (c) 2016 The Johns Hopkins University/Applied Physics Laboratory +# All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); you may +# not use this file except in compliance with the License. You may obtain +# a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. + +from kmip.core import enums +from kmip.core.messages import contents + + +class AttributeRuleSet(object): + """ + A set of flags and indicators defining how an attribute may be used. + + Every attribute defined by the KMIP specification comes with a set of + rules defining how and under what conditions the attribute should be + used. This class acts as a basic struct storing those rules. + + Attributes: + always_has_value: A flag defining if the attribute is always set. + initially_set_by: A list of entities that can implicitly set the + attribute. + modifiable_by_server: A flag defining if the server can modify the + attribute. + modifiable_by_client: A flag defining if the client can modify the + attribute. + deletable_by_client: A flag defining if the client can delete the + attribute. + multiple_instances_permitted: A flag defining if the attribute is + multivalued. + implicitly_set_by: A list of operations that can implicitly set the + attribute. + applies_to_object_types: A list of object types that the attribute + is applicable for. + version_added: The KMIP version in which support for the attribute + was added. + version_deprecated: The KMIP version in which support for the + attribute was deprecated. + """ + + def __init__(self, + always_has_value, + initially_set_by, + modifiable_by_server, + modifiable_by_client, + deletable_by_client, + multivalued, + implicitly_set_by, + applies_to_object_types, + version_added, + version_deprecated=None): + """ + Create an AttributeRuleSet. + + Args: + always_has_value (bool): A flag indicating whether or not this + attribute is always set for a managed object. Required. + initially_set_by (list): A list of strings indicating if the + attribute can be initially set by the 'server' and/or the + 'client'. Required. + modifiable_by_server (bool): A flag indicating whether the server + can independently modify the value of the attribute without + any prompting by the client. Required. + modifiable_by_client (bool): A flag indicating whether the client + can modify the value of the attribute. Required. + deletable_by_client (bool): A flag indicating whether the client + can delete the attribute from the managed object. Required. + multivalued (bool): A flag indicating whether or not a managed + object can have multiple instances of the attribute set at + the same time. Required. + implicitly_set_by (list): A list of Operation enumerations + detailing which server operations are allowed to set the + value of the attribute without direct instruction by the + client.Required. + applies_to_object_types (list): A list of ObjectType enumerations + detailing which managed object types the attribute applies to. + version_added (ProtocolVersion): The KMIP version in which support + for the attribute was added. Required. + version_deprecated (ProtocolVersion): The KMIP version in which + support for the attribute was deprecated. Optional, defaults + to None. + """ + self.always_has_value = always_has_value + self.initially_set_by = initially_set_by + self.modifiable_by_server = modifiable_by_server + self.modifiable_by_client = modifiable_by_client + self.deletable_by_client = deletable_by_client + self.multiple_instances_permitted = multivalued + self.implicitly_set_by = implicitly_set_by + self.applies_to_object_types = applies_to_object_types + self.version_added = version_added + self.version_deprecated = version_deprecated + + +class AttributePolicy(object): + """ + A collection of attribute rules and methods to query those rules. + + This policy class allows for the basic storage and retrieval of + attribute metadata. This metadata changes slightly across KMIP versions + and across the object types associated with different attributes. It + includes information on which entities can modify the attributes, which + object types the attributes are applicable to, and more. It is meant to + be used only by the KmipEngine. + + Metadata queries include questions like: + * Is this attribute supported in KMIP 1.0? + * Is this attribute deprecated in KMIP 1.1? + * Is this attribute applicable for the SymmetricKey object type? + * Is this attribute allowed to have multiple values? + """ + + 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.create(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.create(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.create(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.create(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.create(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.create(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.create(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.create(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.create(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.create(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.create(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.create(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.create(1, 0), + contents.ProtocolVersion.create(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.create(1, 0), + contents.ProtocolVersion.create(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.create(1, 0), + contents.ProtocolVersion.create(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.create(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.create(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.create(1, 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.create(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.create(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.create(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.create(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.create(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.create(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.create(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.create(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.create(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.create(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.create(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.create(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.create(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.create(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.create(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.create(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.create(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.create(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.create(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.create(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.create(1, 0) + ), + } + + def is_attribute_supported(self, attribute): + """ + Check if the attribute is supported by the current KMIP version. + + Args: + attribute (string): The name of the attribute + (e.g., 'Cryptographic Algorithm'). Required. + Returns: + bool: True if the attribute is supported by the current KMIP + version. False otherwise. + """ + if attribute not in self._attribute_rule_sets.keys(): + return False + + rule_set = self._attribute_rule_sets.get(attribute) + if self._version >= rule_set.version_added: + return True + else: + return False + + def is_attribute_deprecated(self, attribute): + """ + Check if the attribute is deprecated by the current KMIP version. + + Args: + attribute (string): The name of the attribute + (e.g., 'Unique Identifier'). Required. + """ + rule_set = self._attribute_rule_sets.get(attribute) + if rule_set.version_deprecated: + if self._version >= rule_set.version_deprecated: + return True + else: + return False + else: + return False + + def is_attribute_applicable_to_object_type(self, attribute, object_type): + """ + Check if the attribute is supported by the given object type. + + Args: + attribute (string): The name of the attribute (e.g., 'Name'). + Required. + object_type (ObjectType): An ObjectType enumeration + (e.g., ObjectType.SYMMETRIC_KEY). Required. + Returns: + bool: True if the attribute is applicable to the object type. + False otherwise. + """ + # TODO (peterhamilton) Handle applicability between certificate types + rule_set = self._attribute_rule_sets.get(attribute) + if object_type in rule_set.applies_to_object_types: + return True + else: + return False + + def is_attribute_multivalued(self, attribute): + """ + Check if the attribute is allowed to have multiple instances. + + Args: + attribute (string): The name of the attribute + (e.g., 'State'). Required. + """ + # TODO (peterhamilton) Handle multivalue swap between certificate types + rule_set = self._attribute_rule_sets.get(attribute) + return rule_set.multiple_instances_permitted diff --git a/kmip/tests/unit/core/messages/contents/test_protocol_version.py b/kmip/tests/unit/core/messages/contents/test_protocol_version.py index 9c1425c..e84901c 100644 --- a/kmip/tests/unit/core/messages/contents/test_protocol_version.py +++ b/kmip/tests/unit/core/messages/contents/test_protocol_version.py @@ -169,6 +169,78 @@ class TestProtocolVersion(TestCase): self.assertTrue(a != b) + def test_less_than(self): + """ + Test that the less than operator returns True/False when comparing + two different ProtocolVersions. + """ + a = ProtocolVersion.create(1, 0) + b = ProtocolVersion.create(1, 1) + c = ProtocolVersion.create(2, 0) + d = ProtocolVersion.create(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) + + def test_greater_than(self): + """ + Test that the greater than operator returns True/False when + comparing two different ProtocolVersions. + """ + a = ProtocolVersion.create(1, 0) + b = ProtocolVersion.create(1, 1) + c = ProtocolVersion.create(2, 0) + d = ProtocolVersion.create(0, 2) + + self.assertFalse(a > b) + self.assertTrue(b > a) + self.assertFalse(a > a) + self.assertFalse(a > c) + self.assertTrue(c > a) + self.assertTrue(c > d) + self.assertFalse(d > c) + + def test_less_than_or_equal(self): + """ + Test that the less than or equal operator returns True/False when + comparing two different ProtocolVersions. + """ + a = ProtocolVersion.create(1, 0) + b = ProtocolVersion.create(1, 1) + c = ProtocolVersion.create(2, 0) + d = ProtocolVersion.create(0, 2) + + self.assertTrue(a <= b) + self.assertFalse(b <= a) + self.assertTrue(a <= a) + self.assertTrue(a <= c) + self.assertFalse(c <= a) + self.assertFalse(c <= d) + self.assertTrue(d <= c) + + def test_greater_than_or_equal(self): + """ + Test that the greater than or equal operator returns True/False when + comparing two different ProtocolVersions. + """ + a = ProtocolVersion.create(1, 0) + b = ProtocolVersion.create(1, 1) + c = ProtocolVersion.create(2, 0) + d = ProtocolVersion.create(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) + def test_repr(self): a = ProtocolVersion.create(1, 0) diff --git a/kmip/tests/unit/core/primitives/test_integer.py b/kmip/tests/unit/core/primitives/test_integer.py index 9dbbeca..02b05dd 100644 --- a/kmip/tests/unit/core/primitives/test_integer.py +++ b/kmip/tests/unit/core/primitives/test_integer.py @@ -223,3 +223,159 @@ class TestInteger(testtools.TestCase): self.assertEqual(len_exp, len_rcv, self.bad_write.format(len_exp, len_rcv)) self.assertEqual(encoding, result, self.bad_encoding) + + def test_repr(self): + """ + Test that the representation of an Integer is formatted properly. + """ + integer = primitives.Integer() + value = "value={0}".format(integer.value) + self.assertEqual( + "Integer({0})".format(value), repr(integer)) + + def test_str(self): + """ + Test that the string representation of an Integer is formatted + properly. + """ + self.assertEqual("0", str(primitives.Integer())) + + def test_equal_on_equal(self): + """ + Test that the equality operator returns True when comparing two + Integers. + """ + a = primitives.Integer(1) + b = primitives.Integer(1) + + self.assertTrue(a == b) + self.assertTrue(b == a) + + def test_equal_on_equal_and_empty(self): + """ + Test that the equality operator returns True when comparing two + Integers. + """ + a = primitives.Integer() + b = primitives.Integer() + + self.assertTrue(a == b) + self.assertTrue(b == a) + + def test_equal_on_not_equal(self): + """ + Test that the equality operator returns False when comparing two + Integers with different values. + """ + a = primitives.Integer(1) + b = primitives.Integer(2) + + self.assertFalse(a == b) + self.assertFalse(b == a) + + def test_equal_on_type_mismatch(self): + """ + Test that the equality operator returns False when comparing an + Integer to a non-Integer object. + """ + a = primitives.Integer() + b = 'invalid' + + self.assertFalse(a == b) + self.assertFalse(b == a) + + def test_not_equal_on_equal(self): + """ + Test that the inequality operator returns False when comparing + two Integers with the same values. + """ + a = primitives.Integer(1) + b = primitives.Integer(1) + + self.assertFalse(a != b) + self.assertFalse(b != a) + + def test_not_equal_on_equal_and_empty(self): + """ + Test that the inequality operator returns False when comparing + two Integers. + """ + a = primitives.Integer() + b = primitives.Integer() + + self.assertFalse(a != b) + self.assertFalse(b != a) + + def test_not_equal_on_not_equal(self): + """ + Test that the inequality operator returns True when comparing two + Integers with different values. + """ + a = primitives.Integer(1) + b = primitives.Integer(2) + + self.assertTrue(a != b) + self.assertTrue(b != a) + + def test_not_equal_on_type_mismatch(self): + """ + Test that the inequality operator returns True when comparing an + Integer to a non-Integer object. + """ + a = primitives.Integer() + b = 'invalid' + + self.assertTrue(a != b) + self.assertTrue(b != a) + + def test_less_than(self): + """ + Test that the less than operator returns True/False when comparing + two Integers with different values. + """ + a = primitives.Integer(1) + b = primitives.Integer(2) + + self.assertTrue(a < b) + self.assertFalse(b < a) + self.assertFalse(a < a) + + def test_greater_than(self): + """ + Test that the greater than operator returns True/False when comparing + two Integers with different values. + """ + a = primitives.Integer(1) + b = primitives.Integer(2) + + self.assertFalse(a > b) + self.assertTrue(b > a) + self.assertFalse(b > b) + + def test_less_than_or_equal(self): + """ + Test that the less than or equal operator returns True/False when + comparing two Integers with different values. + """ + a = primitives.Integer(1) + b = primitives.Integer(2) + c = primitives.Integer(1) + + self.assertTrue(a <= b) + self.assertFalse(b <= c) + self.assertTrue(a <= c) + self.assertTrue(a <= a) + + def test_greater_than_or_equal(self): + """ + Test that the greater than or equal operator returns True/False when + comparing two Integers with different values. + """ + a = primitives.Integer(1) + b = primitives.Integer(2) + c = primitives.Integer(1) + + self.assertFalse(a >= b) + self.assertTrue(b >= c) + self.assertTrue(a >= c) + self.assertTrue(a >= a) diff --git a/kmip/tests/unit/services/server/test_policy.py b/kmip/tests/unit/services/server/test_policy.py new file mode 100644 index 0000000..542d99d --- /dev/null +++ b/kmip/tests/unit/services/server/test_policy.py @@ -0,0 +1,114 @@ +# Copyright (c) 2016 The Johns Hopkins University/Applied Physics Laboratory +# All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); you may +# not use this file except in compliance with the License. You may obtain +# a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. + +import testtools + +from kmip.core import enums +from kmip.core.messages import contents +from kmip.services.server import policy + + +class TestAttributePolicy(testtools.TestCase): + """ + A test engine for AttributePolicy. + """ + + def setUp(self): + super(TestAttributePolicy, self).setUp() + + def tearDown(self): + super(TestAttributePolicy, self).tearDown() + + def test_init(self): + """ + Test that an AttributePolicy can be built without any errors. + """ + policy.AttributePolicy(contents.ProtocolVersion.create(1, 0)) + + def test_is_attribute_supported(self): + """ + Test that is_attribute_supported returns the expected results in all + cases. + """ + rules = policy.AttributePolicy(contents.ProtocolVersion.create(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 test_is_attribute_deprecated(self): + """ + Test that is_attribute_deprecated returns the expected results in all + cases. + """ + rules = policy.AttributePolicy(contents.ProtocolVersion.create(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.create(1, 1)) + + result = rules.is_attribute_deprecated(attribute_b) + self.assertTrue(result) + + 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.create(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_multivalued(self): + """ + Test that is_attribute_multivalued returns the expected results in + all cases. + """ + rules = policy.AttributePolicy(contents.ProtocolVersion.create(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)