Welcome to asn1_der 🎉
This crate provides a basic no_std-compatible, no-panic and 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 crate and offers slice-based object views to avoid
allocations and unnecessary copies.
use asn1_der::{
DerObject,
typed::{ DerEncodable, DerDecodable }
};
fn main() {
/// 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 number");
assert_eq!(number, 7);
// Encode a new `u8`
let mut encoded_number = Vec::new();
7u8.encode(&mut encoded_number).expect("Failed to encode number");
}For the (de-)serialization of structs and similar via derive, see
serde_asn1_der.
There are also some direct DerDecodable/DerDecodable implementations for native Rust type
equivalents:
- The ASN.1-
BOOLEANtype as Rust-bool - The ASN.1-
INTEGERtype as Rust-[u8,u16,u32,u64,u128,usize] - The ASN.1-
NULLtype as either()orOption::None(which allows the encoding of optionals) - The ASN.1-
OctetStringtype asVec<u8> - The ASN.1-
SEQUENCEtype asSequenceVec(Vec<T>) - The ASN.1-
UTF8Stringtype asString
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.
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_panicand will be omitted ifno_panicis 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>)orString - During error propagation
If the crate is compiled without
stdenabled, 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 customSinkimplementation). - When writing to a dynamically allocating sink (e.g.
-
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
abortor similar: Since calls toabortor similar do not trigger stack unwinding, they can also no be detected byno_panic. This also means thatno_panicdoes not work for builds that usepanic = "abort"in their config.This crate by itself does never call
abortdirectly.
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 (
propagateis a no-op if compiled withno_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>andimpl DerEncodable for Vec<u8>) - The native Sequence type wrapper
SequenceVecsince it is based uponVec - The native Utf8String type based upon
String(impl<'a> DerDecodable<'a> for Stringandimpl DerEncodable for String)
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, zero-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).
Since version 0.7.0, the asn1_der_derive-crates has been deprecated in favor of
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 😊