> However, OpenSSL did not do strict validation of the ASN.1 data by default
The more interesting problem was that this was non deterministic, you could encode fields with 64bit integers and they would bomb out on 32bit systems. ASN1 is also mind bogglingly complex, you can encode to arbitrary depths completely nonsensical things like negative numbers and strings, containers of multiple elements, none of the implementations manage to decode blocks the same or adhere to the same limits.
- All numbers are parsed as nonnegative integers, even though X.609-0207 section 8.3.3 specifies that integers are always encoded as two's complement.
- Integers can have length 0, even though section 8.3.1 says they can't.
- Integers with overly long padding are accepted, violation section 8.3.2.
- 127-byte long length descriptors are accepted, even though section 8.1.3.5.c says that they are not.
- Trailing garbage data inside or after the signature is ignored.
- The length descriptor of the sequence is ignored.
But some things were just too awful to implement, e.g.
- Using overly long tag descriptors for the sequence or integers inside, violating section 8.1.2.2.
- Encoding primitive integers as constructed values, violating section 8.3.1.
This last is especially fun, in OpenSSL you can create a constructed value (like a struct) of constructed values of constructed values of strings.. and it will just concatenate up all the bytes in the last level primitive elements and treat the result as a number. ... but only if it's not more than 7 (IIRC) levels deep.
The more interesting problem was that this was non deterministic, you could encode fields with 64bit integers and they would bomb out on 32bit systems. ASN1 is also mind bogglingly complex, you can encode to arbitrary depths completely nonsensical things like negative numbers and strings, containers of multiple elements, none of the implementations manage to decode blocks the same or adhere to the same limits.