Skip to content

parse_der does not apply DER constraints to nested elements #95

Description

@treiher

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.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions