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)." #![deny(/*missing_docs,*/unsafe_code, unstable_features, unused_import_braces, unused_qualifications)] #[macro_use] extern crate nom; #[macro_use] extern crate rusticata_macros; #[macro_use] mod macros; pub mod ber; pub mod der; pub mod error; pub mod oid; // compatibility: re-export at crate root pub use ber::parse_ber; pub use der::parse_der; #[cfg(feature = "bigint")] extern crate num_bigint;