Пример #1
0
    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)
Пример #2
0
    def read(self, input_buffer, kmip_version=enums.KMIPVersion.KMIP_1_0):
        """
        Read the data encoding the ModifyAttribute request payload and decode
        it into its constituent part.

        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:
            InvalidKmipEncoding: Raised if fields are missing from the
                encoding.
        """
        super(ModifyAttributeRequestPayload,
              self).read(input_buffer, kmip_version=kmip_version)
        local_buffer = utils.BytearrayStream(input_buffer.read(self.length))

        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:
            self._unique_identifier = None

        if kmip_version < enums.KMIPVersion.KMIP_2_0:
            if self.is_tag_next(enums.Tags.ATTRIBUTE, local_buffer):
                self._attribute = objects.Attribute()
                self._attribute.read(local_buffer, kmip_version=kmip_version)
            else:
                raise exceptions.InvalidKmipEncoding(
                    "The ModifyAttribute request payload encoding is missing "
                    "the attribute field.")
        else:
            if self.is_tag_next(enums.Tags.CURRENT_ATTRIBUTE, local_buffer):
                self._current_attribute = objects.CurrentAttribute()
                self._current_attribute.read(local_buffer,
                                             kmip_version=kmip_version)
            else:
                self._current_attribute = None

            if self.is_tag_next(enums.Tags.NEW_ATTRIBUTE, local_buffer):
                self._new_attribute = objects.NewAttribute()
                self._new_attribute.read(local_buffer,
                                         kmip_version=kmip_version)
            else:
                raise exceptions.InvalidKmipEncoding(
                    "The ModifyAttribute request payload encoding is missing "
                    "the new attribute field.")

        self.is_oversized(local_buffer)
Пример #3
0
    def read(self, input_buffer, kmip_version=enums.KMIPVersion.KMIP_1_0):
        """
        Read the data encoding the GetAttributes response 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.
        """
        super(GetAttributesResponsePayload, self).read(
            input_buffer,
            kmip_version=kmip_version
        )
        local_buffer = utils.BytearrayStream(input_buffer.read(self.length))

        if 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)
            self.unique_identifier = unique_identifier.value
        else:
            raise exceptions.InvalidKmipEncoding(
                "The GetAttributes response payload encoding is missing the "
                "unique identifier."
            )

        if kmip_version < enums.KMIPVersion.KMIP_2_0:
            self._attributes = list()
            while self.is_tag_next(enums.Tags.ATTRIBUTE, local_buffer):
                attribute = objects.Attribute()
                attribute.read(local_buffer, kmip_version=kmip_version)
                self._attributes.append(attribute)
        else:
            if self.is_tag_next(enums.Tags.ATTRIBUTES, local_buffer):
                attributes = objects.Attributes()
                attributes.read(local_buffer, kmip_version=kmip_version)
                # TODO (ph) Add a new utility to avoid using TemplateAttributes
                temp_attr = objects.convert_attributes_to_template_attribute(
                    attributes
                )
                self._attributes = temp_attr.attributes
            else:
                raise exceptions.InvalidKmipEncoding(
                    "The GetAttributes response payload encoding is missing "
                    "the attributes structure."
                )

        self.is_oversized(local_buffer)
Пример #4
0
    def read(self, istream):
        """
        Read the data encoding the GetAttributeList response payload 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.
        """
        super(GetAttributeListResponsePayload, self).read(istream)
        tstream = utils.BytearrayStream(istream.read(self.length))

        if self.is_tag_next(enums.Tags.UNIQUE_IDENTIFIER, tstream):
            uid = primitives.TextString(tag=enums.Tags.UNIQUE_IDENTIFIER)
            uid.read(tstream)
            self.uid = uid.value
        else:
            raise exceptions.InvalidKmipEncoding(
                "expected uid encoding not found")

        names = list()
        while (self.is_tag_next(enums.Tags.ATTRIBUTE_NAME, tstream)):
            name = primitives.TextString(tag=enums.Tags.ATTRIBUTE_NAME)
            name.read(tstream)
            names.append(name.value)
        self.attribute_names = names

        self.is_oversized(tstream)
        self.validate()
