rasn
A safe, #[no_std] ASN.1 codec framework for Rust that encodes and decodes BER, CER, DER, PER, OER, JER, and XER from one abstract data model.
Repository Health
Technical Analysis
rasn is a Rust crate that lets you model ASN.1 data types once and encode or decode them under any of ASN.1’s standard encoding rules — BER, CER, DER, aligned and unaligned PER, OER, COER, JER, and XER — without rewriting the type for each format. It ships as #[no_std] with alloc, so it targets embedded and constrained environments as well as ordinary application code, and its codecs are written entirely in safe Rust and fuzz-tested to handle untrusted input without crashing.
Beyond the core crate, the librasn organization maintains a family of #[no_std] companion crates that implement ASN.1 data types for specific IETF and industry standards on top of rasn’s traits — CMS, Kerberos, LDAP, OCSP, PKIX, SNMP, S/MIME, and connected-vehicle standards like IEEE 1609.2 and ETSI TS 103 097. Combined with derive macros for AsnType, Encode, and Decode that check tag uniqueness at compile time, rasn is aimed at teams working with ASN.1-based protocols in telecom, PKI, and cryptography who want a memory-safe alternative to the format’s traditional C implementations.
What You Get
- A shared
AsnType/Encode/Decodetrait model that decouples your Rust types from any single ASN.1 encoding rule - Codec modules for BER, CER, DER, APER, UPER, OER, COER, JER, and XER, all implemented in safe Rust
- Derive macros that generate
Encode/Decodeimplementations and enforce distinct ASN.1 tags at compile time - Rich built-in ASN.1 types (INTEGER, OCTET STRING, SEQUENCE, CHOICE, and more) backed by
bitvec,bytes, andchrono - A family of
rasn-*standards crates (CMS, Kerberos, LDAP, OCSP, PKIX, SNMP, SMIME, IEEE 1609.2, ETSI TS 103 097) with ready-made typed models #[no_std]support with onlyallocrequired, so it runs on embedded and other constrained targets
Common Use Cases
- Implementing PKI and X.509 certificate handling (via
rasn-pkix,rasn-cms,rasn-ocsp) in Rust services - Parsing and generating LDAP, SNMP, or Kerberos protocol messages that are specified in ASN.1
- Building connected-vehicle (C-ITS) stacks that use IEEE 1609.2 or ETSI TS 103 097 security envelopes
- Encoding compact telecom or IoT payloads with PER/OER on embedded,
#[no_std]targets - Cross-checking or migrating legacy ASN.1-based systems to a memory-safe Rust implementation
Under The Hood
Architecture
rasn separates the ASN.1 data model from its encodings: src/types defines the abstract types (AsnType, tags, constraints, SEQUENCE/CHOICE field metadata via Fields), the de/enc modules define the generic Decode/Encoder/Decoder traits, and each of ber.rs, der.rs, cer.rs, per.rs, oer.rs, jer.rs, xer.rs, aper.rs, and uper.rs implements a concrete codec against those traits — der.rs, for example, is a thin wrapper that re-exports ber and configures DecoderOptions::der(). A Codec enum in codec.rs lets callers pick an encoding at runtime and dispatch to the right module. Because a type only ever implements AsnType/Encode/Decode once, adding a new codec (or a new standard’s data model in a standards/* crate) doesn’t require touching existing types. Rust’s borrow checker is used deliberately as a correctness net: encode_sequence/decode_sequence take closures over a scoped encoder/decoder so a field literally cannot be encoded through the wrong scope, a pattern the README documents as failing to compile rather than failing at runtime.
Tech Stack
rasn is a #![no_std] (plus alloc) Rust crate built as a Cargo workspace (Cargo.toml workspace members include macros, macros/macros_impl, and standards/*). Core dependencies are bitvec and nom/nom-bitvec for bit-level parsing, num-bigint/num-traits/num-integer for arbitrary-precision INTEGER handling, chrono for ASN.1 time types, snafu for structured error types (with an optional backtraces feature), serde_json and xml-no-std for the JER/XER codecs, and rasn-derive (a separate proc-macro crate under macros/) for the derive macros. An optional compiler feature pulls in rasn-compiler to generate rasn bindings directly from ASN.1 module notation. Dev-dependencies include criterion and iai-callgrind for benchmarking and third-party crates like x509-cert/rustls-webpki for interop testing against other ASN.1/X.509 implementations.
Code Quality
The crate has extensive automated tests: a tests/ directory with dozens of files, many named after specific GitHub issues (issue222.rs, issue508.rs, issue523.rs, etc.), indicating regression tests are added per bug report, plus round-trip tests inline in lib.rs that encode and decode every codec and assert equality via pretty_assertions. Error handling is explicit and typed throughout via snafu-derived DecodeError/EncodeError enums with codec-specific error kinds (BerDecodeErrorKind, DerDecodeErrorKind, etc.) rather than stringly-typed or swallowed errors. CI (.github/workflows/rust.yml) runs the test suite, just fmt, and just lint (clippy) across Windows and cross-compiled targets, and the crate carries #![warn(missing_docs)] at the crate root, enforcing rustdoc coverage on public items. The codec implementations are also fuzzed with AFL++, per the README, specifically to make the decoder robust against malformed/adversarial input.
What Makes It Unique
Most Rust ASN.1 crates are tied to a single encoding rule or a single standard; rasn’s abstract-model design lets one type definition be shared across nine different encoding rules and across a whole family of standards crates (CMS, PKIX, SNMP, LDAP, Kerberos, connected-vehicle standards) maintained under the same librasn organization. Its derive macros push tag-uniqueness checking — a common source of invalid ASN.1 models — to compile time via static_assertions-style const checks, and the encoder API uses Rust’s ownership system so that a sequence’s contents structurally cannot be encoded into the wrong scope. Combined with #[no_std] support and an all-safe-Rust, fuzzed codec implementation, it targets a niche — embedded and security-critical ASN.1 handling — that’s traditionally dominated by unsafe C libraries.