[−][src]Crate der_parser
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.
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.
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.
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.
Notes
BER/DER Integers
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.
Misc Notes
- 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.
Serialization
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
References
Modules
ber | Basic Encoding Rules (BER) objects and parser |
der | Basic Encoding Rules (BER) objects and parser |
error | Error type for BER/DER parsers |
oid | Object ID (OID) representations. |
Macros
oid | Procedural macro to get encoded oids, see the oid module. |
parse_der_application | Parse an application DER element |
parse_der_optional | Parse an optional DER element |
parse_der_sequence_defined | Parse a defined sequence of DER elements |
parse_der_sequence_defined_m | Deprecated Parse a defined sequence of DER elements (macro version) |
parse_der_sequence_of | Parse a sequence of identical DER elements |
parse_der_set_defined | Parse a defined set of DER elements |
parse_der_set_defined_m | Deprecated Parse a defined set of DER elements |
parse_der_set_of | Parse a set of identical DER elements |
parse_der_struct | Parse a constructed DER element |
parse_der_tagged | Parse a tagged DER element |
Functions
parse_ber | Parse BER object recursively |
parse_der | Parse DER object recursively |