]> git.ipfire.org Git - thirdparty/curl.git/commitdiff
bearssl: fix EXC_BAD_ACCESS on incomplete CA cert
authorJan Venekamp <1422460+jan2000@users.noreply.github.com>
Mon, 6 Dec 2021 17:35:55 +0000 (18:35 +0100)
committerJay Satiro <raysatiro@yahoo.com>
Sun, 20 Feb 2022 07:52:56 +0000 (02:52 -0500)
- 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

index 54cf9840bf874891661df31b8a41b4e0d5ee5231..a4d2d910b67b03b8db1637b34e6860c7f2ac8665 100644 (file)
@@ -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)