Parsers/Encoders for ASN.1 BER/DER data
Find a file
Repository files (latest commit first)
Filename Latest commit message Latest commit date
Reynard User 6bced9af6f
Some checks failed
Continuous integration / Check if README is up to date (push) Has been cancelled
Continuous integration / Build documentation (push) Has been cancelled
Continuous integration / Check semver compatibility (push) Has been cancelled
Continuous integration / Validate external types appearing in public API (push) Has been cancelled
Security audit / security_audit (push) Has been cancelled
Continuous integration / Check-1 (push) Has been cancelled
Continuous integration / Check-2 (push) Has been cancelled
Continuous integration / prek (push) Has been cancelled
Continuous integration / Check (push) Has been cancelled
Continuous integration / Rustfmt (push) Has been cancelled
Coverage / coverage (push) Has been cancelled
Continuous integration / Clippy (push) Has been cancelled
Continuous integration / Check-3 (push) Has been cancelled
Continuous integration / Check-4 (push) Has been cancelled
Continuous integration / Check-5 (push) Has been cancelled
Continuous integration / Test suite (with features) (push) Has been cancelled
Continuous integration / Test suite (with features)-1 (push) Has been cancelled
Continuous integration / Test suite (with features)-2 (push) Has been cancelled
Continuous integration / Test suite (with features)-3 (push) Has been cancelled
Continuous integration / Test suite (with features)-4 (push) Has been cancelled
Continuous integration / no-std (push) Has been cancelled
chore: sync dependencies (monorepo)
2026-04-07 18:06:22 +02:00
.github Bump actions/checkout from 5 to 6 2026-01-13 13:20:41 +00:00
derive chore: sync dependencies (monorepo) 2026-04-07 18:06:22 +02:00
doc cleanup: remove trailing whitespaces in comments 2025-09-15 10:15:29 +02:00
examples Fix clippy warning in tests: variables can be used directly in the format! string 2025-08-04 10:11:45 +02:00
impl chore: sync dependencies (monorepo) 2026-04-07 18:06:22 +02:00
src chore: sync dependencies (monorepo) 2026-04-06 20:09:31 +02:00
tests Avoid using hex-literal in const context, it requires rust 1.81 2025-09-15 09:03:45 +02:00
.gitignore Do not ignore Cargo.lock 2024-11-15 10:02:37 +01:00
.pre-commit-config.yaml CI: add support for prek/pre-commit checks 2025-09-15 09:10:46 +00:00
Cargo.lock chore: sync dependencies (monorepo) 2026-04-06 20:09:31 +02:00
Cargo.toml chore: sync dependencies (monorepo) 2026-04-06 20:09:31 +02:00
clippy.toml Forbid using unwrap, expect and panic in crate (enforced by clippy) except tests 2025-03-17 10:10:36 +01:00
LICENSE-APACHE Initial commit for rewrite of der-parser 2021-06-13 23:56:52 +02:00
LICENSE-MIT Initial commit for rewrite of der-parser 2021-06-13 23:56:52 +02:00
README.md Set MSRV to 1.68 (required by time-core) 2025-11-20 16:08:22 +01:00

Maintenance License: MIT Apache License 2.0 docs.rs crates.io Download numbers Github CI Minimum rustc version

asn1-rs

BER/DER Parsers/Encoders

A set of parsers/encoders for Basic Encoding Rules (BER [X.690]) and Distinguished Encoding Rules(DER [X.690]) formats, implemented with the nom parser combinator framework.

It is written in pure Rust, fast, and makes extensive use of zero-copy. A lot of care is taken to ensure security and safety of this crate, including design (recursion limit, defensive programming), tests, and fuzzing. It also aims to be panic-free.

This crate is a rewrite of der-parser to propose a more data-oriented API, and add generalized support for serialization.

Many ideas were initially borrowed from the crypto/utils/der crate (like the Any/TryFrom/FromDer mechanism), adapted and merged into a generalized BER/DER crate. Credits (and many thanks) go to Tony Arcieri for writing the original crate.

BER/DER parsers

BER stands for Basic Encoding Rules, and is defined in [X.690]. It defines a set of rules to encode and decode ASN.1 [X.680] objects in binary.

[X.690] also defines Distinguished Encoding Rules (DER), which is BER with added rules to ensure canonical and unequivocal binary representation of objects.

The choice of which one to use is usually guided by the specification of the data format based on BER or DER: for example, X.509 uses DER as encoding representation.

