Importing a digital ID exported by Windows failed with "PKCS #12: not a
PKCS #12 file" — at the second byte of the file, before the password was
looked at. Windows writes a .p12 in BER: the PFX, its ContentInfo and
the [0] around the AuthenticatedSafe all use the indefinite length form
(0x80 … 00 00), and the AuthenticatedSafe itself is an OCTET STRING
split into segments. der.rs took definite lengths only, so every one of
those files was turned away. OpenSSL writes definite DER, which is why
the fixtures never showed it.
A Tlv now carries the rules it was read with, and its children are read
the same way: Tlv::parse is the strict DER reader it always was,
Tlv::parse_ber also takes the indefinite form, and Tlv::octets joins the
segments of a constructed OCTET STRING, borrowing when there is nothing
to join. Both are depth-bounded. pkcs12 reads the envelope with the BER
reader; x509 and cms keep the strict one, so nothing that is verified
over its own bytes changes.
The MAC decides what is allowed here: it covers the contents of the
authSafe OCTET STRING, the segments joined, which is what the writer
MACed. So the file is never normalised to DER — that would change the
octets the MAC was computed over and turn a right password into a wrong
one.
The test builds the Windows shape out of the OpenSSL fixtures, twice:
the outer wrappers in BER with the MacData intact, which is what proves
the MAC is taken over the right octets, and then the AuthenticatedSafe
re-encoded as well, with the MacData dropped (RFC 7292 §4 makes it
optional), for a file that is BER the whole way down.
Claude-Session: https://claude.ai/code/session_013Q5dhMC58jk1ePNW37xe1b
Co-authored-by: Fernando Areán <soporte@codebit.es>
Co-authored-by: Claude Opus 5 <noreply@anthropic.com>