Пример #5
0
    def read(self, istream):
        """
        Read the data encoding the GetAttributes response payload 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.
        """
        super(GetAttributesResponsePayload, self).read(istream)
        tstream = utils.BytearrayStream(istream.read(self.length))

        if self.is_tag_next(enums.Tags.UNIQUE_IDENTIFIER, tstream):
            unique_identifier = primitives.TextString(
                tag=enums.Tags.UNIQUE_IDENTIFIER)
            unique_identifier.read(tstream)
            self.unique_identifier = unique_identifier.value
        else:
            raise exceptions.InvalidKmipEncoding(
                "expected GetAttributes response unique identifier not found")

        self._attributes = list()
        while self.is_tag_next(enums.Tags.ATTRIBUTE, tstream):
            attribute = objects.Attribute()
            attribute.read(tstream)
            self._attributes.append(attribute)

        self.is_oversized(tstream)
Пример #6
0
    def read(self, input_buffer, kmip_version=enums.KMIPVersion.KMIP_1_0):
        """
        Read the data encoding the Locate 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 attributes structure is missing
                from the encoded payload for KMIP 2.0+ encodings.
        """
        super(LocateRequestPayload, self).read(input_buffer,
                                               kmip_version=kmip_version)
        local_buffer = utils.BytearrayStream(input_buffer.read(self.length))

        if self.is_tag_next(enums.Tags.MAXIMUM_ITEMS, local_buffer):
            self._maximum_items = primitives.Integer(
                tag=enums.Tags.MAXIMUM_ITEMS)
            self._maximum_items.read(local_buffer, kmip_version=kmip_version)

        if self.is_tag_next(enums.Tags.OFFSET_ITEMS, local_buffer):
            self._offset_items = primitives.Integer(
                tag=enums.Tags.OFFSET_ITEMS)
            self._offset_items.read(local_buffer, kmip_version=kmip_version)

        if self.is_tag_next(enums.Tags.STORAGE_STATUS_MASK, local_buffer):
            self._storage_status_mask = primitives.Integer(
                tag=enums.Tags.STORAGE_STATUS_MASK)
            self._storage_status_mask.read(local_buffer,
                                           kmip_version=kmip_version)

        if self.is_tag_next(enums.Tags.OBJECT_GROUP_MEMBER, local_buffer):
            self._object_group_member = primitives.Enumeration(
                enums.ObjectGroupMember, tag=enums.Tags.OBJECT_GROUP_MEMBER)
            self._object_group_member.read(local_buffer,
                                           kmip_version=kmip_version)

        if kmip_version < enums.KMIPVersion.KMIP_2_0:
            while self.is_tag_next(enums.Tags.ATTRIBUTE, local_buffer):
                attribute = objects.Attribute()
                attribute.read(local_buffer, kmip_version=kmip_version)
                self._attributes.append(attribute)
        else:
            if self.is_tag_next(enums.Tags.ATTRIBUTES, local_buffer):
                attributes = objects.Attributes()
                attributes.read(local_buffer, kmip_version=kmip_version)
                # TODO (ph) Add a new utility to avoid using TemplateAttributes
                temp_attr = objects.convert_attributes_to_template_attribute(
                    attributes)
                self._attributes = temp_attr.attributes
            else:
                raise exceptions.InvalidKmipEncoding(
                    "The Locate request payload encoding is missing the "
                    "attributes structure.")
Пример #7
0
    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)
Пример #8
0
    def read(self, istream, kmip_version=enums.KMIPVersion.KMIP_1_0):
        super(MACResponsePayload, self).read(istream,
                                             kmip_version=kmip_version)
        tstream = BytearrayStream(istream.read(self.length))

        if self.is_tag_next(Tags.UNIQUE_IDENTIFIER, tstream):
            self._unique_identifier = attributes.UniqueIdentifier()
            self._unique_identifier.read(tstream, kmip_version=kmip_version)
        else:
            raise exceptions.InvalidKmipEncoding(
                "expected mac response unique identifier not found")

        if self.is_tag_next(Tags.MAC_DATA, tstream):
            self._mac_data = MACData()
            self._mac_data.read(tstream, kmip_version=kmip_version)
        else:
            raise exceptions.InvalidKmipEncoding(
                "expected mac response mac data not found")

        self.is_oversized(tstream)
