]> git.ipfire.org Git - thirdparty/curl.git/commitdiff
gnutls: check conversion of peer cert chain
authorStefan Eissing <stefan@eissing.org>
Thu, 9 Oct 2025 08:41:02 +0000 (10:41 +0200)
committerDaniel Stenberg <daniel@haxx.se>
Fri, 10 Oct 2025 21:41:31 +0000 (23:41 +0200)
Check the result when converting the peer certificate chain
into gnutls internal x590 data structure for errors.

Reported-by: Joshua Rogers
Closes #18964

lib/vtls/gtls.c

index 43edbd57ad2b16449c3af605655ed8aad6e76352..1c0a6fb2d6109b6627748385dec163caed16df9d 100644 (file)
@@ -1701,12 +1701,24 @@ Curl_gtls_verifyserver(struct Curl_cfilter *cf,
     infof(data, "  SSL certificate verification SKIPPED");
 
   /* initialize an X.509 certificate structure. */
-  gnutls_x509_crt_init(&x509_cert);
+  if(gnutls_x509_crt_init(&x509_cert)) {
+    failf(data, "failed to init gnutls x509_crt");
+    *certverifyresult = GNUTLS_E_NO_CERTIFICATE_FOUND;
+    result = CURLE_SSL_CONNECT_ERROR;
+    goto out;
+  }
 
-  if(chain.certs)
+  if(chain.certs) {
     /* convert the given DER or PEM encoded Certificate to the native
        gnutls_x509_crt_t format */
-    gnutls_x509_crt_import(x509_cert, chain.certs, GNUTLS_X509_FMT_DER);
+    rc = gnutls_x509_crt_import(x509_cert, chain.certs, GNUTLS_X509_FMT_DER);
+    if(rc) {
+      failf(data, "error parsing server's certificate chain");
+      *certverifyresult = GNUTLS_E_NO_CERTIFICATE_FOUND;
+      result = CURLE_SSL_CONNECT_ERROR;
+      goto out;
+    }
+  }
 
   /* Check for time-based validity */
   certclock = gnutls_x509_crt_get_expiration_time(x509_cert);
@@ -1773,10 +1785,15 @@ Curl_gtls_verifyserver(struct Curl_cfilter *cf,
 
   if(config->issuercert) {
     gnutls_datum_t issuerp;
-    gnutls_x509_crt_init(&x509_issuer);
+    if(gnutls_x509_crt_init(&x509_issuer)) {
+      failf(data, "failed to init gnutls x509_crt for issuer");
+      result = CURLE_SSL_ISSUER_ERROR;
+      goto out;
+    }
     issuerp = load_file(config->issuercert);
-    gnutls_x509_crt_import(x509_issuer, &issuerp, GNUTLS_X509_FMT_PEM);
-    rc = (int)gnutls_x509_crt_check_issuer(x509_cert, x509_issuer);
+    rc = gnutls_x509_crt_import(x509_issuer, &issuerp, GNUTLS_X509_FMT_PEM);
+    if(!rc)
+      rc = (int)gnutls_x509_crt_check_issuer(x509_cert, x509_issuer);
     unload_file(issuerp);
     if(rc <= 0) {
       failf(data, "server certificate issuer check failed (IssuerCert: %s)",