• Home
Name Date Size #Lines LOC

..--

src/03-May-2024-6,5073,355

tests/03-May-2024-2,0851,897

.cargo_vcs_info.jsonD03-May-202474 65

.gitignoreD03-May-202425 43

Android.bpD03-May-20241.9 KiB6157

CHANGELOG.mdD03-May-20249.2 KiB314215

Cargo.tomlD03-May-20241.8 KiB6655

Cargo.toml.origD03-May-20241.2 KiB5548

LICENSED03-May-202410.6 KiB202169

LICENSE-APACHED03-May-202410.6 KiB202169

LICENSE-MITD03-May-20241 KiB2622

METADATAD03-May-2024385 2019

MODULE_LICENSE_APACHE2D03-May-20240

OWNERSD03-May-202440 21

README.mdD03-May-202410 KiB245172

TEST_MAPPINGD03-May-2024525 3130

UPGRADING.mdD03-May-20244.1 KiB10272

cargo2android.jsonD03-May-202463 55

README.md

1<!-- cargo-sync-readme start -->
2
3[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](./LICENSE-MIT)
4[![Apache License 2.0](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](./LICENSE-APACHE)
5[![docs.rs](https://docs.rs/der-parser/badge.svg)](https://docs.rs/der-parser)
6[![crates.io](https://img.shields.io/crates/v/der-parser.svg)](https://crates.io/crates/der-parser)
7[![Download numbers](https://img.shields.io/crates/d/der-parser.svg)](https://crates.io/crates/der-parser)
8[![dependency status](https://deps.rs/crate/der-parser/5.0.0/status.svg)](https://deps.rs/crate/der-parser/5.0.1)
9[![Github CI](https://github.com/rusticata/der-parser/workflows/Continuous%20integration/badge.svg)](https://github.com/rusticata/der-parser/actions)
10[![Minimum rustc version](https://img.shields.io/badge/rustc-1.48.0+-lightgray.svg)](#rust-version-requirements)
11
12# BER/DER Parser
13
14A parser for Basic Encoding Rules (BER [[X.690]]) and Distinguished Encoding Rules(DER
15[[X.690]]), implemented with the [nom](https://github.com/Geal/nom) parser combinator
16framework.
17
18It is written in pure Rust, fast, and makes extensive use of zero-copy. A lot of care is taken
19to ensure security and safety of this crate, including design (recursion limit, defensive
20programming), tests, and fuzzing. It also aims to be panic-free.
21
22Historically, this parser was intended for DER only, and BER support was added later. This may
23still reflect on some naming schemes, but has no other consequence: the `BerObject` and
24`DerObject` used in this crate are type aliases, so all functions are compatible.
25
26DER parsing functions have additional constraints verification, however.
27
28Serialization has also been added (see [Serialization](#serialization) )
29
30The code is available on [Github](https://github.com/rusticata/der-parser)
31and is part of the [Rusticata](https://github.com/rusticata) project.
32
33# BER/DER parsers
34
35BER stands for Basic Encoding Rules, and is defined in [X.690]. It defines a set of rules to
36encode and decode ASN.1 objects in binary.
37
38[X.690] also defines Distinguished Encoding Rules (DER), which is BER with added rules to
39ensure canonical and unequivocal binary representation of objects.
40
41The choice of which one to use is usually guided by the speficication of the data format based
42on BER or DER: for example, X.509 uses DER as encoding representation.
43
44See the related modules for object definitions, functions, and example:
45- [`ber`]: Basic Encoding Rules
46- [`der`]: Distinguished Encoding Rules
47
48## Examples
49
50Parse two BER integers (see [BER/DER Integers](#berder-integers)):
51
52```rust
53use der_parser::ber::parse_ber_integer;
54
55let bytes = [ 0x02, 0x03, 0x01, 0x00, 0x01,
56              0x02, 0x03, 0x01, 0x00, 0x00,
57];
58
59let (rem, obj1) = parse_ber_integer(&bytes).expect("parsing failed");
60let (rem, obj2) = parse_ber_integer(&bytes).expect("parsing failed");
61```
62
63Parse a DER sequence of integers:
64
65```rust
66use der_parser::der::{parse_der_integer, parse_der_sequence_of};
67
68let bytes = [ 0x30, 0x0a,
69              0x02, 0x03, 0x01, 0x00, 0x01,
70              0x02, 0x03, 0x01, 0x00, 0x00,
71];
72
73let (rem, seq) = parse_der_sequence_of(parse_der_integer)(&bytes)
74                    .expect("parsing failed");
75```
76
77Note: all parsing functions return the remaining (unparsed) bytes and the parsed object, or an
78error.
79
80# DER parser design
81
82Parsing functions are inspired from `nom`, and follow the same interface. The most common
83return type is [`BerResult`](https://docs.rs/der-parser/latest/der_parser/error/type.BerResult.html), that stores the remaining bytes and
84parsed [`BerObject`](https://docs.rs/der-parser/latest/der_parser/ber/struct.BerObject.html), or an error. Reading the nom documentation may
85help understanding how to write parsers and use the output.
86
87There are two different approaches for parsing DER objects: reading the objects recursively as
88long as the tags are known, or specifying a description of the expected objects (generally from
89the [ASN.1][X.680] description).
90
91The first parsing method can be done using the [`parse_ber`](https://docs.rs/der-parser/latest/der_parser/ber/fn.parse_ber.html) and
92[`parse_der`](https://docs.rs/der-parser/latest/der_parser/der/fn.parse_der.html) methods.
93It is useful when decoding an arbitrary DER object.
94However, it cannot fully parse all objects, especially those containing IMPLICIT, OPTIONAL, or
95DEFINED BY items.
96
97```rust
98use der_parser::parse_der;
99
100let bytes = [ 0x30, 0x0a,
101              0x02, 0x03, 0x01, 0x00, 0x01,
102              0x02, 0x03, 0x01, 0x00, 0x00,
103];
104
105let parsed = parse_der(&bytes);
106```
107
108The second (and preferred) parsing method is to specify the expected objects recursively. The
109following functions can be used:
110- [`parse_ber_sequence_defined`](https://docs.rs/der-parser/latest/der_parser/ber/fn.parse_ber_sequence_defined.html) and similar functions
111for sequences and sets variants
112- [`parse_ber_tagged_explicit`](https://docs.rs/der-parser/latest/der_parser/ber/fn.parse_ber_tagged_explicit.html) for tagged explicit
113- [`parse_ber_tagged_implicit`](https://docs.rs/der-parser/latest/der_parser/ber/fn.parse_ber_tagged_implicit.html) for tagged implicit
114- [`parse_ber_container`](https://docs.rs/der-parser/latest/der_parser/ber/fn.parse_ber_container.html) for generic parsing, etc.
115- DER objects use the `_der_` variants
116
117For example, to read a BER sequence containing two integers:
118
119```rust
120use der_parser::ber::*;
121use der_parser::error::BerResult;
122
123fn localparse_seq(i:&[u8]) -> BerResult {
124    parse_ber_sequence_defined(|data| {
125        let (rem, a) = parse_ber_integer(data)?;
126        let (rem, b) = parse_ber_integer(rem)?;
127        Ok((rem, vec![a, b]))
128    })(i)
129}
130
131let bytes = [ 0x30, 0x0a,
132              0x02, 0x03, 0x01, 0x00, 0x01,
133              0x02, 0x03, 0x01, 0x00, 0x00,
134];
135
136let (_, parsed) = localparse_seq(&bytes).expect("parsing failed");
137
138assert_eq!(parsed[0].as_u64(), Ok(65537));
139assert_eq!(parsed[1].as_u64(), Ok(65536));
140```
141
142All functions return a [`BerResult`](https://docs.rs/der-parser/latest/der_parser/error/type.BerResult.html) object: the parsed
143[`BerObject`](https://docs.rs/der-parser/latest/der_parser/ber/struct.BerObject.html), an `Incomplete` value, or an error.
144
145Note that this type is also a `Result`, so usual functions (`map`, `unwrap` etc.) are available.
146
147# Notes
148
149## BER/DER Integers
150
151DER integers can be of any size, so it is not possible to store them as simple integers (they
152are stored as raw bytes).
153
154Note that, by default, BER/DER integers are signed. Functions are provided to request reading
155unsigned values, but they will fail if the integer value is negative.
156
157To get the integer value for all possible integer sign and size, use
158[`BerObject::as_bigint`](https://docs.rs/der-parser/latest/der_parser/ber/struct.BerObject.html#method.as_bigint)) (requires the `bigint` feature).
159
160To get a simple value expected to be in a known range, use methods like
161[`BerObject::as_i32`](ber/struct.BerObject.html#method.as_i32)) and
162[`BerObject::as_i64`](ber/struct.BerObject.html#method.as_i64) (or the unsigned versions
163[`BerObject::as_u32`](ber/struct.BerObject.html#method.as_u32) and
164[`BerObject::as_u64`](ber/struct.BerObject.html#method.as_u64)
165),
166which will return the value, or an error if the integer is too large (or is negative).
167
168```rust
169use der_parser::ber::*;
170
171let data = &[0x02, 0x03, 0x01, 0x00, 0x01];
172
173let (_, object) = parse_ber_integer(data).expect("parsing failed");
174assert_eq!(object.as_u64(), Ok(65537));
175
176#[cfg(feature = "bigint")]
177assert_eq!(object.as_bigint(), Ok(65537.into()))
178```
179
180Access to the raw value is possible using the `as_slice` method.
181
182## Parsers, combinators, macros
183
184Some parsing tools (for ex for tagged objects) are available in different forms:
185- parsers: (regular) functions that takes input and create an object
186- combinators: functions that takes parsers (or combinators) as input, and return a function
187  (usually, the parser). They are used (combined) as building blocks to create more complex
188  parsers.
189- macros: these are generally previous (historic) versions of parsers, kept for compatibility.
190  They can sometime reduce the amount of code to write, but are hard to debug.
191  Parsers should be preferred when possible.
192
193## Misc Notes
194
195- The DER constraints are verified if using `parse_der`.
196- `BerObject` and `DerObject` are the same objects (type alias). The only difference is the
197  verification of constraints *during parsing*.
198
199## Rust version requirements
200
201The 6.0 series of `der-parser` requires **Rustc version 1.48 or greater**, based on nom 7
202dependencies.
203
204# Serialization
205
206Support for encoding BER/DER objects is currently being tested and can be used by activating the `serialize` feature.
207Note that current status is **experimental**.
208
209See the `ber_encode_*` functions in the [`ber`](https://docs.rs/der-parser/latest/der_parser/ber/index.html) module, and
210[`BerObject::to_vec`](https://docs.rs/der-parser/latest/der_parser/ber/struct.BerObject.html#method.to_vec)
211
212# References
213
214- [[X.680]] Abstract Syntax Notation One (ASN.1): Specification of basic notation.
215- [[X.690]] ASN.1 encoding rules: Specification of Basic Encoding Rules (BER), Canonical
216  Encoding Rules (CER) and Distinguished Encoding Rules (DER).
217
218[X.680]: http://www.itu.int/rec/T-REC-X.680/en "Abstract Syntax Notation One (ASN.1):
219  Specification of basic notation."
220[X.690]: https://www.itu.int/rec/T-REC-X.690/en "ASN.1 encoding rules: Specification of
221  Basic Encoding Rules (BER), Canonical Encoding Rules (CER) and Distinguished Encoding Rules
222  (DER)."
223<!-- cargo-sync-readme end -->
224
225## Changes
226
227See `CHANGELOG.md`, and `UPGRADING.md` for instructions for upgrading major versions.
228
229## License
230
231Licensed under either of
232
233 * Apache License, Version 2.0
234   ([LICENSE-APACHE](LICENSE-APACHE) or http://www.apache.org/licenses/LICENSE-2.0)
235 * MIT license
236   ([LICENSE-MIT](LICENSE-MIT) or http://opensource.org/licenses/MIT)
237
238at your option.
239
240## Contribution
241
242Unless you explicitly state otherwise, any contribution intentionally submitted
243for inclusion in the work by you, as defined in the Apache-2.0 license, shall be
244dual licensed as above, without any additional terms or conditions.
245