1
Fork 0
mirror of https://github.com/RGBCube/serenity synced 2025-07-26 08:47:34 +00:00

LibTLS: Implement the extended_master_secret TLS extension

This commit is contained in:
Michiel Visser 2023-11-25 00:27:45 +01:00 committed by Ali Mohammad Pur
parent 5ab64320b2
commit e785172290
4 changed files with 34 additions and 6 deletions

View file

@ -75,6 +75,7 @@ ByteBuffer TLSv12::build_hello()
auto elliptic_curves_length = 2 * m_context.options.elliptic_curves.size(); auto elliptic_curves_length = 2 * m_context.options.elliptic_curves.size();
auto supported_ec_point_formats_length = m_context.options.supported_ec_point_formats.size(); auto supported_ec_point_formats_length = m_context.options.supported_ec_point_formats.size();
bool supports_elliptic_curves = elliptic_curves_length && supported_ec_point_formats_length; bool supports_elliptic_curves = elliptic_curves_length && supported_ec_point_formats_length;
bool enable_extended_master_secret = m_context.options.enable_extended_master_secret;
// signature_algorithms: 2b extension ID, 2b extension length, 2b vector length, 2xN signatures and hashes // 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(); extension_length += 2 + 2 + 2 + 2 * m_context.options.supported_signature_algorithms.size();
@ -86,6 +87,9 @@ ByteBuffer TLSv12::build_hello()
if (supports_elliptic_curves) if (supports_elliptic_curves)
extension_length += 6 + elliptic_curves_length + 5 + supported_ec_point_formats_length; extension_length += 6 + elliptic_curves_length + 5 + supported_ec_point_formats_length;
if (enable_extended_master_secret)
extension_length += 4;
builder.append((u16)extension_length); builder.append((u16)extension_length);
if (sni_length) { if (sni_length) {
@ -130,6 +134,12 @@ ByteBuffer TLSv12::build_hello()
builder.append((u8)format); builder.append((u8)format);
} }
if (enable_extended_master_secret) {
// extended_master_secret extension
builder.append((u16)ExtensionType::EXTENDED_MASTER_SECRET);
builder.append((u16)0);
}
if (alpn_length) { if (alpn_length) {
// TODO // TODO
VERIFY_NOT_REACHED(); VERIFY_NOT_REACHED();

View file

@ -126,12 +126,25 @@ bool TLSv12::compute_master_secret_from_pre_master_secret(size_t length)
return false; return false;
} }
pseudorandom_function( if (m_context.extensions.extended_master_secret) {
m_context.master_key, Crypto::Hash::Manager handshake_hash_copy = m_context.handshake_hash.copy();
m_context.premaster_key, auto digest = handshake_hash_copy.digest();
(u8 const*)"master secret", 13, auto session_hash = ReadonlyBytes { digest.immutable_data(), handshake_hash_copy.digest_size() };
ReadonlyBytes { m_context.local_random, sizeof(m_context.local_random) },
ReadonlyBytes { m_context.remote_random, sizeof(m_context.remote_random) }); pseudorandom_function(
m_context.master_key,
m_context.premaster_key,
(u8 const*)"extended master secret", 22,
session_hash,
{});
} else {
pseudorandom_function(
m_context.master_key,
m_context.premaster_key,
(u8 const*)"master secret", 13,
ReadonlyBytes { m_context.local_random, sizeof(m_context.local_random) },
ReadonlyBytes { m_context.remote_random, sizeof(m_context.remote_random) });
}
m_context.premaster_key.clear(); m_context.premaster_key.clear();
if constexpr (TLS_DEBUG) { if constexpr (TLS_DEBUG) {

View file

@ -189,6 +189,9 @@ ssize_t TLSv12::handle_server_hello(ReadonlyBytes buffer, WritePacketStage& writ
// uncompressed points. Therefore, this extension can be safely ignored as it should always inform us // uncompressed points. Therefore, this extension can be safely ignored as it should always inform us
// that the server supports uncompressed points. // that the server supports uncompressed points.
res += extension_length; res += extension_length;
} else if (extension_type == ExtensionType::EXTENDED_MASTER_SECRET) {
m_context.extensions.extended_master_secret = true;
res += extension_length;
} else { } else {
dbgln("Encountered unknown extension {} with length {}", enum_to_string(extension_type), extension_length); dbgln("Encountered unknown extension {} with length {}", enum_to_string(extension_type), extension_length);
res += extension_length; res += extension_length;

View file

@ -181,6 +181,7 @@ struct Options {
OPTION_WITH_DEFAULTS(Function<void(AlertDescription)>, alert_handler, [](auto) {}) OPTION_WITH_DEFAULTS(Function<void(AlertDescription)>, alert_handler, [](auto) {})
OPTION_WITH_DEFAULTS(Function<void()>, finish_callback, [] {}) OPTION_WITH_DEFAULTS(Function<void()>, finish_callback, [] {})
OPTION_WITH_DEFAULTS(Function<Vector<Certificate>()>, certificate_provider, [] { return Vector<Certificate> {}; }) OPTION_WITH_DEFAULTS(Function<Vector<Certificate>()>, certificate_provider, [] { return Vector<Certificate> {}; })
OPTION_WITH_DEFAULTS(bool, enable_extended_master_secret, true)
#undef OPTION_WITH_DEFAULTS #undef OPTION_WITH_DEFAULTS
}; };
@ -232,6 +233,7 @@ struct Context {
struct { struct {
// Server Name Indicator // Server Name Indicator
DeprecatedString SNI; // I hate your existence DeprecatedString SNI; // I hate your existence
bool extended_master_secret { false };
} extensions; } extensions;
u8 request_client_certificate { 0 }; u8 request_client_certificate { 0 };