From 314dd8761e42d6a610ab147d2e218ffbc12360cf Mon Sep 17 00:00:00 2001 From: Peter Hamilton Date: Mon, 22 Apr 2019 16:59:26 -0400 Subject: [PATCH] Update the Query payloads This change upgrades the Query payloads, fixing error messages, comments, local variables, and internal payload structure to bring Query support up to KMIP 1.4 standards, in addition to compliance with the current payload format. The corresponding unit test suite has been completely rewritten to reflect these changes. This change prepares the Query payloads for future updates to support KMIP 2.0. --- kmip/core/messages/payloads/query.py | 1099 ++++- kmip/services/server/engine.py | 44 +- .../integration/services/test_integration.py | 27 +- .../unit/core/messages/payloads/test_query.py | 4292 +++++++++++++++-- .../tests/unit/services/server/test_engine.py | 182 +- kmip/tests/unit/services/test_kmip_client.py | 10 +- 6 files changed, 4834 insertions(+), 820 deletions(-) diff --git a/kmip/core/messages/payloads/query.py b/kmip/core/messages/payloads/query.py index cc4fc47..f840652 100644 --- a/kmip/core/messages/payloads/query.py +++ b/kmip/core/messages/payloads/query.py @@ -13,24 +13,17 @@ # License for the specific language governing permissions and limitations # under the License. -from six.moves import xrange - -from kmip.core.attributes import ApplicationNamespace -from kmip.core.attributes import ObjectType +import six from kmip.core import enums -from kmip.core.messages.contents import Operation - -from kmip.core.misc import QueryFunction -from kmip.core.misc import ServerInformation -from kmip.core.misc import VendorIdentification - -from kmip.core.objects import ExtensionInformation -from kmip.core.primitives import Struct -from kmip.core.utils import BytearrayStream +from kmip.core import exceptions +from kmip.core import misc +from kmip.core import objects +from kmip.core import primitives +from kmip.core import utils -class QueryRequestPayload(Struct): +class QueryRequestPayload(primitives.Struct): """ A request payload for the Query operation. @@ -50,91 +43,156 @@ class QueryRequestPayload(Struct): """ super(QueryRequestPayload, self).__init__(enums.Tags.REQUEST_PAYLOAD) - if query_functions is None: - self.query_functions = list() + self._query_functions = None + + self.query_functions = query_functions + + @property + def query_functions(self): + if self._query_functions: + return [x.value for x in self._query_functions] + return None + + @query_functions.setter + def query_functions(self, value): + if value is None: + self._query_functions = None + elif isinstance(value, list): + query_functions = [] + for v in value: + if isinstance(v, enums.QueryFunction): + query_functions.append( + primitives.Enumeration( + enums.QueryFunction, + value=v, + tag=enums.Tags.QUERY_FUNCTION + ) + ) + else: + raise TypeError( + "The query functions must be a list of QueryFunction " + "enumerations." + ) + self._query_functions = query_functions else: - self.query_functions = query_functions + raise TypeError( + "The query functions must be a list of QueryFunction " + "enumerations." + ) - self.validate() - - def read(self, istream, kmip_version=enums.KMIPVersion.KMIP_1_0): + def read(self, input_buffer, kmip_version=enums.KMIPVersion.KMIP_1_0): """ Read the data encoding the QueryRequestPayload object and decode it into its constituent parts. Args: - istream (Stream): A data stream containing encoded object data, - supporting a read method; usually a BytearrayStream object. + input_buffer (Stream): A data stream containing encoded object + data, supporting a read method; usually a BytearrayStream + object. kmip_version (KMIPVersion): An enumeration defining the KMIP version with which the object will be decoded. Optional, defaults to KMIP 1.0. + + Raises: + InvalidKmipEncoding: Raised if the query functions are missing + from the encoded payload. """ super(QueryRequestPayload, self).read( - istream, + input_buffer, kmip_version=kmip_version ) - tstream = BytearrayStream(istream.read(self.length)) + local_buffer = utils.BytearrayStream(input_buffer.read(self.length)) - while(self.is_tag_next(enums.Tags.QUERY_FUNCTION, tstream)): - query_function = QueryFunction() - query_function.read(tstream, kmip_version=kmip_version) - self.query_functions.append(query_function) + query_functions = [] + while(self.is_tag_next(enums.Tags.QUERY_FUNCTION, local_buffer)): + query_function = primitives.Enumeration( + enums.QueryFunction, + tag=enums.Tags.QUERY_FUNCTION + ) + query_function.read(local_buffer, kmip_version=kmip_version) + query_functions.append(query_function) - self.is_oversized(tstream) - self.validate() + if query_functions: + self._query_functions = query_functions + else: + raise exceptions.InvalidKmipEncoding( + "The Query request payload encoding is missing the query " + "functions." + ) - def write(self, ostream, kmip_version=enums.KMIPVersion.KMIP_1_0): + self.is_oversized(local_buffer) + + def write(self, output_buffer, kmip_version=enums.KMIPVersion.KMIP_1_0): """ Write the data encoding the QueryRequestPayload object to a stream. Args: - ostream (Stream): A data stream in which to encode object data, - supporting a write method; usually a BytearrayStream object. + output_buffer (Stream): A data stream in which to encode object + data, supporting a write method; usually a BytearrayStream + object. kmip_version (KMIPVersion): An enumeration defining the KMIP version with which the object will be encoded. Optional, defaults to KMIP 1.0. + + Raises: + InvalidField: Raised if the query functions are not defined. """ - tstream = BytearrayStream() + local_buffer = utils.BytearrayStream() - for query_function in self.query_functions: - query_function.write(tstream, kmip_version=kmip_version) + if self._query_functions: + for query_function in self._query_functions: + query_function.write(local_buffer, kmip_version=kmip_version) + else: + raise exceptions.InvalidField( + "The Query request payload is missing the query functions " + "field." + ) - self.length = tstream.length() + self.length = local_buffer.length() super(QueryRequestPayload, self).write( - ostream, + output_buffer, kmip_version=kmip_version ) - ostream.write(tstream.buffer) + output_buffer.write(local_buffer.buffer) - def validate(self): - """ - Error check the attributes of the QueryRequestPayload object. - """ - self.__validate() + def __repr__(self): + d = "query_functions={}".format( + "[{}]".format( + ", ".join(["{}".format(x) for x in self.query_functions]) + ) if self.query_functions else None + ) + return "QueryRequestPayload({})".format(d) - def __validate(self): - if isinstance(self.query_functions, list): - for i in xrange(len(self.query_functions)): - query_function = self.query_functions[i] - if not isinstance(query_function, QueryFunction): - msg = "invalid query function ({0} in list)".format(i) - msg += "; expected {0}, received {1}".format( - QueryFunction, query_function) - raise TypeError(msg) + def __str__(self): + d = '"query_functions": {}'.format( + "[{}]".format( + ", ".join(["{}".format(x) for x in self.query_functions]) + ) if self.query_functions else None + ) + return "{" + d + "}" + + def __eq__(self, other): + if isinstance(other, QueryRequestPayload): + if self.query_functions == other.query_functions: + return True + else: + return False else: - msg = "invalid query functions list" - msg += "; expected {0}, received {1}".format( - list, self.query_functions) - raise TypeError(msg) + return NotImplemented + + def __ne__(self, other): + if isinstance(other, QueryRequestPayload): + return not (self == other) + else: + return NotImplemented -class QueryResponsePayload(Struct): +class QueryResponsePayload(primitives.Struct): """ A response payload for the Query operation. The payload contains different sets of responses that the KMIP server - provides in response to the initial Query request. See Section 4.25 of the - KMIP 1.1 specification for more information. + provides in response to the initial Query request. Attributes: operations: A list of Operations supported by the server. @@ -144,228 +202,839 @@ class QueryResponsePayload(Struct): substructures. application_namespaces: A list of application namespaces supported by the server. - extension_information: A list of ExtensionInformation objects detailing - Objects supported by the server with ItemTag values in the - Extensions range. + extension_information: A list of ExtensionInformation objects + detailing Objects supported by the server with ItemTag values in + the Extensions range. + attestation_types: A list of AttestationType enumerations detailing + the attestation methods supported by the server. + rng_parameters: A list of RNGParameters structures detailing the types + of random number generators supported by the server. + profile_information: A list of ProfileInformation structures detailing + the different profiles supported by the server. + validation_information: A list of ValidationInformation structures + detailing the types of formal validation supported by the server. + capability_information: A list of CapabilityInformation structures + detailing the different capabilities supported by the server. + client_registration_methods: A list of ClientRegistrationMethod + enumerations detailing the different client registration methods + supported by the server. """ - def __init__(self, operations=None, object_types=None, - vendor_identification=None, server_information=None, - application_namespaces=None, extension_information=None): + def __init__(self, + operations=None, + object_types=None, + vendor_identification=None, + server_information=None, + application_namespaces=None, + extension_information=None, + attestation_types=None, + rng_parameters=None, + profile_information=None, + validation_information=None, + capability_information=None, + client_registration_methods=None): """ Construct a QueryResponsePayload object. Args: operations (list): A list of Operations supported by the server. - object_types (list): A list of ObjectTypes supported by the server. - vendor_identification (VendorIdentification): A string identifying - the server vendor. - server_information (ServerInformation): A structure containing - vendor-specific fields and substructures. + Optional, defaults to None. + object_types (list): A list of ObjectTypes supported by the + server. Optional, defaults to None. + vendor_identification (string): A string identifying the server + vendor. Optional, defaults to None. + server_information (structure): A ServerInformation structure + containing vendor-specific fields and substructures. Optional, + defaults to None. application_namespaces (list): A list of application namespaces - supported by the server. + supported by the server. Optional, defaults to None. extension_information (list): A list of ExtensionInformation objects detailing Objects supported by the server with ItemTag - values in the Extensions range. + values in the Extensions range. Optional, defaults to None. + attestation_types (list): A list of AttestationType enumerations + detailing the attestation methods supported by the server. + Optional, defaults to None. + rng_parameters (list): A list of RNGParameters structures detailing + the types of random number generators supported by the server. + Optional, defaults to None. + profile_information (list): A list of ProfileInformation structures + detailing the different profiles supported by the server. + Optional, defaults to None. + validation_information (list): A list of ValidationInformation + structures detailing the types of formal validation supported + by the server. Optional, defaults to None. + capability_information (list): A list of CapabilityInformation + structures detailing the different capabilities supported by + the server. Optional, defaults to None. + client_registration_methods (list): A list of + ClientRegistrationMethod enumerations detailing the different + client registration methods supported by the server. Optional, + defaults to None. """ super(QueryResponsePayload, self).__init__( enums.Tags.RESPONSE_PAYLOAD ) - if operations is None: - self.operations = list() - else: - self.operations = operations - - if object_types is None: - self.object_types = list() - else: - self.object_types = object_types + self._operations = None + self._object_types = None + self._vendor_identification = None + self._server_information = None + self._application_namespaces = None + self._extension_information = None + self._attestation_types = None + self._rng_parameters = None + self._profile_information = None + self._validation_information = None + self._capability_information = None + self._client_registration_methods = None + self.operations = operations + self.object_types = object_types self.vendor_identification = vendor_identification self.server_information = server_information + self.application_namespaces = application_namespaces + self.extension_information = extension_information + self.attestation_types = attestation_types + self.rng_parameters = rng_parameters + self.profile_information = profile_information + self.validation_information = validation_information + self.capability_information = capability_information + self.client_registration_methods = client_registration_methods - if application_namespaces is None: - self.application_namespaces = list() + @property + def operations(self): + if self._operations: + return [x.value for x in self._operations] + return None + + @operations.setter + def operations(self, value): + if value is None: + self._operations = None + elif isinstance(value, list): + operations = [] + for i in value: + if isinstance(i, enums.Operation): + operations.append( + primitives.Enumeration( + enums.Operation, + value=i, + tag=enums.Tags.OPERATION + ) + ) + else: + raise TypeError( + "The operations must be a list of Operation " + "enumerations." + ) + self._operations = operations else: - self.application_namespaces = application_namespaces + raise TypeError( + "The operations must be a list of Operation enumerations." + ) - if extension_information is None: - self.extension_information = list() + @property + def object_types(self): + if self._object_types: + return [x.value for x in self._object_types] + return None + + @object_types.setter + def object_types(self, value): + if value is None: + self._object_types = None + elif isinstance(value, list): + object_types = [] + for i in value: + if isinstance(i, enums.ObjectType): + object_types.append( + primitives.Enumeration( + enums.ObjectType, + value=i, + tag=enums.Tags.OBJECT_TYPE + ) + ) + else: + raise TypeError( + "The object types must be a list of ObjectType " + "enumerations." + ) + self._object_types = object_types else: - self.extension_information = extension_information + raise TypeError( + "The object types must be a list of ObjectType enumerations." + ) - self.validate() + @property + def vendor_identification(self): + if self._vendor_identification: + return self._vendor_identification.value + return None - def read(self, istream, kmip_version=enums.KMIPVersion.KMIP_1_0): + @vendor_identification.setter + def vendor_identification(self, value): + if value is None: + self._vendor_identification = None + elif isinstance(value, six.string_types): + self._vendor_identification = primitives.TextString( + value=value, + tag=enums.Tags.VENDOR_IDENTIFICATION + ) + else: + raise TypeError("The vendor identification must be a string.") + + @property + def server_information(self): + return self._server_information + + @server_information.setter + def server_information(self, value): + if value is None: + self._server_information = None + elif isinstance(value, misc.ServerInformation): + self._server_information = value + else: + raise TypeError( + "The server information must be a ServerInformation structure." + ) + + @property + def application_namespaces(self): + if self._application_namespaces: + return [x.value for x in self._application_namespaces] + return None + + @application_namespaces.setter + def application_namespaces(self, value): + if value is None: + self._application_namespaces = None + elif isinstance(value, list): + application_namespaces = [] + for i in value: + if isinstance(i, six.string_types): + application_namespaces.append( + primitives.TextString( + value=i, + tag=enums.Tags.APPLICATION_NAMESPACE + ) + ) + else: + raise TypeError( + "The application namespaces must be a list of strings." + ) + self._application_namespaces = application_namespaces + else: + raise TypeError( + "The application namespaces must be a list of strings." + ) + + @property + def extension_information(self): + if self._extension_information: + return [x for x in self._extension_information] + return None + + @extension_information.setter + def extension_information(self, value): + if value is None: + self._extension_information = None + elif isinstance(value, list): + extension_information = [] + for i in value: + if isinstance(i, objects.ExtensionInformation): + extension_information.append(i) + else: + raise TypeError( + "The extension information must be a list of " + "ExtensionInformation structures." + ) + self._extension_information = extension_information + else: + raise TypeError( + "The extension information must be a list of " + "ExtensionInformation structures." + ) + + @property + def attestation_types(self): + if self._attestation_types: + return [x.value for x in self._attestation_types] + return None + + @attestation_types.setter + def attestation_types(self, value): + if value is None: + self._attestation_types = None + elif isinstance(value, list): + attestation_types = [] + for i in value: + if isinstance(i, enums.AttestationType): + attestation_types.append( + primitives.Enumeration( + enums.AttestationType, + value=i, + tag=enums.Tags.ATTESTATION_TYPE + ) + ) + else: + raise TypeError( + "The attestation types must be a list of " + "AttestationType enumerations." + ) + self._attestation_types = attestation_types + else: + raise TypeError( + "The attestation types must be a list of AttestationType " + "enumerations." + ) + + @property + def rng_parameters(self): + return self._rng_parameters + + @rng_parameters.setter + def rng_parameters(self, value): + if value is None: + self._rng_parameters = None + elif isinstance(value, list): + rng_parameters = [] + for i in value: + if isinstance(i, objects.RNGParameters): + rng_parameters.append(i) + else: + raise TypeError( + "The RNG parameters must be a list of RNGParameters " + "structures." + ) + self._rng_parameters = rng_parameters + else: + raise TypeError( + "The RNG parameters must be a list of RNGParameters " + "structures." + ) + + @property + def profile_information(self): + return self._profile_information + + @profile_information.setter + def profile_information(self, value): + if value is None: + self._profile_information = None + elif isinstance(value, list): + profile_information = [] + for i in value: + if isinstance(i, objects.ProfileInformation): + profile_information.append(i) + else: + raise TypeError( + "The profile information must be a list of " + "ProfileInformation structures." + ) + self._profile_information = profile_information + else: + raise TypeError( + "The profile information must be a list of " + "ProfileInformation structures." + ) + + @property + def validation_information(self): + return self._validation_information + + @validation_information.setter + def validation_information(self, value): + if value is None: + self._validation_information = None + elif isinstance(value, list): + validation_information = [] + for i in value: + if isinstance(i, objects.ValidationInformation): + validation_information.append(i) + else: + raise TypeError( + "The validation information must be a list of " + "ValidationInformation structures." + ) + self._validation_information = validation_information + else: + raise TypeError( + "The validation information must be a list of " + "ValidationInformation structures." + ) + + @property + def capability_information(self): + return self._capability_information + + @capability_information.setter + def capability_information(self, value): + if value is None: + self._capability_information = None + elif isinstance(value, list): + capability_information = [] + for i in value: + if isinstance(i, objects.CapabilityInformation): + capability_information.append(i) + else: + raise TypeError( + "The capability information must be a list of " + "CapabilityInformation structures." + ) + self._capability_information = capability_information + else: + raise TypeError( + "The capability information must be a list of " + "CapabilityInformation structures." + ) + + @property + def client_registration_methods(self): + if self._client_registration_methods: + return [x.value for x in self._client_registration_methods] + return None + + @client_registration_methods.setter + def client_registration_methods(self, value): + if value is None: + self._client_registration_methods = None + elif isinstance(value, list): + client_registration_methods = [] + for i in value: + if isinstance(i, enums.ClientRegistrationMethod): + client_registration_methods.append( + primitives.Enumeration( + enums.ClientRegistrationMethod, + value=i, + tag=enums.Tags.CLIENT_REGISTRATION_METHOD + ) + ) + else: + raise TypeError( + "The client registration methods must be a list of " + "ClientRegistrationMethod enumerations." + ) + self._client_registration_methods = client_registration_methods + else: + raise TypeError( + "The client registration methods must be a list of " + "ClientRegistrationMethod enumerations." + ) + + def read(self, input_buffer, kmip_version=enums.KMIPVersion.KMIP_1_0): """ Read the data encoding the QueryResponsePayload object and decode it into its constituent parts. Args: - istream (Stream): A data stream containing encoded object data, - supporting a read method; usually a BytearrayStream object. + input_buffer (Stream): A data stream containing encoded object + data, supporting a read method; usually a BytearrayStream + object. kmip_version (KMIPVersion): An enumeration defining the KMIP version with which the object will be decoded. Optional, defaults to KMIP 1.0. """ super(QueryResponsePayload, self).read( - istream, + input_buffer, kmip_version=kmip_version ) - tstream = BytearrayStream(istream.read(self.length)) + local_buffer = utils.BytearrayStream(input_buffer.read(self.length)) - while(self.is_tag_next(enums.Tags.OPERATION, tstream)): - operation = Operation() - operation.read(tstream, kmip_version=kmip_version) - self.operations.append(operation) + operations = [] + while(self.is_tag_next(enums.Tags.OPERATION, local_buffer)): + operation = primitives.Enumeration( + enums.Operation, + tag=enums.Tags.OPERATION + ) + operation.read(local_buffer, kmip_version=kmip_version) + operations.append(operation) + self._operations = operations - while(self.is_tag_next(enums.Tags.OBJECT_TYPE, tstream)): - object_type = ObjectType() - object_type.read(tstream, kmip_version=kmip_version) - self.object_types.append(object_type) + object_types = [] + while(self.is_tag_next(enums.Tags.OBJECT_TYPE, local_buffer)): + object_type = primitives.Enumeration( + enums.ObjectType, + tag=enums.Tags.OBJECT_TYPE + ) + object_type.read(local_buffer, kmip_version=kmip_version) + object_types.append(object_type) + self._object_types = object_types - if self.is_tag_next(enums.Tags.VENDOR_IDENTIFICATION, tstream): - self.vendor_identification = VendorIdentification() - self.vendor_identification.read( - tstream, + if self.is_tag_next(enums.Tags.VENDOR_IDENTIFICATION, local_buffer): + vendor_identification = primitives.TextString( + tag=enums.Tags.VENDOR_IDENTIFICATION + ) + vendor_identification.read( + local_buffer, kmip_version=kmip_version ) + self._vendor_identification = vendor_identification - if self.is_tag_next(enums.Tags.SERVER_INFORMATION, tstream): - self.server_information = ServerInformation() - self.server_information.read(tstream, kmip_version=kmip_version) + if self.is_tag_next(enums.Tags.SERVER_INFORMATION, local_buffer): + server_information = misc.ServerInformation() + server_information.read( + local_buffer, + kmip_version=kmip_version + ) + self._server_information = server_information - while(self.is_tag_next(enums.Tags.APPLICATION_NAMESPACE, tstream)): - application_namespace = ApplicationNamespace() - application_namespace.read(tstream, kmip_version=kmip_version) - self.application_namespaces.append(application_namespace) + application_namespaces = [] + while(self.is_tag_next( + enums.Tags.APPLICATION_NAMESPACE, + local_buffer + ) + ): + application_namespace = primitives.TextString( + tag=enums.Tags.APPLICATION_NAMESPACE + ) + application_namespace.read(local_buffer, kmip_version=kmip_version) + application_namespaces.append(application_namespace) + self._application_namespaces = application_namespaces - while(self.is_tag_next(enums.Tags.EXTENSION_INFORMATION, tstream)): - extension_information = ExtensionInformation() - extension_information.read(tstream, kmip_version=kmip_version) - self.extension_information.append(extension_information) + if kmip_version >= enums.KMIPVersion.KMIP_1_1: + extensions_information = [] + while(self.is_tag_next( + enums.Tags.EXTENSION_INFORMATION, + local_buffer + ) + ): + extension_information = objects.ExtensionInformation() + extension_information.read( + local_buffer, + kmip_version=kmip_version + ) + extensions_information.append(extension_information) + self._extension_information = extensions_information - self.is_oversized(tstream) - self.validate() + if kmip_version >= enums.KMIPVersion.KMIP_1_2: + attestation_types = [] + while(self.is_tag_next(enums.Tags.ATTESTATION_TYPE, local_buffer)): + attestation_type = primitives.Enumeration( + enums.AttestationType, + tag=enums.Tags.ATTESTATION_TYPE + ) + attestation_type.read(local_buffer, kmip_version=kmip_version) + attestation_types.append(attestation_type) + self._attestation_types = attestation_types - def write(self, ostream, kmip_version=enums.KMIPVersion.KMIP_1_0): + if kmip_version >= enums.KMIPVersion.KMIP_1_3: + rngs_parameters = [] + while(self.is_tag_next(enums.Tags.RNG_PARAMETERS, local_buffer)): + rng_parameters = objects.RNGParameters() + rng_parameters.read(local_buffer, kmip_version=kmip_version) + rngs_parameters.append(rng_parameters) + self._rng_parameters = rngs_parameters + + profiles_information = [] + while(self.is_tag_next( + enums.Tags.PROFILE_INFORMATION, + local_buffer + ) + ): + profile_information = objects.ProfileInformation() + profile_information.read( + local_buffer, + kmip_version=kmip_version + ) + profiles_information.append(profile_information) + self._profile_information = profiles_information + + validations_information = [] + while(self.is_tag_next( + enums.Tags.VALIDATION_INFORMATION, + local_buffer + ) + ): + validation_information = objects.ValidationInformation() + validation_information.read( + local_buffer, + kmip_version=kmip_version + ) + validations_information.append(validation_information) + self._validation_information = validations_information + + capabilities_information = [] + while(self.is_tag_next( + enums.Tags.CAPABILITY_INFORMATION, + local_buffer + ) + ): + capability_information = objects.CapabilityInformation() + capability_information.read( + local_buffer, + kmip_version=kmip_version + ) + capabilities_information.append(capability_information) + self._capability_information = capabilities_information + + client_registration_methods = [] + while(self.is_tag_next( + enums.Tags.CLIENT_REGISTRATION_METHOD, + local_buffer + ) + ): + client_registration_method = primitives.Enumeration( + enums.ClientRegistrationMethod, + tag=enums.Tags.CLIENT_REGISTRATION_METHOD + ) + client_registration_method.read( + local_buffer, + kmip_version=kmip_version + ) + client_registration_methods.append(client_registration_method) + self._client_registration_methods = client_registration_methods + + self.is_oversized(local_buffer) + + def write(self, output_buffer, kmip_version=enums.KMIPVersion.KMIP_1_0): """ Write the data encoding the QueryResponsePayload object to a stream. Args: - ostream (Stream): A data stream in which to encode object data, - supporting a write method; usually a BytearrayStream object. + output_buffer (Stream): A data stream in which to encode object + data, supporting a write method; usually a BytearrayStream + object. kmip_version (KMIPVersion): An enumeration defining the KMIP version with which the object will be encoded. Optional, defaults to KMIP 1.0. """ - tstream = BytearrayStream() + local_buffer = utils.BytearrayStream() - for operation in self.operations: - operation.write(tstream, kmip_version=kmip_version) + if self._operations: + for operation in self._operations: + operation.write(local_buffer, kmip_version=kmip_version) - for object_type in self.object_types: - object_type.write(tstream, kmip_version=kmip_version) + if self._object_types: + for object_type in self._object_types: + object_type.write(local_buffer, kmip_version=kmip_version) - if self.vendor_identification is not None: - self.vendor_identification.write( - tstream, + if self._vendor_identification: + self._vendor_identification.write( + local_buffer, kmip_version=kmip_version ) - if self.server_information is not None: - self.server_information.write(tstream, kmip_version=kmip_version) + if self._server_information: + self._server_information.write( + local_buffer, + kmip_version=kmip_version + ) - for application_namespace in self.application_namespaces: - application_namespace.write(tstream, kmip_version=kmip_version) + if self._application_namespaces: + for application_namespace in self._application_namespaces: + application_namespace.write( + local_buffer, + kmip_version=kmip_version + ) - for extension_information in self.extension_information: - extension_information.write(tstream, kmip_version=kmip_version) + if kmip_version >= enums.KMIPVersion.KMIP_1_1: + if self._extension_information: + for extension_information in self._extension_information: + extension_information.write( + local_buffer, + kmip_version=kmip_version + ) - self.length = tstream.length() + if kmip_version >= enums.KMIPVersion.KMIP_1_2: + if self._attestation_types: + for attestation_type in self._attestation_types: + attestation_type.write( + local_buffer, + kmip_version=kmip_version + ) + + if kmip_version >= enums.KMIPVersion.KMIP_1_3: + if self._rng_parameters: + for rng_parameters in self._rng_parameters: + rng_parameters.write( + local_buffer, + kmip_version=kmip_version + ) + if self._profile_information: + for profile_information in self._profile_information: + profile_information.write( + local_buffer, + kmip_version=kmip_version + ) + if self._validation_information: + for validation_information in self._validation_information: + validation_information.write( + local_buffer, + kmip_version=kmip_version + ) + if self._capability_information: + for capability_information in self._capability_information: + capability_information.write( + local_buffer, + kmip_version=kmip_version + ) + if self._client_registration_methods: + for client_reg_method in self._client_registration_methods: + client_reg_method.write( + local_buffer, + kmip_version=kmip_version + ) + + self.length = local_buffer.length() super(QueryResponsePayload, self).write( - ostream, + output_buffer, kmip_version=kmip_version ) - ostream.write(tstream.buffer) + output_buffer.write(local_buffer.buffer) - def validate(self): - """ - Error check the attributes of the QueryRequestPayload object. - """ - self.__validate() + def __repr__(self): + o = "operations={}".format( + "[{}]".format( + ", ".join([str(x) for x in self.operations]) + ) if self.operations else None + ) + ot = "object_types={}".format( + "[{}]".format( + ", ".join([str(x) for x in self.object_types]) + ) if self.object_types else None + ) + vi = 'vendor_identification="{}"'.format(self.vendor_identification) + si = "server_information={}".format(repr(self.server_information)) + an = "application_namespaces={}".format( + "[{}]".format( + ", ".join( + ['"{}"'.format(x) for x in self.application_namespaces] + ) + ) if self.application_namespaces else None + ) + ei = "extension_information={}".format( + "[{}]".format( + ", ".join([repr(x) for x in self.extension_information]) + ) if self.extension_information else None + ) + at = "attestation_types={}".format( + "[{}]".format( + ", ".join([str(x) for x in self.attestation_types]) + ) if self.attestation_types else None + ) + rp = "rng_parameters={}".format( + "[{}]".format( + ", ".join([repr(x) for x in self.rng_parameters]) + ) if self.rng_parameters else None + ) + pi = "profile_information={}".format( + "[{}]".format( + ", ".join([repr(x) for x in self.profile_information]) + ) if self.profile_information else None + ) + vai = "validation_information={}".format( + "[{}]".format( + ", ".join([repr(x) for x in self.validation_information]) + ) if self.validation_information else None + ) + ci = "capability_information={}".format( + "[{}]".format( + ", ".join([repr(x) for x in self.capability_information]) + ) if self.capability_information else None + ) + crm = "client_registration_methods={}".format( + "[{}]".format( + ", ".join([str(x) for x in self.client_registration_methods]) + ) if self.client_registration_methods else None + ) - def __validate(self): - # TODO (peter-hamilton) Add separate validate_list function for this - if isinstance(self.operations, list): - for i in xrange(len(self.operations)): - operation = self.operations[i] - if not isinstance(operation, Operation): - msg = "invalid operation ({0} in list)".format(i) - msg += "; expected {0}, received {1}".format( - Operation, operation) - raise TypeError(msg) + v = ", ".join([o, ot, vi, si, an, ei, at, rp, pi, vai, ci, crm]) + + return "QueryResponsePayload({})".format(v) + + def __str__(self): + o = '"operations": {}'.format( + "[{}]".format( + ", ".join([str(x) for x in self.operations]) + ) if self.operations else None + ) + ot = '"object_types": {}'.format( + "[{}]".format( + ", ".join([str(x) for x in self.object_types]) + ) if self.object_types else None + ) + vi = '"vendor_identification": "{}"'.format(self.vendor_identification) + si = '"server_information": {}'.format(repr(self.server_information)) + an = '"application_namespaces": {}'.format( + "[{}]".format( + ", ".join( + ['"{}"'.format(x) for x in self.application_namespaces] + ) + ) if self.application_namespaces else None + ) + ei = '"extension_information": {}'.format( + "[{}]".format( + ", ".join([repr(x) for x in self.extension_information]) + ) if self.extension_information else None + ) + at = '"attestation_types": {}'.format( + "[{}]".format( + ", ".join([str(x) for x in self.attestation_types]) + ) if self.attestation_types else None + ) + rp = '"rng_parameters": {}'.format( + "[{}]".format( + ", ".join([str(x) for x in self.rng_parameters]) + ) if self.rng_parameters else None + ) + pi = '"profile_information": {}'.format( + "[{}]".format( + ", ".join([str(x) for x in self.profile_information]) + ) if self.profile_information else None + ) + vai = '"validation_information": {}'.format( + "[{}]".format( + ", ".join([str(x) for x in self.validation_information]) + ) if self.validation_information else None + ) + ci = '"capability_information": {}'.format( + "[{}]".format( + ", ".join([str(x) for x in self.capability_information]) + ) if self.capability_information else None + ) + crm = '"client_registration_methods": {}'.format( + "[{}]".format( + ", ".join([str(x) for x in self.client_registration_methods]) + ) if self.client_registration_methods else None + ) + + v = ", ".join([o, ot, vi, si, an, ei, at, rp, pi, vai, ci, crm]) + + return '{' + v + '}' + + def __eq__(self, other): + if isinstance(other, QueryResponsePayload): + if self.operations != other.operations: + return False + elif self.object_types != other.object_types: + return False + elif self.vendor_identification != other.vendor_identification: + return False + elif self.server_information != other.server_information: + return False + elif self.application_namespaces != other.application_namespaces: + return False + elif self.extension_information != other.extension_information: + return False + elif self.attestation_types != other.attestation_types: + return False + elif self.rng_parameters != other.rng_parameters: + return False + elif self.profile_information != other.profile_information: + return False + elif self.validation_information != other.validation_information: + return False + elif self.capability_information != other.capability_information: + return False + elif self.client_registration_methods != \ + other.client_registration_methods: + return False + else: + return True else: - msg = "invalid operations list" - msg += "; expected {0}, received {1}".format( - list, self.operations) - raise TypeError(msg) + return NotImplemented - if isinstance(self.object_types, list): - for i in xrange(len(self.object_types)): - object_type = self.object_types[i] - if not isinstance(object_type, ObjectType): - msg = "invalid object type ({0} in list)".format(i) - msg += "; expected {0}, received {1}".format( - ObjectType, object_type) - raise TypeError(msg) + def __ne__(self, other): + if isinstance(other, QueryResponsePayload): + return not (self == other) else: - msg = "invalid object types list" - msg += "; expected {0}, received {1}".format( - list, self.object_types) - raise TypeError(msg) - - if self.vendor_identification is not None: - if not isinstance(self.vendor_identification, - VendorIdentification): - msg = "invalid vendor identification" - msg += "; expected {0}, received {1}".format( - VendorIdentification, self.vendor_identification) - raise TypeError(msg) - - if self.server_information is not None: - if not isinstance(self.server_information, ServerInformation): - msg = "invalid server information" - msg += "; expected {0}, received {1}".format( - ServerInformation, self.server_information) - raise TypeError(msg) - - if isinstance(self.application_namespaces, list): - for i in xrange(len(self.application_namespaces)): - application_namespace = self.application_namespaces[i] - if not isinstance(application_namespace, ApplicationNamespace): - msg = "invalid application namespace ({0} in list)".format( - i) - msg += "; expected {0}, received {1}".format( - ApplicationNamespace, application_namespace) - raise TypeError(msg) - else: - msg = "invalid application namespaces list" - msg += "; expected {0}, received {1}".format( - list, self.application_namespaces) - raise TypeError(msg) - - if isinstance(self.extension_information, list): - for i in xrange(len(self.extension_information)): - extension_information = self.extension_information[i] - if not isinstance(extension_information, ExtensionInformation): - msg = "invalid extension information ({0} in list)".format( - i) - msg += "; expected {0}, received {1}".format( - ExtensionInformation, extension_information) - raise TypeError(msg) - else: - msg = "invalid extension information list" - msg += "; expected {0}, received {1}".format( - list, self.extension_information) - raise TypeError(msg) + return NotImplemented diff --git a/kmip/services/server/engine.py b/kmip/services/server/engine.py index 06cd63b..7b110d9 100644 --- a/kmip/services/server/engine.py +++ b/kmip/services/server/engine.py @@ -39,8 +39,6 @@ from kmip.core.messages import messages from kmip.core.messages import payloads -from kmip.core import misc - from kmip.pie import factory from kmip.pie import objects from kmip.pie import sqltypes @@ -1917,7 +1915,7 @@ class KmipEngine(object): def _process_query(self, payload): self._logger.info("Processing operation: Query") - queries = [x.value for x in payload.query_functions] + queries = payload.query_functions operations = list() objects = list() @@ -1928,38 +1926,38 @@ class KmipEngine(object): if enums.QueryFunction.QUERY_OPERATIONS in queries: operations = list([ - contents.Operation(enums.Operation.CREATE), - contents.Operation(enums.Operation.CREATE_KEY_PAIR), - contents.Operation(enums.Operation.REGISTER), - contents.Operation(enums.Operation.DERIVE_KEY), - contents.Operation(enums.Operation.LOCATE), - contents.Operation(enums.Operation.GET), - contents.Operation(enums.Operation.GET_ATTRIBUTES), - contents.Operation(enums.Operation.GET_ATTRIBUTE_LIST), - contents.Operation(enums.Operation.ACTIVATE), - contents.Operation(enums.Operation.REVOKE), - contents.Operation(enums.Operation.DESTROY), - contents.Operation(enums.Operation.QUERY) + enums.Operation.CREATE, + enums.Operation.CREATE_KEY_PAIR, + enums.Operation.REGISTER, + enums.Operation.DERIVE_KEY, + enums.Operation.LOCATE, + enums.Operation.GET, + enums.Operation.GET_ATTRIBUTES, + enums.Operation.GET_ATTRIBUTE_LIST, + enums.Operation.ACTIVATE, + enums.Operation.REVOKE, + enums.Operation.DESTROY, + enums.Operation.QUERY ]) if self._protocol_version >= contents.ProtocolVersion(1, 1): operations.extend([ - contents.Operation(enums.Operation.DISCOVER_VERSIONS) + enums.Operation.DISCOVER_VERSIONS ]) if self._protocol_version >= contents.ProtocolVersion(1, 2): operations.extend([ - contents.Operation(enums.Operation.ENCRYPT), - contents.Operation(enums.Operation.DECRYPT), - contents.Operation(enums.Operation.SIGN), - contents.Operation(enums.Operation.SIGNATURE_VERIFY), - contents.Operation(enums.Operation.MAC) + enums.Operation.ENCRYPT, + enums.Operation.DECRYPT, + enums.Operation.SIGN, + enums.Operation.SIGNATURE_VERIFY, + enums.Operation.MAC ]) if enums.QueryFunction.QUERY_OBJECTS in queries: objects = list() if enums.QueryFunction.QUERY_SERVER_INFORMATION in queries: - vendor_identification = misc.VendorIdentification( - "PyKMIP {0} Software Server".format(kmip.__version__) + vendor_identification = "PyKMIP {0} Software Server".format( + kmip.__version__ ) server_information = None if enums.QueryFunction.QUERY_APPLICATION_NAMESPACES in queries: diff --git a/kmip/tests/integration/services/test_integration.py b/kmip/tests/integration/services/test_integration.py index 5b12cf7..c90ef12 100644 --- a/kmip/tests/integration/services/test_integration.py +++ b/kmip/tests/integration/services/test_integration.py @@ -32,7 +32,7 @@ from kmip.core.enums import OpaqueDataType from kmip.core.enums import SecretDataType from kmip.core.enums import ResultStatus from kmip.core.enums import ResultReason -from kmip.core.enums import QueryFunction as QueryFunctionEnum +from kmip.core.enums import QueryFunction from kmip.core.factories.attributes import AttributeFactory from kmip.core.factories.credentials import CredentialFactory @@ -46,8 +46,6 @@ from kmip.core.objects import KeyMaterial from kmip.core.objects import KeyValue from kmip.core.objects import TemplateAttribute -from kmip.core.misc import QueryFunction - from kmip.core.secrets import SymmetricKey from kmip.core.secrets import PrivateKey from kmip.core.secrets import PublicKey @@ -314,19 +312,16 @@ class TestIntegration(TestCase): def test_query(self): # Build query function list, asking for all server data. - query_functions = list() - query_functions.append( - QueryFunction(QueryFunctionEnum.QUERY_OPERATIONS)) - query_functions.append( - QueryFunction(QueryFunctionEnum.QUERY_OBJECTS)) - query_functions.append( - QueryFunction(QueryFunctionEnum.QUERY_SERVER_INFORMATION)) - query_functions.append( - QueryFunction(QueryFunctionEnum.QUERY_APPLICATION_NAMESPACES)) - query_functions.append( - QueryFunction(QueryFunctionEnum.QUERY_EXTENSION_LIST)) - query_functions.append( - QueryFunction(QueryFunctionEnum.QUERY_EXTENSION_MAP)) + query_functions = list( + [ + QueryFunction.QUERY_OPERATIONS, + QueryFunction.QUERY_OBJECTS, + QueryFunction.QUERY_SERVER_INFORMATION, + QueryFunction.QUERY_APPLICATION_NAMESPACES, + QueryFunction.QUERY_EXTENSION_LIST, + QueryFunction.QUERY_EXTENSION_MAP + ] + ) result = self.client.query(query_functions=query_functions) diff --git a/kmip/tests/unit/core/messages/payloads/test_query.py b/kmip/tests/unit/core/messages/payloads/test_query.py index 68b9c9f..0bc16bc 100644 --- a/kmip/tests/unit/core/messages/payloads/test_query.py +++ b/kmip/tests/unit/core/messages/payloads/test_query.py @@ -13,30 +13,18 @@ # License for the specific language governing permissions and limitations # under the License. -from six.moves import xrange - -from testtools import TestCase +import testtools +from kmip.core import enums +from kmip.core import exceptions +from kmip.core import misc +from kmip.core import objects from kmip.core import utils -from kmip.core.attributes import ObjectType - -from kmip.core.enums import ObjectType as ObjectTypeEnum -from kmip.core.enums import Operation as OperationEnum -from kmip.core.enums import QueryFunction as QueryFunctionEnum - -from kmip.core.messages.contents import Operation from kmip.core.messages import payloads -from kmip.core.misc import QueryFunction -from kmip.core.misc import VendorIdentification -from kmip.core.misc import ServerInformation -from kmip.core.objects import ExtensionInformation -from kmip.core.objects import ExtensionName - - -class TestQueryRequestPayload(TestCase): +class TestQueryRequestPayload(testtools.TestCase): """ Test suite for the QueryRequestPayload class. @@ -47,153 +35,301 @@ class TestQueryRequestPayload(TestCase): def setUp(self): super(TestQueryRequestPayload, self).setUp() - self.query_functions_a = list() - self.query_functions_b = list() - self.query_functions_c = list() + # Encoding obtained from the KMIP 1.1 testing document, + # Section 12.1.0. + # + # This encoding matches the following set of values: + # Request Payload + # Query Functions + # Query Operations + # Query Objects + self.full_encoding = utils.BytearrayStream( + b'\x42\x00\x79\x01\x00\x00\x00\x20' + b'\x42\x00\x74\x05\x00\x00\x00\x04\x00\x00\x00\x01\x00\x00\x00\x00' + b'\x42\x00\x74\x05\x00\x00\x00\x04\x00\x00\x00\x02\x00\x00\x00\x00' + ) - self.query_functions_b.append(QueryFunction( - QueryFunctionEnum.QUERY_OPERATIONS)) - self.query_functions_b.append(QueryFunction( - QueryFunctionEnum.QUERY_OBJECTS)) - self.query_functions_b.append(QueryFunction( - QueryFunctionEnum.QUERY_SERVER_INFORMATION)) - - self.query_functions_c.append(QueryFunction( - QueryFunctionEnum.QUERY_EXTENSION_LIST)) - - self.encoding_a = utils.BytearrayStream(( - b'\x42\x00\x79\x01\x00\x00\x00\x00')) - - self.encoding_b = utils.BytearrayStream(( - b'\x42\x00\x79\x01\x00\x00\x00\x30\x42\x00\x74\x05\x00\x00\x00\x04' - b'\x00\x00\x00\x01\x00\x00\x00\x00\x42\x00\x74\x05\x00\x00\x00\x04' - b'\x00\x00\x00\x02\x00\x00\x00\x00\x42\x00\x74\x05\x00\x00\x00\x04' - b'\x00\x00\x00\x03\x00\x00\x00\x00')) - - self.encoding_c = utils.BytearrayStream(( - b'\x42\x00\x79\x01\x00\x00\x00\x10\x42\x00\x74\x05\x00\x00\x00\x04' - b'\x00\x00\x00\x05\x00\x00\x00\x00')) + # This encoding matches the following set of values: + # Request Payload + self.empty_encoding = utils.BytearrayStream( + b'\x42\x00\x79\x01\x00\x00\x00\x00' + ) def tearDown(self): super(TestQueryRequestPayload, self).tearDown() - def test_init_with_none(self): + def test_invalid_query_functions(self): """ - Test that a QueryRequestPayload object can be constructed with no - specified value. + Test that a TypeError is raised when an invalid value is used to set + the query functions of a Query request payload. """ - payloads.QueryRequestPayload() - - def test_init_with_args(self): - """ - Test that a QueryRequestPayload object can be constructed with valid - values. - """ - payloads.QueryRequestPayload(self.query_functions_a) - payloads.QueryRequestPayload(self.query_functions_b) - payloads.QueryRequestPayload(self.query_functions_c) - - def test_validate_with_invalid_query_functions_list(self): - """ - Test that a TypeError exception is raised when an invalid QueryFunction - list is used to construct a QueryRequestPayload object. - """ - kwargs = {'query_functions': 'invalid'} + kwargs = {"query_functions": "invalid"} self.assertRaisesRegex( - TypeError, "invalid query functions list", - payloads.QueryRequestPayload, **kwargs) - - def test_validate_with_invalid_query_functions_item(self): - """ - Test that a TypeError exception is raised when an invalid QueryFunction - item is used to construct a QueryRequestPayload object. - """ - kwargs = {'query_functions': ['invalid']} + TypeError, + "The query functions must be a list of QueryFunction " + "enumerations.", + payloads.QueryRequestPayload, + **kwargs + ) + kwargs = {"query_functions": ["invalid"]} self.assertRaisesRegex( - TypeError, "invalid query function", - payloads.QueryRequestPayload, **kwargs) + TypeError, + "The query functions must be a list of QueryFunction " + "enumerations.", + payloads.QueryRequestPayload, + **kwargs + ) - def _test_read(self, stream, query_functions): + args = ( + payloads.QueryRequestPayload(), + "query_functions", + "invalid" + ) + self.assertRaisesRegex( + TypeError, + "The query functions must be a list of QueryFunction " + "enumerations.", + setattr, + *args + ) + args = ( + payloads.QueryRequestPayload(), + "query_functions", + ["invalid"] + ) + self.assertRaisesRegex( + TypeError, + "The query functions must be a list of QueryFunction " + "enumerations.", + setattr, + *args + ) + + def test_read(self): + """ + Test that a QueryRequestPayload structure can be correctly read in + from a data stream. + """ payload = payloads.QueryRequestPayload() - payload.read(stream) - expected = len(query_functions) - observed = len(payload.query_functions) - msg = "query functions list decoding mismatch" - msg += "; expected {0} results, received {1}".format( - expected, observed) - self.assertEqual(expected, observed, msg) + self.assertIsNone(payload.query_functions) - for i in xrange(len(query_functions)): - expected = query_functions[i] - observed = payload.query_functions[i] + payload.read(self.full_encoding) - msg = "query function decoding mismatch" - msg += "; expected {0}, received {1}".format(expected, observed) - self.assertEqual(expected, observed, msg) + self.assertEqual( + [ + enums.QueryFunction.QUERY_OPERATIONS, + enums.QueryFunction.QUERY_OBJECTS + ], + payload.query_functions + ) - def test_read_with_empty_query_functions_list(self): + def test_read_missing_query_functions(self): """ - Test that a QueryRequestPayload object with no data can be read from - a data stream. + Test that an InvalidKmipEncoding error is raised during the decoding + of a QueryRequestPayload structure when the query functions are + missing from the encoding. """ - self._test_read(self.encoding_a, self.query_functions_a) + payload = payloads.QueryRequestPayload() - def test_read_with_multiple_query_functions(self): + args = (self.empty_encoding, ) + self.assertRaisesRegex( + exceptions.InvalidKmipEncoding, + "The Query request payload encoding is missing the query " + "functions.", + payload.read, + *args + ) + + def test_write(self): """ - Test that a QueryRequestPayload object with multiple pieces of data - can be read from a data stream. + Test that a QueryRequestPayload structure can be written to a data + stream. """ - self._test_read(self.encoding_b, self.query_functions_b) + payload = payloads.QueryRequestPayload( + query_functions=[ + enums.QueryFunction.QUERY_OPERATIONS, + enums.QueryFunction.QUERY_OBJECTS + ] + ) - def test_read_with_one_query_function(self): + buffer = utils.BytearrayStream() + payload.write(buffer) + + self.assertEqual(len(self.full_encoding), len(buffer)) + self.assertEqual(str(self.full_encoding), str(buffer)) + + def test_write_missing_query_functions(self): """ - Test that a QueryRequestPayload object with a single piece of data can - be read from a data stream. + Test that an InvalidField error is raised during the encoding of an + QueryRequestPayload structure when the structure is missing the + query functions field. """ - self._test_read(self.encoding_c, self.query_functions_c) + payload = payloads.QueryRequestPayload() - def _test_write(self, encoding, query_functions): - stream = utils.BytearrayStream() - payload = payloads.QueryRequestPayload(query_functions) - payload.write(stream) + args = (utils.BytearrayStream(), ) + self.assertRaisesRegex( + exceptions.InvalidField, + "The Query request payload is missing the query functions field.", + payload.write, + *args + ) - length_expected = len(encoding) - length_received = len(stream) - - msg = "encoding lengths not equal" - msg += "; expected {0}, received {1}".format( - length_expected, length_received) - self.assertEqual(length_expected, length_received, msg) - - msg = "encoding mismatch" - msg += ";\nexpected:\n{0}\nreceived:\n{1}".format(encoding, stream) - - self.assertEqual(encoding, stream, msg) - - def test_write_with_empty_query_functions_list(self): + def test_repr(self): """ - Test that a QueryRequestPayload object with no data can be written to - a data stream. + Test that repr can be applied to a QueryRequestPayload structure. """ - self._test_write(self.encoding_a, self.query_functions_a) + payload = payloads.QueryRequestPayload( + query_functions=[ + enums.QueryFunction.QUERY_OPERATIONS, + enums.QueryFunction.QUERY_OBJECTS + ] + ) - def test_write_with_multiple_query_functions(self): - """ - Test that a QueryRequestPayload object with multiple pieces of data - can be written to a data stream. - """ - self._test_write(self.encoding_b, self.query_functions_b) + v = "query_functions=" + \ + "[QueryFunction.QUERY_OPERATIONS, QueryFunction.QUERY_OBJECTS]" - def test_write_with_one_query_function(self): + self.assertEqual( + "QueryRequestPayload({})".format(v), + repr(payload) + ) + + def test_str(self): """ - Test that a QueryRequestPayload object with a single piece of data can - be written to a data stream. + Test that str can be applied to a QueryRequestPayload structure. """ - self._test_write(self.encoding_c, self.query_functions_c) + payload = payloads.QueryRequestPayload( + query_functions=[ + enums.QueryFunction.QUERY_OPERATIONS, + enums.QueryFunction.QUERY_OBJECTS + ] + ) + + v = '"query_functions": ' + \ + '[QueryFunction.QUERY_OPERATIONS, QueryFunction.QUERY_OBJECTS]' + + self.assertEqual("{" + v + "}", str(payload)) + + def test_equal_on_equal(self): + """ + Test that the equality operator returns True when comparing two + QueryRequestPayload structures with the same data. + """ + a = payloads.QueryRequestPayload() + b = payloads.QueryRequestPayload() + + self.assertTrue(a == b) + self.assertTrue(b == a) + + a = payloads.QueryRequestPayload( + query_functions=[ + enums.QueryFunction.QUERY_OPERATIONS, + enums.QueryFunction.QUERY_OBJECTS + ] + ) + b = payloads.QueryRequestPayload( + query_functions=[ + enums.QueryFunction.QUERY_OPERATIONS, + enums.QueryFunction.QUERY_OBJECTS + ] + ) + + self.assertTrue(a == b) + self.assertTrue(b == a) + + def test_equal_on_not_equal_query_functions(self): + """ + Test that the equality operator returns False when comparing two + QueryRequestPayload structures with different query functions fields. + """ + a = payloads.QueryRequestPayload( + query_functions=[ + enums.QueryFunction.QUERY_OPERATIONS, + enums.QueryFunction.QUERY_OBJECTS + ] + ) + b = payloads.QueryRequestPayload( + query_functions=[ + enums.QueryFunction.QUERY_OBJECTS, + enums.QueryFunction.QUERY_OPERATIONS + ] + ) + + self.assertFalse(a == b) + self.assertFalse(b == a) + + def test_equal_on_type_mismatch(self): + """ + Test that the equality operator returns False when comparing two + QueryRequestPayload structures with different types. + """ + a = payloads.QueryRequestPayload() + 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 + QueryRequestPayload structures with the same data. + """ + a = payloads.QueryRequestPayload() + b = payloads.QueryRequestPayload() + + self.assertFalse(a != b) + self.assertFalse(b != a) + + a = payloads.QueryRequestPayload( + query_functions=[ + enums.QueryFunction.QUERY_OPERATIONS, + enums.QueryFunction.QUERY_OBJECTS + ] + ) + b = payloads.QueryRequestPayload( + query_functions=[ + enums.QueryFunction.QUERY_OPERATIONS, + enums.QueryFunction.QUERY_OBJECTS + ] + ) + + self.assertFalse(a != b) + self.assertFalse(b != a) + + def test_not_equal_on_not_equal_query_functions(self): + """ + Test that the inequality operator returns True when comparing two + QueryRequestPayload structures with different query functions fields. + """ + a = payloads.QueryRequestPayload( + query_functions=[ + enums.QueryFunction.QUERY_OPERATIONS, + enums.QueryFunction.QUERY_OBJECTS + ] + ) + b = payloads.QueryRequestPayload( + query_functions=[ + enums.QueryFunction.QUERY_OBJECTS, + enums.QueryFunction.QUERY_OPERATIONS + ] + ) + + 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 two + QueryRequestPayload structures with different types. + """ + a = payloads.QueryRequestPayload() + b = "invalid" + + self.assertTrue(a != b) + self.assertTrue(b != a) -class TestQueryResponsePayload(TestCase): +class TestQueryResponsePayload(testtools.TestCase): """ Test encodings obtained from Sections 12.1 and 12.2 of the KMIP 1.1 Test Cases documentation. @@ -202,386 +338,3612 @@ class TestQueryResponsePayload(TestCase): def setUp(self): super(TestQueryResponsePayload, self).setUp() - self.operations = list() - self.object_types = list() - self.application_namespaces = list() - self.extension_information = list() - - self.vendor_identification = VendorIdentification( - "IBM test server, not-TKLM 2.0.1.1 KMIP 2.0.0.1") - self.server_information = ServerInformation() - - self.operations.append(Operation(OperationEnum.CREATE)) - self.operations.append(Operation(OperationEnum.CREATE_KEY_PAIR)) - self.operations.append(Operation(OperationEnum.REGISTER)) - self.operations.append(Operation(OperationEnum.REKEY)) - self.operations.append(Operation(OperationEnum.CERTIFY)) - self.operations.append(Operation(OperationEnum.RECERTIFY)) - self.operations.append(Operation(OperationEnum.LOCATE)) - self.operations.append(Operation(OperationEnum.CHECK)) - self.operations.append(Operation(OperationEnum.GET)) - self.operations.append(Operation(OperationEnum.GET_ATTRIBUTES)) - self.operations.append(Operation(OperationEnum.GET_ATTRIBUTE_LIST)) - self.operations.append(Operation(OperationEnum.ADD_ATTRIBUTE)) - self.operations.append(Operation(OperationEnum.MODIFY_ATTRIBUTE)) - self.operations.append(Operation(OperationEnum.DELETE_ATTRIBUTE)) - self.operations.append(Operation(OperationEnum.OBTAIN_LEASE)) - self.operations.append(Operation(OperationEnum.GET_USAGE_ALLOCATION)) - self.operations.append(Operation(OperationEnum.ACTIVATE)) - self.operations.append(Operation(OperationEnum.REVOKE)) - self.operations.append(Operation(OperationEnum.DESTROY)) - self.operations.append(Operation(OperationEnum.ARCHIVE)) - self.operations.append(Operation(OperationEnum.RECOVER)) - self.operations.append(Operation(OperationEnum.QUERY)) - self.operations.append(Operation(OperationEnum.CANCEL)) - self.operations.append(Operation(OperationEnum.POLL)) - self.operations.append(Operation(OperationEnum.REKEY_KEY_PAIR)) - self.operations.append(Operation(OperationEnum.DISCOVER_VERSIONS)) - - self.object_types.append(ObjectType(ObjectTypeEnum.CERTIFICATE)) - self.object_types.append(ObjectType(ObjectTypeEnum.SYMMETRIC_KEY)) - self.object_types.append(ObjectType(ObjectTypeEnum.PUBLIC_KEY)) - self.object_types.append(ObjectType(ObjectTypeEnum.PRIVATE_KEY)) - self.object_types.append(ObjectType(ObjectTypeEnum.TEMPLATE)) - self.object_types.append(ObjectType(ObjectTypeEnum.SECRET_DATA)) - - self.extension_information.append(ExtensionInformation( - extension_name=ExtensionName("ACME LOCATION"))) - self.extension_information.append(ExtensionInformation( - extension_name=ExtensionName("ACME ZIP CODE"))) - - self.encoding_a = utils.BytearrayStream(( - b'\x42\x00\x7C\x01\x00\x00\x00\x00')) - - self.encoding_b = utils.BytearrayStream(( - b'\x42\x00\x7C\x01\x00\x00\x02\x40\x42\x00\x5C\x05\x00\x00\x00\x04' - b'\x00\x00\x00\x01\x00\x00\x00\x00\x42\x00\x5C\x05\x00\x00\x00\x04' - b'\x00\x00\x00\x02\x00\x00\x00\x00\x42\x00\x5C\x05\x00\x00\x00\x04' - b'\x00\x00\x00\x03\x00\x00\x00\x00\x42\x00\x5C\x05\x00\x00\x00\x04' - b'\x00\x00\x00\x04\x00\x00\x00\x00\x42\x00\x5C\x05\x00\x00\x00\x04' - b'\x00\x00\x00\x06\x00\x00\x00\x00\x42\x00\x5C\x05\x00\x00\x00\x04' - b'\x00\x00\x00\x07\x00\x00\x00\x00\x42\x00\x5C\x05\x00\x00\x00\x04' - b'\x00\x00\x00\x08\x00\x00\x00\x00\x42\x00\x5C\x05\x00\x00\x00\x04' - b'\x00\x00\x00\x09\x00\x00\x00\x00\x42\x00\x5C\x05\x00\x00\x00\x04' - b'\x00\x00\x00\x0A\x00\x00\x00\x00\x42\x00\x5C\x05\x00\x00\x00\x04' - b'\x00\x00\x00\x0B\x00\x00\x00\x00\x42\x00\x5C\x05\x00\x00\x00\x04' - b'\x00\x00\x00\x0C\x00\x00\x00\x00\x42\x00\x5C\x05\x00\x00\x00\x04' - b'\x00\x00\x00\x0D\x00\x00\x00\x00\x42\x00\x5C\x05\x00\x00\x00\x04' - b'\x00\x00\x00\x0E\x00\x00\x00\x00\x42\x00\x5C\x05\x00\x00\x00\x04' - b'\x00\x00\x00\x0F\x00\x00\x00\x00\x42\x00\x5C\x05\x00\x00\x00\x04' - b'\x00\x00\x00\x10\x00\x00\x00\x00\x42\x00\x5C\x05\x00\x00\x00\x04' - b'\x00\x00\x00\x11\x00\x00\x00\x00\x42\x00\x5C\x05\x00\x00\x00\x04' - b'\x00\x00\x00\x12\x00\x00\x00\x00\x42\x00\x5C\x05\x00\x00\x00\x04' - b'\x00\x00\x00\x13\x00\x00\x00\x00\x42\x00\x5C\x05\x00\x00\x00\x04' - b'\x00\x00\x00\x14\x00\x00\x00\x00\x42\x00\x5C\x05\x00\x00\x00\x04' - b'\x00\x00\x00\x15\x00\x00\x00\x00\x42\x00\x5C\x05\x00\x00\x00\x04' - b'\x00\x00\x00\x16\x00\x00\x00\x00\x42\x00\x5C\x05\x00\x00\x00\x04' - b'\x00\x00\x00\x18\x00\x00\x00\x00\x42\x00\x5C\x05\x00\x00\x00\x04' - b'\x00\x00\x00\x19\x00\x00\x00\x00\x42\x00\x5C\x05\x00\x00\x00\x04' - b'\x00\x00\x00\x1A\x00\x00\x00\x00\x42\x00\x5C\x05\x00\x00\x00\x04' - b'\x00\x00\x00\x1D\x00\x00\x00\x00\x42\x00\x5C\x05\x00\x00\x00\x04' - b'\x00\x00\x00\x1E\x00\x00\x00\x00\x42\x00\x57\x05\x00\x00\x00\x04' - b'\x00\x00\x00\x01\x00\x00\x00\x00\x42\x00\x57\x05\x00\x00\x00\x04' - b'\x00\x00\x00\x02\x00\x00\x00\x00\x42\x00\x57\x05\x00\x00\x00\x04' - b'\x00\x00\x00\x03\x00\x00\x00\x00\x42\x00\x57\x05\x00\x00\x00\x04' - b'\x00\x00\x00\x04\x00\x00\x00\x00\x42\x00\x57\x05\x00\x00\x00\x04' - b'\x00\x00\x00\x06\x00\x00\x00\x00\x42\x00\x57\x05\x00\x00\x00\x04' - b'\x00\x00\x00\x07\x00\x00\x00\x00\x42\x00\x9D\x07\x00\x00\x00\x2E' + # Encoding obtained from the KMIP 1.1 testing document, + # Section 12.1.0. Modified to include the Application + # Namespaces. + # + # This encoding matches the following set of values: + # Response Payload + # Operations + # Create + # Create Key Pair + # Register + # Rekey + # Certify + # Recertify + # Locate + # Check + # Get + # Get Attributes + # Get Attribute List + # Add Attribute + # Modify Attribute + # Delete Attribute + # Obtain Lease + # Get Usage Allocation + # Activate + # Revoke + # Destroy + # Archive + # Recover + # Query + # Cancel + # Poll + # Rekey Key Pair + # Discover Versions + # Object Types + # Certificate + # Symmetric Key + # Public Key + # Private Key + # Template + # Secret Data + # Vendor Identification - + # IBM test server, not-TKLM 2.0.1.1 KMIP 2.0.0.1 + # Server Information - empty + # Application Namespaces + # Namespace 1 + # Namespace 2 + self.full_encoding = utils.BytearrayStream( + b'\x42\x00\x7C\x01\x00\x00\x02\x70' + b'\x42\x00\x5C\x05\x00\x00\x00\x04\x00\x00\x00\x01\x00\x00\x00\x00' + b'\x42\x00\x5C\x05\x00\x00\x00\x04\x00\x00\x00\x02\x00\x00\x00\x00' + b'\x42\x00\x5C\x05\x00\x00\x00\x04\x00\x00\x00\x03\x00\x00\x00\x00' + b'\x42\x00\x5C\x05\x00\x00\x00\x04\x00\x00\x00\x04\x00\x00\x00\x00' + b'\x42\x00\x5C\x05\x00\x00\x00\x04\x00\x00\x00\x06\x00\x00\x00\x00' + b'\x42\x00\x5C\x05\x00\x00\x00\x04\x00\x00\x00\x07\x00\x00\x00\x00' + b'\x42\x00\x5C\x05\x00\x00\x00\x04\x00\x00\x00\x08\x00\x00\x00\x00' + b'\x42\x00\x5C\x05\x00\x00\x00\x04\x00\x00\x00\x09\x00\x00\x00\x00' + b'\x42\x00\x5C\x05\x00\x00\x00\x04\x00\x00\x00\x0A\x00\x00\x00\x00' + b'\x42\x00\x5C\x05\x00\x00\x00\x04\x00\x00\x00\x0B\x00\x00\x00\x00' + b'\x42\x00\x5C\x05\x00\x00\x00\x04\x00\x00\x00\x0C\x00\x00\x00\x00' + b'\x42\x00\x5C\x05\x00\x00\x00\x04\x00\x00\x00\x0D\x00\x00\x00\x00' + b'\x42\x00\x5C\x05\x00\x00\x00\x04\x00\x00\x00\x0E\x00\x00\x00\x00' + b'\x42\x00\x5C\x05\x00\x00\x00\x04\x00\x00\x00\x0F\x00\x00\x00\x00' + b'\x42\x00\x5C\x05\x00\x00\x00\x04\x00\x00\x00\x10\x00\x00\x00\x00' + b'\x42\x00\x5C\x05\x00\x00\x00\x04\x00\x00\x00\x11\x00\x00\x00\x00' + b'\x42\x00\x5C\x05\x00\x00\x00\x04\x00\x00\x00\x12\x00\x00\x00\x00' + b'\x42\x00\x5C\x05\x00\x00\x00\x04\x00\x00\x00\x13\x00\x00\x00\x00' + b'\x42\x00\x5C\x05\x00\x00\x00\x04\x00\x00\x00\x14\x00\x00\x00\x00' + b'\x42\x00\x5C\x05\x00\x00\x00\x04\x00\x00\x00\x15\x00\x00\x00\x00' + b'\x42\x00\x5C\x05\x00\x00\x00\x04\x00\x00\x00\x16\x00\x00\x00\x00' + b'\x42\x00\x5C\x05\x00\x00\x00\x04\x00\x00\x00\x18\x00\x00\x00\x00' + b'\x42\x00\x5C\x05\x00\x00\x00\x04\x00\x00\x00\x19\x00\x00\x00\x00' + b'\x42\x00\x5C\x05\x00\x00\x00\x04\x00\x00\x00\x1A\x00\x00\x00\x00' + b'\x42\x00\x5C\x05\x00\x00\x00\x04\x00\x00\x00\x1D\x00\x00\x00\x00' + b'\x42\x00\x5C\x05\x00\x00\x00\x04\x00\x00\x00\x1E\x00\x00\x00\x00' + b'\x42\x00\x57\x05\x00\x00\x00\x04\x00\x00\x00\x01\x00\x00\x00\x00' + b'\x42\x00\x57\x05\x00\x00\x00\x04\x00\x00\x00\x02\x00\x00\x00\x00' + b'\x42\x00\x57\x05\x00\x00\x00\x04\x00\x00\x00\x03\x00\x00\x00\x00' + b'\x42\x00\x57\x05\x00\x00\x00\x04\x00\x00\x00\x04\x00\x00\x00\x00' + b'\x42\x00\x57\x05\x00\x00\x00\x04\x00\x00\x00\x06\x00\x00\x00\x00' + b'\x42\x00\x57\x05\x00\x00\x00\x04\x00\x00\x00\x07\x00\x00\x00\x00' + b'\x42\x00\x9D\x07\x00\x00\x00\x2E' b'\x49\x42\x4D\x20\x74\x65\x73\x74\x20\x73\x65\x72\x76\x65\x72\x2C' b'\x20\x6E\x6F\x74\x2D\x54\x4B\x4C\x4D\x20\x32\x2E\x30\x2E\x31\x2E' b'\x31\x20\x4B\x4D\x49\x50\x20\x32\x2E\x30\x2E\x30\x2E\x31\x00\x00' - b'\x42\x00\x88\x01\x00\x00\x00\x00')) + b'\x42\x00\x88\x01\x00\x00\x00\x00' + b'\x42\x00\x03\x07\x00\x00\x00\x0B' + b'\x4E\x61\x6D\x65\x73\x70\x61\x63\x65\x20\x31\x00\x00\x00\x00\x00' + b'\x42\x00\x03\x07\x00\x00\x00\x0B' + b'\x4E\x61\x6D\x65\x73\x70\x61\x63\x65\x20\x32\x00\x00\x00\x00\x00' + ) - self.encoding_c = utils.BytearrayStream(( - b'\x42\x00\x7C\x01\x00\x00\x00\x40\x42\x00\xA4\x01\x00\x00\x00\x18' - b'\x42\x00\xA5\x07\x00\x00\x00\x0D\x41\x43\x4D\x45\x20\x4C\x4F\x43' - b'\x41\x54\x49\x4F\x4E\x00\x00\x00\x42\x00\xA4\x01\x00\x00\x00\x18' - b'\x42\x00\xA5\x07\x00\x00\x00\x0D\x41\x43\x4D\x45\x20\x5A\x49\x50' - b'\x20\x43\x4F\x44\x45\x00\x00\x00')) + # Encoding obtained from the KMIP 1.1 testing document, + # Section 12.1.0. Modified to include the Application + # Namespaces and Extension Information. + # + # This encoding matches the following set of values: + # Response Payload + # Operations + # Create + # Create Key Pair + # Register + # Rekey + # Certify + # Recertify + # Locate + # Check + # Get + # Get Attributes + # Get Attribute List + # Add Attribute + # Modify Attribute + # Delete Attribute + # Obtain Lease + # Get Usage Allocation + # Activate + # Revoke + # Destroy + # Archive + # Recover + # Query + # Cancel + # Poll + # Rekey Key Pair + # Discover Versions + # Object Types + # Certificate + # Symmetric Key + # Public Key + # Private Key + # Template + # Secret Data + # Vendor Identification - + # IBM test server, not-TKLM 2.0.1.1 KMIP 2.0.0.1 + # Server Information - empty + # Application Namespaces + # Namespace 1 + # Namespace 2 + # Extension Information + # Extension Name - ACME LOCATION + # Extension Tag - 0x0054AA01 + # Extension Type - 7 + # Extension Information + # Extension Name - ACME ZIP CODE + # Extension Tag - 0x0054AA02 + # Extension Type - 2 + self.full_encoding_kmip_1_1 = utils.BytearrayStream( + b'\x42\x00\x7C\x01\x00\x00\x02\xF0' + b'\x42\x00\x5C\x05\x00\x00\x00\x04\x00\x00\x00\x01\x00\x00\x00\x00' + b'\x42\x00\x5C\x05\x00\x00\x00\x04\x00\x00\x00\x02\x00\x00\x00\x00' + b'\x42\x00\x5C\x05\x00\x00\x00\x04\x00\x00\x00\x03\x00\x00\x00\x00' + b'\x42\x00\x5C\x05\x00\x00\x00\x04\x00\x00\x00\x04\x00\x00\x00\x00' + b'\x42\x00\x5C\x05\x00\x00\x00\x04\x00\x00\x00\x06\x00\x00\x00\x00' + b'\x42\x00\x5C\x05\x00\x00\x00\x04\x00\x00\x00\x07\x00\x00\x00\x00' + b'\x42\x00\x5C\x05\x00\x00\x00\x04\x00\x00\x00\x08\x00\x00\x00\x00' + b'\x42\x00\x5C\x05\x00\x00\x00\x04\x00\x00\x00\x09\x00\x00\x00\x00' + b'\x42\x00\x5C\x05\x00\x00\x00\x04\x00\x00\x00\x0A\x00\x00\x00\x00' + b'\x42\x00\x5C\x05\x00\x00\x00\x04\x00\x00\x00\x0B\x00\x00\x00\x00' + b'\x42\x00\x5C\x05\x00\x00\x00\x04\x00\x00\x00\x0C\x00\x00\x00\x00' + b'\x42\x00\x5C\x05\x00\x00\x00\x04\x00\x00\x00\x0D\x00\x00\x00\x00' + b'\x42\x00\x5C\x05\x00\x00\x00\x04\x00\x00\x00\x0E\x00\x00\x00\x00' + b'\x42\x00\x5C\x05\x00\x00\x00\x04\x00\x00\x00\x0F\x00\x00\x00\x00' + b'\x42\x00\x5C\x05\x00\x00\x00\x04\x00\x00\x00\x10\x00\x00\x00\x00' + b'\x42\x00\x5C\x05\x00\x00\x00\x04\x00\x00\x00\x11\x00\x00\x00\x00' + b'\x42\x00\x5C\x05\x00\x00\x00\x04\x00\x00\x00\x12\x00\x00\x00\x00' + b'\x42\x00\x5C\x05\x00\x00\x00\x04\x00\x00\x00\x13\x00\x00\x00\x00' + b'\x42\x00\x5C\x05\x00\x00\x00\x04\x00\x00\x00\x14\x00\x00\x00\x00' + b'\x42\x00\x5C\x05\x00\x00\x00\x04\x00\x00\x00\x15\x00\x00\x00\x00' + b'\x42\x00\x5C\x05\x00\x00\x00\x04\x00\x00\x00\x16\x00\x00\x00\x00' + b'\x42\x00\x5C\x05\x00\x00\x00\x04\x00\x00\x00\x18\x00\x00\x00\x00' + b'\x42\x00\x5C\x05\x00\x00\x00\x04\x00\x00\x00\x19\x00\x00\x00\x00' + b'\x42\x00\x5C\x05\x00\x00\x00\x04\x00\x00\x00\x1A\x00\x00\x00\x00' + b'\x42\x00\x5C\x05\x00\x00\x00\x04\x00\x00\x00\x1D\x00\x00\x00\x00' + b'\x42\x00\x5C\x05\x00\x00\x00\x04\x00\x00\x00\x1E\x00\x00\x00\x00' + b'\x42\x00\x57\x05\x00\x00\x00\x04\x00\x00\x00\x01\x00\x00\x00\x00' + b'\x42\x00\x57\x05\x00\x00\x00\x04\x00\x00\x00\x02\x00\x00\x00\x00' + b'\x42\x00\x57\x05\x00\x00\x00\x04\x00\x00\x00\x03\x00\x00\x00\x00' + b'\x42\x00\x57\x05\x00\x00\x00\x04\x00\x00\x00\x04\x00\x00\x00\x00' + b'\x42\x00\x57\x05\x00\x00\x00\x04\x00\x00\x00\x06\x00\x00\x00\x00' + b'\x42\x00\x57\x05\x00\x00\x00\x04\x00\x00\x00\x07\x00\x00\x00\x00' + b'\x42\x00\x9D\x07\x00\x00\x00\x2E' + b'\x49\x42\x4D\x20\x74\x65\x73\x74\x20\x73\x65\x72\x76\x65\x72\x2C' + b'\x20\x6E\x6F\x74\x2D\x54\x4B\x4C\x4D\x20\x32\x2E\x30\x2E\x31\x2E' + b'\x31\x20\x4B\x4D\x49\x50\x20\x32\x2E\x30\x2E\x30\x2E\x31\x00\x00' + b'\x42\x00\x88\x01\x00\x00\x00\x00' + b'\x42\x00\x03\x07\x00\x00\x00\x0B' + b'\x4E\x61\x6D\x65\x73\x70\x61\x63\x65\x20\x31\x00\x00\x00\x00\x00' + b'\x42\x00\x03\x07\x00\x00\x00\x0B' + b'\x4E\x61\x6D\x65\x73\x70\x61\x63\x65\x20\x32\x00\x00\x00\x00\x00' + b'\x42\x00\xA4\x01\x00\x00\x00\x38' + b'\x42\x00\xA5\x07\x00\x00\x00\x0D' + b'\x41\x43\x4D\x45\x20\x4C\x4F\x43\x41\x54\x49\x4F\x4E\x00\x00\x00' + b'\x42\x00\xA6\x02\x00\x00\x00\x04\x00\x54\xAA\x01\x00\x00\x00\x00' + b'\x42\x00\xA7\x02\x00\x00\x00\x04\x00\x00\x00\x07\x00\x00\x00\x00' + b'\x42\x00\xA4\x01\x00\x00\x00\x38' + b'\x42\x00\xA5\x07\x00\x00\x00\x0D' + b'\x41\x43\x4D\x45\x20\x5A\x49\x50\x20\x43\x4F\x44\x45\x00\x00\x00' + b'\x42\x00\xA6\x02\x00\x00\x00\x04\x00\x54\xAA\x02\x00\x00\x00\x00' + b'\x42\x00\xA7\x02\x00\x00\x00\x04\x00\x00\x00\x02\x00\x00\x00\x00' + ) + + # Encoding obtained from the KMIP 1.1 testing document, + # Section 12.1.0. Modified to include the Application + # Namespaces, Extension Information, and Attestation + # Types. + # + # This encoding matches the following set of values: + # Response Payload + # Operations + # Create + # Create Key Pair + # Register + # Rekey + # Certify + # Recertify + # Locate + # Check + # Get + # Get Attributes + # Get Attribute List + # Add Attribute + # Modify Attribute + # Delete Attribute + # Obtain Lease + # Get Usage Allocation + # Activate + # Revoke + # Destroy + # Archive + # Recover + # Query + # Cancel + # Poll + # Rekey Key Pair + # Discover Versions + # Object Types + # Certificate + # Symmetric Key + # Public Key + # Private Key + # Template + # Secret Data + # Vendor Identification - + # IBM test server, not-TKLM 2.0.1.1 KMIP 2.0.0.1 + # Server Information - empty + # Application Namespaces + # Namespace 1 + # Namespace 2 + # Extension Information + # Extension Name - ACME LOCATION + # Extension Tag - 0x0054AA01 + # Extension Type - 7 + # Extension Information + # Extension Name - ACME ZIP CODE + # Extension Tag - 0x0054AA02 + # Extension Type - 2 + # Attestation Types + # TPM Quote + # TCG Integrity Report + # SAML Assertion + self.full_encoding_kmip_1_2 = utils.BytearrayStream( + b'\x42\x00\x7C\x01\x00\x00\x03\x20' + b'\x42\x00\x5C\x05\x00\x00\x00\x04\x00\x00\x00\x01\x00\x00\x00\x00' + b'\x42\x00\x5C\x05\x00\x00\x00\x04\x00\x00\x00\x02\x00\x00\x00\x00' + b'\x42\x00\x5C\x05\x00\x00\x00\x04\x00\x00\x00\x03\x00\x00\x00\x00' + b'\x42\x00\x5C\x05\x00\x00\x00\x04\x00\x00\x00\x04\x00\x00\x00\x00' + b'\x42\x00\x5C\x05\x00\x00\x00\x04\x00\x00\x00\x06\x00\x00\x00\x00' + b'\x42\x00\x5C\x05\x00\x00\x00\x04\x00\x00\x00\x07\x00\x00\x00\x00' + b'\x42\x00\x5C\x05\x00\x00\x00\x04\x00\x00\x00\x08\x00\x00\x00\x00' + b'\x42\x00\x5C\x05\x00\x00\x00\x04\x00\x00\x00\x09\x00\x00\x00\x00' + b'\x42\x00\x5C\x05\x00\x00\x00\x04\x00\x00\x00\x0A\x00\x00\x00\x00' + b'\x42\x00\x5C\x05\x00\x00\x00\x04\x00\x00\x00\x0B\x00\x00\x00\x00' + b'\x42\x00\x5C\x05\x00\x00\x00\x04\x00\x00\x00\x0C\x00\x00\x00\x00' + b'\x42\x00\x5C\x05\x00\x00\x00\x04\x00\x00\x00\x0D\x00\x00\x00\x00' + b'\x42\x00\x5C\x05\x00\x00\x00\x04\x00\x00\x00\x0E\x00\x00\x00\x00' + b'\x42\x00\x5C\x05\x00\x00\x00\x04\x00\x00\x00\x0F\x00\x00\x00\x00' + b'\x42\x00\x5C\x05\x00\x00\x00\x04\x00\x00\x00\x10\x00\x00\x00\x00' + b'\x42\x00\x5C\x05\x00\x00\x00\x04\x00\x00\x00\x11\x00\x00\x00\x00' + b'\x42\x00\x5C\x05\x00\x00\x00\x04\x00\x00\x00\x12\x00\x00\x00\x00' + b'\x42\x00\x5C\x05\x00\x00\x00\x04\x00\x00\x00\x13\x00\x00\x00\x00' + b'\x42\x00\x5C\x05\x00\x00\x00\x04\x00\x00\x00\x14\x00\x00\x00\x00' + b'\x42\x00\x5C\x05\x00\x00\x00\x04\x00\x00\x00\x15\x00\x00\x00\x00' + b'\x42\x00\x5C\x05\x00\x00\x00\x04\x00\x00\x00\x16\x00\x00\x00\x00' + b'\x42\x00\x5C\x05\x00\x00\x00\x04\x00\x00\x00\x18\x00\x00\x00\x00' + b'\x42\x00\x5C\x05\x00\x00\x00\x04\x00\x00\x00\x19\x00\x00\x00\x00' + b'\x42\x00\x5C\x05\x00\x00\x00\x04\x00\x00\x00\x1A\x00\x00\x00\x00' + b'\x42\x00\x5C\x05\x00\x00\x00\x04\x00\x00\x00\x1D\x00\x00\x00\x00' + b'\x42\x00\x5C\x05\x00\x00\x00\x04\x00\x00\x00\x1E\x00\x00\x00\x00' + b'\x42\x00\x57\x05\x00\x00\x00\x04\x00\x00\x00\x01\x00\x00\x00\x00' + b'\x42\x00\x57\x05\x00\x00\x00\x04\x00\x00\x00\x02\x00\x00\x00\x00' + b'\x42\x00\x57\x05\x00\x00\x00\x04\x00\x00\x00\x03\x00\x00\x00\x00' + b'\x42\x00\x57\x05\x00\x00\x00\x04\x00\x00\x00\x04\x00\x00\x00\x00' + b'\x42\x00\x57\x05\x00\x00\x00\x04\x00\x00\x00\x06\x00\x00\x00\x00' + b'\x42\x00\x57\x05\x00\x00\x00\x04\x00\x00\x00\x07\x00\x00\x00\x00' + b'\x42\x00\x9D\x07\x00\x00\x00\x2E' + b'\x49\x42\x4D\x20\x74\x65\x73\x74\x20\x73\x65\x72\x76\x65\x72\x2C' + b'\x20\x6E\x6F\x74\x2D\x54\x4B\x4C\x4D\x20\x32\x2E\x30\x2E\x31\x2E' + b'\x31\x20\x4B\x4D\x49\x50\x20\x32\x2E\x30\x2E\x30\x2E\x31\x00\x00' + b'\x42\x00\x88\x01\x00\x00\x00\x00' + b'\x42\x00\x03\x07\x00\x00\x00\x0B' + b'\x4E\x61\x6D\x65\x73\x70\x61\x63\x65\x20\x31\x00\x00\x00\x00\x00' + b'\x42\x00\x03\x07\x00\x00\x00\x0B' + b'\x4E\x61\x6D\x65\x73\x70\x61\x63\x65\x20\x32\x00\x00\x00\x00\x00' + b'\x42\x00\xA4\x01\x00\x00\x00\x38' + b'\x42\x00\xA5\x07\x00\x00\x00\x0D' + b'\x41\x43\x4D\x45\x20\x4C\x4F\x43\x41\x54\x49\x4F\x4E\x00\x00\x00' + b'\x42\x00\xA6\x02\x00\x00\x00\x04\x00\x54\xAA\x01\x00\x00\x00\x00' + b'\x42\x00\xA7\x02\x00\x00\x00\x04\x00\x00\x00\x07\x00\x00\x00\x00' + b'\x42\x00\xA4\x01\x00\x00\x00\x38' + b'\x42\x00\xA5\x07\x00\x00\x00\x0D' + b'\x41\x43\x4D\x45\x20\x5A\x49\x50\x20\x43\x4F\x44\x45\x00\x00\x00' + b'\x42\x00\xA6\x02\x00\x00\x00\x04\x00\x54\xAA\x02\x00\x00\x00\x00' + b'\x42\x00\xA7\x02\x00\x00\x00\x04\x00\x00\x00\x02\x00\x00\x00\x00' + b'\x42\x00\xC7\x05\x00\x00\x00\x04\x00\x00\x00\x01\x00\x00\x00\x00' + b'\x42\x00\xC7\x05\x00\x00\x00\x04\x00\x00\x00\x02\x00\x00\x00\x00' + b'\x42\x00\xC7\x05\x00\x00\x00\x04\x00\x00\x00\x03\x00\x00\x00\x00' + ) + + # Encoding obtained from the KMIP 1.1 testing document, + # Section 12.1.0. Modified to include the Application + # Namespaces, Extension Information, Attestation Types, + # RNG Parameters, Profile Information, Validation + # Information, Capability Information, and Client + # Registration Methods. + # + # This encoding matches the following set of values: + # Response Payload + # Operations + # Create + # Create Key Pair + # Register + # Rekey + # Certify + # Recertify + # Locate + # Check + # Get + # Get Attributes + # Get Attribute List + # Add Attribute + # Modify Attribute + # Delete Attribute + # Obtain Lease + # Get Usage Allocation + # Activate + # Revoke + # Destroy + # Archive + # Recover + # Query + # Cancel + # Poll + # Rekey Key Pair + # Discover Versions + # Object Types + # Certificate + # Symmetric Key + # Public Key + # Private Key + # Template + # Secret Data + # Vendor Identification - + # IBM test server, not-TKLM 2.0.1.1 KMIP 2.0.0.1 + # Server Information - empty + # Application Namespaces + # Namespace 1 + # Namespace 2 + # Extension Information + # Extension Name - ACME LOCATION + # Extension Tag - 0x0054AA01 + # Extension Type - 7 + # Extension Information + # Extension Name - ACME ZIP CODE + # Extension Tag - 0x0054AA02 + # Extension Type - 2 + # Attestation Types + # TPM Quote + # TCG Integrity Report + # SAML Assertion + # RNGParameters + # RNG Algorithm - FIPS 186-2 + # Cryptographic Algorithm - AES + # Cryptographic Length - 256 + # Hashing Algorithm - SHA256 + # DRBG Algorithm - Hash + # Recommended Curve - P-192 + # FIPS186 Variation - GP x-Original + # Prediction Resistance - True + # Profile Information + # Profile Name - BASELINE_SERVER_BASIC_KMIPv12 + # Server URI - https://example.com + # Server Port - 5696 + # Validation Information + # Validation Authority Type - COMMON_CRITERIA + # Validation Authority Country - US + # Validation Authority URI - https://example.com + # Validation Version Major - 1 + # Validation Version Minor - 0 + # Validation Type - HYBRID + # Validation Level - 5 + # Validation Certificate Identifier - + # c005d39e-604f-11e9-99df-080027fc1396 + # Validation Certificate URI - https://test.com + # Validation Vendor URI - https://vendor.com + # Validation Profiles - + # Profile 1 + # Profile 2 + # Capability Information + # Streaming Capability - False + # Asynchronous Capability - True + # Attestation Capability - True + # Unwrap Mode - PROCESSED + # Destroy Action - SHREDDED + # Shredding Algorithm - CRYPTOGRAPHIC + # RNG Mode - NON_SHARED_INSTANTIATION + # Client Registration Methods + # Client Generated + # Client Registered + self.full_encoding_kmip_1_3 = utils.BytearrayStream( + b'\x42\x00\x7C\x01\x00\x00\x05\xA8' + b'\x42\x00\x5C\x05\x00\x00\x00\x04\x00\x00\x00\x01\x00\x00\x00\x00' + b'\x42\x00\x5C\x05\x00\x00\x00\x04\x00\x00\x00\x02\x00\x00\x00\x00' + b'\x42\x00\x5C\x05\x00\x00\x00\x04\x00\x00\x00\x03\x00\x00\x00\x00' + b'\x42\x00\x5C\x05\x00\x00\x00\x04\x00\x00\x00\x04\x00\x00\x00\x00' + b'\x42\x00\x5C\x05\x00\x00\x00\x04\x00\x00\x00\x06\x00\x00\x00\x00' + b'\x42\x00\x5C\x05\x00\x00\x00\x04\x00\x00\x00\x07\x00\x00\x00\x00' + b'\x42\x00\x5C\x05\x00\x00\x00\x04\x00\x00\x00\x08\x00\x00\x00\x00' + b'\x42\x00\x5C\x05\x00\x00\x00\x04\x00\x00\x00\x09\x00\x00\x00\x00' + b'\x42\x00\x5C\x05\x00\x00\x00\x04\x00\x00\x00\x0A\x00\x00\x00\x00' + b'\x42\x00\x5C\x05\x00\x00\x00\x04\x00\x00\x00\x0B\x00\x00\x00\x00' + b'\x42\x00\x5C\x05\x00\x00\x00\x04\x00\x00\x00\x0C\x00\x00\x00\x00' + b'\x42\x00\x5C\x05\x00\x00\x00\x04\x00\x00\x00\x0D\x00\x00\x00\x00' + b'\x42\x00\x5C\x05\x00\x00\x00\x04\x00\x00\x00\x0E\x00\x00\x00\x00' + b'\x42\x00\x5C\x05\x00\x00\x00\x04\x00\x00\x00\x0F\x00\x00\x00\x00' + b'\x42\x00\x5C\x05\x00\x00\x00\x04\x00\x00\x00\x10\x00\x00\x00\x00' + b'\x42\x00\x5C\x05\x00\x00\x00\x04\x00\x00\x00\x11\x00\x00\x00\x00' + b'\x42\x00\x5C\x05\x00\x00\x00\x04\x00\x00\x00\x12\x00\x00\x00\x00' + b'\x42\x00\x5C\x05\x00\x00\x00\x04\x00\x00\x00\x13\x00\x00\x00\x00' + b'\x42\x00\x5C\x05\x00\x00\x00\x04\x00\x00\x00\x14\x00\x00\x00\x00' + b'\x42\x00\x5C\x05\x00\x00\x00\x04\x00\x00\x00\x15\x00\x00\x00\x00' + b'\x42\x00\x5C\x05\x00\x00\x00\x04\x00\x00\x00\x16\x00\x00\x00\x00' + b'\x42\x00\x5C\x05\x00\x00\x00\x04\x00\x00\x00\x18\x00\x00\x00\x00' + b'\x42\x00\x5C\x05\x00\x00\x00\x04\x00\x00\x00\x19\x00\x00\x00\x00' + b'\x42\x00\x5C\x05\x00\x00\x00\x04\x00\x00\x00\x1A\x00\x00\x00\x00' + b'\x42\x00\x5C\x05\x00\x00\x00\x04\x00\x00\x00\x1D\x00\x00\x00\x00' + b'\x42\x00\x5C\x05\x00\x00\x00\x04\x00\x00\x00\x1E\x00\x00\x00\x00' + b'\x42\x00\x57\x05\x00\x00\x00\x04\x00\x00\x00\x01\x00\x00\x00\x00' + b'\x42\x00\x57\x05\x00\x00\x00\x04\x00\x00\x00\x02\x00\x00\x00\x00' + b'\x42\x00\x57\x05\x00\x00\x00\x04\x00\x00\x00\x03\x00\x00\x00\x00' + b'\x42\x00\x57\x05\x00\x00\x00\x04\x00\x00\x00\x04\x00\x00\x00\x00' + b'\x42\x00\x57\x05\x00\x00\x00\x04\x00\x00\x00\x06\x00\x00\x00\x00' + b'\x42\x00\x57\x05\x00\x00\x00\x04\x00\x00\x00\x07\x00\x00\x00\x00' + b'\x42\x00\x9D\x07\x00\x00\x00\x2E' + b'\x49\x42\x4D\x20\x74\x65\x73\x74\x20\x73\x65\x72\x76\x65\x72\x2C' + b'\x20\x6E\x6F\x74\x2D\x54\x4B\x4C\x4D\x20\x32\x2E\x30\x2E\x31\x2E' + b'\x31\x20\x4B\x4D\x49\x50\x20\x32\x2E\x30\x2E\x30\x2E\x31\x00\x00' + b'\x42\x00\x88\x01\x00\x00\x00\x00' + b'\x42\x00\x03\x07\x00\x00\x00\x0B' + b'\x4E\x61\x6D\x65\x73\x70\x61\x63\x65\x20\x31\x00\x00\x00\x00\x00' + b'\x42\x00\x03\x07\x00\x00\x00\x0B' + b'\x4E\x61\x6D\x65\x73\x70\x61\x63\x65\x20\x32\x00\x00\x00\x00\x00' + b'\x42\x00\xA4\x01\x00\x00\x00\x38' + b'\x42\x00\xA5\x07\x00\x00\x00\x0D' + b'\x41\x43\x4D\x45\x20\x4C\x4F\x43\x41\x54\x49\x4F\x4E\x00\x00\x00' + b'\x42\x00\xA6\x02\x00\x00\x00\x04\x00\x54\xAA\x01\x00\x00\x00\x00' + b'\x42\x00\xA7\x02\x00\x00\x00\x04\x00\x00\x00\x07\x00\x00\x00\x00' + b'\x42\x00\xA4\x01\x00\x00\x00\x38' + b'\x42\x00\xA5\x07\x00\x00\x00\x0D' + b'\x41\x43\x4D\x45\x20\x5A\x49\x50\x20\x43\x4F\x44\x45\x00\x00\x00' + b'\x42\x00\xA6\x02\x00\x00\x00\x04\x00\x54\xAA\x02\x00\x00\x00\x00' + b'\x42\x00\xA7\x02\x00\x00\x00\x04\x00\x00\x00\x02\x00\x00\x00\x00' + b'\x42\x00\xC7\x05\x00\x00\x00\x04\x00\x00\x00\x01\x00\x00\x00\x00' + b'\x42\x00\xC7\x05\x00\x00\x00\x04\x00\x00\x00\x02\x00\x00\x00\x00' + b'\x42\x00\xC7\x05\x00\x00\x00\x04\x00\x00\x00\x03\x00\x00\x00\x00' + b'\x42\x00\xD9\x01\x00\x00\x00\x80' + b'\x42\x00\xDA\x05\x00\x00\x00\x04\x00\x00\x00\x02\x00\x00\x00\x00' + b'\x42\x00\x28\x05\x00\x00\x00\x04\x00\x00\x00\x03\x00\x00\x00\x00' + b'\x42\x00\x2A\x02\x00\x00\x00\x04\x00\x00\x01\x00\x00\x00\x00\x00' + b'\x42\x00\x38\x05\x00\x00\x00\x04\x00\x00\x00\x06\x00\x00\x00\x00' + b'\x42\x00\xDB\x05\x00\x00\x00\x04\x00\x00\x00\x03\x00\x00\x00\x00' + b'\x42\x00\x75\x05\x00\x00\x00\x04\x00\x00\x00\x01\x00\x00\x00\x00' + b'\x42\x00\xDC\x05\x00\x00\x00\x04\x00\x00\x00\x02\x00\x00\x00\x00' + b'\x42\x00\xDD\x06\x00\x00\x00\x08\x00\x00\x00\x00\x00\x00\x00\x01' + b'\x42\x00\xEB\x01\x00\x00\x00\x40' + b'\x42\x00\xEC\x05\x00\x00\x00\x04\x00\x00\x00\x01\x00\x00\x00\x00' + b'\x42\x00\xED\x07\x00\x00\x00\x13' + b'\x68\x74\x74\x70\x73\x3A\x2F\x2F\x65\x78\x61\x6D\x70\x6C\x65\x2E' + b'\x63\x6F\x6D\x00\x00\x00\x00\x00' + b'\x42\x00\xEE\x02\x00\x00\x00\x04\x00\x00\x16\x40\x00\x00\x00\x00' + b'\x42\x00\xDF\x01\x00\x00\x01\x18' + b'\x42\x00\xE0\x05\x00\x00\x00\x04\x00\x00\x00\x03\x00\x00\x00\x00' + b'\x42\x00\xE1\x07\x00\x00\x00\x02\x55\x53\x00\x00\x00\x00\x00\x00' + b'\x42\x00\xE2\x07\x00\x00\x00\x13' + b'\x68\x74\x74\x70\x73\x3A\x2F\x2F\x65\x78\x61\x6D\x70\x6C\x65\x2E' + b'\x63\x6F\x6D\x00\x00\x00\x00\x00' + b'\x42\x00\xE3\x02\x00\x00\x00\x04\x00\x00\x00\x01\x00\x00\x00\x00' + b'\x42\x00\xE4\x02\x00\x00\x00\x04\x00\x00\x00\x00\x00\x00\x00\x00' + b'\x42\x00\xE5\x05\x00\x00\x00\x04\x00\x00\x00\x05\x00\x00\x00\x00' + b'\x42\x00\xE6\x02\x00\x00\x00\x04\x00\x00\x00\x05\x00\x00\x00\x00' + b'\x42\x00\xE7\x07\x00\x00\x00\x24' + b'\x63\x30\x30\x35\x64\x33\x39\x65\x2D\x36\x30\x34\x66\x2D\x31\x31' + b'\x65\x39\x2D\x39\x39\x64\x66\x2D\x30\x38\x30\x30\x32\x37\x66\x63' + b'\x31\x33\x39\x36\x00\x00\x00\x00' + b'\x42\x00\xE8\x07\x00\x00\x00\x10' + b'\x68\x74\x74\x70\x73\x3A\x2F\x2F\x74\x65\x73\x74\x2E\x63\x6F\x6D' + b'\x42\x00\xE9\x07\x00\x00\x00\x12' + b'\x68\x74\x74\x70\x73\x3A\x2F\x2F\x76\x65\x6E\x64\x6F\x72\x2E\x63' + b'\x6F\x6D\x00\x00\x00\x00\x00\x00' + b'\x42\x00\xEA\x07\x00\x00\x00\x09' + b'\x50\x72\x6F\x66\x69\x6C\x65\x20\x31\x00\x00\x00\x00\x00\x00\x00' + b'\x42\x00\xEA\x07\x00\x00\x00\x09' + b'\x50\x72\x6F\x66\x69\x6C\x65\x20\x32\x00\x00\x00\x00\x00\x00\x00' + b'\x42\x00\xF7\x01\x00\x00\x00\x70' + b'\x42\x00\xEF\x06\x00\x00\x00\x08\x00\x00\x00\x00\x00\x00\x00\x00' + b'\x42\x00\xF0\x06\x00\x00\x00\x08\x00\x00\x00\x00\x00\x00\x00\x01' + b'\x42\x00\xF1\x06\x00\x00\x00\x08\x00\x00\x00\x00\x00\x00\x00\x01' + b'\x42\x00\xF2\x05\x00\x00\x00\x04\x00\x00\x00\x02\x00\x00\x00\x00' + b'\x42\x00\xF3\x05\x00\x00\x00\x04\x00\x00\x00\x07\x00\x00\x00\x00' + b'\x42\x00\xF4\x05\x00\x00\x00\x04\x00\x00\x00\x02\x00\x00\x00\x00' + b'\x42\x00\xF5\x05\x00\x00\x00\x04\x00\x00\x00\x03\x00\x00\x00\x00' + b'\x42\x00\xF6\x05\x00\x00\x00\x04\x00\x00\x00\x04\x00\x00\x00\x00' + b'\x42\x00\xF6\x05\x00\x00\x00\x04\x00\x00\x00\x05\x00\x00\x00\x00' + ) + + # This encoding matches the following set of values: + # Response Payload + self.empty_encoding = utils.BytearrayStream( + b'\x42\x00\x7C\x01\x00\x00\x00\x00' + ) def tearDown(self): super(TestQueryResponsePayload, self).tearDown() - def test_init_with_none(self): + def test_invalid_operations(self): """ - Test that a QueryResponsePayload object can be constructed with no - specified value. + Test that a TypeError is raised when an invalid value is used to set + the operations of a Query response payload. """ - payloads.QueryResponsePayload() - - def test_init_with_args(self): - """ - Test that a QueryResponsePayload object can be constructed with valid - values. - """ - payloads.QueryResponsePayload( - operations=self.operations, - object_types=self.object_types, - vendor_identification=self.vendor_identification, - server_information=self.server_information, - application_namespaces=self.application_namespaces, - extension_information=self.extension_information) - - def test_validate_with_invalid_operations_list(self): - """ - Test that a TypeError exception is raised when an invalid Operations - list is used to construct a QueryResponsePayload object. - """ - kwargs = {'operations': 'invalid'} + kwargs = {"operations": "invalid"} self.assertRaisesRegex( - TypeError, "invalid operations list", - payloads.QueryResponsePayload, **kwargs) - - def test_validate_with_invalid_operations_item(self): - """ - Test that a TypeError exception is raised when an invalid Operations - item is used to construct a QueryResponsePayload object. - """ - kwargs = {'operations': ['invalid']} + TypeError, + "The operations must be a list of Operation enumerations.", + payloads.QueryResponsePayload, + **kwargs + ) + kwargs = {"operations": ["invalid"]} self.assertRaisesRegex( - TypeError, "invalid operation", - payloads.QueryResponsePayload, **kwargs) + TypeError, + "The operations must be a list of Operation enumerations.", + payloads.QueryResponsePayload, + **kwargs + ) - def test_validate_with_invalid_object_types_list(self): - """ - Test that a TypeError exception is raised when an invalid ObjectTypes - list is used to construct a QueryResponsePayload object. - """ - kwargs = {'object_types': 'invalid'} + args = ( + payloads.QueryResponsePayload(), + "operations", + "invalid" + ) self.assertRaisesRegex( - TypeError, "invalid object types list", - payloads.QueryResponsePayload, **kwargs) - - def test_validate_with_invalid_object_types_item(self): - """ - Test that a TypeError exception is raised when an invalid ObjectTypes - item is used to construct a QueryResponsePayload object. - """ - kwargs = {'object_types': ['invalid']} + TypeError, + "The operations must be a list of Operation enumerations.", + setattr, + *args + ) + args = ( + payloads.QueryResponsePayload(), + "operations", + ["invalid"] + ) self.assertRaisesRegex( - TypeError, "invalid object type", - payloads.QueryResponsePayload, **kwargs) + TypeError, + "The operations must be a list of Operation enumerations.", + setattr, + *args + ) - def test_validate_with_invalid_vendor_identification(self): + def test_invalid_object_types(self): """ - Test that a TypeError exception is raised when an invalid - VendorIdentification item is used to construct a QueryResponsePayload - object. + Test that a TypeError is raised when an invalid value is used to set + the object types of a Query response payload. """ - kwargs = {'vendor_identification': 'invalid'} + kwargs = {"object_types": "invalid"} self.assertRaisesRegex( - TypeError, "invalid vendor identification", - payloads.QueryResponsePayload, **kwargs) - - def test_validate_with_invalid_server_information(self): - """ - Test that a TypeError exception is raised when an invalid - ServerInformation item is used to construct a QueryResponsePayload - object. - """ - kwargs = {'server_information': 'invalid'} + TypeError, + "The object types must be a list of ObjectType enumerations.", + payloads.QueryResponsePayload, + **kwargs + ) + kwargs = {"object_types": ["invalid"]} self.assertRaisesRegex( - TypeError, "invalid server information", - payloads.QueryResponsePayload, **kwargs) + TypeError, + "The object types must be a list of ObjectType enumerations.", + payloads.QueryResponsePayload, + **kwargs + ) - def test_validate_with_invalid_application_namespaces_list(self): - """ - Test that a TypeError exception is raised when an invalid - ApplicationNamespaces list is used to construct a QueryResponsePayload - object. - """ - kwargs = {'application_namespaces': 'invalid'} + args = ( + payloads.QueryResponsePayload(), + "object_types", + "invalid" + ) self.assertRaisesRegex( - TypeError, "invalid application namespaces list", - payloads.QueryResponsePayload, **kwargs) - - def test_validate_with_invalid_application_namespaces_item(self): - """ - Test that a TypeError exception is raised when an invalid - ApplicationNamespaces item is used to construct a QueryResponsePayload - object. - """ - kwargs = {'application_namespaces': ['invalid']} + TypeError, + "The object types must be a list of ObjectType enumerations.", + setattr, + *args + ) + args = ( + payloads.QueryResponsePayload(), + "object_types", + ["invalid"] + ) self.assertRaisesRegex( - TypeError, "invalid application namespace", - payloads.QueryResponsePayload, **kwargs) + TypeError, + "The object types must be a list of ObjectType enumerations.", + setattr, + *args + ) - def test_validate_with_invalid_extension_information_list(self): + def test_invalid_vendor_identification(self): """ - Test that a TypeError exception is raised when an invalid - ExtensionInformation list is used to construct a QueryResponsePayload - object. + Test that a TypeError is raised when an invalid value is used to set + the vendor identification of a Query response payload. """ - kwargs = {'extension_information': 'invalid'} + kwargs = {"vendor_identification": 0} self.assertRaisesRegex( - TypeError, "invalid extension information list", - payloads.QueryResponsePayload, **kwargs) + TypeError, + "The vendor identification must be a string.", + payloads.QueryResponsePayload, + **kwargs + ) - def test_validate_with_invalid_extension_information_item(self): - """ - Test that a TypeError exception is raised when an invalid - ExtensionInformation item is used to construct a QueryResponsePayload - object. - """ - kwargs = {'extension_information': ['invalid']} + args = ( + payloads.QueryResponsePayload(), + "vendor_identification", + 0 + ) self.assertRaisesRegex( - TypeError, "invalid extension information", - payloads.QueryResponsePayload, **kwargs) + TypeError, + "The vendor identification must be a string.", + setattr, + *args + ) - def _test_read(self, stream, operations, object_types, - vendor_identification, server_information, - application_namespaces, extension_information): + def test_invalid_server_information(self): + """ + Test that a TypeError is raised when an invalid value is used to set + the server information of a Query response payload. + """ + kwargs = {"server_information": "invalid"} + self.assertRaisesRegex( + TypeError, + "The server information must be a ServerInformation structure.", + payloads.QueryResponsePayload, + **kwargs + ) + + args = ( + payloads.QueryResponsePayload(), + "server_information", + "invalid" + ) + self.assertRaisesRegex( + TypeError, + "The server information must be a ServerInformation structure.", + setattr, + *args + ) + + def test_invalid_application_namespaces(self): + """ + Test that a TypeError is raised when an invalid value is used to set + the application namespaces of a Query response payload. + """ + kwargs = {"application_namespaces": 0} + self.assertRaisesRegex( + TypeError, + "The application namespaces must be a list of strings.", + payloads.QueryResponsePayload, + **kwargs + ) + kwargs = {"application_namespaces": [0]} + self.assertRaisesRegex( + TypeError, + "The application namespaces must be a list of strings.", + payloads.QueryResponsePayload, + **kwargs + ) + + args = ( + payloads.QueryResponsePayload(), + "application_namespaces", + 0 + ) + self.assertRaisesRegex( + TypeError, + "The application namespaces must be a list of strings.", + setattr, + *args + ) + args = ( + payloads.QueryResponsePayload(), + "application_namespaces", + [0] + ) + self.assertRaisesRegex( + TypeError, + "The application namespaces must be a list of strings.", + setattr, + *args + ) + + def test_invalid_extension_information(self): + """ + Test that a TypeError is raised when an invalid value is used to set + the extension information of a Query response payload. + """ + kwargs = {"extension_information": "invalid"} + self.assertRaisesRegex( + TypeError, + "The extension information must be a list of " + "ExtensionInformation structures.", + payloads.QueryResponsePayload, + **kwargs + ) + kwargs = {"extension_information": ["invalid"]} + self.assertRaisesRegex( + TypeError, + "The extension information must be a list of " + "ExtensionInformation structures.", + payloads.QueryResponsePayload, + **kwargs + ) + + args = ( + payloads.QueryResponsePayload(), + "extension_information", + "invalid" + ) + self.assertRaisesRegex( + TypeError, + "The extension information must be a list of " + "ExtensionInformation structures.", + setattr, + *args + ) + args = ( + payloads.QueryResponsePayload(), + "extension_information", + ["invalid"] + ) + self.assertRaisesRegex( + TypeError, + "The extension information must be a list of " + "ExtensionInformation structures.", + setattr, + *args + ) + + def test_invalid_attestation_types(self): + """ + Test that a TypeError is raised when an invalid value is used to set + the attestation types of a Query response payload. + """ + kwargs = {"attestation_types": "invalid"} + self.assertRaisesRegex( + TypeError, + "The attestation types must be a list of AttestationType " + "enumerations.", + payloads.QueryResponsePayload, + **kwargs + ) + kwargs = {"attestation_types": ["invalid"]} + self.assertRaisesRegex( + TypeError, + "The attestation types must be a list of AttestationType " + "enumerations.", + payloads.QueryResponsePayload, + **kwargs + ) + + args = ( + payloads.QueryResponsePayload(), + "attestation_types", + "invalid" + ) + self.assertRaisesRegex( + TypeError, + "The attestation types must be a list of AttestationType " + "enumerations.", + setattr, + *args + ) + args = ( + payloads.QueryResponsePayload(), + "attestation_types", + ["invalid"] + ) + self.assertRaisesRegex( + TypeError, + "The attestation types must be a list of AttestationType " + "enumerations.", + setattr, + *args + ) + + def test_invalid_rng_parameters(self): + """ + Test that a TypeError is raised when an invalid value is used to set + the RNG parameters of a Query response payload. + """ + kwargs = {"rng_parameters": "invalid"} + self.assertRaisesRegex( + TypeError, + "The RNG parameters must be a list of RNGParameters structures.", + payloads.QueryResponsePayload, + **kwargs + ) + kwargs = {"rng_parameters": ["invalid"]} + self.assertRaisesRegex( + TypeError, + "The RNG parameters must be a list of RNGParameters structures.", + payloads.QueryResponsePayload, + **kwargs + ) + + args = ( + payloads.QueryResponsePayload(), + "rng_parameters", + "invalid" + ) + self.assertRaisesRegex( + TypeError, + "The RNG parameters must be a list of RNGParameters structures.", + setattr, + *args + ) + args = ( + payloads.QueryResponsePayload(), + "rng_parameters", + ["invalid"] + ) + self.assertRaisesRegex( + TypeError, + "The RNG parameters must be a list of RNGParameters structures.", + setattr, + *args + ) + + def test_invalid_profile_information(self): + """ + Test that a TypeError is raised when an invalid value is used to set + the profile information of a Query response payload. + """ + kwargs = {"profile_information": "invalid"} + self.assertRaisesRegex( + TypeError, + "The profile information must be a list of ProfileInformation " + "structures.", + payloads.QueryResponsePayload, + **kwargs + ) + kwargs = {"profile_information": ["invalid"]} + self.assertRaisesRegex( + TypeError, + "The profile information must be a list of ProfileInformation " + "structures.", + payloads.QueryResponsePayload, + **kwargs + ) + + args = ( + payloads.QueryResponsePayload(), + "profile_information", + "invalid" + ) + self.assertRaisesRegex( + TypeError, + "The profile information must be a list of ProfileInformation " + "structures.", + setattr, + *args + ) + args = ( + payloads.QueryResponsePayload(), + "profile_information", + ["invalid"] + ) + self.assertRaisesRegex( + TypeError, + "The profile information must be a list of ProfileInformation " + "structures.", + setattr, + *args + ) + + def test_invalid_validation_information(self): + """ + Test that a TypeError is raised when an invalid value is used to set + the validation information of a Query response payload. + """ + kwargs = {"validation_information": "invalid"} + self.assertRaisesRegex( + TypeError, + "The validation information must be a list of " + "ValidationInformation structures.", + payloads.QueryResponsePayload, + **kwargs + ) + kwargs = {"validation_information": ["invalid"]} + self.assertRaisesRegex( + TypeError, + "The validation information must be a list of " + "ValidationInformation structures.", + payloads.QueryResponsePayload, + **kwargs + ) + + args = ( + payloads.QueryResponsePayload(), + "validation_information", + "invalid" + ) + self.assertRaisesRegex( + TypeError, + "The validation information must be a list of " + "ValidationInformation structures.", + setattr, + *args + ) + args = ( + payloads.QueryResponsePayload(), + "validation_information", + ["invalid"] + ) + self.assertRaisesRegex( + TypeError, + "The validation information must be a list of " + "ValidationInformation structures.", + setattr, + *args + ) + + def test_invalid_capability_information(self): + """ + Test that a TypeError is raised when an invalid value is used to set + the capability information of a Query response payload. + """ + kwargs = {"capability_information": "invalid"} + self.assertRaisesRegex( + TypeError, + "The capability information must be a list of " + "CapabilityInformation structures.", + payloads.QueryResponsePayload, + **kwargs + ) + kwargs = {"capability_information": ["invalid"]} + self.assertRaisesRegex( + TypeError, + "The capability information must be a list of " + "CapabilityInformation structures.", + payloads.QueryResponsePayload, + **kwargs + ) + + args = ( + payloads.QueryResponsePayload(), + "capability_information", + "invalid" + ) + self.assertRaisesRegex( + TypeError, + "The capability information must be a list of " + "CapabilityInformation structures.", + setattr, + *args + ) + args = ( + payloads.QueryResponsePayload(), + "capability_information", + ["invalid"] + ) + self.assertRaisesRegex( + TypeError, + "The capability information must be a list of " + "CapabilityInformation structures.", + setattr, + *args + ) + + def test_invalid_client_registration_methods(self): + """ + Test that a TypeError is raised when an invalid value is used to set + the client registration methods of a Query response payload. + """ + kwargs = {"client_registration_methods": "invalid"} + self.assertRaisesRegex( + TypeError, + "The client registration methods must be a list of " + "ClientRegistrationMethod enumerations.", + payloads.QueryResponsePayload, + **kwargs + ) + kwargs = {"client_registration_methods": ["invalid"]} + self.assertRaisesRegex( + TypeError, + "The client registration methods must be a list of " + "ClientRegistrationMethod enumerations.", + payloads.QueryResponsePayload, + **kwargs + ) + + args = ( + payloads.QueryResponsePayload(), + "client_registration_methods", + "invalid" + ) + self.assertRaisesRegex( + TypeError, + "The client registration methods must be a list of " + "ClientRegistrationMethod enumerations.", + setattr, + *args + ) + args = ( + payloads.QueryResponsePayload(), + "client_registration_methods", + ["invalid"] + ) + self.assertRaisesRegex( + TypeError, + "The client registration methods must be a list of " + "ClientRegistrationMethod enumerations.", + setattr, + *args + ) + + def test_read(self): + """ + Test that a QueryResponsePayload structure can be correctly read in + from a data stream. + """ payload = payloads.QueryResponsePayload() - payload.read(stream) - # Test decoding of all operations. - expected = len(operations) - observed = len(payload.operations) + self.assertIsNone(payload.operations) + self.assertIsNone(payload.object_types) + self.assertIsNone(payload.vendor_identification) + self.assertIsNone(payload.server_information) + self.assertIsNone(payload.application_namespaces) - msg = "operations list decoding mismatch" - msg += "; expected {0} results, received {1}".format( - expected, observed) - self.assertEqual(expected, observed, msg) + payload.read(self.full_encoding) - for i in xrange(len(operations)): - expected = operations[i] - observed = payload.operations[i] + self.assertEqual( + [ + enums.Operation.CREATE, + enums.Operation.CREATE_KEY_PAIR, + enums.Operation.REGISTER, + enums.Operation.REKEY, + enums.Operation.CERTIFY, + enums.Operation.RECERTIFY, + enums.Operation.LOCATE, + enums.Operation.CHECK, + enums.Operation.GET, + enums.Operation.GET_ATTRIBUTES, + enums.Operation.GET_ATTRIBUTE_LIST, + enums.Operation.ADD_ATTRIBUTE, + enums.Operation.MODIFY_ATTRIBUTE, + enums.Operation.DELETE_ATTRIBUTE, + enums.Operation.OBTAIN_LEASE, + enums.Operation.GET_USAGE_ALLOCATION, + enums.Operation.ACTIVATE, + enums.Operation.REVOKE, + enums.Operation.DESTROY, + enums.Operation.ARCHIVE, + enums.Operation.RECOVER, + enums.Operation.QUERY, + enums.Operation.CANCEL, + enums.Operation.POLL, + enums.Operation.REKEY_KEY_PAIR, + enums.Operation.DISCOVER_VERSIONS + ], + payload.operations + ) + self.assertEqual( + [ + enums.ObjectType.CERTIFICATE, + enums.ObjectType.SYMMETRIC_KEY, + enums.ObjectType.PUBLIC_KEY, + enums.ObjectType.PRIVATE_KEY, + enums.ObjectType.TEMPLATE, + enums.ObjectType.SECRET_DATA + ], + payload.object_types + ) + self.assertEqual( + "IBM test server, not-TKLM 2.0.1.1 KMIP 2.0.0.1", + payload.vendor_identification + ) + self.assertEqual( + misc.ServerInformation(), + payload.server_information + ) + self.assertEqual( + [ + "Namespace 1", + "Namespace 2" + ], + payload.application_namespaces + ) - msg = "operation decoding mismatch" - msg += "; expected {0}, received {1}".format(expected, observed) - self.assertEqual(expected, observed, msg) - - # Test decoding of all object types. - expected = len(object_types) - observed = len(payload.object_types) - - msg = "object types list decoding mismatch" - msg += "; expected {0} results, received {1}".format( - expected, observed) - self.assertEqual(expected, observed, msg) - - for i in xrange(len(object_types)): - expected = object_types[i] - observed = payload.object_types[i] - - msg = "object type decoding mismatch" - msg += "; expected {0}, received {1}".format(expected, observed) - self.assertEqual(expected, observed, msg) - - # Test decoding of vendor identification. - expected = vendor_identification - observed = payload.vendor_identification - - msg = "vendor identification decoding mismatch" - msg += "; expected {0}, received {1}".format(expected, observed) - self.assertEqual(expected, observed, msg) - - # Test decoding of server information. - expected = server_information - observed = payload.server_information - - msg = "server information decoding mismatch" - msg += "; expected {0}, received {1}".format(expected, observed) - self.assertEqual(expected, observed, msg) - - # Test decoding of all application namespaces. - expected = len(application_namespaces) - observed = len(payload.application_namespaces) - - msg = "application namespaces list decoding mismatch" - msg += "; expected {0} results, received {1}".format( - expected, observed) - self.assertEqual(expected, observed, msg) - - # Test decoding of all extension information. - expected = len(extension_information) - observed = len(payload.extension_information) - - msg = "extension information list decoding mismatch" - msg += "; expected {0} results, received {1}".format( - expected, observed) - self.assertEqual(expected, observed, msg) - - for i in xrange(len(extension_information)): - expected = extension_information[i] - observed = payload.extension_information[i] - - msg = "extension information decoding mismatch" - msg += "; expected {0}, received {1}".format(expected, observed) - self.assertEqual(expected, observed, msg) - - def test_read_with_no_data(self): + def test_read_kmip_1_1(self): """ - Test that a QueryResponsePayload object with no data can be read from - a data stream. + Test that a QueryResponsePayload structure can be correctly read in + from a data stream with KMIP 1.1 features. """ - self._test_read( - self.encoding_a, list(), list(), None, None, list(), list()) + payload = payloads.QueryResponsePayload() - def test_read_with_operations_object_types_and_server_info(self): - """ - Test that a QueryResponsePayload object with multiple pieces of data - can be read from a data stream. - """ - self._test_read( - self.encoding_b, self.operations, self.object_types, - self.vendor_identification, self.server_information, - self.application_namespaces, list()) + self.assertIsNone(payload.operations) + self.assertIsNone(payload.object_types) + self.assertIsNone(payload.vendor_identification) + self.assertIsNone(payload.server_information) + self.assertIsNone(payload.application_namespaces) + self.assertIsNone(payload.extension_information) - def test_read_with_extension_information(self): - """ - Test that a QueryResponsePayload object with one piece of data can be - read from a data stream. - """ - self._test_read( - self.encoding_c, list(), list(), None, None, - self.application_namespaces, self.extension_information) + payload.read( + self.full_encoding_kmip_1_1, + kmip_version=enums.KMIPVersion.KMIP_1_1 + ) - def _test_write(self, encoding, operations, object_types, - vendor_identification, server_information, - application_namespaces, extension_information): - stream = utils.BytearrayStream() + self.assertEqual( + [ + enums.Operation.CREATE, + enums.Operation.CREATE_KEY_PAIR, + enums.Operation.REGISTER, + enums.Operation.REKEY, + enums.Operation.CERTIFY, + enums.Operation.RECERTIFY, + enums.Operation.LOCATE, + enums.Operation.CHECK, + enums.Operation.GET, + enums.Operation.GET_ATTRIBUTES, + enums.Operation.GET_ATTRIBUTE_LIST, + enums.Operation.ADD_ATTRIBUTE, + enums.Operation.MODIFY_ATTRIBUTE, + enums.Operation.DELETE_ATTRIBUTE, + enums.Operation.OBTAIN_LEASE, + enums.Operation.GET_USAGE_ALLOCATION, + enums.Operation.ACTIVATE, + enums.Operation.REVOKE, + enums.Operation.DESTROY, + enums.Operation.ARCHIVE, + enums.Operation.RECOVER, + enums.Operation.QUERY, + enums.Operation.CANCEL, + enums.Operation.POLL, + enums.Operation.REKEY_KEY_PAIR, + enums.Operation.DISCOVER_VERSIONS + ], + payload.operations + ) + self.assertEqual( + [ + enums.ObjectType.CERTIFICATE, + enums.ObjectType.SYMMETRIC_KEY, + enums.ObjectType.PUBLIC_KEY, + enums.ObjectType.PRIVATE_KEY, + enums.ObjectType.TEMPLATE, + enums.ObjectType.SECRET_DATA + ], + payload.object_types + ) + self.assertEqual( + "IBM test server, not-TKLM 2.0.1.1 KMIP 2.0.0.1", + payload.vendor_identification + ) + self.assertEqual( + misc.ServerInformation(), + payload.server_information + ) + self.assertEqual( + [ + "Namespace 1", + "Namespace 2" + ], + payload.application_namespaces + ) + self.assertEqual( + [ + objects.ExtensionInformation( + extension_name=objects.ExtensionName("ACME LOCATION"), + extension_tag=objects.ExtensionTag(0x0054AA01), + extension_type=objects.ExtensionType(7) + ), + objects.ExtensionInformation( + extension_name=objects.ExtensionName("ACME ZIP CODE"), + extension_tag=objects.ExtensionTag(0x0054AA02), + extension_type=objects.ExtensionType(2) + ) + ], + payload.extension_information + ) + + def test_read_kmip_1_2(self): + """ + Test that a QueryResponsePayload structure can be correctly read in + from a data stream with KMIP 1.2 features. + """ + payload = payloads.QueryResponsePayload() + + self.assertIsNone(payload.operations) + self.assertIsNone(payload.object_types) + self.assertIsNone(payload.vendor_identification) + self.assertIsNone(payload.server_information) + self.assertIsNone(payload.application_namespaces) + self.assertIsNone(payload.extension_information) + self.assertIsNone(payload.attestation_types) + + payload.read( + self.full_encoding_kmip_1_2, + kmip_version=enums.KMIPVersion.KMIP_1_2 + ) + + self.assertEqual( + [ + enums.Operation.CREATE, + enums.Operation.CREATE_KEY_PAIR, + enums.Operation.REGISTER, + enums.Operation.REKEY, + enums.Operation.CERTIFY, + enums.Operation.RECERTIFY, + enums.Operation.LOCATE, + enums.Operation.CHECK, + enums.Operation.GET, + enums.Operation.GET_ATTRIBUTES, + enums.Operation.GET_ATTRIBUTE_LIST, + enums.Operation.ADD_ATTRIBUTE, + enums.Operation.MODIFY_ATTRIBUTE, + enums.Operation.DELETE_ATTRIBUTE, + enums.Operation.OBTAIN_LEASE, + enums.Operation.GET_USAGE_ALLOCATION, + enums.Operation.ACTIVATE, + enums.Operation.REVOKE, + enums.Operation.DESTROY, + enums.Operation.ARCHIVE, + enums.Operation.RECOVER, + enums.Operation.QUERY, + enums.Operation.CANCEL, + enums.Operation.POLL, + enums.Operation.REKEY_KEY_PAIR, + enums.Operation.DISCOVER_VERSIONS + ], + payload.operations + ) + self.assertEqual( + [ + enums.ObjectType.CERTIFICATE, + enums.ObjectType.SYMMETRIC_KEY, + enums.ObjectType.PUBLIC_KEY, + enums.ObjectType.PRIVATE_KEY, + enums.ObjectType.TEMPLATE, + enums.ObjectType.SECRET_DATA + ], + payload.object_types + ) + self.assertEqual( + "IBM test server, not-TKLM 2.0.1.1 KMIP 2.0.0.1", + payload.vendor_identification + ) + self.assertEqual( + misc.ServerInformation(), + payload.server_information + ) + self.assertEqual( + [ + "Namespace 1", + "Namespace 2" + ], + payload.application_namespaces + ) + self.assertEqual( + [ + objects.ExtensionInformation( + extension_name=objects.ExtensionName("ACME LOCATION"), + extension_tag=objects.ExtensionTag(0x0054AA01), + extension_type=objects.ExtensionType(7) + ), + objects.ExtensionInformation( + extension_name=objects.ExtensionName("ACME ZIP CODE"), + extension_tag=objects.ExtensionTag(0x0054AA02), + extension_type=objects.ExtensionType(2) + ) + ], + payload.extension_information + ) + self.assertEqual( + [ + enums.AttestationType.TPM_QUOTE, + enums.AttestationType.TCG_INTEGRITY_REPORT, + enums.AttestationType.SAML_ASSERTION + ], + payload.attestation_types + ) + + def test_read_kmip_1_3(self): + """ + Test that a QueryResponsePayload structure can be correctly read in + from a data stream with KMIP 1.3 features. + """ + payload = payloads.QueryResponsePayload() + + self.assertIsNone(payload.operations) + self.assertIsNone(payload.object_types) + self.assertIsNone(payload.vendor_identification) + self.assertIsNone(payload.server_information) + self.assertIsNone(payload.application_namespaces) + self.assertIsNone(payload.extension_information) + self.assertIsNone(payload.attestation_types) + self.assertIsNone(payload.rng_parameters) + self.assertIsNone(payload.profile_information) + self.assertIsNone(payload.validation_information) + self.assertIsNone(payload.capability_information) + self.assertIsNone(payload.client_registration_methods) + + payload.read( + self.full_encoding_kmip_1_3, + kmip_version=enums.KMIPVersion.KMIP_1_3 + ) + + self.assertEqual( + [ + enums.Operation.CREATE, + enums.Operation.CREATE_KEY_PAIR, + enums.Operation.REGISTER, + enums.Operation.REKEY, + enums.Operation.CERTIFY, + enums.Operation.RECERTIFY, + enums.Operation.LOCATE, + enums.Operation.CHECK, + enums.Operation.GET, + enums.Operation.GET_ATTRIBUTES, + enums.Operation.GET_ATTRIBUTE_LIST, + enums.Operation.ADD_ATTRIBUTE, + enums.Operation.MODIFY_ATTRIBUTE, + enums.Operation.DELETE_ATTRIBUTE, + enums.Operation.OBTAIN_LEASE, + enums.Operation.GET_USAGE_ALLOCATION, + enums.Operation.ACTIVATE, + enums.Operation.REVOKE, + enums.Operation.DESTROY, + enums.Operation.ARCHIVE, + enums.Operation.RECOVER, + enums.Operation.QUERY, + enums.Operation.CANCEL, + enums.Operation.POLL, + enums.Operation.REKEY_KEY_PAIR, + enums.Operation.DISCOVER_VERSIONS + ], + payload.operations + ) + self.assertEqual( + [ + enums.ObjectType.CERTIFICATE, + enums.ObjectType.SYMMETRIC_KEY, + enums.ObjectType.PUBLIC_KEY, + enums.ObjectType.PRIVATE_KEY, + enums.ObjectType.TEMPLATE, + enums.ObjectType.SECRET_DATA + ], + payload.object_types + ) + self.assertEqual( + "IBM test server, not-TKLM 2.0.1.1 KMIP 2.0.0.1", + payload.vendor_identification + ) + self.assertEqual( + misc.ServerInformation(), + payload.server_information + ) + self.assertEqual( + [ + "Namespace 1", + "Namespace 2" + ], + payload.application_namespaces + ) + self.assertEqual( + [ + objects.ExtensionInformation( + extension_name=objects.ExtensionName("ACME LOCATION"), + extension_tag=objects.ExtensionTag(0x0054AA01), + extension_type=objects.ExtensionType(7) + ), + objects.ExtensionInformation( + extension_name=objects.ExtensionName("ACME ZIP CODE"), + extension_tag=objects.ExtensionTag(0x0054AA02), + extension_type=objects.ExtensionType(2) + ) + ], + payload.extension_information + ) + self.assertEqual( + [ + enums.AttestationType.TPM_QUOTE, + enums.AttestationType.TCG_INTEGRITY_REPORT, + enums.AttestationType.SAML_ASSERTION + ], + payload.attestation_types + ) + self.assertEqual( + [ + objects.RNGParameters( + rng_algorithm=enums.RNGAlgorithm.FIPS186_2, + cryptographic_algorithm=enums.CryptographicAlgorithm.AES, + cryptographic_length=256, + hashing_algorithm=enums.HashingAlgorithm.SHA_256, + drbg_algorithm=enums.DRBGAlgorithm.HASH, + recommended_curve=enums.RecommendedCurve.P_192, + fips186_variation=enums.FIPS186Variation.GP_X_ORIGINAL, + prediction_resistance=True + ) + ], + payload.rng_parameters + ) + self.assertEqual( + [ + objects.ProfileInformation( + profile_name=( + enums.ProfileName.BASELINE_SERVER_BASIC_KMIPv12 + ), + server_uri="https://example.com", + server_port=5696 + ) + ], + payload.profile_information + ) + self.assertEqual( + [ + objects.ValidationInformation( + validation_authority_type=( + enums.ValidationAuthorityType.COMMON_CRITERIA + ), + validation_authority_country="US", + validation_authority_uri="https://example.com", + validation_version_major=1, + validation_version_minor=0, + validation_type=enums.ValidationType.HYBRID, + validation_level=5, + validation_certificate_identifier=( + "c005d39e-604f-11e9-99df-080027fc1396" + ), + validation_certificate_uri="https://test.com", + validation_vendor_uri="https://vendor.com", + validation_profiles=["Profile 1", "Profile 2"] + ) + ], + payload.validation_information + ) + self.assertEqual( + [ + objects.CapabilityInformation( + streaming_capability=False, + asynchronous_capability=True, + attestation_capability=True, + unwrap_mode=enums.UnwrapMode.PROCESSED, + destroy_action=enums.DestroyAction.SHREDDED, + shredding_algorithm=enums.ShreddingAlgorithm.CRYPTOGRAPHIC, + rng_mode=enums.RNGMode.NON_SHARED_INSTANTIATION + ) + ], + payload.capability_information + ) + self.assertEqual( + [ + enums.ClientRegistrationMethod.CLIENT_GENERATED, + enums.ClientRegistrationMethod.CLIENT_REGISTERED + ], + payload.client_registration_methods + ) + + def test_read_empty(self): + """ + Test that an empty QueryResponsePayload structure can be correctly read + in from a data stream. + """ + payload = payloads.QueryResponsePayload() + + self.assertIsNone(payload.operations) + self.assertIsNone(payload.object_types) + self.assertIsNone(payload.vendor_identification) + self.assertIsNone(payload.server_information) + self.assertIsNone(payload.application_namespaces) + + payload.read(self.empty_encoding) + + self.assertIsNone(payload.operations) + self.assertIsNone(payload.object_types) + self.assertIsNone(payload.vendor_identification) + self.assertIsNone(payload.server_information) + self.assertIsNone(payload.application_namespaces) + + def test_write(self): + """ + Test that a QueryResponsePayload structure can be written to a data + stream. + """ payload = payloads.QueryResponsePayload( - operations, object_types, vendor_identification, - server_information, application_namespaces, extension_information) - payload.write(stream) + operations=[ + enums.Operation.CREATE, + enums.Operation.CREATE_KEY_PAIR, + enums.Operation.REGISTER, + enums.Operation.REKEY, + enums.Operation.CERTIFY, + enums.Operation.RECERTIFY, + enums.Operation.LOCATE, + enums.Operation.CHECK, + enums.Operation.GET, + enums.Operation.GET_ATTRIBUTES, + enums.Operation.GET_ATTRIBUTE_LIST, + enums.Operation.ADD_ATTRIBUTE, + enums.Operation.MODIFY_ATTRIBUTE, + enums.Operation.DELETE_ATTRIBUTE, + enums.Operation.OBTAIN_LEASE, + enums.Operation.GET_USAGE_ALLOCATION, + enums.Operation.ACTIVATE, + enums.Operation.REVOKE, + enums.Operation.DESTROY, + enums.Operation.ARCHIVE, + enums.Operation.RECOVER, + enums.Operation.QUERY, + enums.Operation.CANCEL, + enums.Operation.POLL, + enums.Operation.REKEY_KEY_PAIR, + enums.Operation.DISCOVER_VERSIONS + ], + object_types=[ + enums.ObjectType.CERTIFICATE, + enums.ObjectType.SYMMETRIC_KEY, + enums.ObjectType.PUBLIC_KEY, + enums.ObjectType.PRIVATE_KEY, + enums.ObjectType.TEMPLATE, + enums.ObjectType.SECRET_DATA + ], + vendor_identification=( + "IBM test server, not-TKLM 2.0.1.1 KMIP 2.0.0.1" + ), + server_information=misc.ServerInformation(), + application_namespaces=[ + "Namespace 1", + "Namespace 2" + ] + ) - length_expected = len(encoding) - length_received = len(stream) + buffer = utils.BytearrayStream() + payload.write(buffer) - msg = "encoding lengths not equal" - msg += "; expected {0}, received {1}".format( - length_expected, length_received) - self.assertEqual(length_expected, length_received, msg) + self.assertEqual(len(self.full_encoding), len(buffer)) + self.assertEqual(str(self.full_encoding), str(buffer)) - msg = "encoding mismatch" - msg += ";\nexpected:\n{0}\nreceived:\n{1}".format(encoding, stream) - - self.assertEqual(encoding, stream, msg) - - def test_write_with_no_data(self): + def test_write_kmip_1_1(self): """ - Test that a QueryResponsePayload object with no data can be written to - a data stream. + Test that a QueryResponsePayload structure can be written to a data + stream with KMIP 1.1 features. """ - self._test_write( - self.encoding_a, list(), list(), None, None, list(), list()) + payload = payloads.QueryResponsePayload( + operations=[ + enums.Operation.CREATE, + enums.Operation.CREATE_KEY_PAIR, + enums.Operation.REGISTER, + enums.Operation.REKEY, + enums.Operation.CERTIFY, + enums.Operation.RECERTIFY, + enums.Operation.LOCATE, + enums.Operation.CHECK, + enums.Operation.GET, + enums.Operation.GET_ATTRIBUTES, + enums.Operation.GET_ATTRIBUTE_LIST, + enums.Operation.ADD_ATTRIBUTE, + enums.Operation.MODIFY_ATTRIBUTE, + enums.Operation.DELETE_ATTRIBUTE, + enums.Operation.OBTAIN_LEASE, + enums.Operation.GET_USAGE_ALLOCATION, + enums.Operation.ACTIVATE, + enums.Operation.REVOKE, + enums.Operation.DESTROY, + enums.Operation.ARCHIVE, + enums.Operation.RECOVER, + enums.Operation.QUERY, + enums.Operation.CANCEL, + enums.Operation.POLL, + enums.Operation.REKEY_KEY_PAIR, + enums.Operation.DISCOVER_VERSIONS + ], + object_types=[ + enums.ObjectType.CERTIFICATE, + enums.ObjectType.SYMMETRIC_KEY, + enums.ObjectType.PUBLIC_KEY, + enums.ObjectType.PRIVATE_KEY, + enums.ObjectType.TEMPLATE, + enums.ObjectType.SECRET_DATA + ], + vendor_identification=( + "IBM test server, not-TKLM 2.0.1.1 KMIP 2.0.0.1" + ), + server_information=misc.ServerInformation(), + application_namespaces=[ + "Namespace 1", + "Namespace 2" + ], + extension_information=[ + objects.ExtensionInformation( + extension_name=objects.ExtensionName("ACME LOCATION"), + extension_tag=objects.ExtensionTag(0x0054AA01), + extension_type=objects.ExtensionType(7) + ), + objects.ExtensionInformation( + extension_name=objects.ExtensionName("ACME ZIP CODE"), + extension_tag=objects.ExtensionTag(0x0054AA02), + extension_type=objects.ExtensionType(2) + ) + ] + ) - def test_write_with_operations_object_types_and_server_info(self): - """ - Test that a QueryResponsePayload object with multiple pieces of data - can be written to a data stream. - """ - self._test_write( - self.encoding_b, self.operations, self.object_types, - self.vendor_identification, self.server_information, - self.application_namespaces, list()) + buffer = utils.BytearrayStream() + payload.write(buffer, kmip_version=enums.KMIPVersion.KMIP_1_1) - def test_write_with_extension_information(self): + self.assertEqual(len(self.full_encoding_kmip_1_1), len(buffer)) + self.assertEqual(str(self.full_encoding_kmip_1_1), str(buffer)) + + def test_write_kmip_1_2(self): """ - Test that a QueryResponsePayload object with one piece of data can be - written to a data stream. + Test that a QueryResponsePayload structure can be written to a data + stream with KMIP 1.2 features. """ - self._test_write( - self.encoding_c, list(), list(), None, None, - self.application_namespaces, self.extension_information) + payload = payloads.QueryResponsePayload( + operations=[ + enums.Operation.CREATE, + enums.Operation.CREATE_KEY_PAIR, + enums.Operation.REGISTER, + enums.Operation.REKEY, + enums.Operation.CERTIFY, + enums.Operation.RECERTIFY, + enums.Operation.LOCATE, + enums.Operation.CHECK, + enums.Operation.GET, + enums.Operation.GET_ATTRIBUTES, + enums.Operation.GET_ATTRIBUTE_LIST, + enums.Operation.ADD_ATTRIBUTE, + enums.Operation.MODIFY_ATTRIBUTE, + enums.Operation.DELETE_ATTRIBUTE, + enums.Operation.OBTAIN_LEASE, + enums.Operation.GET_USAGE_ALLOCATION, + enums.Operation.ACTIVATE, + enums.Operation.REVOKE, + enums.Operation.DESTROY, + enums.Operation.ARCHIVE, + enums.Operation.RECOVER, + enums.Operation.QUERY, + enums.Operation.CANCEL, + enums.Operation.POLL, + enums.Operation.REKEY_KEY_PAIR, + enums.Operation.DISCOVER_VERSIONS + ], + object_types=[ + enums.ObjectType.CERTIFICATE, + enums.ObjectType.SYMMETRIC_KEY, + enums.ObjectType.PUBLIC_KEY, + enums.ObjectType.PRIVATE_KEY, + enums.ObjectType.TEMPLATE, + enums.ObjectType.SECRET_DATA + ], + vendor_identification=( + "IBM test server, not-TKLM 2.0.1.1 KMIP 2.0.0.1" + ), + server_information=misc.ServerInformation(), + application_namespaces=[ + "Namespace 1", + "Namespace 2" + ], + extension_information=[ + objects.ExtensionInformation( + extension_name=objects.ExtensionName("ACME LOCATION"), + extension_tag=objects.ExtensionTag(0x0054AA01), + extension_type=objects.ExtensionType(7) + ), + objects.ExtensionInformation( + extension_name=objects.ExtensionName("ACME ZIP CODE"), + extension_tag=objects.ExtensionTag(0x0054AA02), + extension_type=objects.ExtensionType(2) + ) + ], + attestation_types=[ + enums.AttestationType.TPM_QUOTE, + enums.AttestationType.TCG_INTEGRITY_REPORT, + enums.AttestationType.SAML_ASSERTION + ] + ) + + buffer = utils.BytearrayStream() + payload.write(buffer, kmip_version=enums.KMIPVersion.KMIP_1_2) + + self.assertEqual(len(self.full_encoding_kmip_1_2), len(buffer)) + self.assertEqual(str(self.full_encoding_kmip_1_2), str(buffer)) + + def test_write_kmip_1_3(self): + """ + Test that a QueryResponsePayload structure can be written to a data + stream with KMIP 1.3 features. + """ + payload = payloads.QueryResponsePayload( + operations=[ + enums.Operation.CREATE, + enums.Operation.CREATE_KEY_PAIR, + enums.Operation.REGISTER, + enums.Operation.REKEY, + enums.Operation.CERTIFY, + enums.Operation.RECERTIFY, + enums.Operation.LOCATE, + enums.Operation.CHECK, + enums.Operation.GET, + enums.Operation.GET_ATTRIBUTES, + enums.Operation.GET_ATTRIBUTE_LIST, + enums.Operation.ADD_ATTRIBUTE, + enums.Operation.MODIFY_ATTRIBUTE, + enums.Operation.DELETE_ATTRIBUTE, + enums.Operation.OBTAIN_LEASE, + enums.Operation.GET_USAGE_ALLOCATION, + enums.Operation.ACTIVATE, + enums.Operation.REVOKE, + enums.Operation.DESTROY, + enums.Operation.ARCHIVE, + enums.Operation.RECOVER, + enums.Operation.QUERY, + enums.Operation.CANCEL, + enums.Operation.POLL, + enums.Operation.REKEY_KEY_PAIR, + enums.Operation.DISCOVER_VERSIONS + ], + object_types=[ + enums.ObjectType.CERTIFICATE, + enums.ObjectType.SYMMETRIC_KEY, + enums.ObjectType.PUBLIC_KEY, + enums.ObjectType.PRIVATE_KEY, + enums.ObjectType.TEMPLATE, + enums.ObjectType.SECRET_DATA + ], + vendor_identification=( + "IBM test server, not-TKLM 2.0.1.1 KMIP 2.0.0.1" + ), + server_information=misc.ServerInformation(), + application_namespaces=[ + "Namespace 1", + "Namespace 2" + ], + extension_information=[ + objects.ExtensionInformation( + extension_name=objects.ExtensionName("ACME LOCATION"), + extension_tag=objects.ExtensionTag(0x0054AA01), + extension_type=objects.ExtensionType(7) + ), + objects.ExtensionInformation( + extension_name=objects.ExtensionName("ACME ZIP CODE"), + extension_tag=objects.ExtensionTag(0x0054AA02), + extension_type=objects.ExtensionType(2) + ) + ], + attestation_types=[ + enums.AttestationType.TPM_QUOTE, + enums.AttestationType.TCG_INTEGRITY_REPORT, + enums.AttestationType.SAML_ASSERTION + ], + rng_parameters=[ + objects.RNGParameters( + rng_algorithm=enums.RNGAlgorithm.FIPS186_2, + cryptographic_algorithm=enums.CryptographicAlgorithm.AES, + cryptographic_length=256, + hashing_algorithm=enums.HashingAlgorithm.SHA_256, + drbg_algorithm=enums.DRBGAlgorithm.HASH, + recommended_curve=enums.RecommendedCurve.P_192, + fips186_variation=enums.FIPS186Variation.GP_X_ORIGINAL, + prediction_resistance=True + ) + ], + profile_information=[ + objects.ProfileInformation( + profile_name=( + enums.ProfileName.BASELINE_SERVER_BASIC_KMIPv12 + ), + server_uri="https://example.com", + server_port=5696 + ) + ], + validation_information=[ + objects.ValidationInformation( + validation_authority_type=( + enums.ValidationAuthorityType.COMMON_CRITERIA + ), + validation_authority_country="US", + validation_authority_uri="https://example.com", + validation_version_major=1, + validation_version_minor=0, + validation_type=enums.ValidationType.HYBRID, + validation_level=5, + validation_certificate_identifier=( + "c005d39e-604f-11e9-99df-080027fc1396" + ), + validation_certificate_uri="https://test.com", + validation_vendor_uri="https://vendor.com", + validation_profiles=["Profile 1", "Profile 2"] + ) + ], + capability_information=[ + objects.CapabilityInformation( + streaming_capability=False, + asynchronous_capability=True, + attestation_capability=True, + unwrap_mode=enums.UnwrapMode.PROCESSED, + destroy_action=enums.DestroyAction.SHREDDED, + shredding_algorithm=enums.ShreddingAlgorithm.CRYPTOGRAPHIC, + rng_mode=enums.RNGMode.NON_SHARED_INSTANTIATION + ) + ], + client_registration_methods=[ + enums.ClientRegistrationMethod.CLIENT_GENERATED, + enums.ClientRegistrationMethod.CLIENT_REGISTERED + ] + ) + + buffer = utils.BytearrayStream() + payload.write(buffer, kmip_version=enums.KMIPVersion.KMIP_1_3) + + self.assertEqual(len(self.full_encoding_kmip_1_3), len(buffer)) + self.assertEqual(str(self.full_encoding_kmip_1_3), str(buffer)) + + def test_write_empty(self): + """ + Test that an empty QueryResponsePayload structure can be written to a + data stream. + """ + payload = payloads.QueryResponsePayload() + + buffer = utils.BytearrayStream() + payload.write(buffer) + + self.assertEqual(len(self.empty_encoding), len(buffer)) + self.assertEqual(str(self.empty_encoding), str(buffer)) + + def test_repr(self): + """ + Test that repr can be applied to a QueryResponsePayload structure. + """ + payload = payloads.QueryResponsePayload( + operations=[ + enums.Operation.CREATE, + enums.Operation.CREATE_KEY_PAIR, + enums.Operation.REGISTER, + enums.Operation.REKEY, + enums.Operation.CERTIFY, + enums.Operation.RECERTIFY, + enums.Operation.LOCATE, + enums.Operation.CHECK, + enums.Operation.GET, + enums.Operation.GET_ATTRIBUTES, + enums.Operation.GET_ATTRIBUTE_LIST, + enums.Operation.ADD_ATTRIBUTE, + enums.Operation.MODIFY_ATTRIBUTE, + enums.Operation.DELETE_ATTRIBUTE, + enums.Operation.OBTAIN_LEASE, + enums.Operation.GET_USAGE_ALLOCATION, + enums.Operation.ACTIVATE, + enums.Operation.REVOKE, + enums.Operation.DESTROY, + enums.Operation.ARCHIVE, + enums.Operation.RECOVER, + enums.Operation.QUERY, + enums.Operation.CANCEL, + enums.Operation.POLL, + enums.Operation.REKEY_KEY_PAIR, + enums.Operation.DISCOVER_VERSIONS + ], + object_types=[ + enums.ObjectType.CERTIFICATE, + enums.ObjectType.SYMMETRIC_KEY, + enums.ObjectType.PUBLIC_KEY, + enums.ObjectType.PRIVATE_KEY, + enums.ObjectType.TEMPLATE, + enums.ObjectType.SECRET_DATA + ], + vendor_identification=( + "IBM test server, not-TKLM 2.0.1.1 KMIP 2.0.0.1" + ), + server_information=misc.ServerInformation(), + application_namespaces=[ + "Namespace 1", + "Namespace 2" + ], + extension_information=[ + objects.ExtensionInformation( + extension_name=objects.ExtensionName("ACME LOCATION"), + extension_tag=objects.ExtensionTag(0x0054AA01), + extension_type=objects.ExtensionType(7) + ), + objects.ExtensionInformation( + extension_name=objects.ExtensionName("ACME ZIP CODE"), + extension_tag=objects.ExtensionTag(0x0054AA02), + extension_type=objects.ExtensionType(2) + ) + ], + attestation_types=[ + enums.AttestationType.TPM_QUOTE, + enums.AttestationType.TCG_INTEGRITY_REPORT, + enums.AttestationType.SAML_ASSERTION + ], + rng_parameters=[ + objects.RNGParameters( + rng_algorithm=enums.RNGAlgorithm.FIPS186_2, + cryptographic_algorithm=enums.CryptographicAlgorithm.AES, + cryptographic_length=256, + hashing_algorithm=enums.HashingAlgorithm.SHA_256, + drbg_algorithm=enums.DRBGAlgorithm.HASH, + recommended_curve=enums.RecommendedCurve.P_192, + fips186_variation=enums.FIPS186Variation.GP_X_ORIGINAL, + prediction_resistance=True + ) + ], + profile_information=[ + objects.ProfileInformation( + profile_name=( + enums.ProfileName.BASELINE_SERVER_BASIC_KMIPv12 + ), + server_uri="https://example.com", + server_port=5696 + ) + ], + validation_information=[ + objects.ValidationInformation( + validation_authority_type=( + enums.ValidationAuthorityType.COMMON_CRITERIA + ), + validation_authority_country="US", + validation_authority_uri="https://example.com", + validation_version_major=1, + validation_version_minor=0, + validation_type=enums.ValidationType.HYBRID, + validation_level=5, + validation_certificate_identifier=( + "c005d39e-604f-11e9-99df-080027fc1396" + ), + validation_certificate_uri="https://test.com", + validation_vendor_uri="https://vendor.com", + validation_profiles=["Profile 1", "Profile 2"] + ) + ], + capability_information=[ + objects.CapabilityInformation( + streaming_capability=False, + asynchronous_capability=True, + attestation_capability=True, + unwrap_mode=enums.UnwrapMode.PROCESSED, + destroy_action=enums.DestroyAction.SHREDDED, + shredding_algorithm=enums.ShreddingAlgorithm.CRYPTOGRAPHIC, + rng_mode=enums.RNGMode.NON_SHARED_INSTANTIATION + ) + ], + client_registration_methods=[ + enums.ClientRegistrationMethod.CLIENT_GENERATED, + enums.ClientRegistrationMethod.CLIENT_REGISTERED + ] + ) + + operations = [ + "Operation.CREATE", + "Operation.CREATE_KEY_PAIR", + "Operation.REGISTER", + "Operation.REKEY", + "Operation.CERTIFY", + "Operation.RECERTIFY", + "Operation.LOCATE", + "Operation.CHECK", + "Operation.GET", + "Operation.GET_ATTRIBUTES", + "Operation.GET_ATTRIBUTE_LIST", + "Operation.ADD_ATTRIBUTE", + "Operation.MODIFY_ATTRIBUTE", + "Operation.DELETE_ATTRIBUTE", + "Operation.OBTAIN_LEASE", + "Operation.GET_USAGE_ALLOCATION", + "Operation.ACTIVATE", + "Operation.REVOKE", + "Operation.DESTROY", + "Operation.ARCHIVE", + "Operation.RECOVER", + "Operation.QUERY", + "Operation.CANCEL", + "Operation.POLL", + "Operation.REKEY_KEY_PAIR", + "Operation.DISCOVER_VERSIONS" + ] + v = ", ".join(operations) + ops = "operations=[{}]".format(v) + + object_types = [ + "ObjectType.CERTIFICATE", + "ObjectType.SYMMETRIC_KEY", + "ObjectType.PUBLIC_KEY", + "ObjectType.PRIVATE_KEY", + "ObjectType.TEMPLATE", + "ObjectType.SECRET_DATA" + ] + v = ", ".join(object_types) + ot = "object_types=[{}]".format(v) + + vei = 'vendor_identification="{}"'.format( + "IBM test server, not-TKLM 2.0.1.1 KMIP 2.0.0.1" + ) + + sei = "server_information=ServerInformation()" + + an = 'application_namespaces=["{}", "{}"]'.format( + "Namespace 1", + "Namespace 2" + ) + + extensions = [ + objects.ExtensionInformation( + extension_name=objects.ExtensionName("ACME LOCATION"), + extension_tag=objects.ExtensionTag(0x0054AA01), + extension_type=objects.ExtensionType(7) + ), + objects.ExtensionInformation( + extension_name=objects.ExtensionName("ACME ZIP CODE"), + extension_tag=objects.ExtensionTag(0x0054AA02), + extension_type=objects.ExtensionType(2) + ) + ] + ei = "extension_information={}".format(repr(extensions)) + + values = [ + "AttestationType.TPM_QUOTE", + "AttestationType.TCG_INTEGRITY_REPORT", + "AttestationType.SAML_ASSERTION" + ] + v = ", ".join(values) + att = "attestation_types=[{}]".format(v) + + a = "rng_algorithm=RNGAlgorithm.FIPS186_2" + c = "cryptographic_algorithm=CryptographicAlgorithm.AES" + e = "cryptographic_length=256" + h = "hashing_algorithm=HashingAlgorithm.SHA_256" + d = "drbg_algorithm=DRBGAlgorithm.HASH" + r = "recommended_curve=RecommendedCurve.P_192" + f = "fips186_variation=FIPS186Variation.GP_X_ORIGINAL" + p = "prediction_resistance=True" + + v = ", ".join([a, c, e, h, d, r, f, p]) + rp = "rng_parameters=[RNGParameters({})]".format(v) + + n = "profile_name=ProfileName.BASELINE_SERVER_BASIC_KMIPv12" + u = 'server_uri="https://example.com"' + p = "server_port=5696" + + v = ", ".join([n, u, p]) + pi = "profile_information=[ProfileInformation({})]".format(v) + + vat = "validation_authority_type=" + \ + "ValidationAuthorityType.COMMON_CRITERIA" + vac = 'validation_authority_country="US"' + vau = 'validation_authority_uri="https://example.com"' + vvj = "validation_version_major=1" + vvn = "validation_version_minor=0" + vt = "validation_type=ValidationType.HYBRID" + vl = "validation_level=5" + vci = 'validation_certificate_identifier=' + \ + '"c005d39e-604f-11e9-99df-080027fc1396"' + vcu = 'validation_certificate_uri="https://test.com"' + vvu = 'validation_vendor_uri="https://vendor.com"' + vp = 'validation_profiles=["Profile 1", "Profile 2"]' + + v = ", ".join([vat, vac, vau, vvj, vvn, vt, vl, vci, vcu, vvu, vp]) + vi = "validation_information=[ValidationInformation({})]".format(v) + + sc = "streaming_capability=False" + rc = "asynchronous_capability=True" + tc = "attestation_capability=True" + buc = "batch_undo_capability=None" + bcc = "batch_continue_capability=None" + um = "unwrap_mode=UnwrapMode.PROCESSED" + da = "destroy_action=DestroyAction.SHREDDED" + sa = "shredding_algorithm=ShreddingAlgorithm.CRYPTOGRAPHIC" + rm = "rng_mode=RNGMode.NON_SHARED_INSTANTIATION" + + m1 = "ClientRegistrationMethod.CLIENT_GENERATED" + m2 = "ClientRegistrationMethod.CLIENT_REGISTERED" + v = ", ".join([m1, m2]) + crm = "client_registration_methods=[{}]".format(v) + + v = ", ".join([sc, rc, tc, buc, bcc, um, da, sa, rm]) + ci = "capability_information=[CapabilityInformation({})]".format(v) + + v = ", ".join([ops, ot, vei, sei, an, ei, att, rp, pi, vi, ci, crm]) + + self.assertEqual( + "QueryResponsePayload({})".format(v), + repr(payload) + ) + + def test_str(self): + """ + Test that str can be applied to a QueryResponsePayload structure. + """ + payload = payloads.QueryResponsePayload( + operations=[ + enums.Operation.CREATE, + enums.Operation.CREATE_KEY_PAIR, + enums.Operation.REGISTER, + enums.Operation.REKEY, + enums.Operation.CERTIFY, + enums.Operation.RECERTIFY, + enums.Operation.LOCATE, + enums.Operation.CHECK, + enums.Operation.GET, + enums.Operation.GET_ATTRIBUTES, + enums.Operation.GET_ATTRIBUTE_LIST, + enums.Operation.ADD_ATTRIBUTE, + enums.Operation.MODIFY_ATTRIBUTE, + enums.Operation.DELETE_ATTRIBUTE, + enums.Operation.OBTAIN_LEASE, + enums.Operation.GET_USAGE_ALLOCATION, + enums.Operation.ACTIVATE, + enums.Operation.REVOKE, + enums.Operation.DESTROY, + enums.Operation.ARCHIVE, + enums.Operation.RECOVER, + enums.Operation.QUERY, + enums.Operation.CANCEL, + enums.Operation.POLL, + enums.Operation.REKEY_KEY_PAIR, + enums.Operation.DISCOVER_VERSIONS + ], + object_types=[ + enums.ObjectType.CERTIFICATE, + enums.ObjectType.SYMMETRIC_KEY, + enums.ObjectType.PUBLIC_KEY, + enums.ObjectType.PRIVATE_KEY, + enums.ObjectType.TEMPLATE, + enums.ObjectType.SECRET_DATA + ], + vendor_identification=( + "IBM test server, not-TKLM 2.0.1.1 KMIP 2.0.0.1" + ), + server_information=misc.ServerInformation(), + application_namespaces=[ + "Namespace 1", + "Namespace 2" + ], + extension_information=[ + objects.ExtensionInformation( + extension_name=objects.ExtensionName("ACME LOCATION"), + extension_tag=objects.ExtensionTag(0x0054AA01), + extension_type=objects.ExtensionType(7) + ), + objects.ExtensionInformation( + extension_name=objects.ExtensionName("ACME ZIP CODE"), + extension_tag=objects.ExtensionTag(0x0054AA02), + extension_type=objects.ExtensionType(2) + ) + ], + attestation_types=[ + enums.AttestationType.TPM_QUOTE, + enums.AttestationType.TCG_INTEGRITY_REPORT, + enums.AttestationType.SAML_ASSERTION + ], + rng_parameters=[ + objects.RNGParameters( + rng_algorithm=enums.RNGAlgorithm.FIPS186_2, + cryptographic_algorithm=enums.CryptographicAlgorithm.AES, + cryptographic_length=256, + hashing_algorithm=enums.HashingAlgorithm.SHA_256, + drbg_algorithm=enums.DRBGAlgorithm.HASH, + recommended_curve=enums.RecommendedCurve.P_192, + fips186_variation=enums.FIPS186Variation.GP_X_ORIGINAL, + prediction_resistance=True + ) + ], + profile_information=[ + objects.ProfileInformation( + profile_name=( + enums.ProfileName.BASELINE_SERVER_BASIC_KMIPv12 + ), + server_uri="https://example.com", + server_port=5696 + ) + ], + validation_information=[ + objects.ValidationInformation( + validation_authority_type=( + enums.ValidationAuthorityType.COMMON_CRITERIA + ), + validation_authority_country="US", + validation_authority_uri="https://example.com", + validation_version_major=1, + validation_version_minor=0, + validation_type=enums.ValidationType.HYBRID, + validation_level=5, + validation_certificate_identifier=( + "c005d39e-604f-11e9-99df-080027fc1396" + ), + validation_certificate_uri="https://test.com", + validation_vendor_uri="https://vendor.com", + validation_profiles=["Profile 1", "Profile 2"] + ) + ], + capability_information=[ + objects.CapabilityInformation( + streaming_capability=False, + asynchronous_capability=True, + attestation_capability=True, + unwrap_mode=enums.UnwrapMode.PROCESSED, + destroy_action=enums.DestroyAction.SHREDDED, + shredding_algorithm=enums.ShreddingAlgorithm.CRYPTOGRAPHIC, + rng_mode=enums.RNGMode.NON_SHARED_INSTANTIATION + ) + ], + client_registration_methods=[ + enums.ClientRegistrationMethod.CLIENT_GENERATED, + enums.ClientRegistrationMethod.CLIENT_REGISTERED + ] + ) + + operations = [ + "Operation.CREATE", + "Operation.CREATE_KEY_PAIR", + "Operation.REGISTER", + "Operation.REKEY", + "Operation.CERTIFY", + "Operation.RECERTIFY", + "Operation.LOCATE", + "Operation.CHECK", + "Operation.GET", + "Operation.GET_ATTRIBUTES", + "Operation.GET_ATTRIBUTE_LIST", + "Operation.ADD_ATTRIBUTE", + "Operation.MODIFY_ATTRIBUTE", + "Operation.DELETE_ATTRIBUTE", + "Operation.OBTAIN_LEASE", + "Operation.GET_USAGE_ALLOCATION", + "Operation.ACTIVATE", + "Operation.REVOKE", + "Operation.DESTROY", + "Operation.ARCHIVE", + "Operation.RECOVER", + "Operation.QUERY", + "Operation.CANCEL", + "Operation.POLL", + "Operation.REKEY_KEY_PAIR", + "Operation.DISCOVER_VERSIONS" + ] + v = ", ".join(operations) + ops = '"operations": [{}]'.format(v) + + object_types = [ + "ObjectType.CERTIFICATE", + "ObjectType.SYMMETRIC_KEY", + "ObjectType.PUBLIC_KEY", + "ObjectType.PRIVATE_KEY", + "ObjectType.TEMPLATE", + "ObjectType.SECRET_DATA" + ] + v = ", ".join(object_types) + ot = '"object_types": [{}]'.format(v) + + vei = '"vendor_identification": "{}"'.format( + "IBM test server, not-TKLM 2.0.1.1 KMIP 2.0.0.1" + ) + + sei = '"server_information": ServerInformation()' + + an = '"application_namespaces": ["{}", "{}"]'.format( + "Namespace 1", + "Namespace 2" + ) + + extensions = [ + objects.ExtensionInformation( + extension_name=objects.ExtensionName("ACME LOCATION"), + extension_tag=objects.ExtensionTag(0x0054AA01), + extension_type=objects.ExtensionType(7) + ), + objects.ExtensionInformation( + extension_name=objects.ExtensionName("ACME ZIP CODE"), + extension_tag=objects.ExtensionTag(0x0054AA02), + extension_type=objects.ExtensionType(2) + ) + ] + ei = '"extension_information": {}'.format(repr(extensions)) + + values = [ + "AttestationType.TPM_QUOTE", + "AttestationType.TCG_INTEGRITY_REPORT", + "AttestationType.SAML_ASSERTION" + ] + v = ", ".join(values) + att = '"attestation_types": [{}]'.format(v) + + a = '"rng_algorithm": RNGAlgorithm.FIPS186_2' + c = '"cryptographic_algorithm": CryptographicAlgorithm.AES' + e = '"cryptographic_length": 256' + h = '"hashing_algorithm": HashingAlgorithm.SHA_256' + d = '"drbg_algorithm": DRBGAlgorithm.HASH' + r = '"recommended_curve": RecommendedCurve.P_192' + f = '"fips186_variation": FIPS186Variation.GP_X_ORIGINAL' + p = '"prediction_resistance": True' + + v = ", ".join([a, c, e, h, d, r, f, p]) + v = "{" + v + "}" + rp = '"rng_parameters": [{}]'.format(v) + + n = '"profile_name": ProfileName.BASELINE_SERVER_BASIC_KMIPv12' + u = '"server_uri": "https://example.com"' + p = '"server_port": 5696' + + v = ", ".join([n, u, p]) + v = "{" + v + "}" + pi = '"profile_information": [{}]'.format(v) + + vat = '"validation_authority_type": ' + \ + 'ValidationAuthorityType.COMMON_CRITERIA' + vac = '"validation_authority_country": "US"' + vau = '"validation_authority_uri": "https://example.com"' + vvj = '"validation_version_major": 1' + vvn = '"validation_version_minor": 0' + vt = '"validation_type": ValidationType.HYBRID' + vl = '"validation_level": 5' + vci = '"validation_certificate_identifier": ' + \ + '"c005d39e-604f-11e9-99df-080027fc1396"' + vcu = '"validation_certificate_uri": "https://test.com"' + vvu = '"validation_vendor_uri": "https://vendor.com"' + vp = '"validation_profiles": ["Profile 1", "Profile 2"]' + + v = ", ".join([vat, vac, vau, vvj, vvn, vt, vl, vci, vcu, vvu, vp]) + v = "{" + v + "}" + vi = '"validation_information": [{}]'.format(v) + + sc = '"streaming_capability": False' + rc = '"asynchronous_capability": True' + tc = '"attestation_capability": True' + buc = '"batch_undo_capability": None' + bcc = '"batch_continue_capability": None' + um = '"unwrap_mode": UnwrapMode.PROCESSED' + da = '"destroy_action": DestroyAction.SHREDDED' + sa = '"shredding_algorithm": ShreddingAlgorithm.CRYPTOGRAPHIC' + rm = '"rng_mode": RNGMode.NON_SHARED_INSTANTIATION' + + v = ", ".join([sc, rc, tc, buc, bcc, um, da, sa, rm]) + v = "{" + v + "}" + ci = '"capability_information": [{}]'.format(v) + + m1 = "ClientRegistrationMethod.CLIENT_GENERATED" + m2 = "ClientRegistrationMethod.CLIENT_REGISTERED" + v = ", ".join([m1, m2]) + crm = '"client_registration_methods": [{}]'.format(v) + + v = ", ".join([ops, ot, vei, sei, an, ei, att, rp, pi, vi, ci, crm]) + + self.assertEqual("{" + v + "}", str(payload)) + + def test_equal_on_equal(self): + """ + Test that the equality operator returns True when comparing two + QueryResponsePayload structures with the same data. + """ + a = payloads.QueryResponsePayload() + b = payloads.QueryResponsePayload() + + self.assertTrue(a == b) + self.assertTrue(b == a) + + a = payloads.QueryResponsePayload( + operations=[ + enums.Operation.CREATE, + enums.Operation.CREATE_KEY_PAIR, + enums.Operation.REGISTER, + enums.Operation.REKEY, + enums.Operation.CERTIFY, + enums.Operation.RECERTIFY, + enums.Operation.LOCATE, + enums.Operation.CHECK, + enums.Operation.GET, + enums.Operation.GET_ATTRIBUTES, + enums.Operation.GET_ATTRIBUTE_LIST, + enums.Operation.ADD_ATTRIBUTE, + enums.Operation.MODIFY_ATTRIBUTE, + enums.Operation.DELETE_ATTRIBUTE, + enums.Operation.OBTAIN_LEASE, + enums.Operation.GET_USAGE_ALLOCATION, + enums.Operation.ACTIVATE, + enums.Operation.REVOKE, + enums.Operation.DESTROY, + enums.Operation.ARCHIVE, + enums.Operation.RECOVER, + enums.Operation.QUERY, + enums.Operation.CANCEL, + enums.Operation.POLL, + enums.Operation.REKEY_KEY_PAIR, + enums.Operation.DISCOVER_VERSIONS + ], + object_types=[ + enums.ObjectType.CERTIFICATE, + enums.ObjectType.SYMMETRIC_KEY, + enums.ObjectType.PUBLIC_KEY, + enums.ObjectType.PRIVATE_KEY, + enums.ObjectType.TEMPLATE, + enums.ObjectType.SECRET_DATA + ], + vendor_identification=( + "IBM test server, not-TKLM 2.0.1.1 KMIP 2.0.0.1" + ), + server_information=misc.ServerInformation(), + application_namespaces=[ + "Namespace 1", + "Namespace 2" + ], + extension_information=[ + objects.ExtensionInformation( + extension_name=objects.ExtensionName("ACME LOCATION"), + extension_tag=objects.ExtensionTag(0x0054AA01), + extension_type=objects.ExtensionType(7) + ), + objects.ExtensionInformation( + extension_name=objects.ExtensionName("ACME ZIP CODE"), + extension_tag=objects.ExtensionTag(0x0054AA02), + extension_type=objects.ExtensionType(2) + ) + ], + attestation_types=[ + enums.AttestationType.TPM_QUOTE, + enums.AttestationType.TCG_INTEGRITY_REPORT, + enums.AttestationType.SAML_ASSERTION + ], + rng_parameters=[ + objects.RNGParameters( + rng_algorithm=enums.RNGAlgorithm.FIPS186_2, + cryptographic_algorithm=enums.CryptographicAlgorithm.AES, + cryptographic_length=256, + hashing_algorithm=enums.HashingAlgorithm.SHA_256, + drbg_algorithm=enums.DRBGAlgorithm.HASH, + recommended_curve=enums.RecommendedCurve.P_192, + fips186_variation=enums.FIPS186Variation.GP_X_ORIGINAL, + prediction_resistance=True + ) + ], + profile_information=[ + objects.ProfileInformation( + profile_name=( + enums.ProfileName.BASELINE_SERVER_BASIC_KMIPv12 + ), + server_uri="https://example.com", + server_port=5696 + ) + ], + validation_information=[ + objects.ValidationInformation( + validation_authority_type=( + enums.ValidationAuthorityType.COMMON_CRITERIA + ), + validation_authority_country="US", + validation_authority_uri="https://example.com", + validation_version_major=1, + validation_version_minor=0, + validation_type=enums.ValidationType.HYBRID, + validation_level=5, + validation_certificate_identifier=( + "c005d39e-604f-11e9-99df-080027fc1396" + ), + validation_certificate_uri="https://test.com", + validation_vendor_uri="https://vendor.com", + validation_profiles=["Profile 1", "Profile 2"] + ) + ], + capability_information=[ + objects.CapabilityInformation( + streaming_capability=False, + asynchronous_capability=True, + attestation_capability=True, + unwrap_mode=enums.UnwrapMode.PROCESSED, + destroy_action=enums.DestroyAction.SHREDDED, + shredding_algorithm=enums.ShreddingAlgorithm.CRYPTOGRAPHIC, + rng_mode=enums.RNGMode.NON_SHARED_INSTANTIATION + ) + ], + client_registration_methods=[ + enums.ClientRegistrationMethod.CLIENT_GENERATED, + enums.ClientRegistrationMethod.CLIENT_REGISTERED + ] + ) + b = payloads.QueryResponsePayload( + operations=[ + enums.Operation.CREATE, + enums.Operation.CREATE_KEY_PAIR, + enums.Operation.REGISTER, + enums.Operation.REKEY, + enums.Operation.CERTIFY, + enums.Operation.RECERTIFY, + enums.Operation.LOCATE, + enums.Operation.CHECK, + enums.Operation.GET, + enums.Operation.GET_ATTRIBUTES, + enums.Operation.GET_ATTRIBUTE_LIST, + enums.Operation.ADD_ATTRIBUTE, + enums.Operation.MODIFY_ATTRIBUTE, + enums.Operation.DELETE_ATTRIBUTE, + enums.Operation.OBTAIN_LEASE, + enums.Operation.GET_USAGE_ALLOCATION, + enums.Operation.ACTIVATE, + enums.Operation.REVOKE, + enums.Operation.DESTROY, + enums.Operation.ARCHIVE, + enums.Operation.RECOVER, + enums.Operation.QUERY, + enums.Operation.CANCEL, + enums.Operation.POLL, + enums.Operation.REKEY_KEY_PAIR, + enums.Operation.DISCOVER_VERSIONS + ], + object_types=[ + enums.ObjectType.CERTIFICATE, + enums.ObjectType.SYMMETRIC_KEY, + enums.ObjectType.PUBLIC_KEY, + enums.ObjectType.PRIVATE_KEY, + enums.ObjectType.TEMPLATE, + enums.ObjectType.SECRET_DATA + ], + vendor_identification=( + "IBM test server, not-TKLM 2.0.1.1 KMIP 2.0.0.1" + ), + server_information=misc.ServerInformation(), + application_namespaces=[ + "Namespace 1", + "Namespace 2" + ], + extension_information=[ + objects.ExtensionInformation( + extension_name=objects.ExtensionName("ACME LOCATION"), + extension_tag=objects.ExtensionTag(0x0054AA01), + extension_type=objects.ExtensionType(7) + ), + objects.ExtensionInformation( + extension_name=objects.ExtensionName("ACME ZIP CODE"), + extension_tag=objects.ExtensionTag(0x0054AA02), + extension_type=objects.ExtensionType(2) + ) + ], + attestation_types=[ + enums.AttestationType.TPM_QUOTE, + enums.AttestationType.TCG_INTEGRITY_REPORT, + enums.AttestationType.SAML_ASSERTION + ], + rng_parameters=[ + objects.RNGParameters( + rng_algorithm=enums.RNGAlgorithm.FIPS186_2, + cryptographic_algorithm=enums.CryptographicAlgorithm.AES, + cryptographic_length=256, + hashing_algorithm=enums.HashingAlgorithm.SHA_256, + drbg_algorithm=enums.DRBGAlgorithm.HASH, + recommended_curve=enums.RecommendedCurve.P_192, + fips186_variation=enums.FIPS186Variation.GP_X_ORIGINAL, + prediction_resistance=True + ) + ], + profile_information=[ + objects.ProfileInformation( + profile_name=( + enums.ProfileName.BASELINE_SERVER_BASIC_KMIPv12 + ), + server_uri="https://example.com", + server_port=5696 + ) + ], + validation_information=[ + objects.ValidationInformation( + validation_authority_type=( + enums.ValidationAuthorityType.COMMON_CRITERIA + ), + validation_authority_country="US", + validation_authority_uri="https://example.com", + validation_version_major=1, + validation_version_minor=0, + validation_type=enums.ValidationType.HYBRID, + validation_level=5, + validation_certificate_identifier=( + "c005d39e-604f-11e9-99df-080027fc1396" + ), + validation_certificate_uri="https://test.com", + validation_vendor_uri="https://vendor.com", + validation_profiles=["Profile 1", "Profile 2"] + ) + ], + capability_information=[ + objects.CapabilityInformation( + streaming_capability=False, + asynchronous_capability=True, + attestation_capability=True, + unwrap_mode=enums.UnwrapMode.PROCESSED, + destroy_action=enums.DestroyAction.SHREDDED, + shredding_algorithm=enums.ShreddingAlgorithm.CRYPTOGRAPHIC, + rng_mode=enums.RNGMode.NON_SHARED_INSTANTIATION + ) + ], + client_registration_methods=[ + enums.ClientRegistrationMethod.CLIENT_GENERATED, + enums.ClientRegistrationMethod.CLIENT_REGISTERED + ] + ) + + self.assertTrue(a == b) + self.assertTrue(b == a) + + def test_equal_on_not_equal_operations(self): + """ + Test that the equality operator returns False when comparing two + QueryResponsePayload structures with different operations fields. + """ + a = payloads.QueryResponsePayload( + operations=[ + enums.Operation.CREATE, + enums.Operation.CREATE_KEY_PAIR, + enums.Operation.REGISTER, + enums.Operation.REKEY, + enums.Operation.CERTIFY, + enums.Operation.RECERTIFY, + enums.Operation.LOCATE, + enums.Operation.CHECK, + enums.Operation.GET, + enums.Operation.GET_ATTRIBUTES, + enums.Operation.GET_ATTRIBUTE_LIST, + enums.Operation.ADD_ATTRIBUTE, + enums.Operation.MODIFY_ATTRIBUTE, + enums.Operation.DELETE_ATTRIBUTE, + enums.Operation.OBTAIN_LEASE, + enums.Operation.GET_USAGE_ALLOCATION, + enums.Operation.ACTIVATE, + enums.Operation.REVOKE, + enums.Operation.DESTROY, + enums.Operation.ARCHIVE, + enums.Operation.RECOVER, + enums.Operation.QUERY, + enums.Operation.CANCEL, + enums.Operation.POLL, + enums.Operation.REKEY_KEY_PAIR, + enums.Operation.DISCOVER_VERSIONS + ] + ) + b = payloads.QueryResponsePayload( + operations=[ + enums.Operation.CREATE, + enums.Operation.CREATE_KEY_PAIR, + enums.Operation.REGISTER, + enums.Operation.REKEY, + enums.Operation.CERTIFY, + enums.Operation.RECERTIFY, + enums.Operation.LOCATE, + enums.Operation.CHECK, + enums.Operation.GET, + enums.Operation.GET_ATTRIBUTES, + enums.Operation.GET_ATTRIBUTE_LIST, + enums.Operation.ADD_ATTRIBUTE + ] + ) + + self.assertFalse(a == b) + self.assertFalse(b == a) + + def test_equal_on_not_equal_object_types(self): + """ + Test that the equality operator returns False when comparing two + QueryResponsePayload structures with different object types fields. + """ + a = payloads.QueryResponsePayload( + object_types=[ + enums.ObjectType.CERTIFICATE, + enums.ObjectType.SYMMETRIC_KEY, + enums.ObjectType.PUBLIC_KEY, + enums.ObjectType.PRIVATE_KEY, + enums.ObjectType.TEMPLATE, + enums.ObjectType.SECRET_DATA + ] + ) + b = payloads.QueryResponsePayload( + object_types=[ + enums.ObjectType.PRIVATE_KEY, + enums.ObjectType.TEMPLATE, + enums.ObjectType.SECRET_DATA + ] + ) + + self.assertFalse(a == b) + self.assertFalse(b == a) + + def test_equal_on_not_equal_vendor_identification(self): + """ + Test that the equality operator returns False when comparing two + QueryResponsePayload structures with different vendor identification + fields. + """ + a = payloads.QueryResponsePayload( + vendor_identification="IBM test server, KMIP 2.0.0.1" + ) + b = payloads.QueryResponsePayload( + vendor_identification="IBM test server, KMIP 1.0.9.1" + ) + + self.assertFalse(a == b) + self.assertFalse(b == a) + + def test_equal_on_not_equal_server_information(self): + """ + Test that the equality operator returns False when comparing two + QueryResponsePayload structures with different server information + fields. + """ + a = payloads.QueryResponsePayload( + server_information=misc.ServerInformation() + ) + b = payloads.QueryResponsePayload( + server_information=None + ) + + self.assertFalse(a == b) + self.assertFalse(b == a) + + def test_equal_on_not_equal_application_namespaces(self): + """ + Test that the equality operator returns False when comparing two + QueryResponsePayload structures with different application namespaces + fields. + """ + a = payloads.QueryResponsePayload( + application_namespaces=[ + "Namespace 1", + "Namespace 2" + ] + ) + b = payloads.QueryResponsePayload( + application_namespaces=["Namespace 3"] + ) + + self.assertFalse(a == b) + self.assertFalse(b == a) + + def test_equal_on_not_equal_extension_information(self): + """ + Test that the equality operator returns False when comparing two + QueryResponsePayload structures with different extension information + fields. + """ + a = payloads.QueryResponsePayload( + extension_information=[ + objects.ExtensionInformation( + extension_name=objects.ExtensionName("ACME LOCATION"), + extension_tag=objects.ExtensionTag(0x0054AA01), + extension_type=objects.ExtensionType(7) + ) + ] + ) + b = payloads.QueryResponsePayload( + extension_information=[ + objects.ExtensionInformation( + extension_name=objects.ExtensionName("ACME ZIP CODE"), + extension_tag=objects.ExtensionTag(0x0054AA02), + extension_type=objects.ExtensionType(2) + ) + ] + ) + + self.assertFalse(a == b) + self.assertFalse(b == a) + + def test_equal_on_not_equal_attestation_types(self): + """ + Test that the equality operator returns False when comparing two + QueryResponsePayload structures with different attestation types + fields. + """ + a = payloads.QueryResponsePayload( + attestation_types=[ + enums.AttestationType.TPM_QUOTE, + enums.AttestationType.TCG_INTEGRITY_REPORT, + enums.AttestationType.SAML_ASSERTION + ] + ) + b = payloads.QueryResponsePayload( + attestation_types=[ + enums.AttestationType.TPM_QUOTE + ] + ) + + self.assertFalse(a == b) + self.assertFalse(b == a) + + def test_equal_on_not_equal_rng_parameters(self): + """ + Test that the equality operator returns False when comparing two + QueryResponsePayload structures with different RNG parameters + fields. + """ + a = payloads.QueryResponsePayload( + rng_parameters=[ + objects.RNGParameters( + rng_algorithm=enums.RNGAlgorithm.FIPS186_2, + cryptographic_algorithm=enums.CryptographicAlgorithm.AES, + cryptographic_length=256, + hashing_algorithm=enums.HashingAlgorithm.SHA_256, + drbg_algorithm=enums.DRBGAlgorithm.HASH, + recommended_curve=enums.RecommendedCurve.P_192, + fips186_variation=enums.FIPS186Variation.GP_X_ORIGINAL, + prediction_resistance=True + ) + ] + ) + b = payloads.QueryResponsePayload( + rng_parameters=[ + objects.RNGParameters( + rng_algorithm=enums.RNGAlgorithm.FIPS186_2, + cryptographic_algorithm=enums.CryptographicAlgorithm.AES, + cryptographic_length=128, + hashing_algorithm=enums.HashingAlgorithm.SHA_256, + drbg_algorithm=enums.DRBGAlgorithm.HASH, + recommended_curve=enums.RecommendedCurve.P_192, + fips186_variation=enums.FIPS186Variation.GP_X_ORIGINAL, + prediction_resistance=False + ) + ] + ) + + self.assertFalse(a == b) + self.assertFalse(b == a) + + def test_equal_on_not_equal_profile_information(self): + """ + Test that the equality operator returns False when comparing two + QueryResponsePayload structures with different profile information + fields. + """ + a = payloads.QueryResponsePayload( + profile_information=[ + objects.ProfileInformation( + profile_name=( + enums.ProfileName.BASELINE_SERVER_BASIC_KMIPv12 + ), + server_uri="https://example.com", + server_port=5696 + ) + ] + ) + b = payloads.QueryResponsePayload( + profile_information=[ + objects.ProfileInformation( + profile_name=( + enums.ProfileName.TAPE_LIBRARY_SERVER_KMIPv12 + ), + server_uri="https://test.com", + server_port=5696 + ) + ] + ) + + self.assertFalse(a == b) + self.assertFalse(b == a) + + def test_equal_on_not_equal_validation_information(self): + """ + Test that the equality operator returns False when comparing two + QueryResponsePayload structures with different validation information + fields. + """ + a = payloads.QueryResponsePayload( + validation_information=[ + objects.ValidationInformation( + validation_authority_type=( + enums.ValidationAuthorityType.COMMON_CRITERIA + ), + validation_authority_country="US", + validation_authority_uri="https://example.com", + validation_version_major=1, + validation_version_minor=0, + validation_type=enums.ValidationType.HYBRID, + validation_level=5, + validation_certificate_identifier=( + "c005d39e-604f-11e9-99df-080027fc1396" + ), + validation_certificate_uri="https://test.com", + validation_vendor_uri="https://vendor.com", + validation_profiles=["Profile 1", "Profile 2"] + ) + ] + ) + b = payloads.QueryResponsePayload( + validation_information=[ + objects.ValidationInformation( + validation_authority_type=( + enums.ValidationAuthorityType.COMMON_CRITERIA + ), + validation_authority_country="US", + validation_authority_uri="https://authority.com", + validation_version_major=1, + validation_version_minor=1, + validation_type=enums.ValidationType.HYBRID, + validation_level=5, + validation_certificate_identifier=( + "c005d39e-604f-11e9-99df-080027fc1396" + ), + validation_certificate_uri="https://certificate.com", + validation_vendor_uri="https://example.com", + validation_profiles=["Profile 3", "Profile 4"] + ) + ] + ) + + self.assertFalse(a == b) + self.assertFalse(b == a) + + def test_equal_on_not_equal_capability_information(self): + """ + Test that the equality operator returns False when comparing two + QueryResponsePayload structures with different capability information + fields. + """ + a = payloads.QueryResponsePayload( + capability_information=[ + objects.CapabilityInformation( + streaming_capability=False, + asynchronous_capability=True, + attestation_capability=True, + unwrap_mode=enums.UnwrapMode.PROCESSED, + destroy_action=enums.DestroyAction.SHREDDED, + shredding_algorithm=enums.ShreddingAlgorithm.CRYPTOGRAPHIC, + rng_mode=enums.RNGMode.NON_SHARED_INSTANTIATION + ) + ] + ) + b = payloads.QueryResponsePayload( + capability_information=[ + objects.CapabilityInformation( + streaming_capability=True, + asynchronous_capability=False, + attestation_capability=False, + unwrap_mode=enums.UnwrapMode.PROCESSED, + destroy_action=enums.DestroyAction.SHREDDED, + shredding_algorithm=enums.ShreddingAlgorithm.CRYPTOGRAPHIC, + rng_mode=enums.RNGMode.NON_SHARED_INSTANTIATION + ) + ] + ) + + self.assertFalse(a == b) + self.assertFalse(b == a) + + def test_equal_on_not_equal_client_registration_methods(self): + """ + Test that the equality operator returns False when comparing two + QueryResponsePayload structures with different client registration + methods fields. + """ + a = payloads.QueryResponsePayload( + client_registration_methods=[ + enums.ClientRegistrationMethod.CLIENT_GENERATED, + enums.ClientRegistrationMethod.CLIENT_REGISTERED + ] + ) + b = payloads.QueryResponsePayload( + client_registration_methods=[ + enums.ClientRegistrationMethod.CLIENT_GENERATED + ] + ) + + self.assertFalse(a == b) + self.assertFalse(b == a) + + def test_equal_on_type_mismatch(self): + """ + Test that the equality operator returns False when comparing two + QueryResponsePayload structures with different types. + """ + a = payloads.QueryResponsePayload() + 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 + QueryResponsePayload structures with the same data. + """ + a = payloads.QueryResponsePayload() + b = payloads.QueryResponsePayload() + + self.assertFalse(a != b) + self.assertFalse(b != a) + + a = payloads.QueryResponsePayload( + operations=[ + enums.Operation.CREATE, + enums.Operation.CREATE_KEY_PAIR, + enums.Operation.REGISTER, + enums.Operation.REKEY, + enums.Operation.CERTIFY, + enums.Operation.RECERTIFY, + enums.Operation.LOCATE, + enums.Operation.CHECK, + enums.Operation.GET, + enums.Operation.GET_ATTRIBUTES, + enums.Operation.GET_ATTRIBUTE_LIST, + enums.Operation.ADD_ATTRIBUTE, + enums.Operation.MODIFY_ATTRIBUTE, + enums.Operation.DELETE_ATTRIBUTE, + enums.Operation.OBTAIN_LEASE, + enums.Operation.GET_USAGE_ALLOCATION, + enums.Operation.ACTIVATE, + enums.Operation.REVOKE, + enums.Operation.DESTROY, + enums.Operation.ARCHIVE, + enums.Operation.RECOVER, + enums.Operation.QUERY, + enums.Operation.CANCEL, + enums.Operation.POLL, + enums.Operation.REKEY_KEY_PAIR, + enums.Operation.DISCOVER_VERSIONS + ], + object_types=[ + enums.ObjectType.CERTIFICATE, + enums.ObjectType.SYMMETRIC_KEY, + enums.ObjectType.PUBLIC_KEY, + enums.ObjectType.PRIVATE_KEY, + enums.ObjectType.TEMPLATE, + enums.ObjectType.SECRET_DATA + ], + vendor_identification=( + "IBM test server, not-TKLM 2.0.1.1 KMIP 2.0.0.1" + ), + server_information=misc.ServerInformation(), + application_namespaces=[ + "Namespace 1", + "Namespace 2" + ], + extension_information=[ + objects.ExtensionInformation( + extension_name=objects.ExtensionName("ACME LOCATION"), + extension_tag=objects.ExtensionTag(0x0054AA01), + extension_type=objects.ExtensionType(7) + ), + objects.ExtensionInformation( + extension_name=objects.ExtensionName("ACME ZIP CODE"), + extension_tag=objects.ExtensionTag(0x0054AA02), + extension_type=objects.ExtensionType(2) + ) + ], + attestation_types=[ + enums.AttestationType.TPM_QUOTE, + enums.AttestationType.TCG_INTEGRITY_REPORT, + enums.AttestationType.SAML_ASSERTION + ], + rng_parameters=[ + objects.RNGParameters( + rng_algorithm=enums.RNGAlgorithm.FIPS186_2, + cryptographic_algorithm=enums.CryptographicAlgorithm.AES, + cryptographic_length=256, + hashing_algorithm=enums.HashingAlgorithm.SHA_256, + drbg_algorithm=enums.DRBGAlgorithm.HASH, + recommended_curve=enums.RecommendedCurve.P_192, + fips186_variation=enums.FIPS186Variation.GP_X_ORIGINAL, + prediction_resistance=True + ) + ], + profile_information=[ + objects.ProfileInformation( + profile_name=( + enums.ProfileName.BASELINE_SERVER_BASIC_KMIPv12 + ), + server_uri="https://example.com", + server_port=5696 + ) + ], + validation_information=[ + objects.ValidationInformation( + validation_authority_type=( + enums.ValidationAuthorityType.COMMON_CRITERIA + ), + validation_authority_country="US", + validation_authority_uri="https://example.com", + validation_version_major=1, + validation_version_minor=0, + validation_type=enums.ValidationType.HYBRID, + validation_level=5, + validation_certificate_identifier=( + "c005d39e-604f-11e9-99df-080027fc1396" + ), + validation_certificate_uri="https://test.com", + validation_vendor_uri="https://vendor.com", + validation_profiles=["Profile 1", "Profile 2"] + ) + ], + capability_information=[ + objects.CapabilityInformation( + streaming_capability=False, + asynchronous_capability=True, + attestation_capability=True, + unwrap_mode=enums.UnwrapMode.PROCESSED, + destroy_action=enums.DestroyAction.SHREDDED, + shredding_algorithm=enums.ShreddingAlgorithm.CRYPTOGRAPHIC, + rng_mode=enums.RNGMode.NON_SHARED_INSTANTIATION + ) + ], + client_registration_methods=[ + enums.ClientRegistrationMethod.CLIENT_GENERATED, + enums.ClientRegistrationMethod.CLIENT_REGISTERED + ] + ) + b = payloads.QueryResponsePayload( + operations=[ + enums.Operation.CREATE, + enums.Operation.CREATE_KEY_PAIR, + enums.Operation.REGISTER, + enums.Operation.REKEY, + enums.Operation.CERTIFY, + enums.Operation.RECERTIFY, + enums.Operation.LOCATE, + enums.Operation.CHECK, + enums.Operation.GET, + enums.Operation.GET_ATTRIBUTES, + enums.Operation.GET_ATTRIBUTE_LIST, + enums.Operation.ADD_ATTRIBUTE, + enums.Operation.MODIFY_ATTRIBUTE, + enums.Operation.DELETE_ATTRIBUTE, + enums.Operation.OBTAIN_LEASE, + enums.Operation.GET_USAGE_ALLOCATION, + enums.Operation.ACTIVATE, + enums.Operation.REVOKE, + enums.Operation.DESTROY, + enums.Operation.ARCHIVE, + enums.Operation.RECOVER, + enums.Operation.QUERY, + enums.Operation.CANCEL, + enums.Operation.POLL, + enums.Operation.REKEY_KEY_PAIR, + enums.Operation.DISCOVER_VERSIONS + ], + object_types=[ + enums.ObjectType.CERTIFICATE, + enums.ObjectType.SYMMETRIC_KEY, + enums.ObjectType.PUBLIC_KEY, + enums.ObjectType.PRIVATE_KEY, + enums.ObjectType.TEMPLATE, + enums.ObjectType.SECRET_DATA + ], + vendor_identification=( + "IBM test server, not-TKLM 2.0.1.1 KMIP 2.0.0.1" + ), + server_information=misc.ServerInformation(), + application_namespaces=[ + "Namespace 1", + "Namespace 2" + ], + extension_information=[ + objects.ExtensionInformation( + extension_name=objects.ExtensionName("ACME LOCATION"), + extension_tag=objects.ExtensionTag(0x0054AA01), + extension_type=objects.ExtensionType(7) + ), + objects.ExtensionInformation( + extension_name=objects.ExtensionName("ACME ZIP CODE"), + extension_tag=objects.ExtensionTag(0x0054AA02), + extension_type=objects.ExtensionType(2) + ) + ], + attestation_types=[ + enums.AttestationType.TPM_QUOTE, + enums.AttestationType.TCG_INTEGRITY_REPORT, + enums.AttestationType.SAML_ASSERTION + ], + rng_parameters=[ + objects.RNGParameters( + rng_algorithm=enums.RNGAlgorithm.FIPS186_2, + cryptographic_algorithm=enums.CryptographicAlgorithm.AES, + cryptographic_length=256, + hashing_algorithm=enums.HashingAlgorithm.SHA_256, + drbg_algorithm=enums.DRBGAlgorithm.HASH, + recommended_curve=enums.RecommendedCurve.P_192, + fips186_variation=enums.FIPS186Variation.GP_X_ORIGINAL, + prediction_resistance=True + ) + ], + profile_information=[ + objects.ProfileInformation( + profile_name=( + enums.ProfileName.BASELINE_SERVER_BASIC_KMIPv12 + ), + server_uri="https://example.com", + server_port=5696 + ) + ], + validation_information=[ + objects.ValidationInformation( + validation_authority_type=( + enums.ValidationAuthorityType.COMMON_CRITERIA + ), + validation_authority_country="US", + validation_authority_uri="https://example.com", + validation_version_major=1, + validation_version_minor=0, + validation_type=enums.ValidationType.HYBRID, + validation_level=5, + validation_certificate_identifier=( + "c005d39e-604f-11e9-99df-080027fc1396" + ), + validation_certificate_uri="https://test.com", + validation_vendor_uri="https://vendor.com", + validation_profiles=["Profile 1", "Profile 2"] + ) + ], + capability_information=[ + objects.CapabilityInformation( + streaming_capability=False, + asynchronous_capability=True, + attestation_capability=True, + unwrap_mode=enums.UnwrapMode.PROCESSED, + destroy_action=enums.DestroyAction.SHREDDED, + shredding_algorithm=enums.ShreddingAlgorithm.CRYPTOGRAPHIC, + rng_mode=enums.RNGMode.NON_SHARED_INSTANTIATION + ) + ], + client_registration_methods=[ + enums.ClientRegistrationMethod.CLIENT_GENERATED, + enums.ClientRegistrationMethod.CLIENT_REGISTERED + ] + ) + + self.assertFalse(a != b) + self.assertFalse(b != a) + + def test_not_equal_on_not_equal_operations(self): + """ + Test that the inequality operator returns True when comparing two + QueryResponsePayload structures with different operations fields. + """ + a = payloads.QueryResponsePayload( + operations=[ + enums.Operation.CREATE, + enums.Operation.CREATE_KEY_PAIR, + enums.Operation.REGISTER, + enums.Operation.REKEY, + enums.Operation.CERTIFY, + enums.Operation.RECERTIFY, + enums.Operation.LOCATE, + enums.Operation.CHECK, + enums.Operation.GET, + enums.Operation.GET_ATTRIBUTES, + enums.Operation.GET_ATTRIBUTE_LIST, + enums.Operation.ADD_ATTRIBUTE, + enums.Operation.MODIFY_ATTRIBUTE, + enums.Operation.DELETE_ATTRIBUTE, + enums.Operation.OBTAIN_LEASE, + enums.Operation.GET_USAGE_ALLOCATION, + enums.Operation.ACTIVATE, + enums.Operation.REVOKE, + enums.Operation.DESTROY, + enums.Operation.ARCHIVE, + enums.Operation.RECOVER, + enums.Operation.QUERY, + enums.Operation.CANCEL, + enums.Operation.POLL, + enums.Operation.REKEY_KEY_PAIR, + enums.Operation.DISCOVER_VERSIONS + ] + ) + b = payloads.QueryResponsePayload( + operations=[ + enums.Operation.CREATE, + enums.Operation.CREATE_KEY_PAIR, + enums.Operation.REGISTER, + enums.Operation.REKEY, + enums.Operation.CERTIFY, + enums.Operation.RECERTIFY, + enums.Operation.LOCATE, + enums.Operation.CHECK, + enums.Operation.GET, + enums.Operation.GET_ATTRIBUTES, + enums.Operation.GET_ATTRIBUTE_LIST, + enums.Operation.ADD_ATTRIBUTE + ] + ) + + self.assertTrue(a != b) + self.assertTrue(b != a) + + def test_not_equal_on_not_equal_object_types(self): + """ + Test that the inequality operator returns True when comparing two + QueryResponsePayload structures with different object types fields. + """ + a = payloads.QueryResponsePayload( + object_types=[ + enums.ObjectType.CERTIFICATE, + enums.ObjectType.SYMMETRIC_KEY, + enums.ObjectType.PUBLIC_KEY, + enums.ObjectType.PRIVATE_KEY, + enums.ObjectType.TEMPLATE, + enums.ObjectType.SECRET_DATA + ] + ) + b = payloads.QueryResponsePayload( + object_types=[ + enums.ObjectType.PRIVATE_KEY, + enums.ObjectType.TEMPLATE, + enums.ObjectType.SECRET_DATA + ] + ) + + self.assertTrue(a != b) + self.assertTrue(b != a) + + def test_not_equal_on_not_equal_vendor_identification(self): + """ + Test that the inequality operator returns True when comparing two + QueryResponsePayload structures with different vendor identification + fields. + """ + a = payloads.QueryResponsePayload( + vendor_identification="IBM test server, KMIP 2.0.0.1" + ) + b = payloads.QueryResponsePayload( + vendor_identification="IBM test server, KMIP 1.0.9.1" + ) + + self.assertTrue(a != b) + self.assertTrue(b != a) + + def test_not_equal_on_not_equal_server_information(self): + """ + Test that the inequality operator returns True when comparing two + QueryResponsePayload structures with different server information + fields. + """ + a = payloads.QueryResponsePayload( + server_information=misc.ServerInformation() + ) + b = payloads.QueryResponsePayload( + server_information=None + ) + + self.assertTrue(a != b) + self.assertTrue(b != a) + + def test_not_equal_on_not_equal_application_namespaces(self): + """ + Test that the inequality operator returns True when comparing two + QueryResponsePayload structures with different application namespaces + fields. + """ + a = payloads.QueryResponsePayload( + application_namespaces=[ + "Namespace 1", + "Namespace 2" + ] + ) + b = payloads.QueryResponsePayload( + application_namespaces=["Namespace 3"] + ) + + self.assertTrue(a != b) + self.assertTrue(b != a) + + def test_not_equal_on_not_equal_extension_information(self): + """ + Test that the inequality operator returns True when comparing two + QueryResponsePayload structures with different extension information + fields. + """ + a = payloads.QueryResponsePayload( + extension_information=[ + objects.ExtensionInformation( + extension_name=objects.ExtensionName("ACME LOCATION"), + extension_tag=objects.ExtensionTag(0x0054AA01), + extension_type=objects.ExtensionType(7) + ) + ] + ) + b = payloads.QueryResponsePayload( + extension_information=[ + objects.ExtensionInformation( + extension_name=objects.ExtensionName("ACME ZIP CODE"), + extension_tag=objects.ExtensionTag(0x0054AA02), + extension_type=objects.ExtensionType(2) + ) + ] + ) + + self.assertTrue(a != b) + self.assertTrue(b != a) + + def test_not_equal_on_not_equal_attestation_types(self): + """ + Test that the inequality operator returns True when comparing two + QueryResponsePayload structures with different attestation types + fields. + """ + a = payloads.QueryResponsePayload( + attestation_types=[ + enums.AttestationType.TPM_QUOTE, + enums.AttestationType.TCG_INTEGRITY_REPORT, + enums.AttestationType.SAML_ASSERTION + ] + ) + b = payloads.QueryResponsePayload( + attestation_types=[ + enums.AttestationType.TPM_QUOTE + ] + ) + + self.assertTrue(a != b) + self.assertTrue(b != a) + + def test_not_equal_on_not_equal_rng_parameters(self): + """ + Test that the inequality operator returns True when comparing two + QueryResponsePayload structures with different RNG parameters + fields. + """ + a = payloads.QueryResponsePayload( + rng_parameters=[ + objects.RNGParameters( + rng_algorithm=enums.RNGAlgorithm.FIPS186_2, + cryptographic_algorithm=enums.CryptographicAlgorithm.AES, + cryptographic_length=256, + hashing_algorithm=enums.HashingAlgorithm.SHA_256, + drbg_algorithm=enums.DRBGAlgorithm.HASH, + recommended_curve=enums.RecommendedCurve.P_192, + fips186_variation=enums.FIPS186Variation.GP_X_ORIGINAL, + prediction_resistance=True + ) + ] + ) + b = payloads.QueryResponsePayload( + rng_parameters=[ + objects.RNGParameters( + rng_algorithm=enums.RNGAlgorithm.FIPS186_2, + cryptographic_algorithm=enums.CryptographicAlgorithm.AES, + cryptographic_length=128, + hashing_algorithm=enums.HashingAlgorithm.SHA_256, + drbg_algorithm=enums.DRBGAlgorithm.HASH, + recommended_curve=enums.RecommendedCurve.P_192, + fips186_variation=enums.FIPS186Variation.GP_X_ORIGINAL, + prediction_resistance=False + ) + ] + ) + + self.assertTrue(a != b) + self.assertTrue(b != a) + + def test_not_equal_on_not_equal_profile_information(self): + """ + Test that the inequality operator returns True when comparing two + QueryResponsePayload structures with different profile information + fields. + """ + a = payloads.QueryResponsePayload( + profile_information=[ + objects.ProfileInformation( + profile_name=( + enums.ProfileName.BASELINE_SERVER_BASIC_KMIPv12 + ), + server_uri="https://example.com", + server_port=5696 + ) + ] + ) + b = payloads.QueryResponsePayload( + profile_information=[ + objects.ProfileInformation( + profile_name=( + enums.ProfileName.TAPE_LIBRARY_SERVER_KMIPv12 + ), + server_uri="https://test.com", + server_port=5696 + ) + ] + ) + + self.assertTrue(a != b) + self.assertTrue(b != a) + + def test_not_equal_on_not_equal_validation_information(self): + """ + Test that the inequality operator returns True when comparing two + QueryResponsePayload structures with different validation information + fields. + """ + a = payloads.QueryResponsePayload( + validation_information=[ + objects.ValidationInformation( + validation_authority_type=( + enums.ValidationAuthorityType.COMMON_CRITERIA + ), + validation_authority_country="US", + validation_authority_uri="https://example.com", + validation_version_major=1, + validation_version_minor=0, + validation_type=enums.ValidationType.HYBRID, + validation_level=5, + validation_certificate_identifier=( + "c005d39e-604f-11e9-99df-080027fc1396" + ), + validation_certificate_uri="https://test.com", + validation_vendor_uri="https://vendor.com", + validation_profiles=["Profile 1", "Profile 2"] + ) + ] + ) + b = payloads.QueryResponsePayload( + validation_information=[ + objects.ValidationInformation( + validation_authority_type=( + enums.ValidationAuthorityType.COMMON_CRITERIA + ), + validation_authority_country="US", + validation_authority_uri="https://authority.com", + validation_version_major=1, + validation_version_minor=1, + validation_type=enums.ValidationType.HYBRID, + validation_level=5, + validation_certificate_identifier=( + "c005d39e-604f-11e9-99df-080027fc1396" + ), + validation_certificate_uri="https://certificate.com", + validation_vendor_uri="https://example.com", + validation_profiles=["Profile 3", "Profile 4"] + ) + ] + ) + + self.assertTrue(a != b) + self.assertTrue(b != a) + + def test_not_equal_on_not_equal_capability_information(self): + """ + Test that the inequality operator returns True when comparing two + QueryResponsePayload structures with different capability information + fields. + """ + a = payloads.QueryResponsePayload( + capability_information=[ + objects.CapabilityInformation( + streaming_capability=False, + asynchronous_capability=True, + attestation_capability=True, + unwrap_mode=enums.UnwrapMode.PROCESSED, + destroy_action=enums.DestroyAction.SHREDDED, + shredding_algorithm=enums.ShreddingAlgorithm.CRYPTOGRAPHIC, + rng_mode=enums.RNGMode.NON_SHARED_INSTANTIATION + ) + ] + ) + b = payloads.QueryResponsePayload( + capability_information=[ + objects.CapabilityInformation( + streaming_capability=True, + asynchronous_capability=False, + attestation_capability=False, + unwrap_mode=enums.UnwrapMode.PROCESSED, + destroy_action=enums.DestroyAction.SHREDDED, + shredding_algorithm=enums.ShreddingAlgorithm.CRYPTOGRAPHIC, + rng_mode=enums.RNGMode.NON_SHARED_INSTANTIATION + ) + ] + ) + + self.assertTrue(a != b) + self.assertTrue(b != a) + + def test_not_equal_on_not_equal_client_registration_methods(self): + """ + Test that the inequality operator returns True when comparing two + QueryResponsePayload structures with different client registration + methods fields. + """ + a = payloads.QueryResponsePayload( + client_registration_methods=[ + enums.ClientRegistrationMethod.CLIENT_GENERATED, + enums.ClientRegistrationMethod.CLIENT_REGISTERED + ] + ) + b = payloads.QueryResponsePayload( + client_registration_methods=[ + enums.ClientRegistrationMethod.CLIENT_GENERATED + ] + ) + + 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 two + QueryResponsePayload structures with different types. + """ + a = payloads.QueryResponsePayload() + b = "invalid" + + self.assertTrue(a != b) + self.assertTrue(b != a) diff --git a/kmip/tests/unit/services/server/test_engine.py b/kmip/tests/unit/services/server/test_engine.py index 5e452b3..a9a3ec8 100644 --- a/kmip/tests/unit/services/server/test_engine.py +++ b/kmip/tests/unit/services/server/test_engine.py @@ -6421,82 +6421,80 @@ class TestKmipEngine(testtools.TestCase): e._logger = mock.MagicMock() e._protocol_version = contents.ProtocolVersion(1, 0) - payload = payloads.QueryRequestPayload([ - misc.QueryFunction(enums.QueryFunction.QUERY_OPERATIONS), - misc.QueryFunction(enums.QueryFunction.QUERY_OBJECTS), - misc.QueryFunction( - enums.QueryFunction.QUERY_SERVER_INFORMATION - ), - misc.QueryFunction( - enums.QueryFunction.QUERY_APPLICATION_NAMESPACES - ), - misc.QueryFunction(enums.QueryFunction.QUERY_EXTENSION_LIST), - misc.QueryFunction(enums.QueryFunction.QUERY_EXTENSION_MAP) - ]) + payload = payloads.QueryRequestPayload( + query_functions=[ + enums.QueryFunction.QUERY_OPERATIONS, + enums.QueryFunction.QUERY_OBJECTS, + enums.QueryFunction.QUERY_SERVER_INFORMATION, + enums.QueryFunction.QUERY_APPLICATION_NAMESPACES, + enums.QueryFunction.QUERY_EXTENSION_LIST, + enums.QueryFunction.QUERY_EXTENSION_MAP + ] + ) result = e._process_query(payload) e._logger.info.assert_called_once_with("Processing operation: Query") self.assertIsInstance(result, payloads.QueryResponsePayload) - self.assertIsNotNone(result.operations) + self.assertIsInstance(result.operations, list) self.assertEqual(12, len(result.operations)) self.assertEqual( enums.Operation.CREATE, - result.operations[0].value + result.operations[0] ) self.assertEqual( enums.Operation.CREATE_KEY_PAIR, - result.operations[1].value + result.operations[1] ) self.assertEqual( enums.Operation.REGISTER, - result.operations[2].value + result.operations[2] ) self.assertEqual( enums.Operation.DERIVE_KEY, - result.operations[3].value + result.operations[3] ) self.assertEqual( enums.Operation.LOCATE, - result.operations[4].value + result.operations[4] ) self.assertEqual( enums.Operation.GET, - result.operations[5].value + result.operations[5] ) self.assertEqual( enums.Operation.GET_ATTRIBUTES, - result.operations[6].value + result.operations[6] ) self.assertEqual( enums.Operation.GET_ATTRIBUTE_LIST, - result.operations[7].value + result.operations[7] ) self.assertEqual( enums.Operation.ACTIVATE, - result.operations[8].value + result.operations[8] ) self.assertEqual( enums.Operation.REVOKE, - result.operations[9].value + result.operations[9] ) self.assertEqual( enums.Operation.DESTROY, - result.operations[10].value + result.operations[10] ) self.assertEqual( enums.Operation.QUERY, - result.operations[11].value + result.operations[11] ) - self.assertEqual(list(), result.object_types) + self.assertIsNone(result.object_types) self.assertIsNotNone(result.vendor_identification) self.assertEqual( "PyKMIP {0} Software Server".format(kmip.__version__), - result.vendor_identification.value + result.vendor_identification ) self.assertIsNone(result.server_information) - self.assertEqual(list(), result.application_namespaces) - self.assertEqual(list(), result.extension_information) + self.assertIsNone(result.application_namespaces) + self.assertIsNone(result.extension_information) def test_query_1_1(self): """ @@ -6507,86 +6505,84 @@ class TestKmipEngine(testtools.TestCase): e._logger = mock.MagicMock() e._protocol_version = contents.ProtocolVersion(1, 1) - payload = payloads.QueryRequestPayload([ - misc.QueryFunction(enums.QueryFunction.QUERY_OPERATIONS), - misc.QueryFunction(enums.QueryFunction.QUERY_OBJECTS), - misc.QueryFunction( - enums.QueryFunction.QUERY_SERVER_INFORMATION - ), - misc.QueryFunction( - enums.QueryFunction.QUERY_APPLICATION_NAMESPACES - ), - misc.QueryFunction(enums.QueryFunction.QUERY_EXTENSION_LIST), - misc.QueryFunction(enums.QueryFunction.QUERY_EXTENSION_MAP) - ]) + payload = payloads.QueryRequestPayload( + query_functions=[ + enums.QueryFunction.QUERY_OPERATIONS, + enums.QueryFunction.QUERY_OBJECTS, + enums.QueryFunction.QUERY_SERVER_INFORMATION, + enums.QueryFunction.QUERY_APPLICATION_NAMESPACES, + enums.QueryFunction.QUERY_EXTENSION_LIST, + enums.QueryFunction.QUERY_EXTENSION_MAP + ] + ) result = e._process_query(payload) e._logger.info.assert_called_once_with("Processing operation: Query") self.assertIsInstance(result, payloads.QueryResponsePayload) - self.assertIsNotNone(result.operations) + self.assertIsInstance(result.operations, list) self.assertEqual(13, len(result.operations)) self.assertEqual( enums.Operation.CREATE, - result.operations[0].value + result.operations[0] ) self.assertEqual( enums.Operation.CREATE_KEY_PAIR, - result.operations[1].value + result.operations[1] ) self.assertEqual( enums.Operation.REGISTER, - result.operations[2].value + result.operations[2] ) self.assertEqual( enums.Operation.DERIVE_KEY, - result.operations[3].value + result.operations[3] ) self.assertEqual( enums.Operation.LOCATE, - result.operations[4].value + result.operations[4] ) self.assertEqual( enums.Operation.GET, - result.operations[5].value + result.operations[5] ) self.assertEqual( enums.Operation.GET_ATTRIBUTES, - result.operations[6].value + result.operations[6] ) self.assertEqual( enums.Operation.GET_ATTRIBUTE_LIST, - result.operations[7].value + result.operations[7] ) self.assertEqual( enums.Operation.ACTIVATE, - result.operations[8].value + result.operations[8] ) self.assertEqual( enums.Operation.REVOKE, - result.operations[9].value + result.operations[9] ) self.assertEqual( enums.Operation.DESTROY, - result.operations[10].value + result.operations[10] ) self.assertEqual( enums.Operation.QUERY, - result.operations[11].value + result.operations[11] ) self.assertEqual( enums.Operation.DISCOVER_VERSIONS, - result.operations[12].value + result.operations[12] ) - self.assertEqual(list(), result.object_types) + self.assertIsNone(result.object_types) self.assertIsNotNone(result.vendor_identification) self.assertEqual( "PyKMIP {0} Software Server".format(kmip.__version__), - result.vendor_identification.value + result.vendor_identification ) self.assertIsNone(result.server_information) - self.assertEqual(list(), result.application_namespaces) - self.assertEqual(list(), result.extension_information) + self.assertIsNone(result.application_namespaces) + self.assertIsNone(result.extension_information) def test_query_1_2(self): """ @@ -6597,106 +6593,104 @@ class TestKmipEngine(testtools.TestCase): e._logger = mock.MagicMock() e._protocol_version = contents.ProtocolVersion(1, 2) - payload = payloads.QueryRequestPayload([ - misc.QueryFunction(enums.QueryFunction.QUERY_OPERATIONS), - misc.QueryFunction(enums.QueryFunction.QUERY_OBJECTS), - misc.QueryFunction( - enums.QueryFunction.QUERY_SERVER_INFORMATION - ), - misc.QueryFunction( - enums.QueryFunction.QUERY_APPLICATION_NAMESPACES - ), - misc.QueryFunction(enums.QueryFunction.QUERY_EXTENSION_LIST), - misc.QueryFunction(enums.QueryFunction.QUERY_EXTENSION_MAP) - ]) + payload = payloads.QueryRequestPayload( + query_functions=[ + enums.QueryFunction.QUERY_OPERATIONS, + enums.QueryFunction.QUERY_OBJECTS, + enums.QueryFunction.QUERY_SERVER_INFORMATION, + enums.QueryFunction.QUERY_APPLICATION_NAMESPACES, + enums.QueryFunction.QUERY_EXTENSION_LIST, + enums.QueryFunction.QUERY_EXTENSION_MAP + ] + ) result = e._process_query(payload) e._logger.info.assert_called_once_with("Processing operation: Query") self.assertIsInstance(result, payloads.QueryResponsePayload) - self.assertIsNotNone(result.operations) + self.assertIsInstance(result.operations, list) self.assertEqual(18, len(result.operations)) self.assertEqual( enums.Operation.CREATE, - result.operations[0].value + result.operations[0] ) self.assertEqual( enums.Operation.CREATE_KEY_PAIR, - result.operations[1].value + result.operations[1] ) self.assertEqual( enums.Operation.REGISTER, - result.operations[2].value + result.operations[2] ) self.assertEqual( enums.Operation.DERIVE_KEY, - result.operations[3].value + result.operations[3] ) self.assertEqual( enums.Operation.LOCATE, - result.operations[4].value + result.operations[4] ) self.assertEqual( enums.Operation.GET, - result.operations[5].value + result.operations[5] ) self.assertEqual( enums.Operation.GET_ATTRIBUTES, - result.operations[6].value + result.operations[6] ) self.assertEqual( enums.Operation.GET_ATTRIBUTE_LIST, - result.operations[7].value + result.operations[7] ) self.assertEqual( enums.Operation.ACTIVATE, - result.operations[8].value + result.operations[8] ) self.assertEqual( enums.Operation.REVOKE, - result.operations[9].value + result.operations[9] ) self.assertEqual( enums.Operation.DESTROY, - result.operations[10].value + result.operations[10] ) self.assertEqual( enums.Operation.QUERY, - result.operations[11].value + result.operations[11] ) self.assertEqual( enums.Operation.DISCOVER_VERSIONS, - result.operations[12].value + result.operations[12] ) self.assertEqual( enums.Operation.ENCRYPT, - result.operations[13].value + result.operations[13] ) self.assertEqual( enums.Operation.DECRYPT, - result.operations[14].value + result.operations[14] ) self.assertEqual( enums.Operation.SIGN, - result.operations[15].value + result.operations[15] ) self.assertEqual( enums.Operation.SIGNATURE_VERIFY, - result.operations[16].value + result.operations[16] ) self.assertEqual( enums.Operation.MAC, - result.operations[17].value + result.operations[17] ) - self.assertEqual(list(), result.object_types) + self.assertIsNone(result.object_types) self.assertIsNotNone(result.vendor_identification) self.assertEqual( "PyKMIP {0} Software Server".format(kmip.__version__), - result.vendor_identification.value + result.vendor_identification ) self.assertIsNone(result.server_information) - self.assertEqual(list(), result.application_namespaces) - self.assertEqual(list(), result.extension_information) + self.assertIsNone(result.application_namespaces) + self.assertIsNone(result.extension_information) def test_discover_versions(self): """ diff --git a/kmip/tests/unit/services/test_kmip_client.py b/kmip/tests/unit/services/test_kmip_client.py index 5a4a562..172dc49 100644 --- a/kmip/tests/unit/services/test_kmip_client.py +++ b/kmip/tests/unit/services/test_kmip_client.py @@ -45,9 +45,7 @@ from kmip.core.messages.contents import ProtocolVersion from kmip.core.messages import payloads from kmip.core.misc import Offset -from kmip.core.misc import QueryFunction from kmip.core.misc import ServerInformation -from kmip.core.misc import VendorIdentification from kmip.core import objects from kmip.core.objects import TemplateAttribute @@ -375,9 +373,6 @@ class TestKMIPClient(TestCase): payload = batch_item.request_payload - if query_functions is None: - query_functions = list() - msg = base.format(payloads.QueryRequestPayload, payload) self.assertIsInstance(payload, payloads.QueryRequestPayload, msg) @@ -386,7 +381,8 @@ class TestKMIPClient(TestCase): def test_build_query_batch_item_with_input(self): self._test_build_query_batch_item( - [QueryFunction(QueryFunctionEnum.QUERY_OBJECTS)]) + [QueryFunctionEnum.QUERY_OBJECTS] + ) def test_build_query_batch_item_without_input(self): self._test_build_query_batch_item(None) @@ -630,7 +626,7 @@ class TestKMIPClient(TestCase): self._test_process_query_batch_item( list(), list(), - VendorIdentification(), + "", ServerInformation(), list(), list())