make ssl tests more portable (#40303)
authorTomas Weinfurt <tweinfurt@yahoo.com>
Mon, 10 Aug 2020 01:46:16 +0000 (18:46 -0700)
committerGitHub <noreply@github.com>
Mon, 10 Aug 2020 01:46:16 +0000 (18:46 -0700)
* make ssl tests more portable

* feedback from review

* fix build

* fix http broken by one previous commits

* feedback from review

* fix tests with old ssl versions.S

* more ssl fixes

src/libraries/Common/tests/System/Net/Http/HttpClientHandlerTest.SslProtocols.cs
src/libraries/Common/tests/System/Net/SslProtocolSupport.cs
src/libraries/Common/tests/TestUtilities/System/PlatformDetection.cs
src/libraries/System.Net.Http.WinHttpHandler/tests/FunctionalTests/System.Net.Http.WinHttpHandler.Functional.Tests.csproj
src/libraries/System.Net.Http/tests/FunctionalTests/System.Net.Http.Functional.Tests.csproj
src/libraries/System.Net.Security/tests/FunctionalTests/SslStreamNetworkStreamTest.cs
src/libraries/System.Net.Security/tests/FunctionalTests/SslStreamSystemDefaultsTest.cs
src/libraries/System.Net.Security/tests/FunctionalTests/TransportContextTest.cs

index 92845c1..65342bf 100644 (file)
@@ -80,33 +80,19 @@ namespace System.Net.Http.Functional.Tests
         {
             // These protocols are all enabled by default, so we can connect with them both when
             // explicitly specifying it in the client and when not.
-            foreach (SslProtocols protocol in new[] { SslProtocols.Tls, SslProtocols.Tls11, SslProtocols.Tls12 })
+            foreach (SslProtocols protocol in Enum.GetValues(typeof(SslProtocols)))
             {
-                yield return new object[] { protocol, false };
-                yield return new object[] { protocol, true };
-            }
-
-            // These protocols are disabled by default, so we can only connect with them explicitly.
-            // On certain platforms these are completely disabled and cannot be used at all.
-#pragma warning disable 0618
-            if (PlatformDetection.SupportsSsl3)
-            {
-#if !NETFRAMEWORK
-                yield return new object[] { SslProtocols.Ssl3, true };
-#endif
-            }
-            if (PlatformDetection.IsWindows && !PlatformDetection.IsWindows10Version1607OrGreater)
-            {
-                yield return new object[] { SslProtocols.Ssl2, true };
-            }
+                if (protocol != SslProtocols.None && (protocol & SslProtocolSupport.SupportedSslProtocols) == protocol)
+                {
+                    yield return new object[] { protocol, true };
+#pragma warning disable 0618 // SSL2/3 are deprecated
+                     // On certain platforms these are completely disabled and cannot be used at all.
+                    if (protocol != SslProtocols.Ssl2 && protocol != SslProtocols.Ssl3)
+                    {
+                        yield return new object[] { protocol, false };
+                    }
 #pragma warning restore 0618
-            // These protocols are new, and might not be enabled everywhere yet
-            if (PlatformDetection.IsUbuntu1810OrHigher)
-            {
-#if !NETFRAMEWORK
-                yield return new object[] { SslProtocols.Tls13, false };
-                yield return new object[] { SslProtocols.Tls13, true };
-#endif
+                }
             }
         }
 
@@ -129,11 +115,13 @@ namespace System.Net.Http.Functional.Tests
                     // restrictions on minimum TLS/SSL version
                     // We currently know that some platforms like Debian 10 OpenSSL
                     // will by default block < TLS 1.2
+#pragma warning disable 0618 // SSL2/3 are deprecated
 #if !NETFRAMEWORK
                     handler.SslProtocols = SslProtocols.Tls | SslProtocols.Tls11 | SslProtocols.Tls12 | SslProtocols.Tls13;
 #else
                     handler.SslProtocols = SslProtocols.Tls | SslProtocols.Tls11 | SslProtocols.Tls12;
 #endif
+#pragma warning restore 0618
                 }
 
                 var options = new LoopbackServer.Options { UseSsl = true, SslProtocols = acceptedProtocol };
