Skip to content

Commit 7eca7c5

Browse files
davidbenmiss-islington
authored andcommitted
gh-100372: Use BIO_eof to detect EOF for SSL_FILETYPE_ASN1 (GH-100373)
In PEM, we need to parse until error and then suppress `PEM_R_NO_START_LINE`, because PEM allows arbitrary leading and trailing data. DER, however, does not. Parsing until error and suppressing `ASN1_R_HEADER_TOO_LONG` doesn't quite work because that error also covers some cases that should be rejected. Instead, check `BIO_eof` early and stop the loop that way. (cherry picked from commit acfe02f) Co-authored-by: David Benjamin <davidben@google.com> Automerge-Triggered-By: GH:Yhg1s
1 parent d2b2f5e commit 7eca7c5

3 files changed

Lines changed: 10 additions & 4 deletions

File tree

Lib/test/test_ssl.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1559,6 +1559,8 @@ def test_load_verify_cadata(self):
15591559
"not enough data: cadata does not contain a certificate"
15601560
):
15611561
ctx.load_verify_locations(cadata=b"broken")
1562+
with self.assertRaises(ssl.SSLError):
1563+
ctx.load_verify_locations(cadata=cacert_der + b"A")
15621564

15631565
@unittest.skipIf(Py_DEBUG_WIN32, "Avoid mixing debug/release CRT on Windows")
15641566
def test_load_dh_params(self):
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
:meth:`ssl.SSLContext.load_verify_locations` no longer incorrectly accepts
2+
some cases of trailing data when parsing DER.

Modules/_ssl.c

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3978,7 +3978,7 @@ _add_ca_certs(PySSLContext *self, const void *data, Py_ssize_t len,
39783978
{
39793979
BIO *biobuf = NULL;
39803980
X509_STORE *store;
3981-
int retval = -1, err, loaded = 0;
3981+
int retval = -1, err, loaded = 0, was_bio_eof = 0;
39823982

39833983
assert(filetype == SSL_FILETYPE_ASN1 || filetype == SSL_FILETYPE_PEM);
39843984

@@ -4006,6 +4006,10 @@ _add_ca_certs(PySSLContext *self, const void *data, Py_ssize_t len,
40064006
int r;
40074007

40084008
if (filetype == SSL_FILETYPE_ASN1) {
4009+
if (BIO_eof(biobuf)) {
4010+
was_bio_eof = 1;
4011+
break;
4012+
}
40094013
cert = d2i_X509_bio(biobuf, NULL);
40104014
} else {
40114015
cert = PEM_read_bio_X509(biobuf, NULL,
@@ -4041,9 +4045,7 @@ _add_ca_certs(PySSLContext *self, const void *data, Py_ssize_t len,
40414045
}
40424046
_setSSLError(get_state_ctx(self), msg, 0, __FILE__, __LINE__);
40434047
retval = -1;
4044-
} else if ((filetype == SSL_FILETYPE_ASN1) &&
4045-
(ERR_GET_LIB(err) == ERR_LIB_ASN1) &&
4046-
(ERR_GET_REASON(err) == ASN1_R_HEADER_TOO_LONG)) {
4048+
} else if ((filetype == SSL_FILETYPE_ASN1) && was_bio_eof) {
40474049
/* EOF ASN1 file, not an error */
40484050
ERR_clear_error();
40494051
retval = 0;

0 commit comments

Comments
 (0)