]> git.ipfire.org Git - thirdparty/curl.git/commitdiff
ssl-session-cache: check use on config and availability
authorStefan Eissing <stefan@eissing.org>
Mon, 27 Oct 2025 09:33:41 +0000 (10:33 +0100)
committerJay Satiro <raysatiro@yahoo.com>
Wed, 29 Oct 2025 07:07:59 +0000 (03:07 -0400)
Replace the check if a ssl session cache is configured with
a function checking if it is configured *and* if an ssl session
cache is available.

During normal operations, a session cache is always there, however
for "connect-only" transfers this might not be the case. When such
transfers receive new sessions/tickets, they need to silently
discard those and not fail.

Reported-by: Marc Aldorasi
Fixes https://github.com/curl/curl/issues/18983
Closes https://github.com/curl/curl/pull/19251

lib/vquic/curl_ngtcp2.c
lib/vtls/gtls.c
lib/vtls/mbedtls.c
lib/vtls/openssl.c
lib/vtls/schannel.c
lib/vtls/vtls_scache.c
lib/vtls/vtls_scache.h
lib/vtls/wolfssl.c

index 3b918cd87062b5f28635a8981a7a714edad6ac76..3493f996cee197e1227f82c33eec9fe74e5ba2d8 100644 (file)
@@ -2384,7 +2384,6 @@ static CURLcode cf_ngtcp2_tls_ctx_setup(struct Curl_cfilter *cf,
                                         void *user_data)
 {
   struct curl_tls_ctx *ctx = user_data;
-  struct ssl_config_data *ssl_config = Curl_ssl_cf_get_config(cf, data);
 
 #ifdef USE_OPENSSL
 #if defined(OPENSSL_IS_BORINGSSL) || defined(OPENSSL_IS_AWSLC)
@@ -2401,7 +2400,7 @@ static CURLcode cf_ngtcp2_tls_ctx_setup(struct Curl_cfilter *cf,
     return CURLE_FAILED_INIT;
   }
 #endif /* !OPENSSL_IS_BORINGSSL && !OPENSSL_IS_AWSLC */
-  if(ssl_config->primary.cache_session) {
+  if(Curl_ssl_scache_use(cf, data)) {
     /* Enable the session cache because it is a prerequisite for the
      * "new session" callback. Use the "external storage" mode to prevent
      * OpenSSL from creating an internal session cache.
@@ -2417,7 +2416,7 @@ static CURLcode cf_ngtcp2_tls_ctx_setup(struct Curl_cfilter *cf,
     failf(data, "ngtcp2_crypto_gnutls_configure_client_session failed");
     return CURLE_FAILED_INIT;
   }
-  if(ssl_config->primary.cache_session) {
+  if(Curl_ssl_scache_use(cf, data)) {
     gnutls_handshake_set_hook_function(ctx->gtls.session,
                                        GNUTLS_HANDSHAKE_ANY, GNUTLS_HOOK_POST,
                                        quic_gtls_handshake_cb);
@@ -2428,7 +2427,7 @@ static CURLcode cf_ngtcp2_tls_ctx_setup(struct Curl_cfilter *cf,
     failf(data, "ngtcp2_crypto_wolfssl_configure_client_context failed");
     return CURLE_FAILED_INIT;
   }
-  if(ssl_config->primary.cache_session) {
+  if(Curl_ssl_scache_use(cf, data)) {
     /* Register to get notified when a new session is received */
     wolfSSL_CTX_sess_set_new_cb(ctx->wssl.ssl_ctx, wssl_quic_new_session_cb);
   }
index 19c2ce893fb97d9b06b07e8fd32d4f3b3f58f09f..c79f192e823fd09816d6e12059b9da6468724324 100644 (file)
@@ -684,14 +684,13 @@ CURLcode Curl_gtls_cache_session(struct Curl_cfilter *cf,
                                  unsigned char *quic_tp,
                                  size_t quic_tp_len)
 {
-  struct ssl_config_data *ssl_config = Curl_ssl_cf_get_config(cf, data);
   struct Curl_ssl_session *sc_session;
   unsigned char *sdata, *qtp_clone = NULL;
   size_t sdata_len = 0;
   size_t earlydata_max = 0;
   CURLcode result = CURLE_OK;
 
-  if(!ssl_config->primary.cache_session)
+  if(!Curl_ssl_scache_use(cf, data))
     return CURLE_OK;
 
   /* we always unconditionally get the session id here, as even if we
index 89d4eff64ea48d36adea660631526a51ddba0884..ea8981b3cda9256502fb87d3c8a11ccdec1e1102 100644 (file)
@@ -859,7 +859,7 @@ mbed_connect_step1(struct Curl_cfilter *cf, struct Curl_easy *data)
 #endif
 
   /* Check if there is a cached ID we can/should use here! */
-  if(ssl_config->primary.cache_session) {
+  if(Curl_ssl_scache_use(cf, data)) {
     struct Curl_ssl_session *sc_session = NULL;
     CURLcode result;
 
@@ -1086,7 +1086,6 @@ mbed_new_session(struct Curl_cfilter *cf, struct Curl_easy *data)
   struct ssl_connect_data *connssl = cf->ctx;
   struct mbed_ssl_backend_data *backend =
     (struct mbed_ssl_backend_data *)connssl->backend;
-  struct ssl_config_data *ssl_config = Curl_ssl_cf_get_config(cf, data);
   mbedtls_ssl_session session;
   bool msession_alloced = FALSE;
   struct Curl_ssl_session *sc_session = NULL;
@@ -1097,7 +1096,7 @@ mbed_new_session(struct Curl_cfilter *cf, struct Curl_easy *data)
   int ret;
 
   DEBUGASSERT(backend);
-  if(!ssl_config->primary.cache_session)
+  if(!Curl_ssl_scache_use(cf, data))
     return CURLE_OK;
 
   mbedtls_ssl_session_init(&session);
index 535e4118da815e5a77bfcee0de09d32d6cb0ec2f..838c0242213b5e3ecc8e27537c2e271098d9d913 100644 (file)
@@ -3056,7 +3056,6 @@ CURLcode Curl_ossl_add_session(struct Curl_cfilter *cf,
                                unsigned char *quic_tp,
                                size_t quic_tp_len)
 {
-  const struct ssl_config_data *config;
   unsigned char *der_session_buf = NULL;
   unsigned char *qtp_clone = NULL;
   CURLcode result = CURLE_OK;
@@ -3064,8 +3063,7 @@ CURLcode Curl_ossl_add_session(struct Curl_cfilter *cf,
   if(!cf || !data)
     goto out;
 
-  config = Curl_ssl_cf_get_config(cf, data);
-  if(config->primary.cache_session) {
+  if(Curl_ssl_scache_use(cf, data)) {
     struct Curl_ssl_session *sc_session = NULL;
     size_t der_session_size;
     unsigned char *der_session_ptr;
@@ -3755,7 +3753,7 @@ ossl_init_session_and_alpns(struct ossl_ctx *octx,
   Curl_alpn_copy(&alpns, alpns_requested);
 
   octx->reused_session = FALSE;
-  if(ssl_config->primary.cache_session && !conn_cfg->verifystatus) {
+  if(Curl_ssl_scache_use(cf, data) && !conn_cfg->verifystatus) {
     struct Curl_ssl_session *scs = NULL;
 
     result = Curl_ssl_scache_take(cf, data, peer->scache_key, &scs);
@@ -3797,6 +3795,7 @@ ossl_init_session_and_alpns(struct ossl_ctx *octx,
             }
           }
 #else
+          (void)ssl_config;
           (void)sess_reuse_cb;
 #endif
         }
index 376d1a67eae371965f5e40586b32ad2cf904a1c5..55a99b3b437c39ba3a8e39fd859cb198a22bfa07 100644 (file)
@@ -927,7 +927,7 @@ schannel_connect_step1(struct Curl_cfilter *cf, struct Curl_easy *data)
   backend->cred = NULL;
 
   /* check for an existing reusable credential handle */
-  if(ssl_config->primary.cache_session) {
+  if(Curl_ssl_scache_use(cf, data)) {
     struct Curl_schannel_cred *old_cred;
     Curl_ssl_scache_lock(data);
     old_cred = Curl_ssl_scache_get_obj(cf, data, connssl->peer.scache_key);
@@ -1530,7 +1530,6 @@ schannel_connect_step3(struct Curl_cfilter *cf, struct Curl_easy *data)
   struct ssl_connect_data *connssl = cf->ctx;
   struct schannel_ssl_backend_data *backend =
     (struct schannel_ssl_backend_data *)connssl->backend;
-  struct ssl_config_data *ssl_config = Curl_ssl_cf_get_config(cf, data);
   CURLcode result = CURLE_OK;
   SECURITY_STATUS sspi_status = SEC_E_OK;
   CERT_CONTEXT *ccert_context = NULL;
@@ -1598,7 +1597,7 @@ schannel_connect_step3(struct Curl_cfilter *cf, struct Curl_easy *data)
 #endif
 
   /* save the current session data for possible reuse */
-  if(ssl_config->primary.cache_session) {
+  if(Curl_ssl_scache_use(cf, data)) {
     Curl_ssl_scache_lock(data);
     /* Up ref count since call takes ownership */
     backend->cred->refcount++;
index 8203baa9038bc2b162d22af51fd0bbad6dd0f272..b9abc6e3faed04383009ae489554fa6a6348ed5b 100644 (file)
@@ -353,6 +353,15 @@ void Curl_ssl_scache_destroy(struct Curl_ssl_scache *scache)
   }
 }
 
+bool Curl_ssl_scache_use(struct Curl_cfilter *cf, struct Curl_easy *data)
+{
+  if(cf_ssl_scache_get(data)) {
+    struct ssl_config_data *ssl_config = Curl_ssl_cf_get_config(cf, data);
+    return ssl_config ? ssl_config->primary.cache_session : FALSE;
+  }
+  return FALSE;
+}
+
 /* Lock shared SSL session data */
 void Curl_ssl_scache_lock(struct Curl_easy *data)
 {
index deedccfe8c66ef28a9eb71fbd73f718b657be3eb..445f21054937b0cef091f45254dd75d28bd8a544 100644 (file)
@@ -65,6 +65,12 @@ CURLcode Curl_ssl_peer_key_make(struct Curl_cfilter *cf,
                                 const char *tls_id,
                                 char **ppeer_key);
 
+/* Return if there is a session cache shall be used.
+ * An ssl session might not be configured or not available for
+ * "connect-only" transfers.
+ */
+bool Curl_ssl_scache_use(struct Curl_cfilter *cf, struct Curl_easy *data);
+
 /* Lock session cache mutex.
  * Call this before calling other Curl_ssl_*session* functions
  * Caller should unlock this mutex as soon as possible, as it may block
index 1efb5dc370943530488261999a893a59360eebcd..9639709fdbe0ef386f866ac8275635c599c0bcbe 100644 (file)
@@ -1257,7 +1257,7 @@ CURLcode Curl_wssl_ctx_init(struct wssl_ctx *wctx,
   }
 #endif
 
-  if(ssl_config->primary.cache_session && (transport != TRNSPRT_QUIC)) {
+  if(Curl_ssl_scache_use(cf, data) && (transport != TRNSPRT_QUIC)) {
     /* Register to get notified when a new session is received */
     wolfSSL_CTX_sess_set_new_cb(wctx->ssl_ctx, wssl_vtls_new_session_cb);
   }
@@ -1316,7 +1316,7 @@ CURLcode Curl_wssl_ctx_init(struct wssl_ctx *wctx,
 #endif
 
   /* Check if there is a cached ID we can/should use here! */
-  if(ssl_config->primary.cache_session) {
+  if(Curl_ssl_scache_use(cf, data)) {
     /* Set session from cache if there is one */
     (void)wssl_setup_session(cf, data, wctx, &alpns,
                              peer->scache_key, sess_reuse_cb);