Add lookup for initial token assignment on channel start

Start assiging initial tokens, and validating them on receipt

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)
This commit is contained in:
Neil Horman 2025-01-16 15:34:33 -05:00
parent a2fe6435ca
commit 29e861a5a6
2 changed files with 45 additions and 7 deletions

View File

@ -18,6 +18,7 @@
#include "internal/qlog_event_helpers.h"
#include "internal/quic_txp.h"
#include "internal/quic_tls.h"
#include "internal/quic_ssl.h"
#include "../ssl_local.h"
#include "quic_channel_local.h"
#include "quic_port_local.h"
@ -2778,8 +2779,18 @@ static void ch_record_state_transition(QUIC_CHANNEL *ch, uint32_t new_state)
ch->handshake_confirmed);
}
static void free_peer_token(const unsigned char *token,
size_t token_len, void *arg)
{
ossl_quic_free_peer_token((QTOK *)arg);
}
int ossl_quic_channel_start(QUIC_CHANNEL *ch)
{
uint8_t *token;
size_t token_len;
void *token_ptr;
if (ch->is_server)
/*
* This is not used by the server. The server moves to active
@ -2795,6 +2806,18 @@ int ossl_quic_channel_start(QUIC_CHANNEL *ch)
if (!ossl_quic_tx_packetiser_set_peer(ch->txp, &ch->cur_peer_addr))
return 0;
/*
* Look to see if we have a token, and if so, set it on the packetiser
*/
if (!ch->is_server && ossl_quic_get_peer_token(ch->port->channel_ctx,
&ch->cur_peer_addr,
&token, &token_len,
&token_ptr)) {
if (!ossl_quic_tx_packetiser_set_initial_token(ch->txp, token,
token_len, free_token,
token_ptr))
free_token(NULL, 0, token_ptr);
}
/* Plug in secrets for the Initial EL. */
if (!ossl_quic_provide_initial_secret(ch->port->engine->libctx,
ch->port->engine->propq,
@ -2827,6 +2850,11 @@ int ossl_quic_channel_start(QUIC_CHANNEL *ch)
return 1;
}
static void free_token(const unsigned char *token, size_t token_len, void *arg)
{
OPENSSL_free((char *)token);
}
/* Start a locally initiated connection shutdown. */
void ossl_quic_channel_local_close(QUIC_CHANNEL *ch, uint64_t app_error_code,
const char *app_reason)
@ -2843,11 +2871,6 @@ void ossl_quic_channel_local_close(QUIC_CHANNEL *ch, uint64_t app_error_code,
ch_start_terminating(ch, &tcause, 0);
}
static void free_token(const unsigned char *buf, size_t buf_len, void *arg)
{
OPENSSL_free((unsigned char *)buf);
}
/**
* ch_restart - Restarts the QUIC channel by simulating loss of the initial
* packet. This forces the packet to be regenerated with the updated protocol

View File

@ -1487,8 +1487,23 @@ static void port_default_packet_handler(QUIC_URXE *e, void *arg,
*/
if (hdr.token != NULL) {
if (port_validate_token(&hdr, port, &e->peer,
&odcid, &scid) == 0)
goto undesirable;
&odcid, &scid) == 0) {
/*
* RFC 9000 s 8.1.3
* When a server receives an Initial packet with an address
* validation token, it MUST attempt to validate the token,
* unless it has already completed address validation.
* If the token is invalid, then the server SHOULD proceed as
* if the client did not have a validated address,
* including potentially sending a Retry packet
* Note: If address validation is disabled, just act like
* The request is valid
*/
if (port->validate_addr == 1) {
port_send_retry(port, &e->peer, &hdr);
goto undesirable;
}
}
}
port_bind_channel(port, &e->peer, &scid, &hdr.dst_conn_id,