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

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions