From afa98fcb556a3fc136058e38a1b3aeaf0041cfe3 Mon Sep 17 00:00:00 2001 From: Ali Mohammad Pur Date: Wed, 12 May 2021 05:22:18 +0430 Subject: [PATCH] LibTLS: Always send the signature_algorithms extension At some point since Sep 2018, OpenSSL added a ~~bug~~ feature that makes the default set of signature algorithms defined in TLSv1.2 unusable without reducing what they call the "security level", which caused communication with servers using more recent versions of openssl to fail with "internal error". This commit makes LibTLS always send its supported sigalgs, making the server not default to the insecure defaults, and thus enabling us to talk to such servers. --- Userland/Libraries/LibTLS/Handshake.cpp | 15 ++++++++++++++ Userland/Libraries/LibTLS/TLSv12.h | 26 +++++++++++++++++++++++++ 2 files changed, 41 insertions(+) diff --git a/Userland/Libraries/LibTLS/Handshake.cpp b/Userland/Libraries/LibTLS/Handshake.cpp index 99448fd4b3..6fefbf7e1e 100644 --- a/Userland/Libraries/LibTLS/Handshake.cpp +++ b/Userland/Libraries/LibTLS/Handshake.cpp @@ -67,6 +67,9 @@ ByteBuffer TLSv12::build_hello() if (!m_context.extensions.SNI.is_null() && m_context.options.use_sni) sni_length = m_context.extensions.SNI.length(); + // signature_algorithms: 2b extension ID, 2b extension length, 2b vector length, 2xN signatures and hashes + extension_length += 2 + 2 + 2 + 2 * m_context.options.supported_signature_algorithms.size(); + if (sni_length) extension_length += sni_length + 9; @@ -86,6 +89,18 @@ ByteBuffer TLSv12::build_hello() builder.append((const u8*)m_context.extensions.SNI.characters(), sni_length); } + // signature_algorithms extension + builder.append((u16)HandshakeExtension::SignatureAlgorithms); + // Extension length + builder.append((u16)(2 + 2 * m_context.options.supported_signature_algorithms.size())); + // Vector count + builder.append((u16)(m_context.options.supported_signature_algorithms.size() * 2)); + // Entries + for (auto& entry : m_context.options.supported_signature_algorithms) { + builder.append((u8)entry.hash); + builder.append((u8)entry.signature); + } + if (alpn_length) { // TODO VERIFY_NOT_REACHED(); diff --git a/Userland/Libraries/LibTLS/TLSv12.h b/Userland/Libraries/LibTLS/TLSv12.h index a941a2e35a..b45eff3a69 100644 --- a/Userland/Libraries/LibTLS/TLSv12.h +++ b/Userland/Libraries/LibTLS/TLSv12.h @@ -179,6 +179,28 @@ enum ClientVerificationStaus { VerificationNeeded, }; +enum class HashAlgorithm : u8 { + None = 0, + MD5 = 1, + SHA1 = 2, + SHA224 = 3, + SHA256 = 4, + SHA384 = 5, + SHA512 = 6, +}; + +enum class SignatureAlgorithm : u8 { + Anonymous = 0, + RSA = 1, + DSA = 2, + ECDSA = 3, +}; + +struct SignatureAndHashAlgorithm { + HashAlgorithm hash; + SignatureAlgorithm signature; +}; + struct Options { #define OPTION_WITH_DEFAULTS(typ, name, ...) \ static typ default_##name() { return typ { __VA_ARGS__ }; } \ @@ -192,6 +214,10 @@ struct Options { CipherSuite::RSA_WITH_AES_128_GCM_SHA256) OPTION_WITH_DEFAULTS(Version, version, Version::V12) + OPTION_WITH_DEFAULTS(Vector, supported_signature_algorithms, + { HashAlgorithm::SHA512, SignatureAlgorithm::RSA }, + { HashAlgorithm::SHA256, SignatureAlgorithm::RSA }, + { HashAlgorithm::SHA1, SignatureAlgorithm::RSA }); OPTION_WITH_DEFAULTS(bool, use_sni, true) OPTION_WITH_DEFAULTS(bool, use_compression, false)