]> git.ipfire.org Git - thirdparty/curl.git/commitdiff
schannel: fix UAF in client cert store thumbprint handling
authorDaniel Stenberg <daniel@haxx.se>
Tue, 3 Mar 2026 17:38:19 +0000 (18:38 +0100)
committerDaniel Stenberg <daniel@haxx.se>
Tue, 3 Mar 2026 21:14:26 +0000 (22:14 +0100)
Follow-up to 10bb489b22d1777f2984aa5

Found by Codex Security
Closes #20801

lib/vtls/schannel.c

index f97dc65bca9a55c20db315a6fa8dba9b802cd475..650a0e38ca8bf04eee4aba3b40d089a1b7e1d530 100644 (file)
@@ -371,6 +371,7 @@ static CURLcode get_client_cert(struct Curl_easy *data,
     DWORD cert_store_name = 0;
     TCHAR *cert_store_path = NULL;
     TCHAR *cert_thumbprint_str = NULL;
+    TCHAR cert_thumbprint_buf[CERT_THUMBPRINT_STR_LEN + 1];
     CRYPT_HASH_BLOB cert_thumbprint;
     BYTE cert_thumbprint_data[CERT_THUMBPRINT_DATA_LEN];
     HCERTSTORE cert_store = NULL;
@@ -392,6 +393,15 @@ static CURLcode get_client_cert(struct Curl_easy *data,
       result = get_cert_location(cert_path, &cert_store_name,
                                  &cert_store_path, &cert_thumbprint_str);
 
+      /* 'cert_thumbprint_str' points in to the allocated 'cert_path', copy
+         the data. The string is verified to be CERT_THUMBPRINT_STR_LEN bytes
+         long within the get_cert_location() function. */
+      if(!result && cert_thumbprint_str) {
+        memcpy(cert_thumbprint_buf, cert_thumbprint_str,
+               sizeof(cert_thumbprint_buf));
+        cert_thumbprint_str = cert_thumbprint_buf;
+      }
+
       curlx_free(cert_path);
       if(result && (data->set.ssl.primary.clientcert[0] != '\0'))
         fInCert = curlx_fopen(data->set.ssl.primary.clientcert, "rb");