def test_not_equal_on_equal(self): """ Test that the inequality operator returns False when comparing two Rekey request payloads with the same data. """ a = payloads.RekeyRequestPayload() b = payloads.RekeyRequestPayload() self.assertFalse(a != b) self.assertFalse(b != a) a = payloads.RekeyRequestPayload( unique_identifier='1346d253-69d6-474c-8cd5-ad475a3e0a81', offset=0, template_attribute=objects.TemplateAttribute(attributes=[ objects.Attribute( attribute_name=objects.Attribute.AttributeName( 'Activation Date'), attribute_value=primitives.DateTime( value=1136113200, tag=enums.Tags.ACTIVATION_DATE)) ])) b = payloads.RekeyRequestPayload( unique_identifier='1346d253-69d6-474c-8cd5-ad475a3e0a81', offset=0, template_attribute=objects.TemplateAttribute(attributes=[ objects.Attribute( attribute_name=objects.Attribute.AttributeName( 'Activation Date'), attribute_value=primitives.DateTime( value=1136113200, tag=enums.Tags.ACTIVATION_DATE)) ])) self.assertFalse(a != b) self.assertFalse(b != a)
def test_not_equal_on_not_equal_template_attribute(self): """ Test that the inequality operator returns True when comparing two Rekey response payloads with different template attributes. """ a = payloads.RekeyResponsePayload( template_attribute=objects.TemplateAttribute(attributes=[ objects.Attribute(attribute_name=objects.Attribute. AttributeName('Cryptographic Algorithm'), attribute_value=primitives.Enumeration( enums.CryptographicAlgorithm, value=enums.CryptographicAlgorithm.AES, tag=enums.Tags.CRYPTOGRAPHIC_ALGORITHM)) ])) b = payloads.RekeyResponsePayload( template_attribute=objects.TemplateAttribute(attributes=[ objects.Attribute( attribute_name=objects.Attribute.AttributeName( 'Cryptographic Length'), attribute_value=primitives.Integer( value=128, tag=enums.Tags.CRYPTOGRAPHIC_LENGTH)) ])) self.assertTrue(a != b) self.assertTrue(b != a)
def test_init_with_args(self): """ Test that a Rekey response payload can be constructed with valid values. """ payload = payloads.RekeyResponsePayload( unique_identifier='00000000-2222-4444-6666-888888888888', template_attribute=objects.TemplateAttribute()) self.assertEqual('00000000-2222-4444-6666-888888888888', payload.unique_identifier) self.assertEqual(objects.TemplateAttribute(), payload.template_attribute)
def test_read(self): """ Test that a Rekey response payload can be read from a data stream. """ payload = payloads.RekeyResponsePayload() self.assertEqual(None, payload.unique_identifier) self.assertEqual(None, payload.template_attribute) payload.read(self.full_encoding) self.assertEqual('8efbbd67-2847-46b5-b7e7-4ab3b5e175de', payload.unique_identifier) self.assertEqual( objects.TemplateAttribute(attributes=[ objects.Attribute(attribute_name=objects.Attribute. AttributeName('Cryptographic Algorithm'), attribute_value=primitives.Enumeration( enums.CryptographicAlgorithm, value=enums.CryptographicAlgorithm.AES, tag=enums.Tags.CRYPTOGRAPHIC_ALGORITHM)), objects.Attribute( attribute_name=objects.Attribute.AttributeName( 'Cryptographic Length'), attribute_value=primitives.Integer( value=128, tag=enums.Tags.CRYPTOGRAPHIC_LENGTH)) ]), payload.template_attribute)
def test_write(self): """ Test that a Rekey response payload can be written to a data stream. """ payload = payloads.RekeyResponsePayload( unique_identifier='8efbbd67-2847-46b5-b7e7-4ab3b5e175de', template_attribute=objects.TemplateAttribute( attributes=[ objects.Attribute( attribute_name=objects.Attribute.AttributeName( 'Cryptographic Algorithm' ), attribute_value=primitives.Enumeration( enums.CryptographicAlgorithm, value=enums.CryptographicAlgorithm.AES, tag=enums.Tags.CRYPTOGRAPHIC_ALGORITHM ) ), objects.Attribute( attribute_name=objects.Attribute.AttributeName( 'Cryptographic Length' ), attribute_value=primitives.Integer( value=128, tag=enums.Tags.CRYPTOGRAPHIC_LENGTH ) ) ] ) ) stream = utils.BytearrayStream() payload.write(stream) self.assertEqual(len(self.full_encoding), len(stream)) self.assertEqual(str(self.full_encoding), str(stream))
def test_write(self): """ Test that a Rekey request payload can be written to a data stream. """ payload = payloads.RekeyRequestPayload( unique_identifier='1346d253-69d6-474c-8cd5-ad475a3e0a81', offset=0, template_attribute=objects.TemplateAttribute(attributes=[ objects.Attribute( attribute_name=objects.Attribute.AttributeName( 'Activation Date'), attribute_value=primitives.DateTime( value=1136113200, tag=enums.Tags.ACTIVATION_DATE)), objects.Attribute( attribute_name=objects.Attribute.AttributeName( 'Process Start Date'), attribute_value=primitives.DateTime( value=1136113200, tag=enums.Tags.PROCESS_START_DATE)), objects.Attribute( attribute_name=objects.Attribute.AttributeName( 'Protect Stop Date'), attribute_value=primitives.DateTime( value=1577876400, tag=enums.Tags.PROTECT_STOP_DATE)), objects.Attribute( attribute_name=objects.Attribute.AttributeName( 'Deactivation Date'), attribute_value=primitives.DateTime( value=1577876400, tag=enums.Tags.DEACTIVATION_DATE)) ])) stream = utils.BytearrayStream() payload.write(stream) self.assertEqual(len(self.full_encoding), len(stream)) self.assertEqual(str(self.full_encoding), str(stream))
def read(self, input_stream): """ Read the data encoding the Rekey request payload and decode it into its constituent parts. Args: input_stream (stream): A data stream containing encoded object data, supporting a read method; usually a BytearrayStream object. """ super(RekeyRequestPayload, self).read(input_stream) local_stream = utils.BytearrayStream(input_stream.read(self.length)) if self.is_tag_next(enums.Tags.UNIQUE_IDENTIFIER, local_stream): self._unique_identifier = primitives.TextString( tag=enums.Tags.UNIQUE_IDENTIFIER) self._unique_identifier.read(local_stream) if self.is_tag_next(enums.Tags.OFFSET, local_stream): self._offset = primitives.Interval(tag=enums.Tags.OFFSET) self._offset.read(local_stream) if self.is_tag_next(enums.Tags.TEMPLATE_ATTRIBUTE, local_stream): self._template_attribute = objects.TemplateAttribute() self._template_attribute.read(local_stream) self.is_oversized(local_stream)
def test_create(self): """ Test that a symmetric key can be created with proper inputs and that its UID is returned properly. """ # Create the template to test the create call algorithm = enums.CryptographicAlgorithm.AES length = 256 algorithm_attribute = self.attribute_factory.create_attribute( enums.AttributeType.CRYPTOGRAPHIC_ALGORITHM, algorithm) length_attribute = self.attribute_factory.create_attribute( enums.AttributeType.CRYPTOGRAPHIC_LENGTH, length) mask_attribute = self.attribute_factory.create_attribute( enums.AttributeType.CRYPTOGRAPHIC_USAGE_MASK, [ enums.CryptographicUsageMask.ENCRYPT, enums.CryptographicUsageMask.DECRYPT ]) attributes = [algorithm_attribute, length_attribute, mask_attribute] template = obj.TemplateAttribute(attributes=attributes) key_id = 'aaaaaaaa-1111-2222-3333-ffffffffffff' status = enums.ResultStatus.SUCCESS result = results.CreateResult(contents.ResultStatus(status), uuid=attr.UniqueIdentifier(key_id)) with ProxyKmipClient() as client: client.proxy.create.return_value = result uid = client.create(algorithm, length) client.proxy.create.assert_called_with( enums.ObjectType.SYMMETRIC_KEY, template) self.assertIsInstance(uid, six.string_types) self.assertEqual(uid, key_id)
def read(self, input_stream): """ Read the data encoding the DeriveKey response payload and decode it into its constituent parts. Args: input_stream (stream): A data stream containing encoded object data, supporting a read method; usually a BytearrayStream object. Raises: ValueError: Raised if the data attribute is missing from the encoded payload. """ super(DeriveKeyResponsePayload, self).read(input_stream) local_stream = utils.BytearrayStream(input_stream.read(self.length)) if self.is_tag_next(enums.Tags.UNIQUE_IDENTIFIER, local_stream): self._unique_identifier = primitives.TextString( tag=enums.Tags.UNIQUE_IDENTIFIER) self._unique_identifier.read(local_stream) else: raise ValueError("invalid payload missing unique identifier") if self.is_tag_next(enums.Tags.TEMPLATE_ATTRIBUTE, local_stream): self._template_attribute = objects.TemplateAttribute() self._template_attribute.read(local_stream) self.is_oversized(local_stream)
def test_str(self): """ Test that str can be applied to a Rekey request payload """ payload = payloads.RekeyRequestPayload( unique_identifier='49a1ca88-6bea-4fb2-b450-7e58802c3038', offset=0, template_attribute=objects.TemplateAttribute( attributes=[ objects.Attribute( attribute_name=objects.Attribute.AttributeName( 'Deactivation Date' ), attribute_value=primitives.DateTime( value=1577876400, tag=enums.Tags.DEACTIVATION_DATE ) ) ] ) ) # TODO (peter-hamilton) Update this when TemplateAttributes have str expected = str({ 'unique_identifier': '49a1ca88-6bea-4fb2-b450-7e58802c3038', 'offset': 0, 'template_attribute': 'Struct()' }) observed = str(payload) self.assertEqual(expected, observed)
def test_read(self): """ Test that a Rekey request payload can be read from a data stream. """ payload = payloads.RekeyRequestPayload() self.assertEqual(None, payload.unique_identifier) self.assertEqual(None, payload.offset) self.assertEqual(None, payload.template_attribute) payload.read(self.full_encoding) self.assertEqual( '1346d253-69d6-474c-8cd5-ad475a3e0a81', payload.unique_identifier ) self.assertEqual(0, payload.offset) self.assertEqual( objects.TemplateAttribute( attributes=[ objects.Attribute( attribute_name=objects.Attribute.AttributeName( 'Activation Date' ), attribute_value=primitives.DateTime( value=1136113200, tag=enums.Tags.ACTIVATION_DATE ) ), objects.Attribute( attribute_name=objects.Attribute.AttributeName( 'Process Start Date' ), attribute_value=primitives.DateTime( value=1136113200, tag=enums.Tags.PROCESS_START_DATE ) ), objects.Attribute( attribute_name=objects.Attribute.AttributeName( 'Protect Stop Date' ), attribute_value=primitives.DateTime( value=1577876400, tag=enums.Tags.PROTECT_STOP_DATE ) ), objects.Attribute( attribute_name=objects.Attribute.AttributeName( 'Deactivation Date' ), attribute_value=primitives.DateTime( value=1577876400, tag=enums.Tags.DEACTIVATION_DATE ) ) ] ), payload.template_attribute )
def test_str(self): """ Test that str can be applied to a Rekey response payload """ payload = payloads.RekeyResponsePayload( unique_identifier='49a1ca88-6bea-4fb2-b450-7e58802c3038', template_attribute=objects.TemplateAttribute( attributes=[ objects.Attribute( attribute_name=objects.Attribute.AttributeName( 'Cryptographic Length' ), attribute_value=primitives.Integer( value=128, tag=enums.Tags.CRYPTOGRAPHIC_LENGTH ) ) ] ) ) # TODO (peter-hamilton) Update this when TemplateAttributes have str expected = str({ 'unique_identifier': '49a1ca88-6bea-4fb2-b450-7e58802c3038', 'template_attribute': 'Struct()' }) observed = str(payload) self.assertEqual(expected, observed)
def read(self, input_stream, kmip_version=enums.KMIPVersion.KMIP_1_0): """ Read the data encoding the Rekey request payload and decode it into its constituent parts. Args: input_stream (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(RekeyRequestPayload, self).read(input_stream, kmip_version=kmip_version) local_stream = utils.BytearrayStream(input_stream.read(self.length)) if self.is_tag_next(enums.Tags.UNIQUE_IDENTIFIER, local_stream): self._unique_identifier = primitives.TextString( tag=enums.Tags.UNIQUE_IDENTIFIER) self._unique_identifier.read(local_stream, kmip_version=kmip_version) if self.is_tag_next(enums.Tags.OFFSET, local_stream): self._offset = primitives.Interval(tag=enums.Tags.OFFSET) self._offset.read(local_stream, kmip_version=kmip_version) if self.is_tag_next(enums.Tags.TEMPLATE_ATTRIBUTE, local_stream): self._template_attribute = objects.TemplateAttribute() self._template_attribute.read(local_stream, kmip_version=kmip_version) self.is_oversized(local_stream)
def read(self, input_buffer, kmip_version=enums.KMIPVersion.KMIP_1_0): """ Read the data encoding the Create request payload and decode it into its constituent parts. Args: input_buffer (stream): A data buffer containing encoded object data, supporting a read method. 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 object type or template attribute is missing from the encoded payload. """ super(CreateRequestPayload, self).read(input_buffer, kmip_version=kmip_version) local_buffer = utils.BytearrayStream(input_buffer.read(self.length)) if self.is_tag_next(enums.Tags.OBJECT_TYPE, local_buffer): self._object_type = primitives.Enumeration( enums.ObjectType, tag=enums.Tags.OBJECT_TYPE) self._object_type.read(local_buffer, kmip_version=kmip_version) else: raise exceptions.InvalidKmipEncoding( "The Create request payload encoding is missing the object " "type.") if kmip_version < enums.KMIPVersion.KMIP_2_0: if self.is_tag_next(enums.Tags.TEMPLATE_ATTRIBUTE, local_buffer): self._template_attribute = objects.TemplateAttribute() self._template_attribute.read(local_buffer, kmip_version=kmip_version) else: raise exceptions.InvalidKmipEncoding( "The Create request payload encoding is missing the " "template attribute.") else: # NOTE (ph) For now, leave attributes natively in TemplateAttribute # form and just convert to the KMIP 2.0 Attributes form as needed # for encoding/decoding purposes. Changing the payload to require # the new Attributes structure will trigger a bunch of second-order # effects across the client and server codebases that is beyond # the scope of updating the Create payloads to support KMIP 2.0. if self.is_tag_next(enums.Tags.ATTRIBUTES, local_buffer): attributes = objects.Attributes() attributes.read(local_buffer, kmip_version=kmip_version) value = objects.convert_attributes_to_template_attribute( attributes) self._template_attribute = value else: raise exceptions.InvalidKmipEncoding( "The Create request payload encoding is missing the " "attributes structure.") self.is_oversized(local_buffer)
def test_not_equal_on_equal(self): """ Test that the inequality operator returns False when comparing two Rekey response payloads with the same data. """ a = payloads.RekeyResponsePayload() b = payloads.RekeyResponsePayload() self.assertFalse(a != b) self.assertFalse(b != a) a = payloads.RekeyResponsePayload( unique_identifier='1346d253-69d6-474c-8cd5-ad475a3e0a81', template_attribute=objects.TemplateAttribute(attributes=[ objects.Attribute(attribute_name=objects.Attribute. AttributeName('Cryptographic Algorithm'), attribute_value=primitives.Enumeration( enums.CryptographicAlgorithm, value=enums.CryptographicAlgorithm.AES, tag=enums.Tags.CRYPTOGRAPHIC_ALGORITHM)), objects.Attribute( attribute_name=objects.Attribute.AttributeName( 'Cryptographic Length'), attribute_value=primitives.Integer( value=128, tag=enums.Tags.CRYPTOGRAPHIC_LENGTH)) ])) b = payloads.RekeyResponsePayload( unique_identifier='1346d253-69d6-474c-8cd5-ad475a3e0a81', template_attribute=objects.TemplateAttribute(attributes=[ objects.Attribute(attribute_name=objects.Attribute. AttributeName('Cryptographic Algorithm'), attribute_value=primitives.Enumeration( enums.CryptographicAlgorithm, value=enums.CryptographicAlgorithm.AES, tag=enums.Tags.CRYPTOGRAPHIC_ALGORITHM)), objects.Attribute( attribute_name=objects.Attribute.AttributeName( 'Cryptographic Length'), attribute_value=primitives.Integer( value=128, tag=enums.Tags.CRYPTOGRAPHIC_LENGTH)) ])) self.assertFalse(a != b) self.assertFalse(b != a)
def register(self, managed_object): """ Register a managed object with a KMIP appliance. Args: managed_object (ManagedObject): A managed object to register. An instantiatable subclass of ManagedObject from the Pie API. Returns: string: The uid of the newly registered managed object. Raises: ClientConnectionNotOpen: if the client connection is unusable KmipOperationFailure: if the operation result is a failure TypeError: if the input argument is invalid """ # Check input if not isinstance(managed_object, pobjects.ManagedObject): raise TypeError("managed object must be a Pie ManagedObject") # Verify that operations can be given at this time if not self._is_open: raise exceptions.ClientConnectionNotOpen() # Extract and create attributes object_attributes = list() if hasattr(managed_object, 'cryptographic_usage_masks'): if managed_object.cryptographic_usage_masks is not None: mask_attribute = self.attribute_factory.create_attribute( enums.AttributeType.CRYPTOGRAPHIC_USAGE_MASK, managed_object.cryptographic_usage_masks) object_attributes.append(mask_attribute) if hasattr(managed_object, 'operation_policy_name'): if managed_object.operation_policy_name is not None: opn_attribute = self.attribute_factory.create_attribute( enums.AttributeType.OPERATION_POLICY_NAME, managed_object.operation_policy_name) object_attributes.append(opn_attribute) template = cobjects.TemplateAttribute(attributes=object_attributes) object_type = managed_object.object_type # Register the managed object and handle the results secret = self.object_factory.convert(managed_object) result = self.proxy.register(object_type, template, secret) status = result.result_status.value if status == enums.ResultStatus.SUCCESS: uid = result.uuid.value return uid else: reason = result.result_reason.value message = result.result_message.value raise exceptions.KmipOperationFailure(status, reason, message)
def read(self, input_stream): """ Read the data encoding the DeriveKey request payload and decode it into its constituent parts. Args: input_stream (stream): A data stream containing encoded object data, supporting a read method; usually a BytearrayStream object. Raises: ValueError: Raised if the data attribute is missing from the encoded payload. """ super(DeriveKeyRequestPayload, self).read(input_stream) local_stream = utils.BytearrayStream(input_stream.read(self.length)) if self.is_tag_next(enums.Tags.OBJECT_TYPE, local_stream): self._object_type = primitives.Enumeration( enums.ObjectType, tag=enums.Tags.OBJECT_TYPE) self._object_type.read(local_stream) else: raise ValueError("invalid payload missing object type") unique_identifiers = [] while self.is_tag_next(enums.Tags.UNIQUE_IDENTIFIER, local_stream): unique_identifier = primitives.TextString( tag=enums.Tags.UNIQUE_IDENTIFIER) unique_identifier.read(local_stream) unique_identifiers.append(unique_identifier) if not unique_identifiers: raise ValueError("invalid payload missing unique identifiers") else: self._unique_identifiers = unique_identifiers if self.is_tag_next(enums.Tags.DERIVATION_METHOD, local_stream): self._derivation_method = primitives.Enumeration( enums.DerivationMethod, tag=enums.Tags.DERIVATION_METHOD) self._derivation_method.read(local_stream) else: raise ValueError("invalid payload missing derivation method") if self.is_tag_next(enums.Tags.DERIVATION_PARAMETERS, local_stream): self._derivation_parameters = attributes.DerivationParameters() self._derivation_parameters.read(local_stream) else: raise ValueError("invalid payload missing derivation parameters") if self.is_tag_next(enums.Tags.TEMPLATE_ATTRIBUTE, local_stream): self._template_attribute = objects.TemplateAttribute() self._template_attribute.read(local_stream) else: raise ValueError("invalid payload missing template attribute") self.is_oversized(local_stream)
def create(self, algorithm, length, operation_policy_name=None, name=None): """ Create a symmetric key on a KMIP appliance. Args: algorithm (CryptographicAlgorithm): An enumeration defining the algorithm to use to generate the symmetric key. length (int): The length in bits for the symmetric key. operation_policy_name (string): The name of the operation policy to use for the new symmetric key. Optional, defaults to None name (string): The name to give the key. Optional, defaults to None Returns: string: The uid of the newly created symmetric key. Raises: ClientConnectionNotOpen: if the client connection is unusable KmipOperationFailure: if the operation result is a failure TypeError: if the input arguments are invalid """ # Check inputs if not isinstance(algorithm, enums.CryptographicAlgorithm): raise TypeError( "algorithm must be a CryptographicAlgorithm enumeration") elif not isinstance(length, six.integer_types) or length <= 0: raise TypeError("length must be a positive integer") # Verify that operations can be given at this time if not self._is_open: raise exceptions.ClientConnectionNotOpen() # Create the template containing the attributes common_attributes = self._build_common_attributes( operation_policy_name) key_attributes = self._build_key_attributes(algorithm, length) key_attributes.extend(common_attributes) if name: key_attributes.extend(self._build_name_attribute(name)) template = cobjects.TemplateAttribute(attributes=key_attributes) # Create the symmetric key and handle the results result = self.proxy.create(enums.ObjectType.SYMMETRIC_KEY, template) status = result.result_status.value if status == enums.ResultStatus.SUCCESS: uid = result.uuid.value return uid else: reason = result.result_reason.value message = result.result_message.value raise exceptions.KmipOperationFailure(status, reason, message)
def write(self, output_buffer, kmip_version=enums.KMIPVersion.KMIP_1_0): """ Write the data encoding the GetAttributes response payload to a stream. Args: 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. """ local_buffer = utils.BytearrayStream() if self._unique_identifier: self._unique_identifier.write( local_buffer, kmip_version=kmip_version ) else: raise exceptions.InvalidField( "The GetAttributes response payload is missing the unique " "identifier field." ) if kmip_version < enums.KMIPVersion.KMIP_2_0: for attribute in self._attributes: attribute.write(local_buffer, kmip_version=kmip_version) else: if self._attributes: # TODO (ph) Add a new utility to avoid using TemplateAttributes template_attribute = objects.TemplateAttribute( attributes=self.attributes ) attributes = objects.convert_template_attribute_to_attributes( template_attribute ) attributes.write(local_buffer, kmip_version=kmip_version) else: raise exceptions.InvalidField( "The GetAttributes response payload is missing the " "attributes list." ) self.length = local_buffer.length() super(GetAttributesResponsePayload, self).write( output_buffer, kmip_version=kmip_version ) output_buffer.write(local_buffer.buffer)
def test_not_equal_on_not_equal_template_attribute(self): """ Test that the inequality operator returns True when comparing two Rekey request payloads with different template attributes. """ a = payloads.RekeyRequestPayload( template_attribute=objects.TemplateAttribute( attributes=[ objects.Attribute( attribute_name=objects.Attribute.AttributeName( 'Protect Stop Date' ), attribute_value=primitives.DateTime( value=1577876400, tag=enums.Tags.PROTECT_STOP_DATE ) ) ] ) ) b = payloads.RekeyRequestPayload( template_attribute=objects.TemplateAttribute( attributes=[ objects.Attribute( attribute_name=objects.Attribute.AttributeName( 'Deactivation Date' ), attribute_value=primitives.DateTime( value=1577876400, tag=enums.Tags.DEACTIVATION_DATE ) ) ] ) ) self.assertTrue(a != b) self.assertTrue(b != a)
def generate_symmetric_key(self, key_spec): """Generate a symmetric key. Creates KMIP attribute objects based on the given KeySpec to send to the server. :param key_spec: KeySpec with symmetric algorithm and bit_length :returns: dictionary holding key_id returned by server :raises: SecretGeneralException, SecretAlgorithmNotSupportedException """ LOG.debug("Starting symmetric key generation with KMIP plugin") if not self.generate_supports(key_spec): raise ss.SecretAlgorithmNotSupportedException( key_spec.alg) object_type = enums.ObjectType.SYMMETRIC_KEY algorithm = self._create_cryptographic_algorithm_attribute( key_spec.alg) usage_mask = self._create_usage_mask_attribute() length = self._create_cryptographic_length_attribute( key_spec.bit_length) attribute_list = [algorithm, usage_mask, length] template_attribute = kmip_objects.TemplateAttribute( attributes=attribute_list) try: self.client.open() LOG.debug("Opened connection to KMIP client for secret " + "generation") result = self.client.create(object_type, template_attribute, self.credential) except Exception as e: LOG.exception("Error opening or writing to client") raise ss.SecretGeneralException(str(e)) else: if result.result_status.enum == enums.ResultStatus.SUCCESS: LOG.debug("SUCCESS: Symmetric key generated with " "uuid: %s", result.uuid.value) return {KMIPSecretStore.KEY_UUID: result.uuid.value} else: self._raise_secret_general_exception(result) finally: self.client.close() LOG.debug("Closed connection to KMIP client for secret " + "generation")
def write(self, output_buffer, kmip_version=enums.KMIPVersion.KMIP_1_0): """ Write the data encoding the Locate request payload to a buffer. Args: output_buffer (stream): A data buffer in which to encode object data, supporting a write method. kmip_version (KMIPVersion): An enumeration defining the KMIP version with which the object will be encoded. Optional, defaults to KMIP 1.0. """ local_buffer = utils.BytearrayStream() if self._maximum_items: self._maximum_items.write(local_buffer, kmip_version=kmip_version) if self._offset_items: self._offset_items.write(local_buffer, kmip_version=kmip_version) if self._storage_status_mask: self._storage_status_mask.write(local_buffer, kmip_version=kmip_version) if self._object_group_member: self._object_group_member.write(local_buffer, kmip_version=kmip_version) if kmip_version < enums.KMIPVersion.KMIP_2_0: if self._attributes: for attribute in self.attributes: attribute.write(local_buffer, kmip_version=kmip_version) else: if self._attributes: # TODO (ph) Add a new utility to avoid using TemplateAttributes template_attribute = objects.TemplateAttribute( attributes=self.attributes) attributes = objects.convert_template_attribute_to_attributes( template_attribute) attributes.write(local_buffer, kmip_version=kmip_version) else: raise exceptions.InvalidField( "The Locate request payload is missing the attributes " "list.") self.length = local_buffer.length() super(LocateRequestPayload, self).write(output_buffer, kmip_version=kmip_version) output_buffer.write(local_buffer.buffer)
def read(self, input_buffer, kmip_version=enums.KMIPVersion.KMIP_1_0): """ Read the data encoding the Create response payload and decode it into its constituent parts. Args: input_buffer (stream): A data buffer containing encoded object data, supporting a read method. 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 object type or unique identifier is missing from the encoded payload. """ super(CreateResponsePayload, self).read(input_buffer, kmip_version=kmip_version) local_buffer = utils.BytearrayStream(input_buffer.read(self.length)) if self.is_tag_next(enums.Tags.OBJECT_TYPE, local_buffer): self._object_type = primitives.Enumeration( enums.ObjectType, tag=enums.Tags.OBJECT_TYPE) self._object_type.read(local_buffer, kmip_version=kmip_version) else: raise exceptions.InvalidKmipEncoding( "The Create response payload encoding is missing the object " "type.") if self.is_tag_next(enums.Tags.UNIQUE_IDENTIFIER, local_buffer): self._unique_identifier = primitives.TextString( tag=enums.Tags.UNIQUE_IDENTIFIER) self._unique_identifier.read(local_buffer, kmip_version=kmip_version) else: raise exceptions.InvalidKmipEncoding( "The Create response payload encoding is missing the unique " "identifier.") if kmip_version < enums.KMIPVersion.KMIP_2_0: if self.is_tag_next(enums.Tags.TEMPLATE_ATTRIBUTE, local_buffer): self._template_attribute = objects.TemplateAttribute() self._template_attribute.read(local_buffer, kmip_version=kmip_version) self.is_oversized(local_buffer)
def test_create_with_name(self): """ Test that a symmetric key can be created with proper inputs, specifically testing that the name is correctly sent with the request. """ # Create the template to test the create call algorithm = enums.CryptographicAlgorithm.AES length = 256 algorithm_attribute = self.attribute_factory.create_attribute( enums.AttributeType.CRYPTOGRAPHIC_ALGORITHM, algorithm) length_attribute = self.attribute_factory.create_attribute( enums.AttributeType.CRYPTOGRAPHIC_LENGTH, length) mask_attribute = self.attribute_factory.create_attribute( enums.AttributeType.CRYPTOGRAPHIC_USAGE_MASK, [ enums.CryptographicUsageMask.ENCRYPT, enums.CryptographicUsageMask.DECRYPT ]) key_name = "symmetrickey" name_attribute = self.attribute_factory.create_attribute( enums.AttributeType.NAME, key_name) key_attributes = [ algorithm_attribute, length_attribute, mask_attribute, name_attribute ] template = obj.TemplateAttribute(attributes=key_attributes) key_id = 'aaaaaaaa-1111-2222-3333-ffffffffffff' status = enums.ResultStatus.SUCCESS result = results.CreateResult(contents.ResultStatus(status), uuid=attr.UniqueIdentifier(key_id)) with ProxyKmipClient() as client: client.proxy.create.return_value = result client.create(algorithm, length, name=key_name) client.proxy.create.assert_called_with( enums.ObjectType.SYMMETRIC_KEY, template)
def read(self, input_stream, kmip_version=enums.KMIPVersion.KMIP_1_0): """ Read the data encoding the Rekey response payload and decode it into its constituent parts. Args: input_stream (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: ValueError: Raised if the unique identifier attribute is missing from the encoded payload. """ super(RekeyResponsePayload, self).read(input_stream, kmip_version=kmip_version) local_stream = utils.BytearrayStream(input_stream.read(self.length)) if self.is_tag_next(enums.Tags.UNIQUE_IDENTIFIER, local_stream): self._unique_identifier = primitives.TextString( tag=enums.Tags.UNIQUE_IDENTIFIER) self._unique_identifier.read(local_stream, kmip_version=kmip_version) else: raise ValueError( "The Rekey response payload encoding is missing the unique " "identifier.") if self.is_tag_next(enums.Tags.TEMPLATE_ATTRIBUTE, local_stream): self._template_attribute = objects.TemplateAttribute() self._template_attribute.read(local_stream, kmip_version=kmip_version) self.is_oversized(local_stream)
def read(self, input_buffer, kmip_version=enums.KMIPVersion.KMIP_1_0): """ Read the data encoding the DeriveKey request payload and decode it into its constituent parts. Args: 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: ValueError: Raised if the data attribute is missing from the encoded payload. """ super(DeriveKeyRequestPayload, self).read( input_buffer, kmip_version=kmip_version ) local_buffer = utils.BytearrayStream(input_buffer.read(self.length)) if self.is_tag_next(enums.Tags.OBJECT_TYPE, local_buffer): self._object_type = primitives.Enumeration( enums.ObjectType, tag=enums.Tags.OBJECT_TYPE ) self._object_type.read(local_buffer, kmip_version=kmip_version) else: raise exceptions.InvalidKmipEncoding( "The DeriveKey request payload encoding is missing the object " "type." ) unique_identifiers = [] while self.is_tag_next(enums.Tags.UNIQUE_IDENTIFIER, local_buffer): unique_identifier = primitives.TextString( tag=enums.Tags.UNIQUE_IDENTIFIER ) unique_identifier.read(local_buffer, kmip_version=kmip_version) unique_identifiers.append(unique_identifier) if not unique_identifiers: raise exceptions.InvalidKmipEncoding( "The DeriveKey request payload encoding is missing the unique " "identifiers." ) else: self._unique_identifiers = unique_identifiers if self.is_tag_next(enums.Tags.DERIVATION_METHOD, local_buffer): self._derivation_method = primitives.Enumeration( enums.DerivationMethod, tag=enums.Tags.DERIVATION_METHOD ) self._derivation_method.read( local_buffer, kmip_version=kmip_version ) else: raise exceptions.InvalidKmipEncoding( "The DeriveKey request payload encoding is missing the " "derivation method." ) if self.is_tag_next(enums.Tags.DERIVATION_PARAMETERS, local_buffer): self._derivation_parameters = attributes.DerivationParameters() self._derivation_parameters.read( local_buffer, kmip_version=kmip_version ) else: raise exceptions.InvalidKmipEncoding( "The DeriveKey request payload encoding is missing the " "derivation parameters." ) if kmip_version < enums.KMIPVersion.KMIP_2_0: if self.is_tag_next(enums.Tags.TEMPLATE_ATTRIBUTE, local_buffer): self._template_attribute = objects.TemplateAttribute() self._template_attribute.read( local_buffer, kmip_version=kmip_version ) else: raise exceptions.InvalidKmipEncoding( "The DeriveKey request payload encoding is missing the " "template attribute." ) else: if self.is_tag_next(enums.Tags.ATTRIBUTES, local_buffer): attrs = objects.Attributes() attrs.read(local_buffer, kmip_version=kmip_version) value = objects.convert_attributes_to_template_attribute( attrs ) self._template_attribute = value else: raise exceptions.InvalidKmipEncoding( "The DeriveKey request payload encoding is missing the " "attributes structure." ) self.is_oversized(local_buffer)
def store_secret(self, secret_dto): """Stores a secret To store a secret in KMIP, the attributes must be known. :param secret_dto: SecretDTO of the secret to be stored :returns: Dictionary holding the key_uuid assigned by KMIP :raises: SecretGeneralException, SecretAlgorithmNotSupportedException """ LOG.debug("Starting secret storage with KMIP plugin") if not self.store_secret_supports(secret_dto.key_spec): raise ss.SecretAlgorithmNotSupportedException( secret_dto.key_spec.alg) object_type = self._map_type_ss_to_kmip(secret_dto.type) algorithm_value = self._map_algorithm_ss_to_kmip( secret_dto.key_spec.alg) usage_mask = self._create_usage_mask_attribute() attribute_list = [usage_mask] template_attribute = kmip_objects.TemplateAttribute( attributes=attribute_list) secret_features = { 'key_format_type': enums.KeyFormatType.RAW, 'key_value': { 'bytes': self._convert_base64_to_byte_array(secret_dto.secret) }, 'cryptographic_algorithm': algorithm_value, 'cryptographic_length': secret_dto.key_spec.bit_length } secret = secrets.SecretFactory().create_secret(object_type, secret_features) LOG.debug("Created secret object to be stored: %s, %s, %s", secret_features.get('key_format_type'), secret_features.get('cryptographic_algorithm'), secret_features.get('cryptographic_length')) try: self.client.open() LOG.debug("Opened connection to KMIP client for secret storage") result = self.client.register(object_type, template_attribute, secret, self.credential) except Exception as e: LOG.exception(u._LE("Error opening or writing to client")) raise ss.SecretGeneralException(str(e)) else: if result.result_status.enum == enums.ResultStatus.SUCCESS: LOG.debug("SUCCESS: Key stored with uuid: %s", result.uuid.value) return {KMIPSecretStore.KEY_UUID: result.uuid.value} else: self._raise_secret_general_exception(result) finally: self.client.close() LOG.debug("Closed connection to KMIP client for secret storage")
def read(self, input_buffer, kmip_version=enums.KMIPVersion.KMIP_1_0): """ Read the data encoding the CreateKeyPair request payload and decode it into its constituent parts. Args: input_buffer (stream): A data buffer containing encoded object data, supporting a read method. kmip_version (KMIPVersion): An enumeration defining the KMIP version with which the object will be decoded. Optional, defaults to KMIP 1.0. """ super(CreateKeyPairRequestPayload, self).read(input_buffer, kmip_version=kmip_version) local_buffer = utils.BytearrayStream(input_buffer.read(self.length)) if kmip_version < enums.KMIPVersion.KMIP_2_0: if self.is_tag_next(enums.Tags.COMMON_TEMPLATE_ATTRIBUTE, local_buffer): self._common_template_attribute = objects.TemplateAttribute( tag=enums.Tags.COMMON_TEMPLATE_ATTRIBUTE) self._common_template_attribute.read(local_buffer, kmip_version=kmip_version) else: if self.is_tag_next(enums.Tags.COMMON_ATTRIBUTES, local_buffer): attributes = objects.Attributes( tag=enums.Tags.COMMON_ATTRIBUTES) attributes.read(local_buffer, kmip_version=kmip_version) self._common_template_attribute = \ objects.convert_attributes_to_template_attribute( attributes ) if kmip_version < enums.KMIPVersion.KMIP_2_0: if self.is_tag_next(enums.Tags.PRIVATE_KEY_TEMPLATE_ATTRIBUTE, local_buffer): self._private_key_template_attribute = \ objects.TemplateAttribute( tag=enums.Tags.PRIVATE_KEY_TEMPLATE_ATTRIBUTE ) self._private_key_template_attribute.read( local_buffer, kmip_version=kmip_version) else: if self.is_tag_next(enums.Tags.PRIVATE_KEY_ATTRIBUTES, local_buffer): attributes = objects.Attributes( tag=enums.Tags.PRIVATE_KEY_ATTRIBUTES) attributes.read(local_buffer, kmip_version=kmip_version) self._private_key_template_attribute = \ objects.convert_attributes_to_template_attribute( attributes ) if kmip_version < enums.KMIPVersion.KMIP_2_0: if self.is_tag_next(enums.Tags.PUBLIC_KEY_TEMPLATE_ATTRIBUTE, local_buffer): self._public_key_template_attribute = \ objects.TemplateAttribute( tag=enums.Tags.PUBLIC_KEY_TEMPLATE_ATTRIBUTE ) self._public_key_template_attribute.read( local_buffer, kmip_version=kmip_version) else: if self.is_tag_next(enums.Tags.PUBLIC_KEY_ATTRIBUTES, local_buffer): attributes = objects.Attributes( tag=enums.Tags.PUBLIC_KEY_ATTRIBUTES) attributes.read(local_buffer, kmip_version=kmip_version) self._public_key_template_attribute = \ objects.convert_attributes_to_template_attribute( attributes ) if kmip_version >= enums.KMIPVersion.KMIP_2_0: if self.is_tag_next(enums.Tags.COMMON_PROTECTION_STORAGE_MASKS, local_buffer): storage_masks = objects.ProtectionStorageMasks( tag=enums.Tags.COMMON_PROTECTION_STORAGE_MASKS) storage_masks.read(local_buffer, kmip_version=kmip_version) self._common_protection_storage_masks = storage_masks if self.is_tag_next(enums.Tags.PRIVATE_PROTECTION_STORAGE_MASKS, local_buffer): storage_masks = objects.ProtectionStorageMasks( tag=enums.Tags.PRIVATE_PROTECTION_STORAGE_MASKS) storage_masks.read(local_buffer, kmip_version=kmip_version) self._private_protection_storage_masks = storage_masks if self.is_tag_next(enums.Tags.PUBLIC_PROTECTION_STORAGE_MASKS, local_buffer): storage_masks = objects.ProtectionStorageMasks( tag=enums.Tags.PUBLIC_PROTECTION_STORAGE_MASKS) storage_masks.read(local_buffer, kmip_version=kmip_version) self._public_protection_storage_masks = storage_masks self.is_oversized(local_buffer)