From 707b222913bffa59b2eb67b19ef9876e00538d9d Mon Sep 17 00:00:00 2001 From: Michiel Visser Date: Tue, 15 Mar 2022 19:15:44 +0100 Subject: [PATCH] LibTLS: Add certificate chain validation to DHE and ECDHE key exchange The RSA key exchange was the only one actually verifying the validity of the certificate chain supplied by the server. Now the DHE and ECDHE key exchanges also check the certificate chain. --- Userland/Libraries/LibTLS/HandshakeClient.cpp | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/Userland/Libraries/LibTLS/HandshakeClient.cpp b/Userland/Libraries/LibTLS/HandshakeClient.cpp index 2f2efbccfd..52ec095677 100644 --- a/Userland/Libraries/LibTLS/HandshakeClient.cpp +++ b/Userland/Libraries/LibTLS/HandshakeClient.cpp @@ -248,6 +248,13 @@ void TLSv12::build_rsa_pre_master_secret(PacketBuilder& builder) void TLSv12::build_dhe_rsa_pre_master_secret(PacketBuilder& builder) { + const auto& certificate_option = verify_chain_and_get_matching_certificate(m_context.extensions.SNI); // if the SNI is empty, we'll make a special case and match *a* leaf certificate. + if (!certificate_option.has_value()) { + dbgln("certificate verification failed :("); + alert(AlertLevel::Critical, AlertDescription::BadCertificate); + return; + } + auto& dh = m_context.server_diffie_hellman_params; auto dh_p = Crypto::UnsignedBigInteger::import_data(dh.p.data(), dh.p.size()); auto dh_g = Crypto::UnsignedBigInteger::import_data(dh.g.data(), dh.g.size()); @@ -295,6 +302,13 @@ void TLSv12::build_dhe_rsa_pre_master_secret(PacketBuilder& builder) void TLSv12::build_ecdhe_rsa_pre_master_secret(PacketBuilder& builder) { + const auto& certificate_option = verify_chain_and_get_matching_certificate(m_context.extensions.SNI); // if the SNI is empty, we'll make a special case and match *a* leaf certificate. + if (!certificate_option.has_value()) { + dbgln("certificate verification failed :("); + alert(AlertLevel::Critical, AlertDescription::BadCertificate); + return; + } + // Create a random private key auto private_key_result = m_context.server_key_exchange_curve->generate_private_key(); if (private_key_result.is_error()) {