Commit ecdb79eeb9 for openssl.org
commit ecdb79eeb94417062fdb2668df469482e3e1eaa0
Author: Mounir IDRASSI <mounir.idrassi@idrix.fr>
Date: Wed Sep 16 21:37:04 2026 +0900
DTLS: reject trailing bytes after the ACK record number vector
Require the length-prefixed record number vector to consume the entire
DTLS 1.3 ACK body. Previously, dtls_process_ack() ignored bytes following
the vector.
Add direct parser tests for empty and single-entry ACKs, both with and
without trailing data. Both trailing-data cases are accepted without
the fix, while the valid encodings remain accepted with it.
Assisted-by: Codex:gpt-6-astra
Reviewed-by: Matt Caswell <matt@openssl.foundation>
Reviewed-by: Frederik Wedel-Heinen <fwh.openssl@gmail.com>
Merge-date: Fri Sep 18 09:22:41 2026
Merged-from: https://github.com/openssl/openssl/pull/32850
diff --git a/ssl/statem/statem_dtls.c b/ssl/statem/statem_dtls.c
index 76e307b9fb..3fe9403bbc 100644
--- a/ssl/statem/statem_dtls.c
+++ b/ssl/statem/statem_dtls.c
@@ -1270,7 +1270,7 @@ MSG_PROCESS_RETURN dtls_process_ack(SSL_CONNECTION *s, PACKET *pkt)
{
PACKET record_numbers;
- if (!PACKET_get_length_prefixed_2(pkt, &record_numbers)) {
+ if (!PACKET_as_length_prefixed_2(pkt, &record_numbers)) {
SSLfatal(s, SSL_AD_ILLEGAL_PARAMETER, SSL_R_LENGTH_TOO_LONG);
return MSG_PROCESS_ERROR;
}
diff --git a/test/dtls13_internal_test.c b/test/dtls13_internal_test.c
index 8c2a580d4f..5a6d9b61e8 100644
--- a/test/dtls13_internal_test.c
+++ b/test/dtls13_internal_test.c
@@ -9,10 +9,12 @@
#include "../ssl/record/methods/recmethod_local.h"
#include "../ssl/ssl_local.h"
+#include "../ssl/statem/statem_local.h"
#include "internal/nelem.h"
#include "internal/ssl_unwrap.h"
#include "helpers/ssltestlib.h"
#include "testutil.h"
+#include <openssl/err.h>
#include <openssl/evp.h>
#include <openssl/ssl.h>
@@ -166,6 +168,48 @@ static int test_seq_num_reconstruction(int idx)
}
#ifndef OPENSSL_NO_DTLS1_3
+/* Empty and single-entry ACK vectors, with and without trailing data. */
+static int test_dtls13_ack_length(int idx)
+{
+ SSL_CTX *ctx = NULL;
+ SSL *ssl = NULL;
+ SSL_CONNECTION *sc;
+ BIO *wbio;
+ unsigned char ack[2 + 16 + 1] = { 0 };
+ size_t len = idx < 2 ? 2 : 18;
+ int trailing = idx % 2;
+ PACKET pkt;
+ int testresult = 0;
+
+ ack[1] = (unsigned char)(len - 2);
+ ack[len] = 0xff;
+
+ if (!TEST_ptr(ctx = SSL_CTX_new(DTLS_method()))
+ || !TEST_ptr(ssl = SSL_new(ctx))
+ || !TEST_ptr(sc = SSL_CONNECTION_FROM_SSL(ssl))
+ || !TEST_true(PACKET_buf_init(&pkt, ack, len + trailing))
+ || !TEST_ptr(wbio = BIO_new(BIO_s_mem())))
+ goto end;
+
+ SSL_set0_wbio(ssl, wbio);
+
+ if (!TEST_int_eq(dtls_process_ack(sc, &pkt),
+ trailing ? MSG_PROCESS_ERROR : MSG_PROCESS_FINISHED_READING))
+ goto end;
+
+ if (trailing
+ && !TEST_int_eq(ERR_GET_REASON(ERR_peek_last_error()),
+ SSL_R_LENGTH_TOO_LONG))
+ goto end;
+
+ testresult = 1;
+end:
+ SSL_free(ssl);
+ SSL_CTX_free(ctx);
+ ERR_clear_error();
+ return testresult;
+}
+
/*
* Test that dtls1_increment_epoch() enforces the RFC 9147 Section 8 limit
* on the write (sending) epoch for DTLS 1.3: "sending implementations MUST
@@ -241,6 +285,7 @@ int setup_tests(void)
ADD_ALL_TESTS(test_dtls_crypt_sequence_number, OSSL_NELEM(cipher_names));
ADD_ALL_TESTS(test_seq_num_reconstruction, OSSL_NELEM(seq_num_tests));
#ifndef OPENSSL_NO_DTLS1_3
+ ADD_ALL_TESTS(test_dtls13_ack_length, 4);
ADD_TEST(test_dtls13_increment_epoch_max);
#endif
return 1;