Expand description
This crate provides you with the ability to generate and parse ASN.1 encoded data. More precisely, it provides you with the ability to generate and parse data encoded with ASN.1’s DER (Distinguished Encoding Rules) encoding. It does not support BER (Basic Encoding Rules), CER (Canonical Encoding Rules), XER (XML Encoding Rules), CXER (Canonical XML Encoding Rules), or any other alphabet soup encodings – and it never will.
If you wanted to parse an ASN.1 structure like this:
Signature ::= SEQUENCE {
r INTEGER,
s INTEGER
}Then you’d write the following code:
let result: asn1::ParseResult<_> = asn1::parse(data, |d| {
return d.read_element::<asn1::Sequence>()?.parse(|d| {
let r = d.read_element::<u64>()?;
let s = d.read_element::<u64>()?;
return Ok((r, s));
})
});In general everything about parsing is driven by providing different type
parameters to Parser.read_element. Some types implement the
Asn1Readable trait directly on a basic type, as seen with u64 or
&[u8] (OCTET STRING), while others use wrapper types which simply
provide ASN.1 encoding and decoding for some other type (PrintableString
or UtcTime). There are also types such as Implicit and Explicit for
handling tagged values, Choice1, Choice2, and Choice3 available for
choices, and Option<T> for handling OPTIONAL values.
To serialize DER for the Sequence structure, you’d write the following:
let result = asn1::write(|w| {
w.write_element(&asn1::SequenceWriter::new(&|w| {
w.write_element(&r)?;
w.write_element(&s)?;
Ok(())
}))
});§Derive
When built with the derive feature (enabled by default), these can also
be expressed as Rust structs:
#[derive(asn1::Asn1Read, asn1::Asn1Write)]
struct Signature {
r: u64,
s: u64,
}
let sig = asn1::parse_single::<Signature>(data);
let result = asn1::write_single(&Signature{r, s});Fields may be marked as EXPLICIT or IMPLICIT either by struct members
having the types Explicit and Implicit or via the use of
#[explicit] and #[implicit] annotations:
#[derive(asn1::Asn1Read, asn1::Asn1Write)]
struct SomeSequence<'a> {
#[implicit(0)]
a: Option<&'a [u8]>,
#[explicit(1)]
b: Option<u64>,
}Fields can also be annotated with #[default(VALUE)] to indicate ASN.1
OPTIONAL DEFAULT values. In this case, the field’s type should be T,
and not Option<T>.
These derives may also be used with enums to generate CHOICE
implementations.
#[derive(asn1::Asn1Read, asn1::Asn1Write)]
enum Time {
UTCTime(asn1::UtcTime),
X509GeneralizedTime(asn1::X509GeneralizedTime)
}All variants must have a single un-named field.
§DEFINED BY
rust-asn1 also provides utilities for more easily handling the case of
ANY DEFINED BY in an ASN.1 structure. For example, given the following
ASN.1;
MySequence ::= SEQUENCE {
contentType OBJECT IDENTIFIER,
content ANY DEFINED BY contentType
}This can be represented by:
#[derive(asn1::Asn1Read, asn1::Asn1Write)]
struct MySequence {
content_type: asn1::DefinedByMarker<asn1::ObjectIdentifier>,
#[defined_by(content_type)]
content: Content,
}
#[derive(asn1::Asn1DefinedByRead, asn1::Asn1DefinedByWrite)]
enum Content {
#[defined_by(SOME_OID_CONSTANT)]
SomeVariant(i32),
}§Design philosophy
As we have designed the asn1 crate, we value the following things, in
this order:
- Security
- Correctness
- Performance
- Generality
- Ergonomics
Macros§
Structs§
- BMPString
- Type for use with
Parser.read_elementandWriter.write_elementfor handling ASN.1BMPString. ABMPStringcontains encoded (UTF-16-BE) bytes which are known to be valid. - BigInt
- Arbitrary sized signed integer. Contents may be accessed as
&[u8]of big-endian data. Its contents always match the DER encoding of a value (i.e. they are minimal) - BigUint
- Arbitrary sized unsigned integer. Contents may be accessed as
&[u8]of big-endian data. Its contents always match the DER encoding of a value (i.e. they are minimal) - BitString
- Represents an ASN.1
BIT STRINGwhose contents is borrowed. - Date
Time - A structure representing a (UTC timezone) date and time.
Wrapped by
UtcTimeandX509GeneralizedTimeand used inGeneralizedTime. - Defined
ByMarker - Enumerated
- An ASN.1
ENUMERATEDvalue. - Explicit
Explicitis a type which wraps another ASN.1 type, indicating that the tag is an ASN.1EXPLICIT. This will generally be used withOptionorChoice.- Generalized
Time - Used for parsing and writing ASN.1
GENERALIZED TIMEvalues, including values with fractional seconds of up to nanosecond precision. - IA5String
- Type for use with
Parser.read_elementandWriter.write_elementfor handling ASN.1IA5String. AnIA5Stringcontains an&strwith only valid characters. - Implicit
Implicitis a type which wraps another ASN.1 type, indicating that the tag is an ASN.1IMPLICIT. This will generally be used withOptionorChoice.- Object
Identifier - Represents an ASN.1
OBJECT IDENTIFIER. - Octet
String Encoded - Represents values that are encoded as an
OCTET STRINGcontaining an encoded TLV, of typeT. - Owned
BigInt - Arbitrary sized signed integer which owns its contents. Contents may be
accessed as
&[u8]of big-endian data. Its contents always match the DER encoding of a value (i.e. they are minimal) - Owned
BigUint - Arbitrary sized unsigned integer which owns its data. Contents may be
accessed as
&[u8]of big-endian data. Its contents always match the DER encoding of a value (i.e. they are minimal) - Owned
BitString - Represents an ASN.1
BIT STRINGwhose contents owned. When used to parse data this will allocate. - Parse
Error ParseErrorare returned when there is an error parsing the ASN.1 data.- Parser
- Encapsulates an ongoing parse. For almost all use-cases the correct
entry-point is
parseorparse_single. - Printable
String - Type for use with
Parser.read_elementandWriter.write_elementfor handling ASN.1PrintableString. APrintableStringcontains an&strwith only valid characters. - Sequence
- Represents an ASN.1
SEQUENCE. - Sequence
Of - Represents an ASN.1
SEQUENCE OF. This is anIteratorover values that are decoded. - Sequence
OfWriter - Writes a
SEQUENCE OFASN.1 structure from a slice ofT. - Sequence
Writer - Writes an ASN.1
SEQUENCEusing a callback that writes the inner elements. - SetOf
- Represents an ASN.1
SET OF. This is anIteratorover values that are decoded. - SetOf
Writer - Writes an ASN.1
SET OFwhose contents is a slice ofT. This type handles ensuring that the values are properly ordered when written as DER. - Tag
- Tlv
- A TLV (type, length, value) represented as the tag and bytes content.
Generally used for parsing ASN.1
ANYvalues. - Universal
String - Type for use with
Parser.read_elementandWriter.write_elementfor handling ASN.1UniversalString. AUniversalStringcontains encoded (UTF-32-BE) bytes which are known to be valid. - UtcTime
- Used for parsing and writing ASN.1
UTC TIMEvalues. Wraps aDateTime. - Utf8
String - Type for use with
Parser.read_elementandWriter.write_elementfor handling ASN.1UTF8String. - Visible
String - Type for use with
Parser.read_elementandWriter.write_elementfor handling ASN.1VisibleString. AVisibleStringcontains an&strwith only valid characters. - Write
Buf - Writer
- Encapsulates an ongoing write. For almost all use-cases the correct
entrypoint is
write()orwrite_single(). - X509
Generalized Time - Used for parsing and writing ASN.1
GENERALIZED TIMEvalues used in X.509. Wraps aDateTime.
Enums§
- Choice1
- Represents an ASN.1
CHOICEwith the provided number of potential types. - Choice2
- Represents an ASN.1
CHOICEwith the provided number of potential types. - Choice3
- Represents an ASN.1
CHOICEwith the provided number of potential types. - Parse
Error Kind - Write
Error WriteErrorare returned when there is an error writing the ASN.1 data.
Traits§
- Asn1
Defined ByReadable - A trait for types that can be parsed based on a
DEFINED BYvalue. - Asn1
Defined ByWritable - A trait for types that can be written based on a
DEFINED BYvalue. - Asn1
Readable - Any type that can be parsed as DER ASN.1.
- Asn1
Writable - Any type that can be written as DER ASN.1.
- Simple
Asn1 Readable - Types with a fixed-tag that can be parsed as DER ASN.1
- Simple
Asn1 Writable - Types with a fixed-tag that can be written as DER ASN.1.
Functions§
- from_
optional_ default - Decodes an
OPTIONALASN.1 value which has aDEFAULT. Generaly called immediately afterParser::read_element. - parse
- Parse takes a sequence of bytes of DER encoded ASN.1 data, constructs a parser, and invokes a callback to read elements from the ASN.1 parser.
- parse_
single - Parses a single top-level ASN.1 element from
data(does not allow trailing data). Most often this will be used whereTis a type with#[derive(asn1::Asn1Read)]. - strip_
tlv - Attempts to parse the
Tlvat the start ofdata(allows trailing data). If successful, theTlvand the trailing data after it are returned, if unsuccessful aParseErroris returned. - to_
optional_ default - Prepares an
OPTIONALASN.1 value which has aDEFAULTfor writing. Generally called immediately beforeWriter::write_element. - write
- Constructs a writer and invokes a callback which writes ASN.1 elements into the writer, then returns the generated DER bytes.
- write_
single - Writes a single top-level ASN.1 element, returning the generated DER bytes.
Most often this will be used where
Tis a type with#[derive(asn1::Asn1Write)].
Type Aliases§
- Null
- The ASN.1 NULL type, for use with
Parser.read_elementandWriter.write_element. - Parse
Result - The result of a
parse. Either a successful value or aParseError. - Write
Result