Пример #9
0
    def read(self, input_buffer, kmip_version=enums.KMIPVersion.KMIP_2_0):
        """
        Read the data encoding the SetAttribute response 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 (enum): A KMIPVersion enumeration defining the KMIP
                version with which the object will be decoded. Optional,
                defaults to KMIP 1.0.

        Raises:
            VersionNotSupported: Raised when a KMIP version is provided that
                does not support the SetAttribute operation.
            InvalidKmipEncoding: Raised if any required fields are missing
                from the encoding.
        """
        if kmip_version < enums.KMIPVersion.KMIP_2_0:
            raise exceptions.VersionNotSupported(
                "KMIP {} does not support the SetAttribute operation.".format(
                    kmip_version.value))

        super(SetAttributeResponsePayload,
              self).read(input_buffer, kmip_version=kmip_version)
        local_buffer = utils.BytearrayStream(input_buffer.read(self.length))

        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 SetAttribute response payload encoding is missing the "
                "unique identifier field.")

        self.is_oversized(local_buffer)
Пример #10
0
    def read(self, istream):
        super(MACRequestPayload, self).read(istream)
        tstream = BytearrayStream(istream.read(self.length))

        if self.is_tag_next(Tags.UNIQUE_IDENTIFIER, tstream):
            self.unique_identifier = attributes.UniqueIdentifier()
            self.unique_identifier.read(tstream)

        if self.is_tag_next(Tags.CRYPTOGRAPHIC_PARAMETERS, tstream):
            self.cryptographic_parameters = \
                attributes.CryptographicParameters()
            self.cryptographic_parameters.read(tstream)

        if self.is_tag_next(Tags.DATA, tstream):
            self.data = Data()
            self.data.read(tstream)
        else:
            raise exceptions.InvalidKmipEncoding(
                "expected mac request data not found"
            )

        self.is_oversized(tstream)
Пример #11
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:
            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(input_buffer,
                                              kmip_version=kmip_version)
        local_buffer = utils.BytearrayStream(input_buffer.read(self.length))

        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)

        if query_functions:
            self._query_functions = query_functions
        else:
            raise exceptions.InvalidKmipEncoding(
                "The Query request payload encoding is missing the query "
                "functions.")

        self.is_oversized(local_buffer)
Пример #12
0
    def read(self, input_buffer, kmip_version=enums.KMIPVersion.KMIP_1_0):
        """
        Read the data encoding the GetAttributes 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:
            InvalidKmipEncoding: Raised if an invalid type is found for the
                AttributeReference encoding for KMIP 2.0+ encodings.
        """
        super(GetAttributesRequestPayload, self).read(
            input_buffer,
            kmip_version=kmip_version
        )
        local_buffer = utils.BytearrayStream(input_buffer.read(self.length))

        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:
            self._unique_identifier = None

        names = list()
        if kmip_version < enums.KMIPVersion.KMIP_2_0:
            while self.is_tag_next(enums.Tags.ATTRIBUTE_NAME, local_buffer):
                name = primitives.TextString(tag=enums.Tags.ATTRIBUTE_NAME)
                name.read(local_buffer, kmip_version=kmip_version)
                names.append(name)
            self._attribute_names = names
        else:
            while self.is_tag_next(
                    enums.Tags.ATTRIBUTE_REFERENCE,
                    local_buffer
            ):
                if self.is_type_next(enums.Types.STRUCTURE, local_buffer):
                    reference = objects.AttributeReference()
                    reference.read(local_buffer, kmip_version=kmip_version)
                    names.append(
                        primitives.TextString(
                            value=reference.attribute_name,
                            tag=enums.Tags.ATTRIBUTE_NAME
                        )
                    )
                elif self.is_type_next(enums.Types.ENUMERATION, local_buffer):
                    reference = primitives.Enumeration(
                        enums.Tags,
                        tag=enums.Tags.ATTRIBUTE_REFERENCE
                    )
                    reference.read(local_buffer, kmip_version=kmip_version)
                    name = enums.convert_attribute_tag_to_name(reference.value)
                    names.append(
                        primitives.TextString(
                            value=name,
                            tag=enums.Tags.ATTRIBUTE_NAME
                        )
                    )
                else:
                    raise exceptions.InvalidKmipEncoding(
                        "The GetAttributes request payload encoding contains "
                        "an invalid AttributeReference type."
                    )
            self._attribute_names = names

        self.is_oversized(local_buffer)
