Skip to content

Commit 3ed1f75

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 3840112 commit 3ed1f75

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

‎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_PROTOCOL_VERSION => 70,
5051
AL_DESC_NO_RENEGOTIATION => 100

0 commit comments

Comments
 (0)