Skip to content

der: provide optional integration with the bytes crate #1356

@abonander

Description

@abonander

The bytes crate is extremely popular for handling I/O and parsing buffers in the crates ecosystem, especially in respect to crates that build on Tokio.

It ends up being rather annoying/inefficient to use a bytes::Bytes instance with der types, as it either involves creating a wrapper struct, e.g.:

pub struct BytesAsOctetString(pub Bytes);

impl der::FixedTag for BytesAsOctetString {
    const TAG: der::Tag = der::Tag::OctetString;
}

impl der::EncodeValue for BytesAsOctetString {
    fn value_len(&self) -> der::Result<Length> {
        OctetStringRef::new(&self.0)?.value_len()
    }

    fn encode_value(&self, encoder: &mut impl Writer) -> der::Result<()> {
        OctetStringRef::new(&self.0)?.encode_value(encoder)
    }
}

impl<'a> der::DecodeValue<'a> for BytesAsOctetString {
    fn decode_value<R: Reader<'a>>(reader: &mut R, header: Header) -> der::Result<Self> {
        Ok(BytesAsOctetString(
            OctetString::decode_value(reader, header)?
                .into_bytes()
                .into(),
        ))
    }
}

or copying to/from an OctetString. This also invites potential mistakes because the most natural type to convert to is Vec<u8>, which der supports but which actually represents a SEQUENCE OF INTEGER, not an OCTET STRING.

In contrast, Bytes is pretty much as unambiguous as OctetString itself, with the caveat that it doesn't uphold the max-length guarantee that OctetString does.

This is an integration I'd be happy to contribute, because it would let me delete a good handful of lines of code on my end.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions