A parser for Basic Encoding Rules (BER [X.690]) and Distinguished Encoding Rules(DER [X.690]), 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.
The code is available on Github and is part of the Rusticata project.
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.
It is useful when decoding an arbitrary DER object.
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_der_sequence_defined!(i,
parse_ber_integer >>
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.
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
.
use der_parser::ber::*;
use der_parser::error::BerResult;
let data = &[0x02, 0x03, 0x01, 0x00, 0x01];
let (_, object) = parse_ber_integer(data).expect("parsing failed");
assert_eq!(object.as_u64(), Ok(65537));
Access to the raw value is possible using the as_slice
method.
- The DER constraints are verified if using
parse_der
. BerObject
andDerObject
are the same objects (type alias). The only difference is the verification of constraints during parsing.
Support for encoding BER/DER objects is currently being tested and can be used by activating the serialize
feature.
Note that current status is experimental.
See the ber_encode_*
functions in the ber
module, and
BerObject::to_vec
- [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).
See CHANGELOG.md
, and UPGRADING.md
for instructions for upgrading major versions.
Licensed under either of
- Apache License, Version 2.0 (LICENSE-APACHE or http://www.apache.org/licenses/LICENSE-2.0)
- MIT license (LICENSE-MIT or http://opensource.org/licenses/MIT)
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.