From 8f74d8cee3630ede41a4dfa1a85c469d2200c58d Mon Sep 17 00:00:00 2001 From: Neil Horman Date: Fri, 7 Mar 2025 21:52:03 -0500 Subject: [PATCH] If our server channel creates its own qrx, set its initial secret MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit 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 Reviewed-by: Viktor Dukhovni Reviewed-by: Saša Nedvědický (Merged from https://github.com/openssl/openssl/pull/27006) --- ssl/quic/quic_port.c | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/ssl/quic/quic_port.c b/ssl/quic/quic_port.c index 64ebf1c4d65..c333994405e 100644 --- a/ssl/quic/quic_port.c +++ b/ssl/quic/quic_port.c @@ -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 -- 2.47.2