From 59bbb1fc6a3d990d1c9ee87df6207c29e36ad30a Mon Sep 17 00:00:00 2001 From: Radek Zikmund <32671551+rzikm@users.noreply.github.com> Date: Tue, 3 May 2022 16:34:22 -0700 Subject: [PATCH] [Release/6.0] Backport test fixes (#68332) * 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 Co-authored-by: Tomas Weinfurt --- .../tests/System/Net/SslProtocolSupport.cs | 4 +- .../TestUtilities/System/PlatformDetection.cs | 46 +++++++--- .../Net/Security/SslStreamPal.Windows.cs | 23 +++-- .../ClientAsyncAuthenticateTest.cs | 28 +++--- .../tests/FunctionalTests/LoggingTest.cs | 21 +++-- .../ServerAsyncAuthenticateTest.cs | 41 +++------ .../FunctionalTests/ServerNoEncryptionTest.cs | 5 +- .../SslStreamStreamToStreamTest.cs | 1 - .../tests/FunctionalTests/TelemetryTest.cs | 87 ++++++++++--------- .../FunctionalTests/TestConfiguration.cs | 16 +++- 10 files changed, 155 insertions(+), 117 deletions(-) diff --git a/src/libraries/Common/tests/System/Net/SslProtocolSupport.cs b/src/libraries/Common/tests/System/Net/SslProtocolSupport.cs index e6ac1884c358e..302021b8c0853 100644 --- a/src/libraries/Common/tests/System/Net/SslProtocolSupport.cs +++ b/src/libraries/Common/tests/System/Net/SslProtocolSupport.cs @@ -61,10 +61,12 @@ public IEnumerator 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 } } diff --git a/src/libraries/Common/tests/TestUtilities/System/PlatformDetection.cs b/src/libraries/Common/tests/TestUtilities/System/PlatformDetection.cs index 67a875f56ecfc..f8e0a06b7d271 100644 --- a/src/libraries/Common/tests/TestUtilities/System/PlatformDetection.cs +++ b/src/libraries/Common/tests/TestUtilities/System/PlatformDetection.cs @@ -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 { @@ -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) @@ -414,14 +419,16 @@ 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); @@ -429,13 +436,18 @@ private static bool GetTls10Support() 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; @@ -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() diff --git a/src/libraries/System.Net.Security/src/System/Net/Security/SslStreamPal.Windows.cs b/src/libraries/System.Net.Security/src/System/Net/Security/SslStreamPal.Windows.cs index 1824e9b023312..85d176aaa88a6 100644 --- a/src/libraries/System.Net.Security/src/System/Net/Security/SslStreamPal.Windows.cs +++ b/src/libraries/System.Net.Security/src/System/Net/Security/SslStreamPal.Windows.cs @@ -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) diff --git a/src/libraries/System.Net.Security/tests/FunctionalTests/ClientAsyncAuthenticateTest.cs b/src/libraries/System.Net.Security/tests/FunctionalTests/ClientAsyncAuthenticateTest.cs index 50dd158345ff7..7acf2415a3607 100644 --- a/src/libraries/System.Net.Security/tests/FunctionalTests/ClientAsyncAuthenticateTest.cs +++ b/src/libraries/System.Net.Security/tests/FunctionalTests/ClientAsyncAuthenticateTest.cs @@ -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); } @@ -106,17 +106,19 @@ public async Task ClientAsyncAuthenticate_IndividualServerVsAllClientSupportedPr public static IEnumerable 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 diff --git a/src/libraries/System.Net.Security/tests/FunctionalTests/LoggingTest.cs b/src/libraries/System.Net.Security/tests/FunctionalTests/LoggingTest.cs index 1b99f0cd4d85a..87de0e09dc278 100644 --- a/src/libraries/System.Net.Security/tests/FunctionalTests/LoggingTest.cs +++ b/src/libraries/System.Net.Security/tests/FunctionalTests/LoggingTest.cs @@ -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; @@ -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(); - 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(); } } diff --git a/src/libraries/System.Net.Security/tests/FunctionalTests/ServerAsyncAuthenticateTest.cs b/src/libraries/System.Net.Security/tests/FunctionalTests/ServerAsyncAuthenticateTest.cs index 345cfd4101397..4a277a2e84421 100644 --- a/src/libraries/System.Net.Security/tests/FunctionalTests/ServerAsyncAuthenticateTest.cs +++ b/src/libraries/System.Net.Security/tests/FunctionalTests/ServerAsyncAuthenticateTest.cs @@ -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( @@ -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) @@ -287,37 +287,18 @@ public async Task ServerAsyncAuthenticate_NoCertificate_Throws(bool useAsync) public static IEnumerable 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) }; + } } } diff --git a/src/libraries/System.Net.Security/tests/FunctionalTests/ServerNoEncryptionTest.cs b/src/libraries/System.Net.Security/tests/FunctionalTests/ServerNoEncryptionTest.cs index 4515f15843004..6d43dc8f32017 100644 --- a/src/libraries/System.Net.Security/tests/FunctionalTests/ServerNoEncryptionTest.cs +++ b/src/libraries/System.Net.Security/tests/FunctionalTests/ServerNoEncryptionTest.cs @@ -96,7 +96,10 @@ public async Task ServerNoEncryption_ClientNoEncryption_ConnectWithNoEncryption( else { var ae = await Assert.ThrowsAsync(() => sslStream.AuthenticateAsClientAsync("localhost", null, SslProtocolSupport.DefaultSslProtocols, false)); - Assert.IsType(ae.InnerException); + if (!OperatingSystem.IsWindows()) + { + Assert.IsType(ae.InnerException); + } } } } diff --git a/src/libraries/System.Net.Security/tests/FunctionalTests/SslStreamStreamToStreamTest.cs b/src/libraries/System.Net.Security/tests/FunctionalTests/SslStreamStreamToStreamTest.cs index 4db8e9c34ebd9..bc8e3cf471b3f 100644 --- a/src/libraries/System.Net.Security/tests/FunctionalTests/SslStreamStreamToStreamTest.cs +++ b/src/libraries/System.Net.Security/tests/FunctionalTests/SslStreamStreamToStreamTest.cs @@ -72,7 +72,6 @@ public static IEnumerable 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")] diff --git a/src/libraries/System.Net.Security/tests/FunctionalTests/TelemetryTest.cs b/src/libraries/System.Net.Security/tests/FunctionalTests/TelemetryTest.cs index 48a9b61fa1fb0..67188c1c3bbf3 100644 --- a/src/libraries/System.Net.Security/tests/FunctionalTests/TelemetryTest.cs +++ b/src/libraries/System.Net.Security/tests/FunctionalTests/TelemetryTest.cs @@ -8,6 +8,7 @@ using System.Security.Authentication; using System.Threading.Tasks; using Microsoft.DotNet.RemoteExecutor; +using Microsoft.DotNet.XUnitExtensions; using Xunit; namespace System.Net.Security.Tests @@ -28,61 +29,69 @@ public static void EventSource_ExistsWithCorrectId() [OuterLoop] [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 static void EventSource_SuccessfulHandshake_LogsStartStop() { RemoteExecutor.Invoke(async () => { - using var listener = new TestEventListener("System.Net.Security", EventLevel.Verbose, eventCounterInterval: 0.1d); - listener.AddActivityTracking(); - - var events = new ConcurrentQueue<(EventWrittenEventArgs Event, Guid ActivityId)>(); - await listener.RunWithCallbackAsync(e => + try { - events.Enqueue((e, e.ActivityId)); + using var listener = new TestEventListener("System.Net.Security", EventLevel.Verbose, eventCounterInterval: 0.1d); + listener.AddActivityTracking(); - if (e.EventName == "HandshakeStart") + var events = new ConcurrentQueue<(EventWrittenEventArgs Event, Guid ActivityId)>(); + await listener.RunWithCallbackAsync(e => { - // Wait for a new counter group so that current-tls-handshakes is guaranteed a non-zero value - WaitForEventCountersAsync(events).GetAwaiter().GetResult(); - } - }, - async () => - { - // Invoke tests that'll cause some events to be generated - var test = new SslStreamStreamToStreamTest_Async(); - await test.SslStream_StreamToStream_Authentication_Success(); - await WaitForEventCountersAsync(events); - }); - Assert.DoesNotContain(events, ev => ev.Event.EventId == 0); // errors from the EventSource itself + events.Enqueue((e, e.ActivityId)); + + if (e.EventName == "HandshakeStart") + { + // Wait for a new counter group so that current-tls-handshakes is guaranteed a non-zero value + WaitForEventCountersAsync(events).GetAwaiter().GetResult(); + } + }, + async () => + { + // Invoke tests that'll cause some events to be generated + var test = new SslStreamStreamToStreamTest_Async(); + await test.SslStream_StreamToStream_Authentication_Success(); + await WaitForEventCountersAsync(events); + }); + Assert.DoesNotContain(events, ev => ev.Event.EventId == 0); // errors from the EventSource itself - (EventWrittenEventArgs Event, Guid ActivityId)[] starts = events.Where(e => e.Event.EventName == "HandshakeStart").ToArray(); - Assert.Equal(2, starts.Length); - Assert.All(starts, s => Assert.Equal(2, s.Event.Payload.Count)); - Assert.All(starts, s => Assert.NotEqual(Guid.Empty, s.ActivityId)); + (EventWrittenEventArgs Event, Guid ActivityId)[] starts = events.Where(e => e.Event.EventName == "HandshakeStart").ToArray(); + Assert.Equal(2, starts.Length); + Assert.All(starts, s => Assert.Equal(2, s.Event.Payload.Count)); + Assert.All(starts, s => Assert.NotEqual(Guid.Empty, s.ActivityId)); - // isServer - (EventWrittenEventArgs Event, Guid ActivityId) serverStart = Assert.Single(starts, s => (bool)s.Event.Payload[0]); - (EventWrittenEventArgs Event, Guid ActivityId) clientStart = Assert.Single(starts, s => !(bool)s.Event.Payload[0]); + // isServer + (EventWrittenEventArgs Event, Guid ActivityId) serverStart = Assert.Single(starts, s => (bool)s.Event.Payload[0]); + (EventWrittenEventArgs Event, Guid ActivityId) clientStart = Assert.Single(starts, s => !(bool)s.Event.Payload[0]); - // targetHost - Assert.Empty(Assert.IsType(serverStart.Event.Payload[1])); - Assert.NotEmpty(Assert.IsType(clientStart.Event.Payload[1])); + // targetHost + Assert.Empty(Assert.IsType(serverStart.Event.Payload[1])); + Assert.NotEmpty(Assert.IsType(clientStart.Event.Payload[1])); - Assert.NotEqual(serverStart.ActivityId, clientStart.ActivityId); + Assert.NotEqual(serverStart.ActivityId, clientStart.ActivityId); - (EventWrittenEventArgs Event, Guid ActivityId)[] stops = events.Where(e => e.Event.EventName == "HandshakeStop").ToArray(); - Assert.Equal(2, stops.Length); + (EventWrittenEventArgs Event, Guid ActivityId)[] stops = events.Where(e => e.Event.EventName == "HandshakeStop").ToArray(); + Assert.Equal(2, stops.Length); - EventWrittenEventArgs serverStop = Assert.Single(stops, s => s.ActivityId == serverStart.ActivityId).Event; - EventWrittenEventArgs clientStop = Assert.Single(stops, s => s.ActivityId == clientStart.ActivityId).Event; + EventWrittenEventArgs serverStop = Assert.Single(stops, s => s.ActivityId == serverStart.ActivityId).Event; + EventWrittenEventArgs clientStop = Assert.Single(stops, s => s.ActivityId == clientStart.ActivityId).Event; - SslProtocols serverProtocol = ValidateHandshakeStopEventPayload(serverStop); - SslProtocols clientProtocol = ValidateHandshakeStopEventPayload(clientStop); - Assert.Equal(serverProtocol, clientProtocol); + SslProtocols serverProtocol = ValidateHandshakeStopEventPayload(serverStop); + SslProtocols clientProtocol = ValidateHandshakeStopEventPayload(clientStop); + Assert.Equal(serverProtocol, clientProtocol); - Assert.DoesNotContain(events, e => e.Event.EventName == "HandshakeFailed"); + Assert.DoesNotContain(events, e => e.Event.EventName == "HandshakeFailed"); - VerifyEventCounters(events, shouldHaveFailures: false); + VerifyEventCounters(events, shouldHaveFailures: false); + } + catch (SkipTestException) + { + // Don't throw inside RemoteExecutor if SslStream_StreamToStream_Authentication_Success chose to skip the test + } }).Dispose(); } diff --git a/src/libraries/System.Net.Security/tests/FunctionalTests/TestConfiguration.cs b/src/libraries/System.Net.Security/tests/FunctionalTests/TestConfiguration.cs index 82cbe9f14f8ef..dba86c761a3cc 100644 --- a/src/libraries/System.Net.Security/tests/FunctionalTests/TestConfiguration.cs +++ b/src/libraries/System.Net.Security/tests/FunctionalTests/TestConfiguration.cs @@ -38,7 +38,21 @@ public static Task WhenAllOrAnyFailedWithTimeout(params Task[] tasks) // On Windows, null ciphers (no encryption) are supported. if (OperatingSystem.IsWindows()) { - return true; + if (!PlatformDetection.IsWindows10OrLater) + { + // All old versions support null encryption + return true; + } + + try + { + // New Windows can support null but it may be disabled in Azure images + using (Process p = Process.Start(new ProcessStartInfo("powershell", "-Command Get-TlsCipherSuite") { RedirectStandardOutput = true, RedirectStandardError = true })) + { + return p.StandardOutput.ReadToEnd().Contains("WITH_NULL"); + } + } + catch { return true; } // assume availability } // On macOS and Android, the null cipher (no encryption) is not supported.