parse_der checks the DER rules only on the outermost object. SEQUENCE and SET content goes through the BER path, so anything nested is accepted as long as it is valid BER:
use der_parser::parse_der;
// INTEGER with a leading zero octet (X.690 8.3.2)
assert!(parse_der(&[0x02, 0x02, 0x00, 0x01]).is_err()); // rejected
assert!(parse_der(&[0x30, 0x04, 0x02, 0x02, 0x00, 0x01]).is_ok()); // accepted inside a SEQUENCE
// same for BOOLEAN 01 (X.690 11.1) and indefinite lengths (X.690 10.1)
assert!(parse_der(&[0x30, 0x03, 0x01, 0x01, 0x01]).is_ok());
assert!(parse_der(&[0x30, 0x04, 0x02, 0x80, 0x00, 0x00]).is_ok());
Since nearly everything in X.509 or CMS is nested, this means the DER guarantee effectively only holds for the top-level tag. Two different encodings can decode to the same object, which is what DER is supposed to rule out.
The cause is that der_read_element_content_as has no arm for Tag::Sequence / Tag::Set, so it falls through to ber_read_element_content_as, and from there into try_berobject_from_any, which iterates the children with SequenceIterator::<Any, BerParser>.
The typed combinators (parse_der_sequence_defined, parse_der_sequence_of, ...) are not affected, since they call DER element parsers explicitly.
parse_derchecks the DER rules only on the outermost object. SEQUENCE and SET content goes through the BER path, so anything nested is accepted as long as it is valid BER:Since nearly everything in X.509 or CMS is nested, this means the DER guarantee effectively only holds for the top-level tag. Two different encodings can decode to the same object, which is what DER is supposed to rule out.
The cause is that
der_read_element_content_ashas no arm forTag::Sequence/Tag::Set, so it falls through tober_read_element_content_as, and from there intotry_berobject_from_any, which iterates the children withSequenceIterator::<Any, BerParser>.The typed combinators (
parse_der_sequence_defined,parse_der_sequence_of, ...) are not affected, since they call DER element parsers explicitly.