Skip to content

Commit

Permalink
[Release/6.0] Backport test fixes (#68332)
Browse files Browse the repository at this point in the history
* Resolve System.Net.Security.Tests.LoggingTest SkipTestException failure (#65322)

* improve Tls12 detection on Windows7 (#67935)

* disable Tls 1.0 and 1.1 tests on new Windows (#68083)

* Don't throw from RemoteExecutor on SkipTestExceptions (#65105)

* update SSL tests to deal better with disabled protocols (#65120)

* update SSL tests to deal better with disabled protocols

* Improve detection of Null encryption on Windows

* update expectation for Mismatched protocols

* update detection

* wrap win32 exception

* update ProtocolMismatchData sets

* remove debug print

* final cleanup

* generate mismatch data

* avoid SslProtocols.Default

Co-authored-by: Miha Zupan <[email protected]>
Co-authored-by: Tomas Weinfurt <[email protected]>
  • Loading branch information
3 people authored May 3, 2022
1 parent 31c3ba9 commit 59bbb1f
Show file tree
Hide file tree
Showing 10 changed files with 155 additions and 117 deletions.
4 changes: 3 additions & 1 deletion src/libraries/Common/tests/System/Net/SslProtocolSupport.cs
Original file line number Diff line number Diff line change
Expand Up @@ -61,10 +61,12 @@ public IEnumerator<object[]> GetEnumerator()
{
foreach (SslProtocols protocol in Enum.GetValues(typeof(SslProtocols)))
{
if (protocol != SslProtocols.None && (protocol & SupportedSslProtocols) == protocol)
#pragma warning disable 0618 // SSL2/3 are deprecated
if (protocol != SslProtocols.None && protocol != SslProtocols.Default && (protocol & SupportedSslProtocols) == protocol)
{
yield return new object[] { protocol };
}
#pragma warning restore 0618
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -339,7 +339,7 @@ private static bool GetIsInContainer()
return (IsLinux && File.Exists("/.dockerenv"));
}

private static bool GetProtocolSupportFromWindowsRegistry(SslProtocols protocol, bool defaultProtocolSupport)
private static bool GetProtocolSupportFromWindowsRegistry(SslProtocols protocol, bool defaultProtocolSupport, bool disabledByDefault = false)
{
string registryProtocolName = protocol switch
{
Expand All @@ -359,13 +359,18 @@ private static bool GetProtocolSupportFromWindowsRegistry(SslProtocols protocol,
string serverKey = @$"HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\{registryProtocolName}\Server";

object client, server;
object clientDefault, serverDefault;
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)

clientDefault = Registry.GetValue(clientKey, "DisabledByDefault", 1);
serverDefault = Registry.GetValue(serverKey, "DisabledByDefault", 1);

if (client is int c && server is int s && clientDefault is int cd && serverDefault is int sd)
{
return c == 1 && s == 1;
return (c == 1 && s == 1) && (!disabledByDefault || (cd == 0 && sd == 0));
}
}
catch (SecurityException)
Expand Down Expand Up @@ -414,28 +419,35 @@ private static bool AndroidGetSslProtocolSupport(SslProtocols protocol)

private static bool GetTls10Support()
{
// on Windows, macOS, and Android TLS1.0/1.1 are supported.
// on macOS and Android TLS 1.0 is supported.
if (IsOSXLike || IsAndroid)
{
return true;
}

// Windows depend on registry, enabled by default on all supported versions.
if (IsWindows)
{
return GetProtocolSupportFromWindowsRegistry(SslProtocols.Tls, true);
return GetProtocolSupportFromWindowsRegistry(SslProtocols.Tls, defaultProtocolSupport: true) && !IsWindows10Version20348OrGreater;
}

return OpenSslGetTlsSupport(SslProtocols.Tls);
}

private static bool GetTls11Support()
{
// on Windows, macOS, and Android TLS1.0/1.1 are supported.
if (IsWindows)
{
// 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);
// TLS 1.1 can work on Windows 7 but it is disabled by default.
if (IsWindows7)
{
return GetProtocolSupportFromWindowsRegistry(SslProtocols.Tls11, defaultProtocolSupport: false, disabledByDefault: true);
}

// It is enabled on other versions unless explicitly disabled.
return GetProtocolSupportFromWindowsRegistry(SslProtocols.Tls11, defaultProtocolSupport: true) && !IsWindows10Version20348OrGreater;
}
// on macOS and Android TLS 1.1 is supported.
else if (IsOSXLike || IsAndroid)
{
return true;
Expand All @@ -446,9 +458,19 @@ 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.
bool defaultProtocolSupport = !IsWindows7;
return GetProtocolSupportFromWindowsRegistry(SslProtocols.Tls12, defaultProtocolSupport);
if (IsWindows)
{
// TLS 1.2 can work on Windows 7 but it is disabled by default.
if (IsWindows7)
{
return GetProtocolSupportFromWindowsRegistry(SslProtocols.Tls12, defaultProtocolSupport: false, disabledByDefault: true);
}

// It is enabled on other versions unless explicitly disabled.
return GetProtocolSupportFromWindowsRegistry(SslProtocols.Tls12, defaultProtocolSupport: true);
}

return true;
}

private static bool GetTls13Support()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -122,16 +122,23 @@ public static SecurityStatusPal Renegotiate(ref SafeFreeCredentials? credentials

public static SafeFreeCredentials AcquireCredentialsHandle(SslStreamCertificateContext? certificateContext, SslProtocols protocols, EncryptionPolicy policy, bool isServer)
{
// New crypto API supports TLS1.3 but it does not allow to force NULL encryption.
SafeFreeCredentials cred = !UseNewCryptoApi || policy == EncryptionPolicy.NoEncryption ?
AcquireCredentialsHandleSchannelCred(certificateContext, protocols, policy, isServer) :
AcquireCredentialsHandleSchCredentials(certificateContext, protocols, policy, isServer);
if (certificateContext != null && certificateContext.Trust != null && certificateContext.Trust._sendTrustInHandshake)
try
{
AttachCertificateStore(cred, certificateContext.Trust._store!);
}
// New crypto API supports TLS1.3 but it does not allow to force NULL encryption.
SafeFreeCredentials cred = !UseNewCryptoApi || policy == EncryptionPolicy.NoEncryption ?
AcquireCredentialsHandleSchannelCred(certificateContext, protocols, policy, isServer) :
AcquireCredentialsHandleSchCredentials(certificateContext, protocols, policy, isServer);
if (certificateContext != null && certificateContext.Trust != null && certificateContext.Trust._sendTrustInHandshake)
{
AttachCertificateStore(cred, certificateContext.Trust._store!);
}

return cred;
return cred;
}
catch (Win32Exception e)
{
throw new AuthenticationException(SR.net_auth_SSPI, e);
}
}

private static unsafe void AttachCertificateStore(SafeFreeCredentials cred, X509Store store)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -69,11 +69,11 @@ public async Task ClientAsyncAuthenticate_Ssl2WithSelf_Success()
[Theory]
[MemberData(nameof(ProtocolMismatchData))]
public async Task ClientAsyncAuthenticate_MismatchProtocols_Fails(
SslProtocols serverProtocol,
SslProtocols clientProtocol,
SslProtocols serverProtocol,
Type expectedException)
{
Exception e = await Record.ExceptionAsync(() => ClientAsyncSslHelper(serverProtocol, clientProtocol));
Exception e = await Record.ExceptionAsync(() => ClientAsyncSslHelper(clientProtocol, serverProtocol));
Assert.NotNull(e);
Assert.IsAssignableFrom(expectedException, e);
}
Expand Down Expand Up @@ -106,17 +106,19 @@ public async Task ClientAsyncAuthenticate_IndividualServerVsAllClientSupportedPr

public static IEnumerable<object[]> ProtocolMismatchData()
{
#pragma warning disable 0618
yield return new object[] { SslProtocols.Ssl2, SslProtocols.Ssl3, typeof(Exception) };
yield return new object[] { SslProtocols.Ssl2, SslProtocols.Tls12, typeof(Exception) };
yield return new object[] { SslProtocols.Ssl3, SslProtocols.Tls12, typeof(Exception) };
#pragma warning restore 0618
yield return new object[] { SslProtocols.Tls, SslProtocols.Tls11, typeof(AuthenticationException) };
yield return new object[] { SslProtocols.Tls, SslProtocols.Tls12, typeof(AuthenticationException) };
yield return new object[] { SslProtocols.Tls11, SslProtocols.Tls, typeof(AuthenticationException) };
yield return new object[] { SslProtocols.Tls12, SslProtocols.Tls, typeof(AuthenticationException) };
yield return new object[] { SslProtocols.Tls12, SslProtocols.Tls11, typeof(AuthenticationException) };
yield return new object[] { SslProtocols.Tls11, SslProtocols.Tls12, typeof(AuthenticationException) };
var supportedProtocols = new SslProtocolSupport.SupportedSslProtocolsTestData();

foreach (var serverProtocols in supportedProtocols)
foreach (var clientProtocols in supportedProtocols)
{
SslProtocols serverProtocol = (SslProtocols)serverProtocols[0];
SslProtocols clientProtocol = (SslProtocols)clientProtocols[0];

if (clientProtocol != serverProtocol)
{
yield return new object[] { clientProtocol, serverProtocol, typeof(AuthenticationException) };
}
}
}

#region Helpers
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@
// The .NET Foundation licenses this file to you under the MIT license.

using System.Collections.Concurrent;
using System.Diagnostics;
using System.Diagnostics.Tracing;
using Microsoft.DotNet.RemoteExecutor;
using Microsoft.DotNet.XUnitExtensions;
Expand All @@ -25,28 +24,28 @@ public void EventSource_ExistsWithCorrectId()
}

[ConditionalFact(typeof(RemoteExecutor), nameof(RemoteExecutor.IsSupported))]
[SkipOnPlatform(TestPlatforms.iOS | TestPlatforms.tvOS, "X509 certificate store is not supported on iOS or tvOS.")] // Match SslStream_StreamToStream_Authentication_Success
public void EventSource_EventsRaisedAsExpected()
{
if (PlatformDetection.IsWindows10Version22000OrGreater)
RemoteExecutor.Invoke(async () =>
{
// [ActiveIssue("https://github.com/dotnet/runtime/issues/58927")]
throw new SkipTestException("Unstable on Windows 11");
}

RemoteExecutor.Invoke(() =>
{
using (var listener = new TestEventListener("Private.InternalDiagnostics.System.Net.Security", EventLevel.Verbose))
try
{
using var listener = new TestEventListener("Private.InternalDiagnostics.System.Net.Security", EventLevel.Verbose);
var events = new ConcurrentQueue<EventWrittenEventArgs>();
listener.RunWithCallback(events.Enqueue, () =>
await listener.RunWithCallbackAsync(events.Enqueue, async () =>
{
// Invoke tests that'll cause some events to be generated
var test = new SslStreamStreamToStreamTest_Async();
test.SslStream_StreamToStream_Authentication_Success().GetAwaiter().GetResult();
await test.SslStream_StreamToStream_Authentication_Success();
});
Assert.DoesNotContain(events, ev => ev.EventId == 0); // errors from the EventSource itself
Assert.InRange(events.Count, 1, int.MaxValue);
}
catch (SkipTestException)
{
// Don't throw inside RemoteExecutor if SslStream_StreamToStream_Authentication_Success chose to skip the test
}
}).Dispose();
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -46,8 +46,8 @@ public async Task ServerAsyncAuthenticate_EachSupportedProtocol_Success(SslProto
[Theory]
[MemberData(nameof(ProtocolMismatchData))]
public async Task ServerAsyncAuthenticate_MismatchProtocols_Fails(
SslProtocols serverProtocol,
SslProtocols clientProtocol,
SslProtocols serverProtocol,
Type expectedException)
{
Exception e = await Record.ExceptionAsync(
Expand Down Expand Up @@ -236,7 +236,7 @@ public async Task ServerAsyncAuthenticate_ConstructorVerificationDelegate_Succes

(Stream clientStream, Stream serverStream) = TestHelper.GetConnectedStreams();
var client = new SslStream(clientStream);
var server = new SslStream(serverStream, false, (sender, certificate, chain, sslPolicyErrors) => { validationCallbackCalled = true; return true;});
var server = new SslStream(serverStream, false, (sender, certificate, chain, sslPolicyErrors) => { validationCallbackCalled = true; return true; });

using (client)
using (server)
Expand Down Expand Up @@ -287,37 +287,18 @@ public async Task ServerAsyncAuthenticate_NoCertificate_Throws(bool useAsync)

public static IEnumerable<object[]> ProtocolMismatchData()
{
if (PlatformDetection.SupportsSsl3)
{
#pragma warning disable 0618
yield return new object[] { SslProtocols.Ssl3, SslProtocols.Tls12, typeof(Exception) };
if (PlatformDetection.SupportsSsl2)
{
yield return new object[] { SslProtocols.Ssl2, SslProtocols.Ssl3, typeof(Exception) };
yield return new object[] { SslProtocols.Ssl2, SslProtocols.Tls12, typeof(Exception) };
}
#pragma warning restore 0618
}

// It is OK if server does not support given protocol. It should still fail.
// But if client does not support it, it will simply fail without sending out any data.

if (PlatformDetection.SupportsTls10)
{
yield return new object[] { SslProtocols.Tls11, SslProtocols.Tls, typeof(AuthenticationException) };
yield return new object[] { SslProtocols.Tls12, SslProtocols.Tls, typeof(AuthenticationException) };
}
var supportedProtocols = new SslProtocolSupport.SupportedSslProtocolsTestData();

if (PlatformDetection.SupportsTls11)
foreach (var serverProtocols in supportedProtocols)
foreach (var clientProtocols in supportedProtocols)
{
yield return new object[] { SslProtocols.Tls, SslProtocols.Tls11, typeof(AuthenticationException) };
yield return new object[] { SslProtocols.Tls12, SslProtocols.Tls11, typeof(AuthenticationException) };
}
SslProtocols serverProtocol = (SslProtocols)serverProtocols[0];
SslProtocols clientProtocol = (SslProtocols)clientProtocols[0];

if (PlatformDetection.SupportsTls12)
{
yield return new object[] { SslProtocols.Tls, SslProtocols.Tls12, typeof(AuthenticationException) };
yield return new object[] { SslProtocols.Tls11, SslProtocols.Tls12, typeof(AuthenticationException) };
if (clientProtocol != serverProtocol)
{
yield return new object[] { clientProtocol, serverProtocol, typeof(AuthenticationException) };
}
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,10 @@ public async Task ServerNoEncryption_ClientNoEncryption_ConnectWithNoEncryption(
else
{
var ae = await Assert.ThrowsAsync<AuthenticationException>(() => sslStream.AuthenticateAsClientAsync("localhost", null, SslProtocolSupport.DefaultSslProtocols, false));
Assert.IsType<PlatformNotSupportedException>(ae.InnerException);
if (!OperatingSystem.IsWindows())
{
Assert.IsType<PlatformNotSupportedException>(ae.InnerException);
}
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,6 @@ public static IEnumerable<object[]> SslStream_StreamToStream_Authentication_Succ
[SkipOnPlatform(TestPlatforms.iOS | TestPlatforms.tvOS, "X509 certificate store is not supported on iOS or tvOS.")]
public async Task SslStream_StreamToStream_Authentication_Success(X509Certificate serverCert = null, X509Certificate clientCert = null)
{

if (PlatformDetection.IsWindows10Version20348OrGreater)
{
// [ActiveIssue("https://github.com/dotnet/runtime/issues/58927")]
Expand Down
Loading

0 comments on commit 59bbb1f

Please sign in to comment.