From f36e32b5b80129c1177d8d8e01341b02505f8fc4 Mon Sep 17 00:00:00 2001 From: Jan Venekamp <1422460+jan2000@users.noreply.github.com> Date: Mon, 6 Dec 2021 18:35:55 +0100 Subject: [PATCH] bearssl: fix EXC_BAD_ACCESS on incomplete CA cert - Do not create trust anchor object for a CA certificate until after it is processed. Prior to this change the object was created at state BR_PEM_BEGIN_OBJ (certificate processing begin state). An incomplete certificate (for example missing a newline at the end) never reaches BR_PEM_END_OBJ (certificate processing end state) and therefore the trust anchor data was not set in those objects, which caused EXC_BAD_ACCESS. Ref: https://github.com/curl/curl/pull/8106 Closes https://github.com/curl/curl/pull/8476 --- lib/vtls/bearssl.c | 25 ++++++++++++++----------- 1 file changed, 14 insertions(+), 11 deletions(-) diff --git a/lib/vtls/bearssl.c b/lib/vtls/bearssl.c index 54cf9840bf..a4d2d910b6 100644 --- a/lib/vtls/bearssl.c +++ b/lib/vtls/bearssl.c @@ -161,6 +161,18 @@ static CURLcode load_cafile(struct cafile_source *source, if(strcmp(name, "CERTIFICATE") && strcmp(name, "X509 CERTIFICATE")) break; br_x509_decoder_init(&ca.xc, append_dn, &ca); + ca.in_cert = TRUE; + ca.dn_len = 0; + break; + case BR_PEM_END_OBJ: + if(!ca.in_cert) + break; + ca.in_cert = FALSE; + if(br_x509_decoder_last_error(&ca.xc)) { + ca.err = CURLE_SSL_CACERT_BADFILE; + goto fail; + } + /* add trust anchor */ if(ca.anchors_len == SIZE_MAX / sizeof(ca.anchors[0])) { ca.err = CURLE_OUT_OF_MEMORY; goto fail; @@ -174,19 +186,8 @@ static CURLcode load_cafile(struct cafile_source *source, } ca.anchors = new_anchors; ca.anchors_len = new_anchors_len; - ca.in_cert = TRUE; - ca.dn_len = 0; ta = &ca.anchors[ca.anchors_len - 1]; ta->dn.data = NULL; - break; - case BR_PEM_END_OBJ: - if(!ca.in_cert) - break; - ca.in_cert = FALSE; - if(br_x509_decoder_last_error(&ca.xc)) { - ca.err = CURLE_SSL_CACERT_BADFILE; - goto fail; - } ta->flags = 0; if(br_x509_decoder_isCA(&ca.xc)) ta->flags |= BR_X509_TA_CA; @@ -240,6 +241,8 @@ static CURLcode load_cafile(struct cafile_source *source, } while(source->type != CAFILE_SOURCE_BLOB); if(fp && ferror(fp)) ca.err = CURLE_READ_ERROR; + else if(ca.in_cert) + ca.err = CURLE_SSL_CACERT_BADFILE; fail: if(fp) -- 2.47.3