RustCrypto / formats

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

der: Use #[asn1(type = "OCTET STRING")] with Vec<u8> #1539

Open dzil123 opened 1 month ago

dzil123 commented 1 month ago

I'm trying to use the der and der_derive crates to implement encoding and encoding a struct containing a Vec<u8> as an OCTET STRING. I need my struct to be owned, not borrowed from the input DER bytes.

Using OctetString in the struct definition is inconvenient because I must use the fallible new() method when manually creating an instance of the struct. I would rather the struct use Vec<u8> directly, and keep the der-specific types and encoding error in the encode and decode steps.

I thought #[asn1(type = "OCTET STRING")] would implement this, as the documentation states:

performs an intermediate conversion to der::asn1::OctetString

This does not work. Contrary to the documentation, the macro performs an intermediate conversion to OctetStringRef, which does not have a TryFrom and Into implemented for Vec<u8>.

use der::Sequence;

#[derive(Sequence)]
struct Foo {
    #[asn1(type = "OCTET STRING")]
    bar: Vec<u8>,
}
error[E0277]: the trait bound `Vec<u8>: TryFrom<OctetStringRef<'_>>` is not satisfied
 --> src/lib.rs:3:10
  |
3 | #[derive(Sequence)]
  |          ^^^^^^^^ the trait `From<OctetStringRef<'_>>` is not implemented for `Vec<u8>`, which is required by `OctetStringRef<'_>: TryInto<_>`
  |
  = help: the following other types implement trait `From<T>`:
            <Vec<u8> as From<&str>>
            <Vec<u8> as From<CString>>
            <Vec<u8> as From<String>>
  = note: required for `OctetStringRef<'_>` to implement `Into<Vec<u8>>`
  = note: required for `Vec<u8>` to implement `TryFrom<OctetStringRef<'_>>`
  = note: required for `OctetStringRef<'_>` to implement `TryInto<Vec<u8>>`
  = note: this error originates in the derive macro `Sequence` (in Nightly builds, run with -Z macro-backtrace for more info)

error[E0308]: mismatched types
  --> src/lib.rs:3:10
   |
3  | #[derive(Sequence)]
   |          ^^^^^^^^
   |          |
   |          expected `&[u8]`, found `Vec<u8>`
   |          arguments to this function are incorrect
   |
   = note: expected reference `&[u8]`
                 found struct `Vec<u8>`
note: associated function defined here
  --> /home/user/.cargo/registry/src/index.crates.io-6f17d22bba15001f/der-0.7.9/src/asn1/octet_string.rs:21:12
   |
21 |     pub fn new(slice: &'a [u8]) -> Result<Self> {
   |            ^^^
   = note: this error originates in the derive macro `Sequence` (in Nightly builds, run with -Z macro-backtrace for more info)
tarcieri commented 1 month ago

1540 should handle the conversions from OctetString(Ref) to Vec<u8>

dzil123 commented 1 month ago

Thank you, that PR fixes the first error "trait bound is not satisfied" on the call of ::der::asn1::OctetStringRef::decode(reader)?.try_into()? in the macro expansion. However, there is still the second error "mismatched types", occurring on the call of ::der::asn1::OctetStringRef::new(self.bar)?.encode(writer)?.

tarcieri commented 1 month ago

1562 should help although I don't know if it actually solves this