formats icon indicating copy to clipboard operation
formats copied to clipboard

der: add `new` and derives to SequenceRef

Open kamulos opened this issue 6 months ago • 2 comments

This is a reopening of #1977 which was closed because there was too little explaination. The motivation for adding the derives is that I cannot use SequenceRef in my structs that I want to output in the debug format or compare for equality.

The motivation for creating new SequenceRef is a bit harder to explain: I have something like X.509 ContentInfo that needs raw data access. When decoding I need the buffer data to validate a signature and I need to add a raw buffer which I have signed when compiling the data. I also want to use der_derive annotations to do all the validation for me.

Up until recently I was using AnyRef for this purpose, but this broke in the recent 0.8.0 release candidates (please see #1976 for more info). The thing is, instead of an explicit tag mode like in ContentInfo the format I am parsing is using the implicit tag mode and has the constructed bit set. AnyRef does not work with this anymore and I can understand the reasoning.

The next best thing we found in the linked case was (ab)using SequenceRef because it accepts having the implicit tag mode and the constructed bit set. And to be able to construct the type I need some kind of constructor for SequenceRef.

To be honest I would prefer having something that is more intentional for the purpose of raw data access, but still allows me to use the derive macro to specify the tag and tag mode implicit.

Tagging @dishmaker because we had a lengthy discussion in the linked case

Copying the example from the linked case. This used to work, but does not anymore:

use der::{AnyRef, Decode, Sequence, oid::ObjectIdentifier};

#[derive(Debug, Sequence)]
pub struct SomeType<'a> {
    pub oid: ObjectIdentifier,
    #[asn1(context_specific = "0", tag_mode = "IMPLICIT")]
    pub data: AnyRef<'a>,
}

fn main() {
    let bytes = b"\x30\x12\x06\x07\x2a\x86\x48\xce\x3d\x02\x01\xa0\x07\x63\x6f\x6e\x74\x65\x6e\x74";
    let decoded = SomeType::from_der(bytes).unwrap();
    println!("{:02x?}", decoded.data.value());
}

kamulos avatar Aug 04 '25 06:08 kamulos