Keyboard shortcuts

Press ← or → to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

ASN.1 tutorial

This walkthrough generates a small DER codec from an ASN.1 module and uses it to parse and serialize a message.

Define a module

Create message.asn1:

Message DEFINITIONS EXPLICIT TAGS ::= BEGIN
    Kind ::= ENUMERATED {
        request(0),
        response(1)
    }

    Packet ::= SEQUENCE {
        kind Kind,
        payload [0] IMPLICIT OCTET STRING (SIZE (1..32)) OPTIONAL
    }
END

Generate DER

vest_asn1 is currently a repository tool rather than a published crate:

cargo run -p vest_asn1 -- message.asn1 -o src/message.rs

DER is the default. Use --rules ber for BER, or definition overrides for a module with canonical DER substructures inside a BER envelope; see DER, BER, and rule overrides.

The generator emits Kind and Packet<'i> value types. Unlike the Vest DSL, their verified format values are KIND::Fmt and PACKET::Fmt. Uppercase format names avoid collisions with the idiomatic Rust value names. Tagged formats also store their effective tag to support IMPLICIT retagging.

Parse and serialize

use vest_lib::core::exec::{Parser, Prepare, SerializerExt};
use crate::message::{Kind, PACKET};

let encoded: &[u8] = &[
    0x30, 0x07,             // SEQUENCE, seven content octets
    0x0a, 0x01, 0x00,       // Kind::Request
    0x80, 0x02, 0xaa, 0xbb, // [0] IMPLICIT OCTET STRING
];

let (consumed, packet) = PACKET::Fmt.parse(&encoded).unwrap();
assert_eq!(consumed, encoded.len());
assert_eq!(packet.kind, Kind::Request);
assert_eq!(packet.payload, Some(&[0xaa, 0xbb][..]));

let size = PACKET::Fmt.prepare(&packet).unwrap();
let mut output = vec![0u8; size];
PACKET::Fmt.serialize(&packet, &mut output);
assert_eq!(output, encoded);

DER byte strings and UTF-8-compatible character strings borrow from the input. BER string formats concatenate constructed fragments into owned values. BMPString and UniversalString are always owned because their wire encodings must be converted to UTF-8.

What is checked

TODO. Discuss the proof obligations for format non-ambiguity, etc.