]> git.ipfire.org Git - thirdparty/openssl.git/commitdiff
Make version negotiation packets use network byte order
authorNeil Horman <nhorman@openssl.org>
Thu, 21 Nov 2024 14:18:53 +0000 (09:18 -0500)
committerNeil Horman <nhorman@openssl.org>
Mon, 17 Feb 2025 16:27:33 +0000 (11:27 -0500)
@t8m pointed out that versino negotiation packets weren't guaranteeing
network byte ordering in the array of supported versions.

Convert the client to use network byte order on send and receipt.

Reviewed-by: Tomas Mraz <tomas@openssl.org>
Reviewed-by: Saša Nedvědický <sashan@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/25968)

ssl/quic/quic_channel.c
ssl/quic/quic_port.c

index dad12b7e6357dd148ae474a2dd9c74f8598d7f32..6b4aee68d85159994868a81a03443ad46592f3ed 100644 (file)
@@ -2186,8 +2186,8 @@ static void ch_rx_handle_packet(QUIC_CHANNEL *ch, int channel_only)
     uint32_t enc_level;
     int old_have_processed_any_pkt = ch->have_processed_any_pkt;
     OSSL_QTX_IOVEC iovec;
-    uint32_t *supported_ver;
-    size_t remaining_len;
+    PACKET vpkt;
+    unsigned long supported_ver;
 
     assert(ch->qrx_pkt != NULL);
 
@@ -2301,14 +2301,20 @@ static void ch_rx_handle_packet(QUIC_CHANNEL *ch, int channel_only)
          * needs to be traversed so that we can find a matching
          * version
          */
-        supported_ver = (uint32_t *)ch->qrx_pkt->hdr->data;
-        remaining_len = ch->qrx_pkt->hdr->len;
-        while (remaining_len > 0) {
+        if (!PACKET_buf_init(&vpkt, ch->qrx_pkt->hdr->data,
+                             ch->qrx_pkt->hdr->len))
+            return;
+
+        while (PACKET_remaining(&vpkt) > 0) {
             /*
              * We only support quic version 1 at the moment, so
              * look to see if thats offered
              */
-            if (*supported_ver == QUIC_VERSION_1) {
+            if (!PACKET_get_net_4(&vpkt, &supported_ver))
+                return;
+
+            supported_ver = ntohl(supported_ver);
+            if (supported_ver == QUIC_VERSION_1) {
                 /*
                  * If the server supports version 1, set it as
                  * the packetisers version
@@ -2324,9 +2330,6 @@ static void ch_rx_handle_packet(QUIC_CHANNEL *ch, int channel_only)
                                                            0, "handling ver negotiation packet");
                 return;
             }
-            /* move to the next supported ver */
-            supported_ver++;
-            remaining_len -= sizeof(uint32_t);
         }
 
         /*
index 0571d6c39958d30c12c14db804d1fe097ce03696..58dbe60b38953ba69b0b66650728bb86f39e8deb 100644 (file)
@@ -784,6 +784,7 @@ static void port_send_version_negotiation(QUIC_PORT *port, BIO_ADDR *peer,
     WPACKET wpkt;
     uint32_t supported_versions[1];
     size_t written;
+    size_t i;
 
     memset(&hdr, 0, sizeof(QUIC_PKT_HDR));
     /*
@@ -825,8 +826,10 @@ static void port_send_version_negotiation(QUIC_PORT *port, BIO_ADDR *peer,
     /*
      * Add the array of supported versions to the end of the packet
      */
-    if (!WPACKET_memcpy(&wpkt, supported_versions, sizeof(supported_versions)))
-        return;
+    for (i = 0; i < OSSL_NELEM(supported_versions); i++) {
+        if (!WPACKET_put_bytes_u32(&wpkt, htonl(supported_versions[i])))
+            return;
+    }
 
     if (!WPACKET_get_total_written(&wpkt, &msg[0].data_len))
         return;
@@ -967,7 +970,7 @@ static void port_default_packet_handler(QUIC_URXE *e, void *arg,
         /*
          * If we don't get a supported version, respond with a ver
          * negotiation packet, and discard
-         * TODO: Rate limit the reception of these
+         * TODO(QUIC SERVER): Rate limit the reception of these
          */
         port_send_version_negotiation(port, &e->peer, &hdr);
         goto undesirable;