Rendered at 13:06:35 GMT+0000 (Coordinated Universal Time) with Cloudflare Workers.
winstonwinston 22 hours ago [-]
`Cryptography` is not a Python stdlib:
try:
from cryptography import x509
from cryptography.hazmat.primitives import hashes
from cryptography.x509.oid import NameOID
except ImportError: # pragma: no cover
sys.exit("missing dependency: pip install cryptography")
Then it goes on with a subprocess for openssl for a case that `cryptography` package does not handle.
Why not submit issue with `cryptography` project to get it fixed if it is a problem that needs fixing?
westurner 43 minutes ago [-]
Which package to send a PR to (to fix this for everyone else, too)?
It sounds like actually the bug is in the ASN.1 parser which is written in Rust? Add test cases. And then fuzz around this with e.g. cargo-fuzz
rurban 1 days ago [-]
So has the rust parser already the ticket to fix parsing Austria, the UAE and Japan?
I see dozens of Rust ASN 1.1 parsers
Eginn-33 2 days ago [-]
Author here. Some background on why this exists.
To validate the signature on an electronic passport you need the issuing country's CSCA certificate. States distribute these in bulk as a "Master List" - a CMS SignedData wrapping a SEQUENCE OF Certificate, specified in ICAO Doc 9303 Part 12. The format is not hard. What surprised me is how little public tooling just opens the file and hands you the certificates; most eMRTD code buries the parse inside a larger verification stack.
So I wrote the parse on its own. Then I ran it against a real Master List and six of the 581 entries failed:
Live, government-issued CAs carrying trailing bytes in the signature AlgorithmIdentifier that the Rust ASN.1 parser in `cryptography` treats as ExtraData. Austria, the UAE and Japan are not edge cases you get to skip: drop them silently and passports from those states fail with "unknown issuer" instead of a real error - which is genuinely unpleasant to debug, because the trust store looks fine and the count looks plausible.
So the default path falls back to `openssl x509` for anything the strict parser refuses, and the manifest records which parser produced each row, so the gap is visible rather than silent. --strict turns the fallback off if you want to see what a strict parser alone gives you.
It handles only public trust anchors - the certificates states publish precisely so that anyone can validate the documents they issue. No private keys, no chip communication, no passport data.
I have not torn those six apart byte by byte yet; my guess is a redundant explicit NULL or a PSS parameter block. Would be glad to hear from anyone who has hit the same six, or a different set from a newer Master List.
croemer 2 days ago [-]
Interesting but would be better if you didn't copy/paste AI generated text here. Also, the link seems to go to a tool and the "Python doesn't parse 6 certificates" is only a sidenote to the repo's main purpose. Either focus on one or the other, don't mix the 2. Your comment I'm replying to here mixes the 2 as well. The default path and open SSL fallback is irrelevant to the invalidity finding.
westurner 51 minutes ago [-]
This is a useful finding. I don't think that they need to rephrase this.
Have you tried further fuzzing the
ASN.1 parser?
What can coverage-guided fuzzing find if there is 100% test coverage?
Why not submit issue with `cryptography` project to get it fixed if it is a problem that needs fixing?
It sounds like actually the bug is in the ASN.1 parser which is written in Rust? Add test cases. And then fuzz around this with e.g. cargo-fuzz
To validate the signature on an electronic passport you need the issuing country's CSCA certificate. States distribute these in bulk as a "Master List" - a CMS SignedData wrapping a SEQUENCE OF Certificate, specified in ICAO Doc 9303 Part 12. The format is not hard. What surprised me is how little public tooling just opens the file and hands you the certificates; most eMRTD code buries the parse inside a larger verification stack.
So I wrote the parse on its own. Then I ran it against a real Master List and six of the 581 entries failed:
They are not junk. OpenSSL reads every one of them: Live, government-issued CAs carrying trailing bytes in the signature AlgorithmIdentifier that the Rust ASN.1 parser in `cryptography` treats as ExtraData. Austria, the UAE and Japan are not edge cases you get to skip: drop them silently and passports from those states fail with "unknown issuer" instead of a real error - which is genuinely unpleasant to debug, because the trust store looks fine and the count looks plausible.So the default path falls back to `openssl x509` for anything the strict parser refuses, and the manifest records which parser produced each row, so the gap is visible rather than silent. --strict turns the fallback off if you want to see what a strict parser alone gives you.
It handles only public trust anchors - the certificates states publish precisely so that anyone can validate the documents they issue. No private keys, no chip communication, no passport data.
I have not torn those six apart byte by byte yet; my guess is a redundant explicit NULL or a PSS parameter block. Would be glad to hear from anyone who has hit the same six, or a different set from a newer Master List.
Have you tried further fuzzing the ASN.1 parser?
What can coverage-guided fuzzing find if there is 100% test coverage?
Write tests for these to prevent regressions?