Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ToBer is missing? #31

Open
KarstenB opened this issue Jan 10, 2024 · 3 comments
Open

ToBer is missing? #31

KarstenB opened this issue Jan 10, 2024 · 3 comments

Comments

@KarstenB
Copy link

The main readme hints at the existence of a ToBer trait:

BER/DER encoding is symmetrical to decoding, using the traits ToBer and [ToDer] traits. 

However I can't find anything about this in the code. Am I just missing something obvious?

@chifflier
Copy link
Member

Hi,

You're not missing anything! Only DER is currently supported, but since DER is a subset of BER, generating DER will result in valid BER data.

The limit is that using ToDer will always generate canonical encoding, and will not allow you to generate for example dequences with indefinite length

@KarstenB
Copy link
Author

Unfortunately using ToDer is not an option for me as I try to implement this ASN.1 https://github.com/wireshark/wireshark/blob/master/epan/dissectors/asn1/sv/sv.asn

Which uses explicit tagging all the time. I am not sure I found the best solution for creating these, but it surely feels hacky:

fn write_implicit_header(
    writer: &mut dyn std::io::Write,
    tag: u8,
    field: &impl ToDer,
) -> asn1_rs::SerializeResult<usize> {
    let mut inner_buffer = Vec::new();
    let inner_header_size = field.write_der_header(&mut inner_buffer)?;
    let header = asn1_rs::Header::new(
        asn1_rs::Class::ContextSpecific,
        false,
        Tag::EndOfContent,
        asn1_rs::Length::Definite(field.to_der_len()? - inner_header_size),
    );
    let header = header.with_raw_tag(Some(Cow::Owned(vec![
        tag | 0x80, /* context specific */
    ])));
    header.write_der_raw(writer)
}

Or am I missing something very obvious on how I could generate implicit tags?

@chifflier
Copy link
Member

Ah, I see.

Objects like TaggedParser and TaggedValue do implement ToDer, so you just have to build an implicit object and call .to_der_vec().
You can also use TaggedImplicit.
All these APIs are equivalent, you can choose the one you prefer (I suggest TaggedImplicit), for ex something like:

let object = Integer::from(2);
let tagged: TaggedImplicit::<_, Error, 0> = TaggedValue::implicit(object); // 0 is the implicit tag here
let v = tagged.to_der_vec()?;

See this unit test for examples.

Note: I assumed you want to serialize the entire tagged object. If you want only the header, use tagged.write_der_header(v) with a writer, like v = &mut Vec<u8>, to store the result.

Serialization could be better documented, I think.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants