lib: TLS session ticket caching reworked

Described in detail in internal doc TLS-SESSIONS.md

Main points:
- use a new `ssl_peer_key` for cache lookups by connection filters
- recognize differences between TLSv1.3 and other tickets
  * TLSv1.3 tickets are single-use, cache can hold several of them for a peer
  * TLSv1.2 are reused, keep only a single one per peer
- differentiate between ticket BLOB to store (that could be persisted) and object instances
- use put/take/return pattern for cache access
- remember TLS version, ALPN protocol, time received and lifetime of ticket
- auto-expire tickets after their lifetime

Closes #15774
This commit is contained in:
Stefan Eissing 2024-12-18 13:22:35 +01:00 committed by Daniel Stenberg
parent e5e2e09a75
commit fa0ccd9f1f
No known key found for this signature in database
GPG key ID: 5CC908FDB71E12C2
36 changed files with 1784 additions and 780 deletions

View file

@ -2131,7 +2131,8 @@ static int quic_ossl_new_session_cb(SSL *ssl, SSL_SESSION *ssl_sessionid)
ctx = cf ? cf->ctx : NULL;
data = cf ? CF_DATA_CURRENT(cf) : NULL;
if(cf && data && ctx) {
Curl_ossl_add_session(cf, data, &ctx->peer, ssl_sessionid);
Curl_ossl_add_session(cf, data, ctx->peer.scache_key, ssl_sessionid,
SSL_version(ssl), "h3");
return 1;
}
return 0;
@ -2158,7 +2159,8 @@ static int quic_gtls_handshake_cb(gnutls_session_t session, unsigned int htype,
}
switch(htype) {
case GNUTLS_HANDSHAKE_NEW_SESSION_TICKET: {
(void)Curl_gtls_update_session_id(cf, data, session, &ctx->peer, "h3");
(void)Curl_gtls_cache_session(cf, data, ctx->peer.scache_key,
session, -1, "h3");
break;
}
default:
@ -2181,7 +2183,8 @@ static int wssl_quic_new_session_cb(WOLFSSL *ssl, WOLFSSL_SESSION *session)
struct Curl_easy *data = CF_DATA_CURRENT(cf);
DEBUGASSERT(data);
if(data && ctx) {
(void)wssl_cache_session(cf, data, &ctx->peer, session);
(void)Curl_wssl_cache_session(cf, data, ctx->peer.scache_key,
session, wolfSSL_version(ssl), "h3");
}
}
return 0;
@ -2258,10 +2261,6 @@ static CURLcode cf_connect_start(struct Curl_cfilter *cf,
int qfd;
DEBUGASSERT(ctx->initialized);
result = Curl_ssl_peer_init(&ctx->peer, cf, TRNSPRT_QUIC);
if(result)
return result;
#define H3_ALPN "\x2h3\x5h3-29"
result = Curl_vquic_tls_init(&ctx->tls, cf, data, &ctx->peer,
H3_ALPN, sizeof(H3_ALPN) - 1,

View file

@ -1162,9 +1162,6 @@ static CURLcode cf_osslq_ctx_start(struct Curl_cfilter *cf,
BIO_ADDR *baddr = NULL;
DEBUGASSERT(ctx->initialized);
result = Curl_ssl_peer_init(&ctx->peer, cf, TRNSPRT_QUIC);
if(result)
goto out;
#define H3_ALPN "\x2h3"
result = Curl_vquic_tls_init(&ctx->tls, cf, data, &ctx->peer,

View file

@ -1278,10 +1278,6 @@ static CURLcode cf_quiche_ctx_open(struct Curl_cfilter *cf,
if(result)
return result;
result = Curl_ssl_peer_init(&ctx->peer, cf, TRNSPRT_QUIC);
if(result)
return result;
ctx->cfg = quiche_config_new(QUICHE_PROTOCOL_VERSION);
if(!ctx->cfg) {
failf(data, "cannot create quiche config");

View file

@ -50,6 +50,7 @@
#include "multiif.h"
#include "vtls/keylog.h"
#include "vtls/vtls.h"
#include "vtls/vtls_scache.h"
#include "vquic-tls.h"
/* The last 3 #include files should be in this order */
@ -221,7 +222,7 @@ static CURLcode wssl_init_ssl(struct curl_tls_ctx *ctx,
}
if(ssl_config->primary.cache_session) {
(void)wssl_setup_session(cf, data, &ctx->wssl, peer);
(void)Curl_wssl_setup_session(cf, data, &ctx->wssl, peer->scache_key);
}
return CURLE_OK;
@ -236,11 +237,26 @@ CURLcode Curl_vquic_tls_init(struct curl_tls_ctx *ctx,
Curl_vquic_tls_ctx_setup *cb_setup,
void *cb_user_data, void *ssl_user_data)
{
char tls_id[80];
CURLcode result;
#ifdef USE_OPENSSL
Curl_ossl_version(tls_id, sizeof(tls_id));
#elif defined(USE_GNUTLS)
Curl_gtls_version(tls_id, sizeof(tls_id));
#elif defined(USE_WOLFSSL)
Curl_wssl_version(tls_id, sizeof(tls_id));
#else
#error "no TLS lib in used, should not happen"
return CURLE_FAILED_INIT;
#endif
result = Curl_ssl_peer_init(peer, cf, tls_id, TRNSPRT_QUIC);
if(result)
return result;
#ifdef USE_OPENSSL
(void)result;
return Curl_ossl_ctx_init(&ctx->ossl, cf, data, peer, TRNSPRT_QUIC,
return Curl_ossl_ctx_init(&ctx->ossl, cf, data, peer,
(const unsigned char *)alpn, alpn_len,
cb_setup, cb_user_data, NULL, ssl_user_data);
#elif defined(USE_GNUTLS)
@ -346,6 +362,9 @@ CURLcode Curl_vquic_tls_verify_peer(struct curl_tls_ctx *ctx,
}
#endif
/* on error, remove any session we might have in the pool */
if(result)
Curl_ssl_scache_remove_all(cf, data, peer->scache_key);
return result;
}

View file

@ -26,6 +26,7 @@
#include "curl_setup.h"
#include "bufq.h"
#include "vtls/vtls.h"
#include "vtls/openssl.h"
#if defined(USE_HTTP3) && \
@ -33,6 +34,8 @@
#include "vtls/wolfssl.h"
struct ssl_peer;
struct curl_tls_ctx {
#ifdef USE_OPENSSL
struct ossl_ctx ossl;