From: Igor Ustinov Date: Thu, 8 Jan 2026 13:02:54 +0000 (+0100) Subject: Check the received uncompressed certificate length to prevent excessive X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=84f73f79af9f69c1527a9a372b7a9e771a394c2a;p=thirdparty%2Fopenssl.git 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ý Reviewed-by: Tomas Mraz MergeDate: Mon Jan 26 19:45:21 2026 --- diff --git a/ssl/statem/statem_lib.c b/ssl/statem/statem_lib.c index 3e3d00a8bec..d83b647a658 100644 --- a/ssl/statem/statem_lib.c +++ b/ssl/statem/statem_lib.c @@ -2848,6 +2848,12 @@ MSG_PROCESS_RETURN tls13_process_compressed_certificate(SSL_CONNECTION *sc, goto err; } + /* Prevent excessive pre-decompression allocation */ + if (expected_length > sc->max_cert_list) { + SSLfatal(sc, SSL_AD_BAD_CERTIFICATE, SSL_R_EXCESSIVE_MESSAGE_SIZE); + goto err; + } + if (PACKET_remaining(pkt) != comp_length || comp_length == 0) { SSLfatal(sc, SSL_AD_DECODE_ERROR, SSL_R_BAD_DECOMPRESSION); goto err; diff --git a/test/recipes/70-test_tls13certcomp.t b/test/recipes/70-test_tls13certcomp.t index 57712de7c75..379e861ae86 100644 --- a/test/recipes/70-test_tls13certcomp.t +++ b/test/recipes/70-test_tls13certcomp.t @@ -11,6 +11,7 @@ use OpenSSL::Test qw/:DEFAULT cmdstr srctop_file srctop_dir bldtop_dir/; use OpenSSL::Test::Utils; use File::Temp qw(tempfile); use TLSProxy::Proxy; +use TLSProxy::Message; use checkhandshake qw(checkhandshake @handmessages @extensions); use Cwd qw(abs_path); @@ -223,7 +224,7 @@ $proxy->clear(); $proxy->serverflags("-no_tx_cert_comp -no_rx_cert_comp"); # One final skip check $proxy->start() or plan skip_all => "Unable to start up Proxy for tests"; -plan tests => 8; +plan tests => 9; checkhandshake($proxy, checkhandshake::DEFAULT_HANDSHAKE, checkhandshake::DEFAULT_EXTENSIONS | checkhandshake::CERT_COMP_CLI_EXTENSION, @@ -299,3 +300,42 @@ $proxy->start(); checkhandshake($proxy, checkhandshake::DEFAULT_HANDSHAKE, checkhandshake::DEFAULT_EXTENSIONS, "Send but not accept compressed certificates"); + +#Test 9: Excessive uncompressed certificate length in CompressedCertificate +$proxy->clear(); +$proxy->filter(\&excessive_uncompressed_len_filter); +$proxy->serverflags("-cert_comp"); +$proxy->start(); +ok(is_alert_message(TLSProxy::Message::AL_DESC_BAD_CERTIFICATE), + "Excessive uncompressed certificate length rejected"); + +my $done = 0; + +sub excessive_uncompressed_len_filter +{ + my $proxy = shift; + + return if $done; + + foreach my $m (@{$proxy->message_list}) { + next unless $m->mt == TLSProxy::Message::MT_COMPRESSED_CERTIFICATE; + + my $data = $m->data; + # RFC8879 CompressedCertificate: + # uint16 algorithm; uint24 uncompressed_length; ... + substr($data, 2, 3) = "\xFF\xFF\xFF"; # uncompressed_length + $m->data($data); + $m->repack(); + $done = 1; + last; + } +} + +# Test if the last message was a failure and matches the expected type. +sub is_alert_message +{ + my $alert_type = shift; + return 0 unless TLSProxy::Message->fail(); + return 1 if TLSProxy::Message->alert->description() == $alert_type; + return 0; +} diff --git a/util/perl/TLSProxy/Message.pm b/util/perl/TLSProxy/Message.pm index de923f0903f..f79962aac51 100644 --- a/util/perl/TLSProxy/Message.pm +++ b/util/perl/TLSProxy/Message.pm @@ -45,6 +45,7 @@ use constant { AL_DESC_CLOSE_NOTIFY => 0, AL_DESC_UNEXPECTED_MESSAGE => 10, AL_DESC_BAD_RECORD_MAC => 20, + AL_DESC_BAD_CERTIFICATE => 42, AL_DESC_ILLEGAL_PARAMETER => 47, AL_DESC_DECODE_ERROR => 50, AL_DESC_PROTOCOL_VERSION => 70,