Пример #13
0
    def read(self, input_buffer, kmip_version=enums.KMIPVersion.KMIP_1_0):
        """
        Read the data encoding the SplitKey object and decode it.

        Args:
            input_buffer (stream): A data stream containing the 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(SplitKey, self).read(input_buffer, kmip_version=kmip_version)
        local_buffer = utils.BytearrayStream(input_buffer.read(self.length))

        if self.is_tag_next(enums.Tags.SPLIT_KEY_PARTS, local_buffer):
            self._split_key_parts = primitives.Integer(
                tag=enums.Tags.SPLIT_KEY_PARTS
            )
            self._split_key_parts.read(local_buffer, kmip_version=kmip_version)
        else:
            raise exceptions.InvalidKmipEncoding(
                "The SplitKey encoding is missing the SplitKeyParts field."
            )

        if self.is_tag_next(enums.Tags.KEY_PART_IDENTIFIER, local_buffer):
            self._key_part_identifier = primitives.Integer(
                tag=enums.Tags.KEY_PART_IDENTIFIER
            )
            self._key_part_identifier.read(
                local_buffer,
                kmip_version=kmip_version
            )
        else:
            raise exceptions.InvalidKmipEncoding(
                "The SplitKey encoding is missing the KeyPartIdentifier field."
            )

        if self.is_tag_next(enums.Tags.SPLIT_KEY_THRESHOLD, local_buffer):
            self._split_key_threshold = primitives.Integer(
                tag=enums.Tags.SPLIT_KEY_THRESHOLD
            )
            self._split_key_threshold.read(
                local_buffer,
                kmip_version=kmip_version
            )
        else:
            raise exceptions.InvalidKmipEncoding(
                "The SplitKey encoding is missing the SplitKeyThreshold field."
            )

        if self.is_tag_next(enums.Tags.SPLIT_KEY_METHOD, local_buffer):
            self._split_key_method = primitives.Enumeration(
                enums.SplitKeyMethod,
                tag=enums.Tags.SPLIT_KEY_METHOD
            )
            self._split_key_method.read(
                local_buffer,
                kmip_version=kmip_version
            )
        else:
            raise exceptions.InvalidKmipEncoding(
                "The SplitKey encoding is missing the SplitKeyMethod field."
            )

        if self.is_tag_next(enums.Tags.PRIME_FIELD_SIZE, local_buffer):
            self._prime_field_size = primitives.BigInteger(
                tag=enums.Tags.PRIME_FIELD_SIZE
            )
            self._prime_field_size.read(
                local_buffer,
                kmip_version=kmip_version
            )
        else:
            corner_case = enums.SplitKeyMethod.POLYNOMIAL_SHARING_PRIME_FIELD
            if self.split_key_method == corner_case:
                raise exceptions.InvalidKmipEncoding(
                    "The SplitKey encoding is missing the PrimeFieldSize "
                    "field. This field is required when the SplitKeyMethod is "
                    "PolynomialSharingPrimeField."
                )

        if self.is_tag_next(enums.Tags.KEY_BLOCK, local_buffer):
            self._key_block = objects.KeyBlock()
            self._key_block.read(local_buffer, kmip_version=kmip_version)
        else:
            raise exceptions.InvalidKmipEncoding(
                "The SplitKey encoding is missing the KeyBlock field."
            )

        self.is_oversized(local_buffer)
Пример #14
0
    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)