From: Neil Horman Date: Thu, 30 Jan 2025 19:38:18 +0000 (-0500) Subject: Modify ossl_quic_get_peer_token to return QUIC_TOKEN X-Git-Tag: openssl-3.5.0-alpha1~225 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=f0e516522cbf50f3b58eed461375f37ac842eed1;p=thirdparty%2Fopenssl.git Modify ossl_quic_get_peer_token to return QUIC_TOKEN we use this struct internally to track computed tokens, we may as well use it when fetching those tokens, as it allows the removeal of the QTOK type Reviewed-by: Matt Caswell Reviewed-by: Saša Nedvědický (Merged from https://github.com/openssl/openssl/pull/26517) --- diff --git a/include/internal/quic_ssl.h b/include/internal/quic_ssl.h index 17cac02cc03..bf0e079afb7 100644 --- a/include/internal/quic_ssl.h +++ b/include/internal/quic_ssl.h @@ -12,6 +12,7 @@ # include # include +# include "internal/refcount.h" # include "internal/quic_record_rx.h" /* OSSL_QRX */ # include "internal/quic_ackm.h" /* OSSL_ACKM */ # include "internal/quic_channel.h" /* QUIC_CHANNEL */ @@ -25,7 +26,17 @@ __owur SSL *ossl_quic_new_listener_from(SSL *ssl, uint64_t flags); __owur SSL *ossl_quic_new_from_listener(SSL *ssl, uint64_t flags); __owur SSL *ossl_quic_new_domain(SSL_CTX *ctx, uint64_t flags); -typedef void QTOK; +/* + * Datatype returned from ossl_quic_get_peer_token + */ +typedef struct quic_token_st { + CRYPTO_REF_COUNT references; + uint8_t *hashkey; + size_t hashkey_len; + uint8_t *token; + size_t token_len; +} QUIC_TOKEN; + SSL_TOKEN_STORE_HANDLE *ossl_quic_new_token_store(void); void ossl_quic_free_token_store(SSL_TOKEN_STORE_HANDLE *hdl); SSL_TOKEN_STORE_HANDLE *ossl_quic_get0_token_store(SSL_CTX *ctx); @@ -33,9 +44,8 @@ int ossl_quic_set1_token_store(SSL_CTX *ctx, SSL_TOKEN_STORE_HANDLE *hdl); int ossl_quic_set_peer_token(SSL_CTX *ctx, BIO_ADDR *peer, const uint8_t *token, size_t token_len); int ossl_quic_get_peer_token(SSL_CTX *ctx, BIO_ADDR *peer, - uint8_t **token, size_t *token_len, - QTOK **token_free_ptr); -void ossl_quic_free_peer_token(QTOK *token); + QUIC_TOKEN **token); +void ossl_quic_free_peer_token(QUIC_TOKEN *token); __owur int ossl_quic_init(SSL *s); void ossl_quic_deinit(SSL *s); diff --git a/ssl/quic/quic_channel.c b/ssl/quic/quic_channel.c index a180f1ce8de..762c333d24b 100644 --- a/ssl/quic/quic_channel.c +++ b/ssl/quic/quic_channel.c @@ -1128,6 +1128,14 @@ static int ch_on_handshake_complete(void *arg) ch->handshake_complete = 1; if (ch->pending_new_token != NULL) { + /* + * Note this is a best effort operation here + * If scheduling a new token fails, the worst outcome is that + * a client, not having received it, will just have to go through + * an extra roundtrip on a subsequent connection via the retry frame + * path, at which point we get another opportunity to schedule another + * new token. As a result, we don't need to handle any errors here + */ ossl_quic_channel_schedule_new_token(ch, ch->pending_new_token, ch->pending_new_token_len); @@ -2792,14 +2800,12 @@ static void ch_record_state_transition(QUIC_CHANNEL *ch, uint32_t new_state) static void free_peer_token(const unsigned char *token, size_t token_len, void *arg) { - ossl_quic_free_peer_token((QTOK *)arg); + ossl_quic_free_peer_token((QUIC_TOKEN *)arg); } int ossl_quic_channel_start(QUIC_CHANNEL *ch) { - uint8_t *token; - size_t token_len; - QTOK *token_ptr; + QUIC_TOKEN *token; if (ch->is_server) /* @@ -2822,13 +2828,12 @@ int ossl_quic_channel_start(QUIC_CHANNEL *ch) if (!ch->is_server && ossl_quic_get_peer_token(ch->port->channel_ctx, &ch->cur_peer_addr, - &token, &token_len, - &token_ptr) - && !ossl_quic_tx_packetiser_set_initial_token(ch->txp, token, - token_len, + &token) + && !ossl_quic_tx_packetiser_set_initial_token(ch->txp, token->token, + token->token_len, free_peer_token, - token_ptr)) - free_peer_token(NULL, 0, token_ptr); + token)) + free_peer_token(NULL, 0, token); /* Plug in secrets for the Initial EL. */ if (!ossl_quic_provide_initial_secret(ch->port->engine->libctx, diff --git a/ssl/quic/quic_impl.c b/ssl/quic/quic_impl.c index b0ad6fdfa77..f2c3d44800b 100644 --- a/ssl/quic/quic_impl.c +++ b/ssl/quic/quic_impl.c @@ -4632,17 +4632,6 @@ err: return NULL; } -/* - * Token store management - */ -typedef struct quic_token_st { - CRYPTO_REF_COUNT references; - uint8_t *hashkey; - size_t hashkey_len; - uint8_t *token; - size_t token_len; -} QUIC_TOKEN; - DEFINE_LHASH_OF_EX(QUIC_TOKEN); typedef struct ssl_token_store_st { @@ -4706,7 +4695,7 @@ out: static void free_this_token(QUIC_TOKEN *tok) { - ossl_quic_free_peer_token((QTOK *)tok); + ossl_quic_free_peer_token(tok); } void ossl_quic_free_token_store(SSL_TOKEN_STORE_HANDLE *hdl) @@ -4823,7 +4812,7 @@ static QUIC_TOKEN *ossl_quic_build_new_token(BIO_ADDR *peer, uint8_t *token, *famptr = family; *portptr = port; if (!BIO_ADDR_rawaddress(peer, addrptr, NULL)) { - ossl_quic_free_peer_token((QTOK *)new_token); + ossl_quic_free_peer_token(new_token); return NULL; } if (token != NULL) @@ -4850,7 +4839,7 @@ int ossl_quic_set_peer_token(SSL_CTX *ctx, BIO_ADDR *peer, old = lh_QUIC_TOKEN_retrieve(c->cache, tok); if (old != NULL) { lh_QUIC_TOKEN_delete(c->cache, old); - ossl_quic_free_peer_token((QTOK *)old); + ossl_quic_free_peer_token(old); } lh_QUIC_TOKEN_insert(c->cache, tok); @@ -4859,8 +4848,7 @@ int ossl_quic_set_peer_token(SSL_CTX *ctx, BIO_ADDR *peer, } int ossl_quic_get_peer_token(SSL_CTX *ctx, BIO_ADDR *peer, - uint8_t **token, size_t *token_len, - QTOK **token_free_ptr) + QUIC_TOKEN **token) { SSL_TOKEN_STORE *c = ctx->tokencache; QUIC_TOKEN *key = NULL; @@ -4875,31 +4863,28 @@ int ossl_quic_get_peer_token(SSL_CTX *ctx, BIO_ADDR *peer, ossl_crypto_mutex_lock(c->mutex); tok = lh_QUIC_TOKEN_retrieve(c->cache, key); if (tok != NULL) { - *token = tok->token; - *token_len = tok->token_len; - *token_free_ptr = (QTOK *)tok; + *token = tok; CRYPTO_UP_REF(&tok->references, &ret); rc = 1; } ossl_crypto_mutex_unlock(c->mutex); - ossl_quic_free_peer_token((QTOK *)key); + ossl_quic_free_peer_token(key); return rc; } -void ossl_quic_free_peer_token(QTOK *token) +void ossl_quic_free_peer_token(QUIC_TOKEN *token) { - QUIC_TOKEN *tok = (QUIC_TOKEN *)token; int refs = 0; - if (!CRYPTO_DOWN_REF(&tok->references, &refs)) + if (!CRYPTO_DOWN_REF(&token->references, &refs)) return; if (refs > 0) return; - CRYPTO_FREE_REF(&tok->references); - OPENSSL_free(tok); + CRYPTO_FREE_REF(&token->references); + OPENSSL_free(token); } /* diff --git a/ssl/ssl_lib.c b/ssl/ssl_lib.c index 19d274b1b9a..6a6af9ebf61 100644 --- a/ssl/ssl_lib.c +++ b/ssl/ssl_lib.c @@ -4216,7 +4216,8 @@ SSL_CTX *SSL_CTX_new_ex(OSSL_LIB_CTX *libctx, const char *propq, # ifndef OPENSSL_NO_QUIC /* only create a cache for client CTX-es */ if (meth == OSSL_QUIC_client_method()) - ret->tokencache = ossl_quic_new_token_store(); + if ((ret->tokencache = ossl_quic_new_token_store()) == NULL) + goto err; ret->domain_flags = 0; if (IS_QUIC_METHOD(meth)) { # if defined(OPENSSL_THREADS)