The variant ContextSpecific
has been removed from BerObject
, and 2 new variants have been added:
Tagged
for explicit tagged objects,Optional
to simplify writing subparsers with only BerObject
This is also used to clarify parsing of tagged values, and the API now clearly says if trying to parse an optional value or not.
The len
field of BerObjectHeader
is now an enum, to represent definite and indefinite lengths. To get the value, either match the type, or use try_from
(which will fail if indefinite).
Functions and combinators are now the preferred way of parsing constructed objects.
Macros have been upgrading and use the combinators internally. As a consequence, they do not return a tuple (BerObjectHeader, T)
but only the built object T
. The header should be removed from function signatures, for ex:
-fn parse_struct01(i: &[u8]) -> BerResult<(BerObjectHeader,MyStruct)> { +fn parse_struct01(i: &[u8]) -> BerResult<MyStruct> {
The header was usually ignored, so this should simplify most uses of this macro. To get the header, use parse_ber_container
directly.
The class
, structured
and tag
fields were duplicated in BerObject
and the header. Now, a header is always created and embedded in the BER object, with the following changes:
obj.tag
becomes obj.header.tag
, etc.BerObject::to_header()
is now deprecatedlen
field is now public. However, in some cases it can be 0 (when creating an object, 0 means that serialization will calculate the length)PartialEq
on BER objects and headers compare len
only if set in both objectsSome BER String types (IA5String
, NumericString
, PrintableString
and UTF8String
) are now verified, and will now only parse if the characters are valid.
Their types have change from slice to str
in the BerObjectContent
enum.
The class
field of BerObject
struct now uses the newtype BerClass
. Use the provided constants (for ex BerClass:Universal
). To access the value, just use class.0
.
The depth
argument of functions (for ex. ber_read_element_content_as
) has changed, and is now the maximum possible depth while parsing. Change it (usually from 0
) to a possible limit, for ex der_parser::ber::MAX_RECURSION
.
This is probably the most impacting change.
OID objects have been refactored, and are now zero-copy. This has several consequences:
Oid
struct now has a lifetime, which must be propagated to objects using them'static
object is possible using the oid
macro. For ex:const SOME_STATIC_OID: Oid<'static> = oid!(1.2.456);
oid
macro can not directly be used in patterns, also not through constants. You can do this, though:# use der_parser::{oid, oid::Oid}; # let some_oid: Oid<'static> = oid!(1.2.456); const SOME_OID: Oid<'static> = oid!(1.2.456); if some_oid == SOME_OID || some_oid == oid!(1.2.456) { println!("match"); } // Alternatively, compare the DER encoded form directly: const SOME_OID_RAW: &[u8] = &oid!(raw 1.2.456); match some_oid.bytes() { SOME_OID_RAW => println!("match"), _ => panic!("no match"), }
Attention, be aware that the latter version might not handle the case of a relative oid correctly. An extra check might be necessary.
Oid
, the from
, new
or new_relative
methods can be used.from
method now returns a Result
(failure can happen if the first components are too large, for ex)oid
macro has also been added in the der-oid-macro
crate to easily build an Oid
(see above).