Skip to content

Commit 966a247

Browse files
igus68t8m
authored andcommitted
Check the received uncompressed certificate length to prevent excessive
pre-decompression allocation. The patch was proposed by Tomas Dulka and Stanislav Fort (Aisle Research). Fixes: CVE-2025-66199 Reviewed-by: Saša Nedvědický <sashan@openssl.org> Reviewed-by: Tomas Mraz <tomas@openssl.org> MergeDate: Mon Jan 26 19:45:21 2026 (cherry picked from commit 84f73f7)
1 parent 68a7cd2 commit 966a247

3 files changed

Lines changed: 48 additions & 1 deletion

File tree

‎ssl/statem/statem_lib.c‎

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2899,6 +2899,12 @@ MSG_PROCESS_RETURN tls13_process_compressed_certificate(SSL_CONNECTION *sc,
28992899
goto err;
29002900
}
29012901

2902+
/* Prevent excessive pre-decompression allocation */
2903+
if (expected_length > sc->max_cert_list) {
2904+
SSLfatal(sc, SSL_AD_BAD_CERTIFICATE, SSL_R_EXCESSIVE_MESSAGE_SIZE);
2905+
goto err;
2906+
}
2907+
29022908
if (PACKET_remaining(pkt) != comp_length || comp_length == 0) {
29032909
SSLfatal(sc, SSL_AD_DECODE_ERROR, SSL_R_BAD_DECOMPRESSION);
29042910
goto err;

‎test/recipes/70-test_tls13certcomp.t‎

Lines changed: 41 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ use OpenSSL::Test qw/:DEFAULT cmdstr srctop_file srctop_dir bldtop_dir/;
1111
use OpenSSL::Test::Utils;
1212
use File::Temp qw(tempfile);
1313
use TLSProxy::Proxy;
14+
use TLSProxy::Message;
1415
use checkhandshake qw(checkhandshake @handmessages @extensions);
1516

1617
my $test_name = "test_tls13certcomp";
@@ -220,7 +221,7 @@ $proxy->clear();
220221
$proxy->serverflags("-no_tx_cert_comp -no_rx_cert_comp");
221222
# One final skip check
222223
$proxy->start() or plan skip_all => "Unable to start up Proxy for tests";
223-
plan tests => 8;
224+
plan tests => 9;
224225
checkhandshake($proxy, checkhandshake::DEFAULT_HANDSHAKE,
225226
checkhandshake::DEFAULT_EXTENSIONS
226227
| checkhandshake::CERT_COMP_CLI_EXTENSION,
@@ -296,3 +297,42 @@ $proxy->start();
296297
checkhandshake($proxy, checkhandshake::DEFAULT_HANDSHAKE,
297298
checkhandshake::DEFAULT_EXTENSIONS,
298299
"Send but not accept compressed certificates");
300+
301+
#Test 9: Excessive uncompressed certificate length in CompressedCertificate
302+
$proxy->clear();
303+
$proxy->filter(\&excessive_uncompressed_len_filter);
304+
$proxy->serverflags("-cert_comp");
305+
$proxy->start();
306+
ok(is_alert_message(TLSProxy::Message::AL_DESC_BAD_CERTIFICATE),
307+
"Excessive uncompressed certificate length rejected");
308+
309+
my $done = 0;
310+
311+
sub excessive_uncompressed_len_filter
312+
{
313+
my $proxy = shift;
314+
315+
return if $done;
316+
317+
foreach my $m (@{$proxy->message_list}) {
318+
next unless $m->mt == TLSProxy::Message::MT_COMPRESSED_CERTIFICATE;
319+
320+
my $data = $m->data;
321+
# RFC8879 CompressedCertificate:
322+
# uint16 algorithm; uint24 uncompressed_length; ...
323+
substr($data, 2, 3) = "\xFF\xFF\xFF"; # uncompressed_length
324+
$m->data($data);
325+
$m->repack();
326+
$done = 1;
327+
last;
328+
}
329+
}
330+
331+
# Test if the last message was a failure and matches the expected type.
332+
sub is_alert_message
333+
{
334+
my $alert_type = shift;
335+
return 0 unless TLSProxy::Message->fail();
336+
return 1 if TLSProxy::Message->alert->description() == $alert_type;
337+
return 0;
338+
}

‎util/perl/TLSProxy/Message.pm‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@ use constant {
4545
AL_DESC_CLOSE_NOTIFY => 0,
4646
AL_DESC_UNEXPECTED_MESSAGE => 10,
4747
AL_DESC_BAD_RECORD_MAC => 20,
48+
AL_DESC_BAD_CERTIFICATE => 42,
4849
AL_DESC_ILLEGAL_PARAMETER => 47,
4950
AL_DESC_DECODE_ERROR => 50,
5051
AL_DESC_PROTOCOL_VERSION => 70,

0 commit comments

Comments
 (0)