]> git.ipfire.org Git - thirdparty/curl.git/commitdiff
wolfSSL: fix handling of TLSv1.3 sessions
authorStefan Eissing <stefan@eissing.org>
Thu, 10 Oct 2024 09:44:39 +0000 (11:44 +0200)
committerDaniel Stenberg <daniel@haxx.se>
Sun, 13 Oct 2024 21:11:39 +0000 (23:11 +0200)
Register a callback to get notified of new SSL sessions by wolfSSL.
Remove the explicit session retrieval after handshake, since this does
not work for TLSv1.3.

Adjust test expectations now that TLSv1.3 session resumption works
in wolfSSL.

Closes #15243

lib/vtls/wolfssl.c
tests/http/test_17_ssl_use.py

index c36306c6a854582992b2c2b73d0d9c03914b4ede..c77b18afc7752866ecbbf0160fc320b0f10541ad 100644 (file)
@@ -370,6 +370,38 @@ static void wolfssl_bio_cf_free_methods(void)
 
 #endif /* !USE_BIO_CHAIN */
 
+static void wolfssl_session_free(void *sessionid, size_t idsize)
+{
+  (void)idsize;
+  wolfSSL_SESSION_free(sessionid);
+}
+
+static int wolfssl_new_session_cb(WOLFSSL *ssl, WOLFSSL_SESSION *session)
+{
+  struct Curl_cfilter *cf;
+
+  cf = (struct Curl_cfilter*)wolfSSL_get_app_data(ssl);
+  DEBUGASSERT(cf != NULL);
+  if(cf && session) {
+    struct ssl_connect_data *connssl = cf->ctx;
+    struct Curl_easy *data = CF_DATA_CURRENT(cf);
+    DEBUGASSERT(connssl);
+    DEBUGASSERT(data);
+    if(connssl && data) {
+      CURLcode result;
+      Curl_ssl_sessionid_lock(data);
+      result = Curl_ssl_set_sessionid(cf, data, &connssl->peer, NULL,
+                                      session, 0, wolfssl_session_free);
+      Curl_ssl_sessionid_unlock(data);
+      if(result)
+        failf(data, "failed to add new ssl session to cache (%d)", result);
+      else
+        CURL_TRC_CF(data, cf, "added new session to cache");
+    }
+  }
+  return 1;
+}
+
 static CURLcode populate_x509_store(struct Curl_cfilter *cf,
                                     struct Curl_easy *data,
                                     X509_STORE *store,
@@ -1057,6 +1089,10 @@ wolfssl_connect_step1(struct Curl_cfilter *cf, struct Curl_easy *data)
   if(ssl_config->primary.cache_session) {
     void *ssl_sessionid = NULL;
 
+    /* Register to get notified when a new session is received */
+    wolfSSL_set_app_data(backend->handle, cf);
+    wolfSSL_CTX_sess_set_new_cb(backend->ctx, wolfssl_new_session_cb);
+
     Curl_ssl_sessionid_lock(data);
     if(!Curl_ssl_getsessionid(cf, data, &connssl->peer,
                               &ssl_sessionid, NULL, NULL)) {
@@ -1430,50 +1466,6 @@ wolfssl_connect_step2(struct Curl_cfilter *cf, struct Curl_easy *data)
   return CURLE_OK;
 }
 
-
-static void wolfssl_session_free(void *sessionid, size_t idsize)
-{
-  (void)idsize;
-  wolfSSL_SESSION_free(sessionid);
-}
-
-
-static CURLcode
-wolfssl_connect_step3(struct Curl_cfilter *cf, struct Curl_easy *data)
-{
-  CURLcode result = CURLE_OK;
-  struct ssl_connect_data *connssl = cf->ctx;
-  struct wolfssl_ctx *backend =
-    (struct wolfssl_ctx *)connssl->backend;
-  const struct ssl_config_data *ssl_config = Curl_ssl_cf_get_config(cf, data);
-
-  DEBUGASSERT(ssl_connect_3 == connssl->connecting_state);
-  DEBUGASSERT(backend);
-
-  if(ssl_config->primary.cache_session) {
-    /* wolfSSL_get1_session allocates memory that has to be freed. */
-    WOLFSSL_SESSION *our_ssl_sessionid = wolfSSL_get1_session(backend->handle);
-
-    if(our_ssl_sessionid) {
-      Curl_ssl_sessionid_lock(data);
-      /* call takes ownership of `our_ssl_sessionid` */
-      result = Curl_ssl_set_sessionid(cf, data, &connssl->peer, NULL,
-                                      our_ssl_sessionid, 0,
-                                      wolfssl_session_free);
-      Curl_ssl_sessionid_unlock(data);
-      if(result) {
-        failf(data, "failed to store ssl session");
-        return result;
-      }
-    }
-  }
-
-  connssl->connecting_state = ssl_connect_done;
-
-  return result;
-}
-
-
 static ssize_t wolfssl_send(struct Curl_cfilter *cf,
                             struct Curl_easy *data,
                             const void *mem,
@@ -1834,9 +1826,9 @@ wolfssl_connect_common(struct Curl_cfilter *cf,
   } /* repeat step2 until all transactions are done. */
 
   if(ssl_connect_3 == connssl->connecting_state) {
-    result = wolfssl_connect_step3(cf, data);
-    if(result)
-      return result;
+    /* In other backends, this is where we verify the certificate, but
+     * wolfSSL already does that as part of the handshake. */
+    connssl->connecting_state = ssl_connect_done;
   }
 
   if(ssl_connect_done == connssl->connecting_state) {
index 9ea89debe07a71e11d8f1e179ca3d14b97374f46..5d26d22f3034207b6502541e480da358f46fc172 100644 (file)
@@ -67,9 +67,6 @@ class TestSSLUse:
         if env.curl_uses_lib('libressl'):
             if tls_max == '1.3':
                 exp_resumed = 'Initial'  # 1.2 works in LibreSSL, but 1.3 does not, TODO
-        if env.curl_uses_lib('wolfssl'):
-            if tls_max == '1.3':
-                exp_resumed = 'Initial'  # 1.2 works in wolfSSL, but 1.3 does not, TODO
         if env.curl_uses_lib('rustls-ffi'):
             exp_resumed = 'Initial'  # Rustls does not support sessions, TODO
         if env.curl_uses_lib('bearssl') and tls_max == '1.3':