From 14bba6e1c3af713fe6dd346e12904103c04c46b8 Mon Sep 17 00:00:00 2001 From: Guido Urdaneta Date: Fri, 25 Sep 2020 16:00:51 +0200 Subject: [PATCH] Add API to allow legacy TLS protocols. Bug: webrtc:10261 Change-Id: I87aeb36b8c8a08b5406516bf15bf22261e4916ed NOKEYCHECK: true Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/185052 Reviewed-by: Harald Alvestrand Commit-Queue: Guido Urdaneta Cr-Commit-Position: refs/heads/master@{#32213} --- rtc_base/openssl_stream_adapter.cc | 19 +++++++++-- rtc_base/openssl_stream_adapter.h | 8 +++++ rtc_base/ssl_stream_adapter_unittest.cc | 42 +++++++++++++++++++++++++ 3 files changed, 67 insertions(+), 2 deletions(-) diff --git a/rtc_base/openssl_stream_adapter.cc b/rtc_base/openssl_stream_adapter.cc index cd7f8025c7..0f8c1fcb13 100644 --- a/rtc_base/openssl_stream_adapter.cc +++ b/rtc_base/openssl_stream_adapter.cc @@ -21,6 +21,7 @@ #include #endif +#include #include #include #include @@ -265,6 +266,21 @@ static long stream_ctrl(BIO* b, int cmd, long num, void* ptr) { // OpenSSLStreamAdapter ///////////////////////////////////////////////////////////////////////////// +static std::atomic g_use_legacy_tls_protocols_override(false); +static std::atomic g_allow_legacy_tls_protocols(false); + +void SetAllowLegacyTLSProtocols(const absl::optional& allow) { + g_use_legacy_tls_protocols_override.store(allow.has_value()); + if (allow.has_value()) + g_allow_legacy_tls_protocols.store(allow.value()); +} + +bool ShouldAllowLegacyTLSProtocols() { + return g_use_legacy_tls_protocols_override.load() + ? g_allow_legacy_tls_protocols.load() + : !webrtc::field_trial::IsDisabled("WebRTC-LegacyTlsProtocols"); +} + OpenSSLStreamAdapter::OpenSSLStreamAdapter( std::unique_ptr stream) : SSLStreamAdapter(std::move(stream)), @@ -278,8 +294,7 @@ OpenSSLStreamAdapter::OpenSSLStreamAdapter( ssl_max_version_(SSL_PROTOCOL_TLS_12), // Default is to support legacy TLS protocols. // This will be changed to default non-support in M82 or M83. - support_legacy_tls_protocols_flag_( - !webrtc::field_trial::IsDisabled("WebRTC-LegacyTlsProtocols")) {} + support_legacy_tls_protocols_flag_(ShouldAllowLegacyTLSProtocols()) {} OpenSSLStreamAdapter::~OpenSSLStreamAdapter() { Cleanup(0); diff --git a/rtc_base/openssl_stream_adapter.h b/rtc_base/openssl_stream_adapter.h index 7ea324321b..d4cde84d74 100644 --- a/rtc_base/openssl_stream_adapter.h +++ b/rtc_base/openssl_stream_adapter.h @@ -19,11 +19,13 @@ #include #include +#include "absl/types/optional.h" #include "rtc_base/buffer.h" #include "rtc_base/openssl_identity.h" #include "rtc_base/ssl_identity.h" #include "rtc_base/ssl_stream_adapter.h" #include "rtc_base/stream.h" +#include "rtc_base/system/rtc_export.h" namespace rtc { @@ -55,6 +57,12 @@ class SSLCertChain; /////////////////////////////////////////////////////////////////////////////// +// If |allow| has a value, its value determines if legacy TLS protocols are +// allowed, overriding the default configuration. +// If |allow| has no value, any previous override is removed and the default +// configuration is restored. +RTC_EXPORT void SetAllowLegacyTLSProtocols(const absl::optional& allow); + class OpenSSLStreamAdapter final : public SSLStreamAdapter { public: explicit OpenSSLStreamAdapter(std::unique_ptr stream); diff --git a/rtc_base/ssl_stream_adapter_unittest.cc b/rtc_base/ssl_stream_adapter_unittest.cc index f6d20d1607..c1017b773d 100644 --- a/rtc_base/ssl_stream_adapter_unittest.cc +++ b/rtc_base/ssl_stream_adapter_unittest.cc @@ -21,6 +21,7 @@ #include "rtc_base/memory/fifo_buffer.h" #include "rtc_base/memory_stream.h" #include "rtc_base/message_digest.h" +#include "rtc_base/openssl_stream_adapter.h" #include "rtc_base/ssl_adapter.h" #include "rtc_base/ssl_identity.h" #include "rtc_base/ssl_stream_adapter.h" @@ -1630,3 +1631,44 @@ TEST_F(SSLStreamAdapterTestDTLSLegacyProtocols, SetupProtocolVersions(rtc::SSL_PROTOCOL_DTLS_10, rtc::SSL_PROTOCOL_DTLS_10); TestHandshake(false); } + +// Both client and server have legacy TLS versions enabled and support DTLS 1.0. +// This should work. +TEST_F(SSLStreamAdapterTestDTLSLegacyProtocols, + TestGetSslVersionLegacyOverrideEnabledClient10Server10) { + rtc::SetAllowLegacyTLSProtocols(true); + ConfigureClient(""); + ConfigureServer(""); + // Remove override. + rtc::SetAllowLegacyTLSProtocols(absl::nullopt); + SetupProtocolVersions(rtc::SSL_PROTOCOL_DTLS_10, rtc::SSL_PROTOCOL_DTLS_10); + TestHandshake(); +} + +// Client has legacy TLS disabled and server has legacy TLS enabled via +// override. Handshake for DTLS 1.0 should fail. +TEST_F(SSLStreamAdapterTestDTLSLegacyProtocols, + TestGetSslVersionLegacyOverrideDisabledClient10EnabledServer10) { + rtc::SetAllowLegacyTLSProtocols(false); + ConfigureClient(""); + rtc::SetAllowLegacyTLSProtocols(true); + ConfigureServer(""); + // Remove override. + rtc::SetAllowLegacyTLSProtocols(absl::nullopt); + SetupProtocolVersions(rtc::SSL_PROTOCOL_DTLS_10, rtc::SSL_PROTOCOL_DTLS_10); + TestHandshake(false); +} + +// Client has legacy TLS enabled and server has legacy TLS disabled via +// override. Handshake for DTLS 1.0 should fail. +TEST_F(SSLStreamAdapterTestDTLSLegacyProtocols, + TestGetSslVersionLegacyOverrideEnabledClient10DisabledServer10) { + rtc::SetAllowLegacyTLSProtocols(true); + ConfigureClient(""); + rtc::SetAllowLegacyTLSProtocols(false); + ConfigureServer(""); + // Remove override. + rtc::SetAllowLegacyTLSProtocols(absl::nullopt); + SetupProtocolVersions(rtc::SSL_PROTOCOL_DTLS_10, rtc::SSL_PROTOCOL_DTLS_10); + TestHandshake(false); +}