]> git.ipfire.org Git - thirdparty/openssl.git/commitdiff
If our server channel creates its own qrx, set its initial secret
authorNeil Horman <nhorman@openssl.org>
Sat, 8 Mar 2025 02:52:03 +0000 (21:52 -0500)
committerNeil Horman <nhorman@openssl.org>
Sat, 8 Mar 2025 02:56:34 +0000 (21:56 -0500)
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)

ssl/quic/quic_port.c

index 64ebf1c4d657f09fe8184900bc553c032cc9e2f7..c333994405ed26bad84308d212a5a1144bd38cc3 100644 (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