Skip to content

Commit

Permalink
Improve SSL platform detection (dotnet#64923)
Browse files Browse the repository at this point in the history
* 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 <jajahoda@microsoft.com>
  • Loading branch information
wfurt and Jan Jahoda committed Feb 9, 2022
1 parent 6de5c5b commit 3c03fcc
Showing 1 changed file with 60 additions and 37 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -333,34 +333,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));
Expand All @@ -384,21 +409,26 @@ 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);
}

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)
{
Expand All @@ -411,7 +441,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()
Expand All @@ -422,25 +453,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)
{
Expand Down

0 comments on commit 3c03fcc

Please sign in to comment.