1# der-parser
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[![Build Status](https://travis-ci.org/rusticata/der-parser.svg?branch=master)](https://travis-ci.org/rusticata/der-parser)
6[![Crates.io Version](https://img.shields.io/crates/v/der-parser.svg)](https://crates.io/crates/der-parser)
7
8<!-- cargo-sync-readme start -->
9
10# BER/DER Parser
11
12A parser for Basic Encoding Rules (BER [[X.690]]) and Distinguished Encoding Rules(DER
13[[X.690]]), implemented with the [nom](https://github.com/Geal/nom) parser combinator
14framework.
15
16The code is available on [Github](https://github.com/rusticata/der-parser)
17and is part of the [Rusticata](https://github.com/rusticata) project.
18
19# DER parser design
20
21There are two different approaches for parsing DER objects: reading the objects recursively as
22long as the tags are known, or specifying a description of the expected objects (generally from
23the [ASN.1][X.680] description).
24
25The first parsing method can be done using the [`parse_ber`](ber/fn.parse_ber.html) and
26[`parse_der`](der/fn.parse_der.html) methods.
27However, it cannot fully parse all objects, especially those containing IMPLICIT, OPTIONAL, or
28DEFINED BY items.
29
30```rust
31use der_parser::parse_der;
32
33let bytes = [ 0x30, 0x0a,
34              0x02, 0x03, 0x01, 0x00, 0x01,
35              0x02, 0x03, 0x01, 0x00, 0x00,
36];
37
38let parsed = parse_der(&bytes);
39```
40
41The second (and preferred) parsing method is to specify the expected objects recursively. The
42following macros can be used:
43[`parse_der_sequence_defined`](macro.parse_der_sequence_defined.html) and similar functions,
44[`parse_der_struct`](macro.parse_der_struct.html), etc.
45
46For example, to read a sequence containing two integers:
47
48```rust
49use der_parser::ber::*;
50use der_parser::error::BerResult;
51
52fn localparse_seq(i:&[u8]) -> BerResult {
53    parse_der_sequence_defined!(i,
54        parse_ber_integer >>
55        parse_ber_integer
56    )
57}
58
59let bytes = [ 0x30, 0x0a,
60              0x02, 0x03, 0x01, 0x00, 0x01,
61              0x02, 0x03, 0x01, 0x00, 0x00,
62];
63let parsed = localparse_seq(&bytes);
64```
65
66All functions return a [`BerResult`](error/type.BerResult.html) object: the parsed
67[`BerObject`](ber/struct.BerObject.html), an `Incomplete` value, or an error.
68
69Note that this type is also a `Result`, so usual functions (`map`, `unwrap` etc.) are available.
70
71# Notes
72
73- The DER constraints are verified if using `parse_der`.
74- `BerObject` and `DerObject` are the same objects (type alias). The only difference is the
75  verification of constraints *during parsing*.
76- DER integers can be of any size, so it is not possible to store them as simple integers (they
77are stored as raw bytes). To get a simple value, use
78[`BerObject::as_u32`](ber/struct.BerObject.html#method.as_u32) (knowning that this method will
79return an error if the integer is too large), [`BerObject::as_u64`](ber/struct.BerObject.html#method.as_u64),
80or use the `bigint` feature of this crate and use
81[`BerObject::as_bigint`](ber/struct.BerObject.html#method.as_bigint).
82
83# References
84
85- [[X.680]] Abstract Syntax Notation One (ASN.1): Specification of basic notation.
86- [[X.690]] ASN.1 encoding rules: Specification of Basic Encoding Rules (BER), Canonical
87  Encoding Rules (CER) and Distinguished Encoding Rules (DER).
88
89[X.680]: http://www.itu.int/rec/T-REC-X.680/en "Abstract Syntax Notation One (ASN.1):
90  Specification of basic notation."
91[X.690]: https://www.itu.int/rec/T-REC-X.690/en "ASN.1 encoding rules: Specification of
92  Basic Encoding Rules (BER), Canonical Encoding Rules (CER) and Distinguished Encoding Rules
93  (DER)."
94
95<!-- cargo-sync-readme end -->
96
97## Changes
98
99### 3.0.4
100
101- Use cloned instead of copied to support older rust compiler (1.33)
102- Fix new clippy warnings (rust 1.40)
103
104### 3.0.3
105
106- Make the pretty-printer function public
107- Fix DER datestring sanity check
108- CI
109  - add rusfmt check
110  - add cargo clippy
111
112### 3.0.2
113
114- Add `parse_ber_u32` and `parse_ber_u64` functions
115- Fix typo in description
116
117### 3.0.1
118
119- Add crate `BerResult` and `DerResult` types
120- Use crate result types, remove uneeded imports
121  - Crates using `der-parser` do not need to import `nom` or `rusticata-macros` anymore
122  - Result types are aliases, so API is unchanged
123
124### 3.0.0
125
126- Upgrade to nom 5 (breaks API)
127- New error types, now all functions use `BerError`
128
129### 2.1.0
130
131- Handle BER/DER tags that are longer than one byte.
132- Set edition to 2018
133
134### 2.0.2
135
136- Revert 2.0.1 release, breaks API
137
138### 2.0.1
139
140- Handle BER/DER tags that are longer than one byte.
141
142### 2.0.0
143
144- Refactor code, split BER and DER, check DER constraints
145- Add recursion limit for sequences and sets
146- Rustfmt
147- Documentation
148- Remove unused function `ber_read_element_content`
149
150### 1.1.1
151
152- Fix OID parsing, and add support for relative OIDs
153- Add FromStr trait for Oid
154
155### 1.1.0
156
157- Use num-bigint over num and upgrade to 0.2
158
159### 1.0.0
160
161- Upgrade to nom 4
162
163### 0.5.5
164
165- Add functions `parse_der_u32` and `parse_der_u64` to quickly parse integers
166- Remove `Oid::from_vec`, `Oid::from` does the same
167- Enforce constraints on DER booleans
168
169### 0.5.4
170
171- Add `BitStringObject` to wrap BitString objects
172- Mark constructed BitStrings as unsupported
173- Do not try to parse application-specific data in `parse_der`
174
175### 0.5.3
176
177- Add function `DerObject::as_u64`
178- Add function `DerObject::as_oid_val`
179- Add `parse_der_struct!` variant to check tag
180
181### 0.5.2
182
183- Add functions to test object class and primitive/constructed state
184- Add macro `parse_der_application!`
185- Add macro `parse_der_tagged!` to parse `[x] EXPLICIT` or `[x] IMPLICIT` tagged values
186
187### 0.5.1
188
189- Add type GeneralString
190- Add macro `parse_der_struct!`
191
192### 0.5.0
193
194- Allow use of crate without extra use statements
195- Use constants for u32 errors instead of magical numbers
196- Rename `tag_of_der_content()` to `DerObjectContent::tag`
197- Rename DerElementxxx structs to have a consistent naming scheme
198- Add documentation for parsing DER sequences and sets, and fix wrong return type for sets
199- Fix a lot of clippy warnings
200- QA: add pragma rules (disable unsafe code, unstable features etc.)
201- More documentation
202- Switch license to MIT + APLv2
203
204### 0.4.4
205
206- Add macro parse_der_defined_m, to parse a defined sequence or set
207  This macro differs from `parse_der_defined` because it allows using macros
208- Rename `DerObject::new_int` to `DerObject::from_int_slice`
209- Rename `Oid::to_hex` to `Oid::to_string`
210- Document more functions
211
212### 0.4.1
213
214- Add new feature 'bigint' to export DER integers
215- OID is now a specific type
216- Add new types T61String and BmpString
217- Fix wrong expected tag in parse_der_set_of
218
219### 0.4.0
220
221- Der Integers are now represented as slices (byte arrays) since they can be larger than u64.
222
223## License
224
225Licensed under either of
226
227 * Apache License, Version 2.0
228   ([LICENSE-APACHE](LICENSE-APACHE) or http://www.apache.org/licenses/LICENSE-2.0)
229 * MIT license
230   ([LICENSE-MIT](LICENSE-MIT) or http://opensource.org/licenses/MIT)
231
232at your option.
233
234## Contribution
235
236Unless you explicitly state otherwise, any contribution intentionally submitted
237for inclusion in the work by you, as defined in the Apache-2.0 license, shall be
238dual licensed as above, without any additional terms or conditions.
239