The main traits for parsing are the BerParser and DerParser traits. These traits provide methods to parse binary input wrapped in Input, and return either the remaining (unparsed) bytes and the parsed object, or an error. The [Input] types is a simple wrapper around &[u8] to keep information on data span. This is especially useful to print information or to debug parsing errors.

This crates also provides the FromBer and FromDer traits for parsing (working on slices).

The parsers follow the interface from nom, and the [ParseResult] object is a specialized version of nom::IResult. This means that most nom combinators (map, many0, etc.) can be used in combination to objects and methods from this crate. Reading the nom documentation may help understanding how to write and combine parsers and use the output.

Minimum Supported Rust Version: 1.68

no_std support: asn1-rs supports #[no_std] (with a requirement on alloc).

Recipes

See [doc::recipes] and [doc::derive] for more examples and recipes.

See [doc::debug] for advice and tools to debug parsers.

Examples

Parse 2 BER integers:

use asn1_rs::{Integer, FromBer};

let bytes = [ 0x02, 0x03, 0x01, 0x00, 0x01,
              0x02, 0x03, 0x01, 0x00, 0x00,
];

let (rem, obj1) = Integer::from_ber(&bytes).expect("parsing failed");
let (rem, obj2) = Integer::from_ber(&bytes).expect("parsing failed");

assert_eq!(obj1, Integer::from_u32(65537));

In the above example, the generic [Integer] type is used. This type can contain integers of any size, but do not provide a simple API to manipulate the numbers.

In most cases, the integer either has a limit, or is expected to fit into a primitive type. To get a simple value, just use the from_ber/from_der methods on the primitive types:

use asn1_rs::FromBer;

let bytes = [ 0x02, 0x03, 0x01, 0x00, 0x01,
              0x02, 0x03, 0x01, 0x00, 0x00,
];

let (rem, obj1) = u32::from_ber(&bytes).expect("parsing failed");
let (rem, obj2) = u32::from_ber(&rem).expect("parsing failed");

assert_eq!(obj1, 65537);
assert_eq!(obj2, 65536);

If the parsing succeeds, but the integer cannot fit into the expected type, the method will return an IntegerTooLarge error.

BER/DER encoders

BER/DER encoding is symmetrical to decoding, using the traits ToBer and ToDer traits. These traits provide methods to write encoded content to objects with the io::Write trait, or return an allocated Vec<u8> with the encoded data. If the serialization fails, an error is returned.

Examples

Writing 2 BER integers:

use asn1_rs::{Integer, ToDer};

let mut writer = Vec::new();

let obj1 = Integer::from_u32(65537);
let obj2 = Integer::from_u32(65536);

let _ = obj1.write_der(&mut writer).expect("serialization failed");
let _ = obj2.write_der(&mut writer).expect("serialization failed");

let bytes = &[ 0x02, 0x03, 0x01, 0x00, 0x01,
               0x02, 0x03, 0x01, 0x00, 0x00,
];
assert_eq!(&writer, bytes);

Similarly to BerParser/DerParser, serialization methods are also implemented for primitive types:

use asn1_rs::ToDer;

let mut writer = Vec::new();

let _ = 65537.write_der(&mut writer).expect("serialization failed");
let _ = 65536.write_der(&mut writer).expect("serialization failed");

let bytes = &[ 0x02, 0x03, 0x01, 0x00, 0x01,
               0x02, 0x03, 0x01, 0x00, 0x00,
];
assert_eq!(&writer, bytes);

If the parsing succeeds, but the integer cannot fit into the expected type, the method will return an IntegerTooLarge error.

Custom derive attributes

To simplify the code needed to declare common/usual ASN.1 objects, custom derive attributes are provided.

For example, to derive a MyType SEQUENCE { a INTEGER }, declare a struct and add the Sequence attribute:

#[derive(Sequence)]
pub struct MyType {
  a: u32,
}

See [doc::derive] for documentation and examples.

Changes

See CHANGELOG.md, and UPGRADING.md for instructions for upgrading major versions.

References

  • [X.680] Abstract Syntax Notation One (ASN.1): Specification of basic notation.
  • [X.690] ASN.1 encoding rules: Specification of Basic Encoding Rules (BER), Canonical Encoding Rules (CER) and Distinguished Encoding Rules (DER).

License

Licensed under either of

at your option.

Contribution

Unless you explicitly state otherwise, any contribution intentionally submitted for inclusion in the work by you, as defined in the Apache-2.0 license, shall be dual licensed as above, without any additional terms or conditions.