]> git.ipfire.org Git - thirdparty/openssl.git/commitdiff
Schedule new token frame after handshake complete
authorNeil Horman <nhorman@openssl.org>
Sat, 25 Jan 2025 00:51:01 +0000 (19:51 -0500)
committerNeil Horman <nhorman@openssl.org>
Mon, 17 Feb 2025 16:27:33 +0000 (11:27 -0500)
We don't want to schedule the NEW_TOKEN frame until such time as the
handshake is complete, otherwise we risk giving a token to validate a
future connection to a peer we haven't decided to trust yet

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)

ssl/quic/quic_channel.c
ssl/quic/quic_channel_local.h
ssl/quic/quic_impl.c
ssl/quic/quic_port.c

index a9b453e69f223f0bee336c2fdee09dfc1cbc4051..bfefa272c34755b9101a9ee4a26f11a278df624c 100644 (file)
@@ -405,6 +405,7 @@ static void ch_cleanup(QUIC_CHANNEL *ch)
     OPENSSL_free((char *)ch->terminate_cause.reason);
     OSSL_ERR_STATE_free(ch->err_state);
     OPENSSL_free(ch->ack_range_scratch);
+    OPENSSL_free(ch->pending_new_token);
 
     if (ch->on_port_list) {
         ossl_list_ch_remove(&ch->port->channel_list, ch);
@@ -1126,6 +1127,15 @@ static int ch_on_handshake_complete(void *arg)
 
     ch->handshake_complete = 1;
 
+    if (ch->pending_new_token != NULL) {
+        ossl_quic_channel_schedule_new_token(ch,
+                                             ch->pending_new_token,
+                                             ch->pending_new_token_len);
+        OPENSSL_free(ch->pending_new_token);
+        ch->pending_new_token = NULL;
+        ch->pending_new_token_len = 0;
+    }
+
     if (ch->is_server) {
         /*
          * On the server, the handshake is confirmed as soon as it is complete.
index 63f10412189beb51ee6f015bc607f05724b9398b..6ba6366f4b58b4cda629592648a0f77ca5034821 100644 (file)
@@ -60,6 +60,12 @@ struct quic_channel_st {
      */
     unsigned char                   *local_transport_params;
 
+    /*
+     * Pending new token to send once handshake is complete
+     */
+    uint8_t                         *pending_new_token;
+    size_t                          pending_new_token_len;
+
     /* Our current L4 peer address, if any. */
     BIO_ADDR                        cur_peer_addr;
 
index 1afa4f27a8e21eb259bb21a628219981e0370943..4f99a68934b1ebcf750574b8be1de574e77a3a14 100644 (file)
@@ -4815,7 +4815,6 @@ static QUIC_TOKEN *ossl_quic_build_new_token(BIO_ADDR *peer, uint8_t *token,
     BIO_ADDR_rawaddress(peer, addrptr, NULL);
     if (token != NULL)
         memcpy(new_token->token, token, token_len);
-
     return new_token;
 }
 
@@ -4836,12 +4835,13 @@ int ossl_quic_update_peer_token(SSL_CTX *ctx, BIO_ADDR *peer,
     ossl_crypto_mutex_lock(c->mutex);
 
     old = lh_QUIC_TOKEN_retrieve(c->cache, tok);
-    if (old != NULL)
-        lh_QUIC_TOKEN_delete(c->cache, tok);
+    if (old != NULL) {
+        lh_QUIC_TOKEN_delete(c->cache, old);
+        free_quic_token(old);
+    }
     lh_QUIC_TOKEN_insert(c->cache, tok);
 
     ossl_crypto_mutex_unlock(c->mutex);
-    free_quic_token(old);
     return 1;
 }
 
@@ -4861,11 +4861,6 @@ 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) {
-        if (tok->token_len > *token_len) {
-            /* allow reuse here */
-            tok = NULL;
-            goto out;
-        }
         *token = tok->token;
         *token_len = tok->token_len;
         *token_free_ptr = tok;
@@ -4873,7 +4868,6 @@ int ossl_quic_get_peer_token(SSL_CTX *ctx, BIO_ADDR *peer,
         rc = 1;
     }
 
-out:
     ossl_crypto_mutex_unlock(c->mutex);
     free_quic_token(key);
     return rc;
index f85c5579ef698c370d00eca2a7fccaa499ee2b49..e6e2762463f2207c455f69532c2da153a7f6b457 100644 (file)
@@ -1348,7 +1348,7 @@ static void generate_new_token(QUIC_CHANNEL *ch, BIO_ADDR *peer)
     QUIC_CONN_ID rscid = { 0 };
     QUIC_VALIDATION_TOKEN token;
     unsigned char buffer[ENCRYPTED_TOKEN_MAX_LEN];
-    unsigned char ct_buf[ENCRYPTED_TOKEN_MAX_LEN];
+    unsigned char *ct_buf;
     size_t ct_len;
     size_t token_buf_len = 0;
 
@@ -1356,6 +1356,10 @@ static void generate_new_token(QUIC_CHANNEL *ch, BIO_ADDR *peer)
     if (!ch->is_server)
         return;
 
+    ct_buf = OPENSSL_zalloc(ENCRYPTED_TOKEN_MAX_LEN);
+    if (ct_buf == NULL)
+        return;
+
     if (!ossl_quic_lcidm_get_unused_cid(ch->port->lcidm, &rscid))
         return;
 
@@ -1366,10 +1370,14 @@ static void generate_new_token(QUIC_CHANNEL *ch, BIO_ADDR *peer)
         || ct_len > ENCRYPTED_TOKEN_MAX_LEN
         || !encrypt_validation_token(ch->port, buffer, token_buf_len, ct_buf,
                                      &ct_len)
-        || !ossl_assert(ct_len >= QUIC_RETRY_INTEGRITY_TAG_LEN))
+        || !ossl_assert(ct_len >= QUIC_RETRY_INTEGRITY_TAG_LEN)) {
+        OPENSSL_free(ct_buf);
         return;
+    }
+
+    ch->pending_new_token = ct_buf;
+    ch->pending_new_token_len = ct_len;
 
-    ossl_quic_channel_schedule_new_token(ch, ct_buf, ct_len);
     cleanup_validation_token(&token);
 }