index de9f381..78ae108 100644 (file)
@@ -3,6 +3,7 @@
 
 using System.Collections;
 using System.Collections.Generic;
+using System.Diagnostics;
 using System.Runtime.InteropServices;
 using System.Security.Authentication;
 
@@ -16,24 +17,41 @@ namespace System.Net.Test.Common
 #endif
             SslProtocols.Tls12 | SslProtocols.Tls11 | SslProtocols.Tls;
 
+        public const SslProtocols NonTls13Protocols = SslProtocols.Tls | SslProtocols.Tls11 | SslProtocols.Tls12;
+
         public static SslProtocols SupportedSslProtocols
         {
             get
             {
-                SslProtocols supported = SslProtocols.Tls | SslProtocols.Tls11 | SslProtocols.Tls12;
+                SslProtocols supported = SslProtocols.None;
 #pragma warning disable 0618 // SSL2/3 are deprecated
                 if (PlatformDetection.SupportsSsl3)
                 {
                     supported |= SslProtocols.Ssl3;
                 }
 #pragma warning restore 0618
+                if (PlatformDetection.SupportsTls10)
+                {
+                    supported |= SslProtocols.Tls;
+                }
+
+                if (PlatformDetection.SupportsTls11)
+                {
+                    supported |= SslProtocols.Tls11;
+                }
+
+                if (PlatformDetection.SupportsTls12)
+                {
+                    supported |= SslProtocols.Tls12;
+                }
 #if !NETSTANDARD2_0
-                // TLS 1.3 is new
-                if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux) && PlatformDetection.OpenSslVersion >= new Version(1, 1, 1))
+                if (PlatformDetection.SupportsTls13)
                 {
                     supported |= SslProtocols.Tls13;
                 }
 #endif
+                Debug.Assert(SslProtocols.None != supported);
+
                 return supported;
             }
         }
