mirror of
https://github.com/storytold/pdfcraft.git
synced 2026-10-27 11:37:59 -06:00
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>