From: Stefan Eissing Date: Mon, 27 Oct 2025 09:33:41 +0000 (+0100) Subject: ssl-session-cache: check use on config and availability X-Git-Tag: curl-8_17_0~75 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=c82a70628dea815364ed41f30e2f6b8eb87f9fdd;p=thirdparty%2Fcurl.git ssl-session-cache: check use on config and availability 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 --- diff --git a/lib/vquic/curl_ngtcp2.c b/lib/vquic/curl_ngtcp2.c index 3b918cd870..3493f996ce 100644 --- a/lib/vquic/curl_ngtcp2.c +++ b/lib/vquic/curl_ngtcp2.c @@ -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); } diff --git a/lib/vtls/gtls.c b/lib/vtls/gtls.c index 19c2ce893f..c79f192e82 100644 --- a/lib/vtls/gtls.c +++ b/lib/vtls/gtls.c @@ -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 diff --git a/lib/vtls/mbedtls.c b/lib/vtls/mbedtls.c index 89d4eff64e..ea8981b3cd 100644 --- a/lib/vtls/mbedtls.c +++ b/lib/vtls/mbedtls.c @@ -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); diff --git a/lib/vtls/openssl.c b/lib/vtls/openssl.c index 535e4118da..838c024221 100644 --- a/lib/vtls/openssl.c +++ b/lib/vtls/openssl.c @@ -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 } diff --git a/lib/vtls/schannel.c b/lib/vtls/schannel.c index 376d1a67ea..55a99b3b43 100644 --- a/lib/vtls/schannel.c +++ b/lib/vtls/schannel.c @@ -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++; diff --git a/lib/vtls/vtls_scache.c b/lib/vtls/vtls_scache.c index 8203baa903..b9abc6e3fa 100644 --- a/lib/vtls/vtls_scache.c +++ b/lib/vtls/vtls_scache.c @@ -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) { diff --git a/lib/vtls/vtls_scache.h b/lib/vtls/vtls_scache.h index deedccfe8c..445f210549 100644 --- a/lib/vtls/vtls_scache.h +++ b/lib/vtls/vtls_scache.h @@ -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 diff --git a/lib/vtls/wolfssl.c b/lib/vtls/wolfssl.c index 1efb5dc370..9639709fdb 100644 --- a/lib/vtls/wolfssl.c +++ b/lib/vtls/wolfssl.c @@ -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);