RustCrypto / formats

Cryptography-related format encoders/decoders: DER, PEM, PKCS, PKIX
228 stars 122 forks source link

der: provide optional integration with the `bytes` crate #1356

Closed abonander closed 3 months ago

abonander commented 4 months ago

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.

abonander commented 4 months ago

Nevermind, I just saw #1156. Looks like it'll be available in 0.8.0. Thanks! Sorry for the noise.

tarcieri commented 3 months ago

It's actually available as of der v0.7.8