Expand description
§BER/DER Parsers/Encoders
A set of parsers/encoders for Basic Encoding Rules (BER [X.690]) and Distinguished Encoding Rules(DER [X.690]) formats, implemented with the nom parser combinator framework.
It is written in pure Rust, fast, and makes extensive use of zero-copy. A lot of care is taken to ensure security and safety of this crate, including design (recursion limit, defensive programming), tests, and fuzzing. It also aims to be panic-free.
This crate is a rewrite of der-parser to propose a more data-oriented API, and add generalized support for serialization.
Many ideas were initially borrowed from the crypto/utils/der crate (like
the Any/TryFrom/FromDer mechanism), adapted and merged into a generalized BER/DER crate.
Credits (and many thanks) go to Tony Arcieri for writing the original crate.
§BER/DER parsers
BER stands for Basic Encoding Rules, and is defined in [X.690]. It defines a set of rules to encode and decode ASN.1 [X.680] objects in binary.
[X.690] also defines Distinguished Encoding Rules (DER), which is BER with added rules to ensure canonical and unequivocal binary representation of objects.
The choice of which one to use is usually guided by the specification of the data format based on BER or DER: for example, X.509 uses DER as encoding representation.
The main traits for parsing are the BerParser and
DerParser traits.
These traits provide methods to parse binary input wrapped in
Input, and return either the remaining (unparsed) bytes and the
parsed object, or an error.
The Input types is a simple wrapper around &[u8] to keep information on data span. This is
especially useful to print information or to debug parsing errors.
This crates also provides the FromBer and
FromDer traits for parsing (working on slices).
The parsers follow the interface from nom, and the ParseResult object is a specialized version
of nom::IResult. This means that most nom combinators (map, many0, etc.) can be used in
combination to objects and methods from this crate. Reading the nom documentation may
help understanding how to write and combine parsers and use the output.
Minimum Supported Rust Version: 1.65.0
no_std support: asn1-rs supports #[no_std] (with a requirement on alloc).
§Recipes
See doc::recipes and doc::derive for more examples and recipes.
See doc::debug for advice and tools to debug parsers.
§Examples
Parse 2 BER integers:
use asn1_rs::{Integer, FromBer};
let bytes = [ 0x02, 0x03, 0x01, 0x00, 0x01,
0x02, 0x03, 0x01, 0x00, 0x00,
];
let (rem, obj1) = Integer::from_ber(&bytes).expect("parsing failed");
let (rem, obj2) = Integer::from_ber(&bytes).expect("parsing failed");
assert_eq!(obj1, Integer::from_u32(65537));In the above example, the generic Integer type is used. This type can contain integers of any
size, but do not provide a simple API to manipulate the numbers.
In most cases, the integer either has a limit, or is expected to fit into a primitive type.
To get a simple value, just use the from_ber/from_der methods on the primitive types:
use asn1_rs::FromBer;
let bytes = [ 0x02, 0x03, 0x01, 0x00, 0x01,
0x02, 0x03, 0x01, 0x00, 0x00,
];
let (rem, obj1) = u32::from_ber(&bytes).expect("parsing failed");
let (rem, obj2) = u32::from_ber(&rem).expect("parsing failed");
assert_eq!(obj1, 65537);
assert_eq!(obj2, 65536);If the parsing succeeds, but the integer cannot fit into the expected type, the method will return
an IntegerTooLarge error.
§BER/DER encoders
BER/DER encoding is symmetrical to decoding, using the traits
ToBer and ToDer traits.
These traits provide methods to write encoded content to objects with the io::Write trait,
or return an allocated Vec<u8> with the encoded data.
If the serialization fails, an error is returned.
§Examples
Writing 2 BER integers:
use asn1_rs::{Integer, ToDer};
let mut writer = Vec::new();
let obj1 = Integer::from_u32(65537);
let obj2 = Integer::from_u32(65536);
let _ = obj1.write_der(&mut writer).expect("serialization failed");
let _ = obj2.write_der(&mut writer).expect("serialization failed");
let bytes = &[ 0x02, 0x03, 0x01, 0x00, 0x01,
0x02, 0x03, 0x01, 0x00, 0x00,
];
assert_eq!(&writer, bytes);Similarly to BerParser/DerParser, serialization methods are also implemented for primitive types:
use asn1_rs::ToDer;
let mut writer = Vec::new();
let _ = 65537.write_der(&mut writer).expect("serialization failed");
let _ = 65536.write_der(&mut writer).expect("serialization failed");
let bytes = &[ 0x02, 0x03, 0x01, 0x00, 0x01,
0x02, 0x03, 0x01, 0x00, 0x00,
];
assert_eq!(&writer, bytes);If the parsing succeeds, but the integer cannot fit into the expected type, the method will return
an IntegerTooLarge error.
§Custom derive attributes
To simplify the code needed to declare common/usual ASN.1 objects, custom derive attributes are provided.
For example, to derive a MyType SEQUENCE { a INTEGER }, declare a struct and add the Sequence attribute:
#[derive(Sequence)]
pub struct MyType {
a: u32,
}See doc::derive for documentation and examples.
§ASN.1 types mapping
When using types-based parsing, the usual method is to map the ASN.1 definition of types into asn1-rs (Rust) types, and call the matching trait methods on these types.
For generic (not types-based) parsing, other methods are available (but not shown in the following table).
The following table describes how to declare and use ASN.1 types in asn1-rs. Some types will have a lifetime, as they try to borrow the input and avoid useless copies.
| ASN.1 type | Example | `asn1-rs` type(s) |
|---|---|---|
| BIT STRING |
|
|
| BOOLEAN |
|
or |
| CHOICE |
|
|
| ENUMERATED |
|
Generic values:
Value is parsed as Derive attribute: |
| INTEGER |
|
If integer has known constraints (sign / max), native types can be used: |
| INTEGER |
|
Variable-length integer: |
| NULL |
|
or |
| OBJECT IDENTIFIER |
|
The |
| OCTET STRING |
|
To use a shared reference (zero-copy) on data: or, to use a Copy-on-Write (possible owned) type: |
| REAL |
|
or |
| RELATIVE-OID |
|
Relative object identifiers are also implemented using |
| UTF8String |
|
or the Copy-on-Write version: |
| Restricted Character Strings |
|
Copy-on-Write versions: Owned Versions: |
| Unrestricted Character Strings |
|
Not Supported |
| Time |
|
Owned versions: |
| Other Time representations |
|
Not Yet Supported |
| Sequence |
|
Use custom derive: Generic Versions: Fixed length version: Note: when parsing a tuple, all subtypes parsers must return the same type of error |
| SequenceOf |
|
Generic Version: Native types version: Fixed length version: |
| Set |
|
Use custom derive: Generic Versions: Generic Versions (requires ⓘ
|
| SetOf |
|
Generic Version: Native types versions (requires ⓘ
|
| Optional and default fields |
|
When parsing a single type: Using custom derive attribute for a |
| Tagged Explicit |
|
Using tagged types: Note: the error type has to be specified in the type declaration. or using the generic Note: |
| Tagged Implicit |
|
Using tagged types: Note: the error type has to be specified in the type declaration. or using the generic Note: |
| ANY |
Not strictly an ASN.1 type |
|
In all of the above examples, parsing and encoding functions can be called directly on the generated type. For example:
use asn1_rs::{BerParser, Boolean};
type MyType = Boolean;
let input = asn1_rs::Input::from(b"\x01\x01\xff");
let (rem, my_object) = MyType::parse_ber(input).unwrap();
// Note: you can also use Rust primitive types directly:
let input = asn1_rs::Input::from(b"\x01\x01\xff");
let (rem, my_object) = <bool>::parse_ber(input).unwrap();
§Changes
See CHANGELOG.md, and UPGRADING.md for instructions for upgrading major versions.
§References
Re-exports§
pub use crate::Error;pub use nom;pub use bitvec;pub use num_bigint;
Modules§
- doc
- Additional documentation: recipes, specific use cases and examples, etc.
Macros§
- impl_
toder_ from_ tober - Helper macro to implement
ToDerfor types where implementation is the same asToBer - int
- Helper macro to declare integers at compile-time
- oid
- Helper macro to declare integers at compile-time
Structs§
- ASN1
Date Time - Any
- The
Anyobject is not strictly an ASN.1 type, but holds a generic description of any object that could be encoded. - AnyIterator
- Iterator for constructed sub-objects contained in an ANY object
- AnySequence
- The
SEQUENCEobject is an ordered list of heteregeneous types. - AnySet
- The
SETobject is an unordered list of heteregeneous types. - BerClass
From IntError - BerError
- BerGeneric
Encoder - Encoder for generic objects
- BigInt
bigint - A big signed integer type.
- BigUint
bigint - A big unsigned integer type.
- BitString
- ASN.1
BITSTRINGtype - BmpString
- ASN.1
BMPSTRINGtype - Boolean
- ASN.1
BOOLEANtype - Constructed
- Encoder for constructed objects, with Definite length
- Constructed
Indefinite - Encoder for constructed objects, with Indefinite length
- Embedded
Pdv - EMBEDDED PDV ASN.1 Object
- EndOf
Content - End-of-contents octets
- Enumerated
- ASN.1
ENUMERATEDtype - General
String - ASN.1 restricted character string type (
GeneralString) - Generalized
Time - Graphic
String - ASN.1 restricted character string type (
GraphicString) - Header
- BER/DER object header (identifier and length)
- Ia5String
- ASN.1 restricted character string type (
Ia5String) - Indefinite
Vec - Wrapper for sequence, to force using Indefinite length when serializing
- Input
- BER/DER parser input type
- Integer
- ASN.1
INTEGERtype - Null
- ASN.1
NULLtype - Numeric
String - ASN.1 restricted character string type (
NumericString) - Object
Descriptor - ASN.1 restricted character string type (
ObjectDescriptor) - Octet
String - ASN.1
OCTETSTRINGtype - Oid
- Object ID (OID) representation which can be relative or non-relative.
- OptTagged
Parser - Helper object to parse TAGGED OPTIONAL types (explicit or implicit)
- Primitive
- Printable
String - ASN.1 restricted character string type (
PrintableString) - Sequence
- The
SEQUENCEobject is an ordered list of heteregeneous types. - Sequence
Iterator - An Iterator over binary data, parsing elements of type
T - Sequence
Iterator Input - Sequence
Of - The
SEQUENCE OFobject is an ordered list of homogeneous types. - Set
- The
SETobject is an unordered list of heteregeneous types. - SetOf
- The
SET OFobject is an unordered list of homogeneous types. - Tag
- BER/DER Tag as defined in X.680 section 8.4
- Tagged
Parser - Tagged
Parser Builder - A builder for parsing tagged values (
IMPLICITorEXPLICIT) - Tagged
Value - Helper object for creating
FromBer/FromDertypes for TAGGED OPTIONAL types - Teletex
String - ASN.1 restricted character string type (
TeletexString) - Universal
String - ASN.1
UniversalStringtype - UtcTime
- Utf8
String - ASN.1 restricted character string type (
Utf8String) - Videotex
String - ASN.1 restricted character string type (
VideotexString) - Visible
String - ASN.1 restricted character string type (
VisibleString)
Enums§
- ASN1
Time Zone - Class
- BER Object class of tag
- DerConstraint
- Error types for DER constraints
- Err
- The
Errenum indicates the parser was not successful - Error
- The error type for operations of the
FromBer,FromDer, and associated traits. - Explicit
- A type parameter for
EXPLICITtagged values. - Implicit
- A type parameter for
IMPLICITtagged values. - Inner
Error - The error type for operations of the
FromBer,FromDer, and associated traits. - Length
- BER Object Length
- Needed
- Contains information on needed data if a parser returned
Incomplete - OidParse
Error - An error for OID parsing functions.
- PdvIdentification
- Real
- ASN.1
REALtype - Serialize
Error - The error type for serialization operations of the
ToDertrait. - Sign
bigint - A
Signis aBigInt’s composing element.
Constants§
- MAX_
RECURSION - Default maximum recursion limit
Traits§
- Appendable
- AsTagged
Explicit - Helper trait for creating tagged EXPLICIT values
- AsTagged
Implicit - Helper trait for creating tagged IMPLICIT values
- BerChoice
- BerEncoder
- Common trait for BER encoders
- BerParser
- Base trait for BER object parsers
- Check
DerConstraints - Verification of DER constraints
- Choice
- DerAuto
Derive - Trait to automatically derive
FromDer - DerChoice
- DerParser
- Base trait for DER object parsers
- DynTagged
- Common trait for all tagged objects
- FromBer
- Base trait for BER object parsers
- FromDer
- Base trait for DER object parsers
- GetObject
Content - TagKind
- A type parameter for tagged values either
ExplicitorImplicit. - Tagged
- Test
Valid Charset - Base trait for BER string objects and character set validation
- ToBer
- Common trait for BER encoding functions
- ToDer
- Common trait for DER encoding functions
- ToStatic
- Common trait for objects that can be transformed to a
'staticversion ofself
Functions§
- ber_
get_ content - Read the content bytes matching length defined in
header(BER) - ber_
header_ length - Returns the length (in bytes) required for the full header (tag+length)
- ber_
length_ constructed_ items - Return the length (in bytes) required for a set of objects (BER)
- ber_
length_ length - Returns the length (in bytes) required for the given length
- ber_
tag_ length - Returns the length (in bytes) required for the given tag
- ber_
total_ length - Returns the total length (header+content) required for an object, given the input parameters
- der_
get_ content - Read the content bytes matching length defined in
header(BER) - der_
length_ constructed_ items - Return the length (in bytes) required for a set of objects (DER)
- from_
nom_ bererror - Flatten all
nom::Errvariants error into a single error type - from_
nom_ error - Flatten all
nom::Errvariants error into a single error type - parse_
der_ tagged_ explicit - parse_
der_ tagged_ explicit_ g - parse_
der_ tagged_ implicit - parse_
der_ tagged_ implicit_ g
Type Aliases§
- Application
Explicit - A helper object to parse
[APPLICATION n] EXPLICIT T - Application
Implicit - A helper object to parse
[APPLICATION n] IMPLICIT T - IResult
- Holds the result of parsing functions
- OptTagged
Explicit - A helper object to parse
[ n ] EXPLICIT T OPTIONAL - OptTagged
Implicit - A helper object to parse
[ n ] IMPLICIT T OPTIONAL - Parse
Result - Holds the result of BER/DER serialization functions
- Private
Explicit - A helper object to parse
[PRIVATE n] EXPLICIT T - Private
Implicit - A helper object to parse
[PRIVATE n] IMPLICIT T - Result
- A specialized
Resulttype for all operations from this crate. - Serialize
Result - Holds the result of BER/DER encoding functions
- SetIterator
- An Iterator over binary data, parsing elements of type
T - Tagged
Explicit - A helper object to parse
[ n ] EXPLICIT T - Tagged
Implicit - A helper object to parse
[ n ] IMPLICIT T
Derive Macros§
- Alias
- Create an ASN.1 type alias
- BerAlias
- BerAlias custom derive
- BerParser
Alias - BerParserAlias custom derive
- BerParser
Sequence - BerParserSequence custom derive
- BerParser
Set - BerParserSet custom derive
- BerSequence
- BerSequence custom derive
- BerSet
- BerSet custom derive
- Choice
- Derive parsers and encoders for an
enumrepresenting aCHOICE - DerAlias
- DerAlias custom derive
- DerParser
Alias - DerParserAlias custom derive
- DerParser
Sequence - DerParserSequence custom derive
- DerParser
Set - DerParserSet custom derive
- DerSequence
- DerSequence custom derive
- DerSet
- DerSet custom derive
- Enumerated
- Derive parsers and encoders for an
enumrepresenting anENUMERATED - Sequence
- Derive parsers and encoders for a
structrepresenting aSEQUENCE - Set
- Derive parsers and encoders for a
structrepresenting aSET - ToBer
Sequence - ToBerSequence custom derive
- ToBer
Set - ToBerSet custom derive
- ToDer
Sequence - ToDerSequence custom derive
- ToDer
Set - ToDerSet custom derive
- ToStatic
- ToStatic custom derive