]> git.ipfire.org Git - thirdparty/curl.git/commitdiff
wolfssl: CA store share fix
authorStefan Eissing <stefan@eissing.org>
Fri, 26 Jul 2024 13:07:52 +0000 (15:07 +0200)
committerDaniel Stenberg <daniel@haxx.se>
Mon, 29 Jul 2024 17:54:08 +0000 (19:54 +0200)
When sharing the x509 store in wolfSSL, always use an explicitly
constructed one, as the SSLCTX might have "only" an internal one which
is not obeying reference count lifetimes.

Fixes #14278
Reported-by: Alex Snast
Closes #14279

lib/vtls/wolfssl.c

index 43460dd9e54961e179ba0fa3fa722904c9c1fd59..29728ae8e17e297bc6ddc9db9cf60bbea8439bcc 100644 (file)
@@ -434,10 +434,10 @@ static CURLcode populate_x509_store(struct Curl_cfilter *cf,
     }
     infof(data, " CAfile: %s", ssl_cafile ? ssl_cafile : "none");
     infof(data, " CApath: %s", ssl_capath ? ssl_capath : "none");
-    wssl->x509_store_setup = TRUE;
   }
 #endif
   (void)store;
+  wssl->x509_store_setup = TRUE;
   return CURLE_OK;
 }
 
@@ -585,14 +585,26 @@ CURLcode Curl_wssl_setup_x509_store(struct Curl_cfilter *cf,
      && wolfSSL_X509_STORE_up_ref(cached_store)) {
     wolfSSL_CTX_set_cert_store(wssl->ctx, cached_store);
   }
-  else {
-    X509_STORE *store = wolfSSL_CTX_get_cert_store(wssl->ctx);
+  else if(cache_criteria_met) {
+    /* wolfSSL's initial store in CTX is not shareable by default.
+     * Make a new one, suitable for adding to the cache. See #14278 */
+    X509_STORE *store = wolfSSL_X509_STORE_new();
+    if(!store) {
+      failf(data, "SSL: could not create a X509 store");
+      return CURLE_OUT_OF_MEMORY;
+    }
+    wolfSSL_CTX_set_cert_store(wssl->ctx, store);
 
     result = populate_x509_store(cf, data, store, wssl);
-    if(result == CURLE_OK && cache_criteria_met) {
+    if(!result) {
       set_cached_x509_store(cf, data, store);
     }
   }
+  else {
+   /* We never share the CTX's store, use it. */
+   X509_STORE *store = wolfSSL_CTX_get_cert_store(wssl->ctx);
+   result = populate_x509_store(cf, data, store, wssl);
+  }
 
   return result;
 }
@@ -821,8 +833,14 @@ wolfssl_connect_step1(struct Curl_cfilter *cf, struct Curl_easy *data)
 
   /* give application a chance to interfere with SSL set up. */
   if(data->set.ssl.fsslctx) {
-    CURLcode result = (*data->set.ssl.fsslctx)(data, backend->ctx,
-                                               data->set.ssl.fsslctxp);
+    CURLcode result;
+    if(!backend->x509_store_setup) {
+      result = Curl_wssl_setup_x509_store(cf, data, backend);
+      if(result)
+        return result;
+    }
+    result = (*data->set.ssl.fsslctx)(data, backend->ctx,
+                                      data->set.ssl.fsslctxp);
     if(result) {
       failf(data, "error signaled by ssl ctx callback");
       return result;
@@ -1059,15 +1077,9 @@ wolfssl_connect_step2(struct Curl_cfilter *cf, struct Curl_easy *data)
     /* After having send off the ClientHello, we prepare the x509
      * store to verify the coming certificate from the server */
     CURLcode result;
-    struct wolfssl_ctx wssl;
-    wssl.ctx = backend->ctx;
-    wssl.handle = backend->handle;
-    wssl.io_result = CURLE_OK;
-    wssl.x509_store_setup = FALSE;
-    result = Curl_wssl_setup_x509_store(cf, data, &wssl);
+    result = Curl_wssl_setup_x509_store(cf, data, backend);
     if(result)
       return result;
-    backend->x509_store_setup = wssl.x509_store_setup;
   }
 
   connssl->io_need = CURL_SSL_IO_NEED_NONE;