]> 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>
Sat, 11 Jan 2025 21:02:29 +0000 (16:02 -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 e6d890fa407c1a6b41a6789972c8315fe16f2043..9bb14baf57b9a95ade25debda695d17bfb1ed5e7 100644 (file)
@@ -2166,8 +2166,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);
 
@@ -2281,14 +2281,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
@@ -2304,9 +2310,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;