1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
//! # BER/DER Parser
//!
//! A parser for Basic Encoding Rules (BER [[X.690]]) and Distinguished Encoding Rules(DER
//! [[X.690]]), implemented with the [nom](https://github.com/Geal/nom) parser combinator
//! framework.
//!
//! The code is available on [Github](https://github.com/rusticata/der-parser)
//! and is part of the [Rusticata](https://github.com/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][X.680] description).
//!
//! The first parsing method can be done using the [`parse_ber`](ber/fn.parse_ber.html) and
//! [`parse_der`](der/fn.parse_der.html) methods.
//! However, it cannot fully parse all objects, especially those containing IMPLICIT, OPTIONAL, or
//! DEFINED BY items.
//!
//! ```rust
//! # #[macro_use] extern crate der_parser;
//! use der_parser::parse_der;
//!
//! # fn main() {
//! 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`](macro.parse_der_sequence_defined.html) and similar functions,
//! [`parse_der_struct`](macro.parse_der_struct.html), etc.
//!
//! For example, to read a sequence containing two integers:
//!
//! ```rust
//! # #[macro_use] extern crate nom;
//! # #[macro_use] extern crate rusticata_macros;
//! # #[macro_use] extern crate der_parser;
//! use der_parser::ber::*;
//! use nom::{IResult,Err,ErrorKind};
//!
//! # fn main() {
//! fn localparse_seq(i:&[u8]) -> IResult<&[u8],BerObject> {
//! 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 an `IResult` object from `nom`: the parsed
//! [`BerObject`](ber/struct.BerObject.html), an `Incomplete` value, or an error.
//!
//! # Notes
//!
//! - 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`](ber/struct.BerObject.html#method.as_u32) (knowning that this method will
//! return an error if the integer is too large), [`BerObject::as_u64`](ber/struct.BerObject.html#method.as_u64),
//! or use the `bigint` feature of this crate and use
//! [`BerObject::as_bigint`](ber/struct.BerObject.html#method.as_bigint).
//!
//! # References
//!
//! - [[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).
//!
//! [X.680]: http://www.itu.int/rec/T-REC-X.680/en "Abstract Syntax Notation One (ASN.1):
//! Specification of basic notation."
//! [X.690]: https://www.itu.int/rec/T-REC-X.690/en "ASN.1 encoding rules: Specification of
//! Basic Encoding Rules (BER), Canonical Encoding Rules (CER) and Distinguished Encoding Rules
//! (DER)."
extern crate nom;
extern crate rusticata_macros;
// compatibility: re-export at crate root
pub use parse_ber;
pub use parse_der;
extern crate num_bigint;