From: Alexander Sosedkin Date: Mon, 30 Mar 2026 15:31:07 +0000 (+0200) Subject: lib/auth/rsa: check that ciphertext matches the modulus size X-Git-Tag: 3.8.13^2~43 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=77228f2d1ac207d2f894e5a168fbb47e5378e42f;p=thirdparty%2Fgnutls.git lib/auth/rsa: check that ciphertext matches the modulus size A client sending extremely short premaster secret as part of an RSA key exchange could've theoretically triggered a short heap overread to nowhere when the RSA key was backed with a PKCS#11 token. With this fix, the internal decryption function will not be called with an mismatching plaintext length specified, avoiding the overread. Reported-by: Joshua Rogers of AISLE Research Team Fixes: #1814 Fixes: CVE-2026-5260 Fixes: GNUTLS-SA-2026-04-29-10 CVSS: 5.9 Medium CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:N/I:N/A:H Signed-off-by: Alexander Sosedkin --- diff --git a/lib/auth/rsa.c b/lib/auth/rsa.c index 4d181327ba..496c378b3a 100644 --- a/lib/auth/rsa.c +++ b/lib/auth/rsa.c @@ -158,6 +158,7 @@ static int proc_rsa_client_kx(gnutls_session_t session, uint8_t *data, int ret, dsize; ssize_t data_size = _data_size; volatile uint8_t ver_maj, ver_min; + unsigned int key_bits; #ifdef ENABLE_SSL3 if (get_num_version(session) == GNUTLS_SSL3) { @@ -180,6 +181,10 @@ static int proc_rsa_client_kx(gnutls_session_t session, uint8_t *data, } ciphertext.size = dsize; } + gnutls_privkey_get_pk_algorithm(session->internals.selected_key, + &key_bits); + if (ciphertext.size != (key_bits + 7) / 8) + return gnutls_assert_val(GNUTLS_E_DECRYPTION_FAILED); ver_maj = _gnutls_get_adv_version_major(session); ver_min = _gnutls_get_adv_version_minor(session); diff --git a/lib/auth/rsa_psk.c b/lib/auth/rsa_psk.c index 27caf18769..24ef8f134d 100644 --- a/lib/auth/rsa_psk.c +++ b/lib/auth/rsa_psk.c @@ -257,6 +257,7 @@ static int _gnutls_proc_rsa_psk_client_kx(gnutls_session_t session, ssize_t data_size = _data_size; gnutls_psk_server_credentials_t cred; volatile uint8_t ver_maj, ver_min; + unsigned int rsa_key_bits; cred = (gnutls_psk_server_credentials_t)_gnutls_get_cred( session, GNUTLS_CRD_PSK); @@ -313,6 +314,10 @@ static int _gnutls_proc_rsa_psk_client_kx(gnutls_session_t session, return GNUTLS_E_UNEXPECTED_PACKET_LENGTH; } ciphertext.size = dsize; + gnutls_privkey_get_pk_algorithm(session->internals.selected_key, + &rsa_key_bits); + if (ciphertext.size != (rsa_key_bits + 7) / 8) + return gnutls_assert_val(GNUTLS_E_DECRYPTION_FAILED); ver_maj = _gnutls_get_adv_version_major(session); ver_min = _gnutls_get_adv_version_minor(session);