Crate red_asn1_derive

Source
Expand description

Macros to create ASN1 sequence or choice from Rust struct or enums

§Sequence macro

Macro to create ASN1 sequence from Rust struct

§Attributes

  • seq: Define attributes for the struct definition. Has the following flags:

    • application_tag : Number of application tag
  • seq_field: Define attributes for a field of the struct. Has the following flags:

    • context_tag: Number of context tag
    • implicit: Indicates if the tag is implicit

§Example

/*
Person ::= [APPLICATION 1] SEQUENCE {
    name:       [0] GeneralString,
    age:        [1] IMPLICIT Integer,
    address:    [2] GeneralString OPTIONAL,
}
*/

use red_asn1::*;
use red_asn1_derive::Sequence;

#[derive(Sequence, Default)]
#[seq(application_tag = 1)]
struct Person {
    #[seq_field(context_tag = 0)]
    name: GeneralString,
    #[seq_field(context_tag = 1, implicit)]
    age: Integer,
    #[seq_field(context_tag = 2)]
    address: Option<GeneralString>
}

let john = Person{
    name: GeneralString::from("John").into(),
    age: Integer::from(18).into(),
    address: None
};

assert_eq!(
    vec![
        0x61, 0xd, 0x30, 0xb,
        0xa0, 0x6, 0x1b, 0x4, 0x4a, 0x6f, 0x68, 0x6e, // "John"
        0x80, 0x1, 0x12 // 18
    ]
    , john.build()
);

let (_, rachel) = Person::parse(&[
    0x61, 0x19, 0x30, 0x17,
    0xa0, 0x8, 0x1b, 0x6, 0x52, 0x61, 0x63, 0x68, 0x65, 0x6c, // "Rachel"
    0x80, 0x1, 0x1e, // 30
    0xa2, 0x8, 0x1b, 0x6, 0x48, 0x61, 0x77, 0x61, 0x69, 0x69 // "Hawaii"
]).unwrap();

assert_eq!("Rachel", rachel.name);
assert_eq!(30, rachel.age);
assert_eq!(Some("Hawaii".to_string()), rachel.address);

§Choice Macro

Macro to create ASN1 choice from Rust enums

§Choice Attributes

  • choice: Define attributes for the enum definition. Has the following flags:

    • application_tag : Number of application tag
  • choice_field: Define attributes for a variant of the enum. Has the following flags:

    • context_tag: Number of context tag
    • implicit: Indicates if the tag is implicit

§Example

/*
PersonAttr ::= [APPLICATION 1] CHOICE {
    name:       [0] GeneralString,
    age:        [1] IMPLICIT Integer,
}
*/

use red_asn1::*;
use red_asn1_derive::Choice;

#[derive(Choice, Debug, PartialEq)]
#[choice(application_tag = 1)]
enum PersonAttr {
    #[choice_field(context_tag = 0)]
    GeneralString(GeneralString),
    #[choice_field(context_tag = 1, implicit)]
    Integer(Integer),
}

// Asn1Obj needs to implement default
impl Default for PersonAttr {
    fn default() -> Self {
        return Self::Integer(Integer::from(0));
    }
}

let pa = PersonAttr::GeneralString(GeneralString::from("John").into());
assert_eq!(
    vec![
        0x61, 0x8, // application tag
        0xa0, 0x6, 0x1b, 0x4, 0x4a, 0x6f, 0x68, 0x6e, // "John"
    ],
    pa.build()
);

assert_eq!(
    PersonAttr::parse(&[
        0x61, 0x8, // application tag
        0xa0, 0x6, 0x1b, 0x4, 0x4a, 0x6f, 0x68, 0x6e, // "John"
    ])
    .unwrap()
    .1,
    pa
);

let pa = PersonAttr::Integer(Integer::from(77));
assert_eq!(
    vec![
        0x61, 0x3, // application tag
        0x80, 0x1, 77, // "John"
    ],
    pa.build()
);

assert_eq!(
    PersonAttr::parse(&[
        0x61, 0x3, // application tag
        0x80, 0x1, 77, // "John"
    ])
    .unwrap()
    .1,
    pa
);

Derive Macros§

Choice
Sequence