If our server channel creates its own qrx, set its initial secret

With the addition of larger client hellos, stemming from the use of
larger PQC key shares, it may happen that we get a client hello accross
multiple datagrams. Normally this is not a problem as
port_default_packet_handler allocates a qrx and initializes its initial
secret immediately.  But if server address validation is disabled, then
the channel creates the qrx in port_bind_channel itself, without initial
secrets.  As a result, we validate the first datagram in
port_default_packet_handler, but the subsequent datagrams containing the
remaining client hello fragments fail decode.

Fix it by ensuring that we add the initial secret in port_bind_channel
if we don't give it a preconfigured qrx

Fixes openssl/project#1131

Reviewed-by: Tim Hudson <tjh@openssl.org>
Reviewed-by: Viktor Dukhovni <viktor@openssl.org>
Reviewed-by: Saša Nedvědický <sashan@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/27006)
This commit is contained in:
Neil Horman 2025-03-07 21:52:03 -05:00
parent 8d6fd6142b
commit 8f74d8cee3

View File

@ -741,6 +741,21 @@ static void port_bind_channel(QUIC_PORT *port, const BIO_ADDR *peer,
if (ch == NULL)
return;
/*
* If we didn't provide a qrx here that means we need to set our initial
* secret here, since we just created a qrx
* Normally its not needed, as the initial secret gets added when we send
* our first server hello, but if we get a huge client hello, crossing
* multiple datagrams, we don't have a chance to do that, and datagrams
* after the first won't get decoded properly, for lack of secrets
*/
if (qrx == NULL)
if (!ossl_quic_provide_initial_secret(ch->port->engine->libctx,
ch->port->engine->propq,
dcid, /* is_server */ 1,
ch->qrx, NULL))
return;
if (odcid->id_len != 0) {
/*
* If we have an odcid, then we went through server address validation