From 76a717c175de2d3308f6f9928a5ddea35b21d9cb Mon Sep 17 00:00:00 2001 From: Tomas Weinfurt Date: Fri, 11 Mar 2022 12:42:03 -0800 Subject: [PATCH 1/2] Improve SSL platform detection (#64923) (#65054) * CI matrix change: add Windows Server 2022 * Add registry check for ssl3 - tls1.2 tests * Disable TLS1.3 on framework code * Fix typo * revert queue change Co-authored-by: Jan Jahoda Co-authored-by: Jan Jahoda --- .../TestUtilities/System/PlatformDetection.cs | 97 ++++++++++++------- 1 file changed, 60 insertions(+), 37 deletions(-) diff --git a/src/libraries/Common/tests/TestUtilities/System/PlatformDetection.cs b/src/libraries/Common/tests/TestUtilities/System/PlatformDetection.cs index 6b77b65fefd10..95ef127a44191 100644 --- a/src/libraries/Common/tests/TestUtilities/System/PlatformDetection.cs +++ b/src/libraries/Common/tests/TestUtilities/System/PlatformDetection.cs @@ -339,34 +339,59 @@ private static bool GetIsInContainer() return (IsLinux && File.Exists("/.dockerenv")); } - private static bool GetSsl3Support() + private static bool GetProtocolSupportFromWindowsRegistry(SslProtocols protocol, bool defaultProtocolSupport) { - if (IsWindows) + string registryProtocolName = protocol switch { - string clientKey = @"HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\SSL 3.0\Client"; - string serverKey = @"HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\SSL 3.0\Server"; +#pragma warning disable CS0618 // Ssl2 and Ssl3 are obsolete + SslProtocols.Ssl3 => "SSL 3.0", +#pragma warning restore CS0618 + SslProtocols.Tls => "TLS 1.0", + SslProtocols.Tls11 => "TLS 1.1", + SslProtocols.Tls12 => "TLS 1.2", +#if !NETFRAMEWORK + SslProtocols.Tls13 => "TLS 1.3", +#endif + _ => throw new Exception($"Registry key not defined for {protocol}.") + }; - object client, server; - try - { - client = Registry.GetValue(clientKey, "Enabled", null); - server = Registry.GetValue(serverKey, "Enabled", null); - } - catch (SecurityException) - { - // Insufficient permission, assume that we don't have SSL3 (since we aren't exactly sure) - return false; - } + string clientKey = @$"HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\{registryProtocolName}\Client"; + string serverKey = @$"HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\{registryProtocolName}\Server"; + object client, server; + try + { + client = Registry.GetValue(clientKey, "Enabled", defaultProtocolSupport ? 1 : 0); + server = Registry.GetValue(serverKey, "Enabled", defaultProtocolSupport ? 1 : 0); if (client is int c && server is int s) { return c == 1 && s == 1; } + } + catch (SecurityException) + { + // Insufficient permission, assume that we don't have protocol support (since we aren't exactly sure) + return false; + } + catch { } + + return defaultProtocolSupport; + } + + private static bool GetSsl3Support() + { + if (IsWindows) + { // Missing key. If we're pre-20H1 then assume SSL3 is enabled. // Otherwise, disabled. (See comments on https://github.com/dotnet/runtime/issues/1166) // Alternatively the returned values must have been some other types. - return !IsWindows10Version2004OrGreater; + bool ssl3DefaultSupport = !IsWindows10Version2004OrGreater; + +#pragma warning disable CS0618 // Ssl2 and Ssl3 are obsolete + return GetProtocolSupportFromWindowsRegistry(SslProtocols.Ssl3, ssl3DefaultSupport); +#pragma warning restore CS0618 + } return (IsOSX || (IsLinux && OpenSslVersion < new Version(1, 0, 2) && !IsDebian)); @@ -390,9 +415,13 @@ private static bool AndroidGetSslProtocolSupport(SslProtocols protocol) private static bool GetTls10Support() { // on Windows, macOS, and Android TLS1.0/1.1 are supported. - if (IsWindows || IsOSXLike || IsAndroid) + if (IsOSXLike || IsAndroid) { return true; + } + if (IsWindows) + { + return GetProtocolSupportFromWindowsRegistry(SslProtocols.Tls, true); } return OpenSslGetTlsSupport(SslProtocols.Tls); @@ -400,11 +429,12 @@ private static bool GetTls10Support() private static bool GetTls11Support() { - // on Windows, macOS, and Android TLS1.0/1.1 are supported. - // TLS 1.1 and 1.2 can work on Windows7 but it is not enabled by default. + // on Windows, macOS, and Android TLS1.0/1.1 are supported. if (IsWindows) { - return !IsWindows7; + // TLS 1.1 and 1.2 can work on Windows7 but it is not enabled by default. + bool defaultProtocolSupport = !IsWindows7; + return GetProtocolSupportFromWindowsRegistry(SslProtocols.Tls11, defaultProtocolSupport); } else if (IsOSXLike || IsAndroid) { @@ -417,7 +447,8 @@ private static bool GetTls11Support() private static bool GetTls12Support() { // TLS 1.1 and 1.2 can work on Windows7 but it is not enabled by default. - return !IsWindows7; + bool defaultProtocolSupport = !IsWindows7; + return GetProtocolSupportFromWindowsRegistry(SslProtocols.Tls12, defaultProtocolSupport); } private static bool GetTls13Support() @@ -428,25 +459,17 @@ private static bool GetTls13Support() { return false; } - - string clientKey = @"HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\TLS 1.3\Client"; - string serverKey = @"HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\TLS 1.3\Server"; - - object client, server; - try - { - client = Registry.GetValue(clientKey, "Enabled", null); - server = Registry.GetValue(serverKey, "Enabled", null); - if (client is int c && server is int s) - { - return c == 1 && s == 1; - } - } - catch { } // assume no if positive entry is missing on older Windows // Latest insider builds have TLS 1.3 enabled by default. // The build number is approximation. - return IsWindows10Version2004Build19573OrGreater; + bool defaultProtocolSupport = IsWindows10Version2004Build19573OrGreater; + +#if NETFRAMEWORK + return false; +#else + return GetProtocolSupportFromWindowsRegistry(SslProtocols.Tls13, defaultProtocolSupport); +#endif + } else if (IsOSX || IsMacCatalyst || IsiOS || IstvOS) { From 323bf2dd0ef1004687a8bafa10a0c66f63252dee Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Fri, 11 Mar 2022 12:51:44 -0800 Subject: [PATCH 2/2] [release/6.0] update expected exception for cases when all requested TLS versions are disabled (#65046) * update expected exception for cases when all requested TLS versions are disabled * port test fix Co-authored-by: wfurt Co-authored-by: Dan Moseley --- .../System/Net/Http/HttpClientHandlerTest.SslProtocols.cs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/libraries/Common/tests/System/Net/Http/HttpClientHandlerTest.SslProtocols.cs b/src/libraries/Common/tests/System/Net/Http/HttpClientHandlerTest.SslProtocols.cs index 5a643c09aec38..d6ecb3bca3a2d 100644 --- a/src/libraries/Common/tests/System/Net/Http/HttpClientHandlerTest.SslProtocols.cs +++ b/src/libraries/Common/tests/System/Net/Http/HttpClientHandlerTest.SslProtocols.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. using System.Collections.Generic; +using System.ComponentModel; using System.IO; using System.Net.Security; using System.Net.Test.Common; @@ -294,9 +295,10 @@ await LoopbackServer.CreateServerAsync(async (server, url) => { await serverTask; } - catch (Exception e) when (e is IOException || e is AuthenticationException) + catch (Exception e) when (e is IOException || e is AuthenticationException || e is Win32Exception) { // Some SSL implementations simply close or reset connection after protocol mismatch. + // The call may fail if neither of the requested protocols is available // Newer OpenSSL sends Fatal Alert message before closing. return; }