]> git.ipfire.org Git - thirdparty/openssl.git/commitdiff
extend internal api to allow for add/lookup token ops
authorNeil Horman <nhorman@openssl.org>
Wed, 15 Jan 2025 20:16:24 +0000 (15:16 -0500)
committerNeil Horman <nhorman@openssl.org>
Tue, 4 Feb 2025 14:12:04 +0000 (09:12 -0500)
Reviewed-by: Matt Caswell <matt@openssl.org>
Reviewed-by: Saša Nedvědický <sashan@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/26517)

include/internal/quic_ssl.h
ssl/quic/quic_impl.c

index e01de740c2482e8eae6e459199dcc1cad3ddac63..da00816940dbebeceae4644af16bfce0e6da75d9 100644 (file)
@@ -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);
index 8a03483a8acd264ef28144616d6e01f42e6f15ec..cccad727d5c003edb160e2e7cd1435c032b2b393 100644 (file)
@@ -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
  * -----------------------------------