35 releases (12 stable)

✓ Uses Rust 2018 edition

3.0.4 Jan 30, 2020
3.0.3 Nov 26, 2019
3.0.2 Sep 1, 2019
2.1.0 Jul 25, 2019
0.3.3 Mar 27, 2017

#5 in Parser implementations

Download history 3634/week @ 2019-11-01 2906/week @ 2019-11-08 2762/week @ 2019-11-15 3136/week @ 2019-11-22 2512/week @ 2019-11-29 2874/week @ 2019-12-06 2521/week @ 2019-12-13 725/week @ 2019-12-20 599/week @ 2019-12-27 1087/week @ 2020-01-03 1839/week @ 2020-01-10 1649/week @ 2020-01-17 1550/week @ 2020-01-24 1507/week @ 2020-01-31 1670/week @ 2020-02-07

9,094 downloads per month
Used in 13 crates (9 directly)




License: MIT Apache License 2.0 Build Status Crates.io Version

BER/DER Parser

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

The code is available on Github and is part of the Rusticata project.

DER parser design

There are two different approaches for parsing DER objects: reading the objects recursively as long as the tags are known, or specifying a description of the expected objects (generally from the ASN.1 description).

The first parsing method can be done using the parse_ber and parse_der methods. However, it cannot fully parse all objects, especially those containing IMPLICIT, OPTIONAL, or DEFINED BY items.

use der_parser::parse_der;

let bytes = [ 0x30, 0x0a,
              0x02, 0x03, 0x01, 0x00, 0x01,
              0x02, 0x03, 0x01, 0x00, 0x00,

let parsed = parse_der(&bytes);

The second (and preferred) parsing method is to specify the expected objects recursively. The following macros can be used: parse_der_sequence_defined and similar functions, parse_der_struct, etc.

For example, to read a sequence containing two integers:

use der_parser::ber::*;
use der_parser::error::BerResult;

fn localparse_seq(i:&[u8]) -> BerResult {
        parse_ber_integer >>

let bytes = [ 0x30, 0x0a,
              0x02, 0x03, 0x01, 0x00, 0x01,
              0x02, 0x03, 0x01, 0x00, 0x00,
let parsed = localparse_seq(&bytes);

All functions return a BerResult object: the parsed BerObject, an Incomplete value, or an error.

Note that this type is also a Result, so usual functions (map, unwrap etc.) are available.


  • The DER constraints are verified if using parse_der.
  • BerObject and DerObject are the same objects (type alias). The only difference is the verification of constraints during parsing.
  • DER integers can be of any size, so it is not possible to store them as simple integers (they are stored as raw bytes). To get a simple value, use BerObject::as_u32 (knowning that this method will return an error if the integer is too large), BerObject::as_u64, or use the bigint feature of this crate and use BerObject::as_bigint.


  • [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).



  • Use cloned instead of copied to support older rust compiler (1.33)
  • Fix new clippy warnings (rust 1.40)


  • Make the pretty-printer function public
  • Fix DER datestring sanity check
  • CI
    • add rusfmt check
    • add cargo clippy


  • Add parse_ber_u32 and parse_ber_u64 functions
  • Fix typo in description


  • Add crate BerResult and DerResult types
  • Use crate result types, remove uneeded imports
    • Crates using der-parser do not need to import nom or rusticata-macros anymore
    • Result types are aliases, so API is unchanged


  • Upgrade to nom 5 (breaks API)
  • New error types, now all functions use BerError


  • Handle BER/DER tags that are longer than one byte.
  • Set edition to 2018


  • Revert 2.0.1 release, breaks API


  • Handle BER/DER tags that are longer than one byte.


  • Refactor code, split BER and DER, check DER constraints
  • Add recursion limit for sequences and sets
  • Rustfmt
  • Documentation
  • Remove unused function ber_read_element_content


  • Fix OID parsing, and add support for relative OIDs
  • Add FromStr trait for Oid


  • Use num-bigint over num and upgrade to 0.2


  • Upgrade to nom 4


  • Add functions parse_der_u32 and parse_der_u64 to quickly parse integers
  • Remove Oid::from_vec, Oid::from does the same
  • Enforce constraints on DER booleans


  • Add BitStringObject to wrap BitString objects
  • Mark constructed BitStrings as unsupported
  • Do not try to parse application-specific data in parse_der


  • Add function DerObject::as_u64
  • Add function DerObject::as_oid_val
  • Add parse_der_struct! variant to check tag


  • Add functions to test object class and primitive/constructed state
  • Add macro parse_der_application!
  • Add macro parse_der_tagged! to parse [x] EXPLICIT or [x] IMPLICIT tagged values


  • Add type GeneralString
  • Add macro parse_der_struct!


  • Allow use of crate without extra use statements
  • Use constants for u32 errors instead of magical numbers
  • Rename tag_of_der_content() to DerObjectContent::tag
  • Rename DerElementxxx structs to have a consistent naming scheme
  • Add documentation for parsing DER sequences and sets, and fix wrong return type for sets
  • Fix a lot of clippy warnings
  • QA: add pragma rules (disable unsafe code, unstable features etc.)
  • More documentation
  • Switch license to MIT + APLv2


  • Add macro parse_der_defined_m, to parse a defined sequence or set This macro differs from parse_der_defined because it allows using macros
  • Rename DerObject::new_int to DerObject::from_int_slice
  • Rename Oid::to_hex to Oid::to_string
  • Document more functions


  • Add new feature 'bigint' to export DER integers
  • OID is now a specific type
  • Add new types T61String and BmpString
  • Fix wrong expected tag in parse_der_set_of


  • Der Integers are now represented as slices (byte arrays) since they can be larger than u64.


Licensed under either of

at your option.


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.


~16K SLoC