Description
Bug report
SSLContext.load_verify_locations
detects EOF by looking for PEM_R_NO_START_LINE
and ASN1_R_HEADER_TOO_LONG
in PEM and DER, respectively. The former is correct. PEM allows arbitrary trailing data before and after and the OpenSSL API involves looking for that particular error code.
ASN1_R_HEADER_TOO_LONG
, however doesn't appear anywhere in OpenSSL's documentation and isn't the right way to detect EOF for a sequence of DER elements. It's signaled whenever there weren't enough bytes to read a full ASN.1 header. That could be because of EOF, but it could also be there was one byte, or any other truncated ASN.1 header. (It could also happen inside a deeply nested ASN.1 structure, but OpenSSL happens to push ERR_R_NESTED_ASN1_ERROR
in that case, so that case doesn't confuse CPython.)
To repro, add this test to test_load_verify_cadata
. It should fail.
with self.assertRaises(ssl.SSLError):
ctx.load_verify_locations(cadata=cacert_der + b"A")
The fix is instead to stop at BIO_eof
for DER, as there's no need to skip surrounding data. I'll upload a PR shortly to do that.
Your environment
- CPython versions tested on: main
- Operating system and architecture: Linux, x86_64