1<!-- cargo-sync-readme start --> 2 3[](./LICENSE-MIT) 4[](./LICENSE-APACHE) 5[](https://docs.rs/der-parser) 6[](https://crates.io/crates/der-parser) 7[](https://crates.io/crates/der-parser) 8[](https://deps.rs/crate/der-parser/5.0.1) 9[](https://github.com/rusticata/der-parser/actions) 10[](#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