@@ -44,7 +62,7 @@ namespace System.Net.Test.Common
             {
                 foreach (SslProtocols protocol in Enum.GetValues(typeof(SslProtocols)))
                 {
-                    if (protocol != 0 && (protocol & SupportedSslProtocols) == protocol)
+                    if (protocol != SslProtocols.None && (protocol & SupportedSslProtocols) == protocol)
                     {
                         yield return new object[] { protocol };
                     }
index 6d5811e..3db016a 100644 (file)
@@ -127,6 +127,8 @@ namespace System
         public static bool SupportsClientAlpn => SupportsAlpn || IsOSX || IsiOS || IstvOS;
 
         // TLS 1.1 and 1.2 can work on Windows7 but it is not enabled by default.
+        //
+        public static bool SupportsTls10 => !IsDebian10;
         public static bool SupportsTls11 => !IsWindows7 && !IsDebian10;
         public static bool SupportsTls12 => !IsWindows7;
         // OpenSSL 1.1.1 and above.
index 1d0dcec..48ed903 100644 (file)
              Link="Common\System\Net\Http\LoopbackServer.cs" />
     <Compile Include="$(CommonTestPath)System\Net\Http\LoopbackServer.AuthenticationHelpers.cs"
              Link="Common\System\Net\Http\LoopbackServer.AuthenticationHelpers.cs" />
+    <Compile Include="$(CommonTestPath)System\Net\SslProtocolSupport.cs"
+             Link="Common\System\Net\SslProtocolSupport.cs" />
     <Compile Include="$(CommonTestPath)System\Net\Http\TestHelper.cs"
              Link="Common\System\Net\Http\TestHelper.cs" />
     <Compile Include="$(CommonTestPath)System\Net\Http\PostScenarioTest.cs"
     <Reference Include="System.Net.Http" />
     <ProjectReference Include="$(LibrariesProjectRoot)System.Net.Http.Json\src\System.Net.Http.Json.csproj" />
   </ItemGroup>
-</Project>
\ No newline at end of file
+</Project>
index 2c97dd4..9a5928a 100644 (file)
              Link="Common\System\Net\Http\GenericLoopbackServer.cs" />
     <Compile Include="$(CommonTestPath)System\Net\Http\HttpClientHandlerTestBase.cs"
              Link="Common\System\Net\Http\HttpClientHandlerTestBase.cs" />
+    <Compile Include="$(CommonTestPath)System\Net\SslProtocolSupport.cs"
+             Link="Common\System\Net\SslProtocolSupport.cs" />
     <Compile Include="$(CommonTestPath)System\Net\Http\TestHelper.cs"
              Link="Common\System\Net\Http\TestHelper.cs" />
     <Compile Include="$(CommonTestPath)System\Threading\TrackingSynchronizationContext.cs"
     <PackageReference Include="System.Net.TestData" Version="$(SystemNetTestDataVersion)" />
     <ProjectReference Include="$(LibrariesProjectRoot)System.DirectoryServices.Protocols\src\System.DirectoryServices.Protocols.csproj" />
   </ItemGroup>
-</Project>
\ No newline at end of file
+</Project>
index 3b77a45..28cb923 100644 (file)
@@ -8,6 +8,7 @@ using System.Security.Authentication;
 using System.Security.Cryptography.X509Certificates;
 using System.Text;
 using System.Threading.Tasks;
+using Microsoft.DotNet.XUnitExtensions;
 using Xunit;
 
 namespace System.Net.Security.Tests
@@ -83,10 +84,31 @@ namespace System.Net.Security.Tests
             listener.Stop();
         }
 
-        [Fact]
+        [ConditionalFact]
         [PlatformSpecific(TestPlatforms.Linux)] // This only applies where OpenSsl is used.
         public async Task SslStream_SendReceiveOverNetworkStream_AuthenticationException()
         {
+            SslProtocols clientProtocol;
+            SslProtocols serverProtocol;
+
+            // Try to find protocol mismatch.
+            if (PlatformDetection.SupportsTls12 && (PlatformDetection.SupportsTls10 || PlatformDetection.SupportsTls11))
+            {
+                // OpenSSL 1.0 where new is Tls12
+                clientProtocol = SslProtocols.Tls | SslProtocols.Tls11;
+                serverProtocol = SslProtocols.Tls12;
+            }
+            else if (PlatformDetection.SupportsTls12 && PlatformDetection.SupportsTls13)
+            {
+                // OpenSSl 1.1 where new is 1.3 and legacy is 1.2
+                clientProtocol = SslProtocols.Tls13;
+                serverProtocol = SslProtocols.Tls12;
+            }
+            else
+            {
+                throw new SkipTestException("Did not find disjoined sets");
+            }
+
             TcpListener listener = new TcpListener(IPAddress.Loopback, 0);
 
             using (X509Certificate2 serverCertificate = Configuration.Certificates.GetServerCertificate())
@@ -117,13 +139,13 @@ namespace System.Net.Security.Tests
                     Task clientAuthenticationTask = clientStream.AuthenticateAsClientAsync(
                         serverCertificate.GetNameInfo(X509NameType.SimpleName, false),
                         null,
-                        SslProtocols.Tls11,
+                        clientProtocol,
                         false);
 
                     AuthenticationException e = await Assert.ThrowsAsync<AuthenticationException>(() => serverStream.AuthenticateAsServerAsync(
                         serverCertificate,
                         false,
-                        SslProtocols.Tls12,
+                        serverProtocol,
                         false));
 
                     Assert.NotNull(e.InnerException);
index 58f54b9..4136320 100644 (file)
@@ -1,6 +1,7 @@
 // Licensed to the .NET Foundation under one or more agreements.
 // The .NET Foundation licenses this file to you under the MIT license.
 
+using System.Collections.Generic;
 using System.IO;
 using System.Net.Http;
 using System.Net.Test.Common;
@@ -31,21 +32,48 @@ namespace System.Net.Security.Tests
         protected abstract Task AuthenticateClientAsync(string targetHost, X509CertificateCollection clientCertificates, bool checkCertificateRevocation, SslProtocols? protocols = null);
         protected abstract Task AuthenticateServerAsync(X509Certificate serverCertificate, bool clientCertificateRequired, bool checkCertificateRevocation, SslProtocols? protocols = null);
 
-        [ConditionalTheory(nameof(IsNotWindows7))]
-        [InlineData(null, null)]
-        [InlineData(SslProtocols.None, null)]
-        [InlineData(null, SslProtocols.None)]
-        [InlineData(SslProtocols.None, SslProtocols.None)]
-        [InlineData(NegotiatedCipherSuiteTest.NonTls13Protocols, SslProtocols.Tls11)]
-        [InlineData(SslProtocols.Tls11, NegotiatedCipherSuiteTest.NonTls13Protocols)]
-        [InlineData(null, SslProtocols.Tls12)]
-        [InlineData(SslProtocols.Tls12, null)]
-        [InlineData(SslProtocols.Tls | SslProtocols.Tls11 | SslProtocols.Tls12, null)]
-        [InlineData(null, SslProtocols.Tls | SslProtocols.Tls11 | SslProtocols.Tls12)]
+        public static IEnumerable<object[]> OneOrBothUseDefaulData()
+        {
+            yield return new object[] { null, null };
+            yield return new object[] { SslProtocols.None, null };
+            yield return new object[] { null, SslProtocols.None };
+            yield return new object[] { SslProtocols.None, SslProtocols.None };
 #pragma warning disable 0618
-        [InlineData(SslProtocols.Default, NegotiatedCipherSuiteTest.NonTls13Protocols)]
-        [InlineData(NegotiatedCipherSuiteTest.NonTls13Protocols, SslProtocols.Default)]
+            if (PlatformDetection.SupportsTls10)
+            {
+                // Default only has Ssl3 and Tls1.0 for legacy reasons.
+                yield return new object[] { SslProtocols.Default, SslProtocolSupport.NonTls13Protocols };
+                yield return new object[] { SslProtocolSupport.NonTls13Protocols, SslProtocols.Default };
+            }
+
 #pragma warning restore 0618
+            if (PlatformDetection.SupportsTls11)
+            {
+                yield return new object[] { SslProtocolSupport.NonTls13Protocols, SslProtocols.Tls11 };
+                yield return new object[] { SslProtocols.Tls11, SslProtocolSupport.NonTls13Protocols };
+            }
+
+            if (PlatformDetection.SupportsTls12)
+            {
+                yield return new object[] { null, SslProtocols.Tls12 };
+                yield return new object[] { SslProtocols.Tls12, null };
+            }
+
+            if (PlatformDetection.SupportsTls13)
+            {
+                yield return new object[] { null, SslProtocols.Tls13 };
+                yield return new object[] { SslProtocols.Tls13, null };
+            }
+
+            if ((SslProtocolSupport.SupportedSslProtocols & SslProtocolSupport.NonTls13Protocols) != 0)
+            {
+                yield return new object[] { SslProtocolSupport.NonTls13Protocols, null };
+                yield return new object[] { null, SslProtocolSupport.NonTls13Protocols };
+            }
+        }
+
+        [ConditionalTheory]
+        [MemberData(nameof(OneOrBothUseDefaulData))]
         public async Task ClientAndServer_OneOrBothUseDefault_Ok(SslProtocols? clientProtocols, SslProtocols? serverProtocols)
         {
             using (X509Certificate2 serverCertificate = Configuration.Certificates.GetServerCertificate())
index fb0fc5a..17b91a5 100644 (file)
@@ -35,7 +35,7 @@ namespace System.Net.Security.Tests
 
                 using (var sslStream = new SslStream(client.GetStream(), false, AllowAnyServerCertificate, null, EncryptionPolicy.RequireEncryption))
                 {
-                    await sslStream.AuthenticateAsClientAsync("localhost", null, SslProtocols.Tls, false);
+                    await sslStream.AuthenticateAsClientAsync("localhost", null, SslProtocols.None, false);
 
                     TransportContext context = sslStream.TransportContext;
                     CheckTransportContext(context);