From 26989578f96dda41f2a5673d4f74d809537a7e83 Mon Sep 17 00:00:00 2001 From: Neil Horman Date: Wed, 15 Jan 2025 15:16:24 -0500 Subject: [PATCH] extend internal api to allow for add/lookup token ops MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit Reviewed-by: Matt Caswell Reviewed-by: Saša Nedvědický (Merged from https://github.com/openssl/openssl/pull/26517) --- include/internal/quic_ssl.h | 4 ++ ssl/quic/quic_impl.c | 125 ++++++++++++++++++++++++++++++++++++ 2 files changed, 129 insertions(+) diff --git a/include/internal/quic_ssl.h b/include/internal/quic_ssl.h index e01de740c24..da00816940d 100644 --- a/include/internal/quic_ssl.h +++ b/include/internal/quic_ssl.h @@ -29,6 +29,10 @@ 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_get_token_store(SSL_CTX *ctx); int ossl_quic_set_token_store(SSL_CTX *ctx, SSL_TOKEN_STORE_HANDLE *hdl); +int ossl_quic_update_peer_token(SSL_CTX *ctx, BIO_ADDR *peer, + 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); __owur int ossl_quic_init(SSL *s); void ossl_quic_deinit(SSL *s); diff --git a/ssl/quic/quic_impl.c b/ssl/quic/quic_impl.c index 8a03483a8ac..cccad727d5c 100644 --- a/ssl/quic/quic_impl.c +++ b/ssl/quic/quic_impl.c @@ -4741,6 +4741,131 @@ int ossl_quic_set_token_store(SSL_CTX *ctx, SSL_TOKEN_STORE_HANDLE *hdl) return 1; } +/** + * @brief build a new QUIC_TOKEN + * + * This function creates a new token storage structure for saving in our + * tokencache + * + * In an effort to make allocation and freeing of these tokens a bit faster + * We do them in a single allocation in this format + * +---------------+ --\ + * | hashkey * |---| | + * | hashkey_len | | | QUIC_TOKEN + * | token * |---|--| | + * | token_len | | | | + * +---------------+<--| | --/ + * | hashkey buf | | + * | | | + * |---------------|<-----| + * | token buf | + * | | + * +---------------+ + * + * @param peer - the peer address that sent the token + * @param token - the buffer holding the token + * @param token_len - the size of token + * + * @returns a QUIC_TOKEN pointer or NULL on error + */ +static QUIC_TOKEN *ossl_quic_build_new_token(BIO_ADDR *peer, uint8_t *token, + size_t token_len) +{ + QUIC_TOKEN *new_token; + size_t hashkey_len = 0; + size_t addr_len = 0; + int family; + unsigned short port; + int *famptr; + unsigned short *portptr; + uint8_t *addrptr; + + if (!BIO_ADDR_rawaddress(peer, NULL, &addr_len)) + return NULL; + family = BIO_ADDR_family(peer); + port = BIO_ADDR_rawport(peer); + + hashkey_len += sizeof(int); /*hashkey(family)*/ + hashkey_len += sizeof(unsigned short); /*hashkey(port)*/ + hashkey_len += addr_len; /*hashkey(address)*/ + + new_token = OPENSSL_zalloc(sizeof(QUIC_TOKEN) + hashkey_len + token_len); + if (new_token == NULL) + return NULL; + new_token->hashkey_len = hashkey_len; + new_token->hashkey = (uint8_t *)(new_token + 1); /*hashkey lives after the struct */ + new_token->token = new_token->hashkey + hashkey_len; /*token follows */ + new_token->token_len = token_len; + famptr = (int *)new_token->hashkey; + portptr = (unsigned short *)(famptr + 1); + addrptr = (uint8_t *)(portptr + 1); + *famptr = family; + *portptr = port; + BIO_ADDR_rawaddress(peer, addrptr, NULL); + if (token != NULL) + memcpy(new_token->token, token, token_len); + + return new_token; +} + +int ossl_quic_update_peer_token(SSL_CTX *ctx, BIO_ADDR *peer, + uint8_t *token, size_t token_len) +{ + SSL_TOKEN_STORE *c = ctx->tokencache; + QUIC_TOKEN *tok, *old = NULL; + + if (ctx->tokencache == NULL) + return 0; + + tok = ossl_quic_build_new_token(peer, token, token_len); + if (tok == NULL) + return 0; + + /* we might be sharing this cache, lock it */ + ossl_crypto_mutex_lock(c->mutex); + + old = lh_QUIC_TOKEN_retrieve(c->cache, tok); + if (old != NULL) + lh_QUIC_TOKEN_delete(c->cache, tok); + lh_QUIC_TOKEN_insert(c->cache, tok); + + ossl_crypto_mutex_unlock(c->mutex); + free_quic_token(old); + return 1; +} + +int ossl_quic_get_peer_token(SSL_CTX *ctx, BIO_ADDR *peer, + uint8_t **token, size_t *token_len) +{ + SSL_TOKEN_STORE *c = ctx->tokencache; + QUIC_TOKEN *key = NULL; + QUIC_TOKEN *tok = NULL; + int rc = 0; + + if (c == NULL) + return 0; + + key = ossl_quic_build_new_token(peer, NULL, 0); + ossl_crypto_mutex_lock(c->mutex); + tok = lh_QUIC_TOKEN_retrieve(c->cache, key); + if (tok != NULL) { + if (tok->token_len > *token_len) { + tok = NULL; /*allow reuse here */ + goto out; + } + memcpy(*token, tok->token, tok->token_len); + *token_len = tok->token_len; + lh_QUIC_TOKEN_delete(c->cache, key); + rc = 1; + } + +out: + ossl_crypto_mutex_unlock(c->mutex); + free_quic_token(tok); + free_quic_token(key); + return rc; +} + /* * SSL_get_accept_connection_queue_len * ----------------------------------- -- 2.47.2