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
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
//! [![docs.rs](https://docs.rs/asn1_der/badge.svg)](https://docs.rs/asn1_der)
//! [![License BSD-2-Clause](https://img.shields.io/badge/License-BSD--2--Clause-blue.svg)](https://opensource.org/licenses/BSD-2-Clause)
//! [![License MIT](https://img.shields.io/badge/License-MIT-blue.svg)](https://opensource.org/licenses/MIT)
//! [![crates.io](https://img.shields.io/crates/v/asn1_der.svg)](https://crates.io/crates/asn1_der)
//! [![Download numbers](https://img.shields.io/crates/d/asn1_der.svg)](https://crates.io/crates/asn1_der)
//! [![Travis CI](https://travis-ci.org/KizzyCode/asn1_der-rust.svg?branch=master)](https://travis-ci.org/KizzyCode/asn1_der-rust)
//! [![AppVeyor CI](https://ci.appveyor.com/api/projects/status/github/KizzyCode/asn1_der-rust?svg=true)](https://ci.appveyor.com/project/KizzyCode/asn1-der-rust)
//! [![dependency status](https://deps.rs/crate/asn1_der/0.7.0/status.svg)](https://deps.rs/crate/asn1_der/0.7.0)
//!
//! # asn1_der
//! Welcome to `asn1_der` 🎉
//!
//! This crate provides a basic `no_std`-compatible, [no-panic](#no-panic) and
//! [zero-copy](#zero-copy) DER implementation. It is designed to be reliable and reasonable fast
//! without getting too large or sacrificing too much comfort. To achieve this, `asn1_der` makes
//! extensive use of the [`no-panic`](https://crates.io/crates/no-panic) crate and offers
//! slice-based object views to avoid allocations and unnecessary copies.
//!
//!
//! ## Example
//! ```rust
//! # #[cfg(all(feature = "native_types", not(any(feature = "no_std", feature = "no_panic"))))] {
//! use asn1_der::{
//!     DerObject,
//!     typed::{ DerEncodable, DerDecodable }
//! };
//!
//! /// An ASN.1-DER encoded integer `7`
//! const INT7: &'static[u8] = b"\x02\x01\x07";
//!
//! // Decode an arbitrary DER object
//! let object = DerObject::decode(INT7).expect("Failed to decode object");
//!
//! // Encode an arbitrary DER object
//! let mut encoded_object = Vec::new();
//! object.encode(&mut encoded_object).expect("Failed to encode object");
//!
//! // Decode a `u8`
//! let number = u8::decode(INT7).expect("Failed to decode string");
//! assert_eq!(number, 7);
//!
//! // Encode a new `u8`
//! let mut encoded_number = Vec::new();
//! 7u8.encode(&mut encoded_number).expect("Failed to encode string");
//! # }
//! ```
//!
//! For the (de-)serialization of structs and similar via `derive`, see
//! [`serde_asn1_der`](https://crates.io/crates/serde_asn1_der).
//!
//!
//! ## Typed Implementations
//! There are also some direct `DerDecodable`/`DerDecodable` implementations for native Rust type
//! equivalents:
//!  - The ASN.1-`BOOLEAN` type as Rust-`bool`
//!  - The ASN.1-`INTEGER` type as Rust-[`u8`, `u16`, `u32`, `u64`, `u128`, `usize`]
//!  - The ASN.1-`NULL` type as either `()` or `Option::None` (which allows the encoding of
//!    optionals)
//!  - The ASN.1-`OctetString` type as `Vec<u8>`
//!  - The ASN.1-`SEQUENCE` type as `SequenceVec(Vec<T>)`
//!  - The ASN.1-`UTF8String` type as `String`
//!
//!
//! ## No-Panic
//! `asn1_der` is designed to be as panic-free as possible. To ensure that, nearly every function is
//! attributed with `#[no_panic]`, which forces the compiler to prove that a function cannot panic
//! in the given circumstances. However since `no_panic` can cause a lot of false-positives, it is
//! currently only used by the CI-tests and disabled by default in normal builds. If you want to use
//! this crate with `no_panic` enabled, you can do so by specifying the `no_panic` feature.
//!
//! ### What No-Panic Does Not Cover
//! It is important to know that `no_panic` is no silver bullet and does not help against certain
//! kinds of errors that can also happen in this crate. This especially includes:
//!  - Dynamic memory allocation errors: Since it is not possible to predict memory allocation
//!    errors, everything that requires dynamic memory allocation is mutually exclusive to
//!    `no_panic` and will be omitted if `no_panic` is enabled.
//!
//!    This crate might allocate memory in the following circumstances:
//!     - When writing to a dynamically allocating sink (e.g. `Vec<u8>`, `VecBacking(Vec<u8>)`)
//!     - When decoding a native owned type such as `Vec<u8>`, `SequenceVec(Vec<T>)` or `String`
//!     - During error propagation
//!
//!    If the crate is compiled with `no_std` enabled, it does performy any dynamic memory
//!    allocation directly by itself – however for foreign implementations passed to this crate may
//!    still allocate memory and fail (e.g. a custom `Sink` implementation).
//!
//!  - Stack overflows: Since the stack size is not necessarily known during compile time, it is not
//!    possible to predict stack overflow errors e.g. caused by recursion.
//!  - Calls to `abort` or similar: Since calls to `abort` or similar do not trigger stack
//!    unwinding, they can also no be detected by `no_panic`. __This also means that `no_panic` does
//!    not work for builds that use `panic = "abort"` in their config.__
//!
//!    This crate by itself does never call `abort` directly.
//!
//! Due to the limitations described above, the following functions are mutually exclusive to
//! `no_panic` and disabled if `no_panic` is set:
//!  - Error stacking/propagation (`propagate` is a no-op if compiled with `no_panic`)
//!  - The sink implementation for a byte vector (`impl Sink for Vec<u8>`)
//!  - The `VecBacking(Vec<u8>)` type
//!  - The native OctetString type which uses `Vec<u8>` (`impl<'a> DerDecodable<'a> for Vec<u8>` and
//!    `impl DerEncodable for Vec<u8>`)
//!  - The native Sequence type wrapper `SequenceVec` since it is based upon `Vec`
//!  - The native Utf8String type based upon `String` (`impl<'a> DerDecodable<'a> for String` and
//!    `impl DerEncodable for String`)
//!
//!
//! ## Zero-Copy
//! The crate is designed to be as much zero-copy as possible. In fact this means that the
//! `DerObject` type and all typed views are zero-copy views over the underlying slice. Of course,
//! ero-copy is not always reasonable: The `new`-constructors are not zero-copy because they
//! construct a new object into a sink and the native type implementations are not zero-copy because
//! they are either `Copy`-types (e.g. `u128`) or owned (e.g. `String`).
//!
//!
//! ## What happened to `asn1_der_derive`?
//! Since version 0.7.0, the `asn1_der_derive`-crates has been deprecated in favor of
//! [`serde_asn1_der`](https://crates.io/crates/serde_asn1_der). If you have a specific use-case why
//! you cannot use `serde`, let me know; it's probably not that hard to revive `asn1_der_derive` 😊

// Forbid warnings during tests
#![cfg_attr(test, forbid(warnings))]

// Handle no_std if set
#![cfg_attr(feature = "no_std", no_std)]
#[cfg(not(feature = "no_std"))]
	use std as rust;
#[cfg(feature = "no_std")]
	use core as rust;


#[macro_use]
#[doc(hidden)]
pub mod error;
mod data;
#[doc(hidden)]
pub mod der;
#[cfg(feature = "native_types")]
	pub mod typed;


// Reexport common types
pub use crate::{
	der::DerObject,
	data::{ Source, CountingSource, CopyingSource, Sink, SliceSink },
	error::{ Asn1DerError, Asn1DerErrorVariant, ErrorChain }
};
#[cfg(not(any(feature = "no_std", feature = "no_panic")))]
	pub use crate::data::VecBacking;