From: Neil Horman Date: Thu, 21 Nov 2024 14:18:53 +0000 (-0500) Subject: Make version negotiation packets use network byte order X-Git-Tag: openssl-3.5.0-alpha1~318 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=128619a43b713b507abd211c9a149a5b16d22dff;p=thirdparty%2Fopenssl.git Make version negotiation packets use network byte order @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 Reviewed-by: Saša Nedvědický (Merged from https://github.com/openssl/openssl/pull/25968) --- diff --git a/ssl/quic/quic_channel.c b/ssl/quic/quic_channel.c index dad12b7e635..6b4aee68d85 100644 --- a/ssl/quic/quic_channel.c +++ b/ssl/quic/quic_channel.c @@ -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); } /* diff --git a/ssl/quic/quic_port.c b/ssl/quic/quic_port.c index 0571d6c3995..58dbe60b389 100644 --- a/ssl/quic/quic_port.c +++ b/ssl/quic/quic_port.c @@ -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;