1## Upgrading from 3.x to 4.0 2 3### Ber Object and Header 4 5The `class`, `structured` and `tag` fields were duplicated in `BerObject` and the header. 6Now, a header is always created and embedded in the BER object, with the following changes: 7 8- To access these fields, use the header: `obj.tag` becomes `obj.header.tag`, etc. 9- `BerObject::to_header()` is now deprecated 10- The `len` field is now public. However, in some cases it can be 0 (when creating an object, 0 means that serialization will calculate the length) 11- As a consequence, `PartialEq` on BER objects and headers compare `len` only if set in both objects 12 13### BER String types verification 14 15Some BER String types (`IA5String`, `NumericString`, `PrintableString` and `UTF8String`) are now 16verified, and will now only parse if the characters are valid. 17 18Their types have change from slice to `str` in the `BerObjectContent` enum. 19 20### BerClass 21 22The `class` field of `BerObject` struct now uses the newtype `BerClass`. Use the provided constants 23(for ex `BerClass:Universal`). To access the value, just use `class.0`. 24 25### Maximum depth 26 27The `depth` argument of functions (for ex. `ber_read_element_content_as`) has changed, and is now the maximum possible depth while parsing. 28Change it (usually from `0`) to a possible limit, for ex `der_parser::ber::MAX_RECURSION`. 29 30### Oid 31 32This is probably the most impacting change. 33 34OID objects have been refactored, and are now zero-copy. This has several consequences: 35 36- `Oid` struct now has a lifetime, which must be propagated to objects using them 37 - This makes having globally static structs difficult. Obtaining a `'static` object is possible 38 using the `oid` macro. For ex: 39 40```rust 41const SOME_STATIC_OID: Oid<'static> = oid!(1.2.456); 42``` 43 44- Due to limitations of procedural macros ([rust 45 issue](https://github.com/rust-lang/rust/issues/54727)) and constants used in patterns ([rust issue](https://github.com/rust-lang/rust/issues/31434)), the `oid` macro can not directly be used in patterns, also not through constants. 46You can do this, though: 47 48```rust 49# use der_parser::{oid, oid::Oid}; 50# let some_oid: Oid<'static> = oid!(1.2.456); 51const SOME_OID: Oid<'static> = oid!(1.2.456); 52if some_oid == SOME_OID || some_oid == oid!(1.2.456) { 53 println!("match"); 54} 55 56// Alternatively, compare the DER encoded form directly: 57const SOME_OID_RAW: &[u8] = &oid!(raw 1.2.456); 58match some_oid.bytes() { 59 SOME_OID_RAW => println!("match"), 60 _ => panic!("no match"), 61} 62``` 63*Attention*, be aware that the latter version might not handle the case of a relative oid correctly. An 64extra check might be necessary. 65 66- To build an `Oid`, the `from`, `new` or `new_relative` methods can be used. 67- The `from` method now returns a `Result` (failure can happen if the first components are too 68 large, for ex) 69- An `oid` macro has also been added in the `der-oid-macro` crate to easily build an `Oid` (see 70 above). 71