diff --git a/src/libraries/System.Net.Quic/tests/FunctionalTests/System.Net.Quic.Functional.Tests.csproj b/src/libraries/System.Net.Quic/tests/FunctionalTests/System.Net.Quic.Functional.Tests.csproj index 471ca7ee5bf80c..2fcbb42d4008c3 100644 --- a/src/libraries/System.Net.Quic/tests/FunctionalTests/System.Net.Quic.Functional.Tests.csproj +++ b/src/libraries/System.Net.Quic/tests/FunctionalTests/System.Net.Quic.Functional.Tests.csproj @@ -24,6 +24,7 @@ + diff --git a/src/libraries/System.Net.Security/tests/FunctionalTests/ClientAsyncAuthenticateTest.cs b/src/libraries/System.Net.Security/tests/FunctionalTests/ClientAsyncAuthenticateTest.cs index 19517cf2e9f600..132b8ca440439e 100644 --- a/src/libraries/System.Net.Security/tests/FunctionalTests/ClientAsyncAuthenticateTest.cs +++ b/src/libraries/System.Net.Security/tests/FunctionalTests/ClientAsyncAuthenticateTest.cs @@ -2,8 +2,6 @@ // The .NET Foundation licenses this file to you under the MIT license. using System.Collections.Generic; -using System.IO; -using System.Net.Sockets; using System.Net.Test.Common; using System.Security.Authentication; using System.Security.Cryptography.X509Certificates; @@ -131,25 +129,49 @@ private async Task ClientAsyncSslHelper( { _log.WriteLine("Server: " + serverSslProtocols + "; Client: " + clientSslProtocols); - IPEndPoint endPoint = new IPEndPoint(IPAddress.Loopback, 0); + (SslStream client, SslStream server) = TestHelper.GetConnectedSslStreams(); - using (var server = new DummyTcpServer(endPoint, encryptionPolicy)) - using (var client = new TcpClient()) + using (client) + using (server) { - server.SslProtocols = serverSslProtocols; // Use a different SNI for each connection to prevent TLS 1.3 renegotiation issue: https://github.com/dotnet/runtime/issues/47378 string serverName = TestHelper.GetTestSNIName(nameof(ClientAsyncSslHelper), clientSslProtocols, serverSslProtocols); - await client.ConnectAsync(server.RemoteEndPoint.Address, server.RemoteEndPoint.Port); - using (SslStream sslStream = new SslStream(client.GetStream(), false, certificateCallback != null ? certificateCallback : AllowAnyServerCertificate, null)) + Task serverTask = default; + try { - Task clientAuthTask = sslStream.AuthenticateAsClientAsync(serverName, null, clientSslProtocols, false); - await clientAuthTask.WaitAsync(TestConfiguration.PassingTestTimeout); - - _log.WriteLine("Client authenticated to server({0}) with encryption cipher: {1} {2}-bit strength", - server.RemoteEndPoint, sslStream.CipherAlgorithm, sslStream.CipherStrength); - Assert.True(sslStream.CipherAlgorithm != CipherAlgorithmType.Null, "Cipher algorithm should not be NULL"); - Assert.True(sslStream.CipherStrength > 0, "Cipher strength should be greater than 0"); + Task clientTask = client.AuthenticateAsClientAsync(new SslClientAuthenticationOptions + { + EnabledSslProtocols = clientSslProtocols, + RemoteCertificateValidationCallback = AllowAnyServerCertificate, + TargetHost = serverName }); + serverTask = server.AuthenticateAsServerAsync( new SslServerAuthenticationOptions + { + EncryptionPolicy = encryptionPolicy, + EnabledSslProtocols = serverSslProtocols, + ServerCertificate = TestConfiguration.ServerCertificate, + CertificateRevocationCheckMode = X509RevocationMode.NoCheck }); + + await clientTask.WaitAsync(TestConfiguration.PassingTestTimeout); + + _log.WriteLine("Client authenticated to server with encryption cipher: {0} {1}-bit strength", + client.CipherAlgorithm, client.CipherStrength); + Assert.True(client.CipherAlgorithm != CipherAlgorithmType.Null, "Cipher algorithm should not be NULL"); + Assert.True(client.CipherStrength > 0, "Cipher strength should be greater than 0"); + } + finally + { + // make sure we signal server in case of client failures + client.Close(); + try + { + await serverTask; + } + catch (Exception ex) + { + // We generally don't care about server but can log exception to help diagnose test failures + _log.WriteLine(ex.ToString()); + } } } } diff --git a/src/libraries/System.Net.Security/tests/FunctionalTests/ClientDefaultEncryptionTest.cs b/src/libraries/System.Net.Security/tests/FunctionalTests/ClientDefaultEncryptionTest.cs index 8723feac8e6823..b308d395f13713 100644 --- a/src/libraries/System.Net.Security/tests/FunctionalTests/ClientDefaultEncryptionTest.cs +++ b/src/libraries/System.Net.Security/tests/FunctionalTests/ClientDefaultEncryptionTest.cs @@ -1,11 +1,9 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. -using System.IO; using System.Net.Sockets; using System.Net.Test.Common; using System.Security.Authentication; -using System.Security.Cryptography.X509Certificates; using System.Threading.Tasks; using Xunit; @@ -17,37 +15,29 @@ public class ClientDefaultEncryptionTest { private readonly ITestOutputHelper _log; - public ClientDefaultEncryptionTest() + public ClientDefaultEncryptionTest(ITestOutputHelper output) { - _log = TestLogging.GetInstance(); - } - - // The following method is invoked by the RemoteCertificateValidationDelegate. - public bool AllowAnyServerCertificate( - object sender, - X509Certificate certificate, - X509Chain chain, - SslPolicyErrors sslPolicyErrors) - { - return true; // allow everything + _log = output; } [Fact] public async Task ClientDefaultEncryption_ServerRequireEncryption_ConnectWithEncryption() { - using (var serverRequireEncryption = new DummyTcpServer( - new IPEndPoint(IPAddress.Loopback, 0), EncryptionPolicy.RequireEncryption)) - using (var client = new TcpClient()) + (NetworkStream clientStream, NetworkStream serverStream) = TestHelper.GetConnectedTcpStreams(); + using (clientStream) + using (serverStream) { - await client.ConnectAsync(serverRequireEncryption.RemoteEndPoint.Address, serverRequireEncryption.RemoteEndPoint.Port); - - using (var sslStream = new SslStream(client.GetStream(), false, AllowAnyServerCertificate, null)) + using (var client = new SslStream(clientStream, false, TestHelper.AllowAnyServerCertificate, null)) + using (var server = new SslStream(serverStream)) { - await sslStream.AuthenticateAsClientAsync("localhost", null, SslProtocolSupport.DefaultSslProtocols, false); + await TestConfiguration.WhenAllOrAnyFailedWithTimeout( + client.AuthenticateAsClientAsync("localhost", null, SslProtocolSupport.DefaultSslProtocols, false), + server.AuthenticateAsServerAsync(TestConfiguration.ServerCertificate)); + _log.WriteLine("Client authenticated to server({0}) with encryption cipher: {1} {2}-bit strength", - serverRequireEncryption.RemoteEndPoint, sslStream.CipherAlgorithm, sslStream.CipherStrength); - Assert.True(sslStream.CipherAlgorithm != CipherAlgorithmType.Null, "Cipher algorithm should not be NULL"); - Assert.True(sslStream.CipherStrength > 0, "Cipher strength should be greater than 0"); + clientStream.Socket.RemoteEndPoint, client.CipherAlgorithm, client.CipherStrength) ; + Assert.True(client.CipherAlgorithm != CipherAlgorithmType.Null, "Cipher algorithm should not be NULL"); + Assert.True(client.CipherStrength > 0, "Cipher strength should be greater than 0"); } } } @@ -55,19 +45,21 @@ public async Task ClientDefaultEncryption_ServerRequireEncryption_ConnectWithEnc [Fact] public async Task ClientDefaultEncryption_ServerAllowNoEncryption_ConnectWithEncryption() { - using (var serverAllowNoEncryption = new DummyTcpServer( - new IPEndPoint(IPAddress.Loopback, 0), EncryptionPolicy.AllowNoEncryption)) - using (var client = new TcpClient()) + (NetworkStream clientStream, NetworkStream serverStream) = TestHelper.GetConnectedTcpStreams(); + using (clientStream) + using (serverStream) { - await client.ConnectAsync(serverAllowNoEncryption.RemoteEndPoint.Address, serverAllowNoEncryption.RemoteEndPoint.Port); - - using (var sslStream = new SslStream(client.GetStream(), false, AllowAnyServerCertificate, null)) + using (var client = new SslStream(clientStream, false, TestHelper.AllowAnyServerCertificate, null)) + using (var server = new SslStream(serverStream)) { - await sslStream.AuthenticateAsClientAsync("localhost", null, SslProtocolSupport.DefaultSslProtocols, false); + await TestConfiguration.WhenAllOrAnyFailedWithTimeout( + client.AuthenticateAsClientAsync("localhost", null, SslProtocolSupport.DefaultSslProtocols, false), + server.AuthenticateAsServerAsync(TestConfiguration.ServerCertificate)); + _log.WriteLine("Client authenticated to server({0}) with encryption cipher: {1} {2}-bit strength", - serverAllowNoEncryption.RemoteEndPoint, sslStream.CipherAlgorithm, sslStream.CipherStrength); - Assert.True(sslStream.CipherAlgorithm != CipherAlgorithmType.Null, "Cipher algorithm should not be NULL"); - Assert.True(sslStream.CipherStrength > 0, "Cipher strength should be greater than 0"); + clientStream.Socket.RemoteEndPoint, client.CipherAlgorithm, client.CipherStrength); + Assert.True(client.CipherAlgorithm != CipherAlgorithmType.Null, "Cipher algorithm should not be NULL"); + Assert.True(client.CipherStrength > 0, "Cipher strength should be greater than 0"); } } } @@ -75,16 +67,26 @@ public async Task ClientDefaultEncryption_ServerAllowNoEncryption_ConnectWithEnc [Fact] public async Task ClientDefaultEncryption_ServerNoEncryption_NoConnect() { - using (var serverNoEncryption = new DummyTcpServer( - new IPEndPoint(IPAddress.Loopback, 0), EncryptionPolicy.NoEncryption)) - using (var client = new TcpClient()) + (NetworkStream clientStream, NetworkStream serverStream) = TestHelper.GetConnectedTcpStreams(); + using (clientStream) + using (serverStream) { - await client.ConnectAsync(serverNoEncryption.RemoteEndPoint.Address, serverNoEncryption.RemoteEndPoint.Port); - - using (var sslStream = new SslStream(client.GetStream(), false, AllowAnyServerCertificate, null)) + using (var client = new SslStream(clientStream, false, TestHelper.AllowAnyServerCertificate, null)) + using (var server = new SslStream(serverStream, false, TestHelper.AllowAnyServerCertificate, null, EncryptionPolicy.NoEncryption)) { + Task serverTask = server.AuthenticateAsServerAsync(TestConfiguration.ServerCertificate); await Assert.ThrowsAsync(() => - sslStream.AuthenticateAsClientAsync("localhost", null, SslProtocolSupport.DefaultSslProtocols, false)); + client.AuthenticateAsClientAsync("localhost", null, SslProtocolSupport.DefaultSslProtocols, false)); + try + { + await serverTask.WaitAsync(TestConfiguration.PassingTestTimeout); + } + catch (Exception ex) + { + // serverTask will fail. + // We generally don't care but can log exception to help diagnose test failures + _log.WriteLine(ex.ToString()); + } } } } diff --git a/src/libraries/System.Net.Security/tests/FunctionalTests/DummyTcpServer.cs b/src/libraries/System.Net.Security/tests/FunctionalTests/DummyTcpServer.cs deleted file mode 100644 index 148a613e5ffc16..00000000000000 --- a/src/libraries/System.Net.Security/tests/FunctionalTests/DummyTcpServer.cs +++ /dev/null @@ -1,326 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using System.IO; -using System.Net.Sockets; -using System.Net.Test.Common; -using System.Security.Authentication; -using System.Security.Cryptography.X509Certificates; -using System.Threading.Tasks; - -namespace System.Net.Security.Tests -{ - using Configuration = System.Net.Test.Common.Configuration; - - // Callback method that is called when the server receives data from a connected client. - // The callback method should return a byte array and the number of bytes to send from that array. - public delegate void DummyTcpServerReceiveCallback(byte[] bufferReceived, int bytesReceived, Stream stream); - - // Provides a dummy TCP/IP server that accepts connections and supports SSL/TLS. - // It normally echoes data received but can be configured to write a byte array - // specified by a callback method. - public class DummyTcpServer : IDisposable - { - private readonly string _creationStack = Environment.StackTrace; - private VerboseTestLogging _log; - private TcpListener _listener; - private bool _useSsl; -#pragma warning disable SYSLIB0039 // TLS 1.0 and 1.1 are obsolete - private SslProtocols _sslProtocols = SslProtocols.Tls12 | SslProtocols.Tls11 | SslProtocols.Tls; -#pragma warning restore SYSLIB0039 - private EncryptionPolicy _sslEncryptionPolicy; - private IPEndPoint _remoteEndPoint; - private DummyTcpServerReceiveCallback _receiveCallback; - - private void StartListener(IPEndPoint endPoint) - { - _listener = new TcpListener(endPoint); - _listener.Start(5); - _log.WriteLine("Server {0} listening", endPoint.Address.ToString()); - _listener.AcceptTcpClientAsync().ContinueWith(t => OnAccept(t), TaskScheduler.Default); - } - - public DummyTcpServer(IPEndPoint endPoint) : this(endPoint, null) - { - } - - public DummyTcpServer(IPEndPoint endPoint, EncryptionPolicy? sslEncryptionPolicy) - { - _log = VerboseTestLogging.GetInstance(); - - if (sslEncryptionPolicy != null) - { - _remoteEndPoint = endPoint; - _useSsl = true; - _sslEncryptionPolicy = (EncryptionPolicy)sslEncryptionPolicy; - } - - StartListener(endPoint); - } - - public IPEndPoint RemoteEndPoint - { - get { return (IPEndPoint)_listener.LocalEndpoint; } - } - - public SslProtocols SslProtocols - { - get { return _sslProtocols; } - set { _sslProtocols = value; } - } - - protected DummyTcpServerReceiveCallback ReceiveCallback - { - get { return _receiveCallback; } - set { _receiveCallback = value; } - } - - public void Dispose() - { - Dispose(true); - } - - protected virtual void Dispose(bool disposing) - { - if (disposing) - { - _listener.Stop(); - } - } - - protected virtual void OnClientAccepted(TcpClient client) - { - } - - private void OnAuthenticate(Task result, ClientState state) - { - SslStream sslStream = (SslStream)state.Stream; - - try - { - result.GetAwaiter().GetResult(); - _log.WriteLine("Server authenticated to client with encryption cipher: {0} {1}-bit strength", - sslStream.CipherAlgorithm, sslStream.CipherStrength); - - // Start listening for data from the client connection. - sslStream.BeginRead(state.ReceiveBuffer, 0, state.ReceiveBuffer.Length, OnReceive, state); - } - catch (AuthenticationException authEx) - { - _log.WriteLine( - "Server disconnecting from client during authentication. No shared SSL/TLS algorithm. ({0})", - authEx); - state.Dispose(); - } - catch (Exception ex) - { - _log.WriteLine("Server disconnecting from client during authentication. Exception: {0}", - ex.Message); - state.Dispose(); - } - } - - private void OnAccept(Task result) - { - TcpClient client = null; - - // Accept current connection - try - { - client = result.Result; - } - catch - { - } - - // If we have a connection, then process it - if (client != null) - { - OnClientAccepted(client); - - ClientState state; - - // Start authentication for SSL? - if (_useSsl) - { - state = new ClientState(client, _sslEncryptionPolicy); - _log.WriteLine("Server: starting SSL authentication."); - - - SslStream sslStream = null; - X509Certificate2 certificate = Configuration.Certificates.GetServerCertificate(); - - try - { - sslStream = (SslStream)state.Stream; - - _log.WriteLine("Server: attempting to open SslStream."); - sslStream.AuthenticateAsServerAsync(certificate, false, _sslProtocols, false).ContinueWith(t => - { - certificate.Dispose(); - OnAuthenticate(t, state); - }, TaskScheduler.Default); - } - catch (Exception ex) - { - _log.WriteLine("Server: Exception: {0}", ex); - certificate.Dispose(); - state.Dispose(); // close connection to client - } - } - else - { - state = new ClientState(client); - - // Start listening for data from the client connection - try - { - state.Stream.BeginRead(state.ReceiveBuffer, 0, state.ReceiveBuffer.Length, OnReceive, state); - } - catch - { - } - } - } - - // Listen for more client connections - try - { - _listener.AcceptTcpClientAsync().ContinueWith(t => OnAccept(t), TaskScheduler.Default); - } - catch - { - } - } - - private void OnReceive(IAsyncResult result) - { - ClientState state = (ClientState)result.AsyncState; - - try - { - int bytesReceived = state.Stream.EndRead(result); - if (bytesReceived == 0) - { - state.Dispose(); - return; - } - - if (_receiveCallback != null) - { - _receiveCallback(state.ReceiveBuffer, bytesReceived, state.Stream); - } - else - { - // Echo back what we received - state.Stream.Write(state.ReceiveBuffer, 0, bytesReceived); - } - - // Read more from client (asynchronous) - state.Stream.BeginRead(state.ReceiveBuffer, 0, state.ReceiveBuffer.Length, OnReceive, state); - } - catch (IOException) - { - state.Dispose(); - return; - } - catch (SocketException) - { - state.Dispose(); - return; - } - catch (ObjectDisposedException) - { - state.Dispose(); - return; - } - catch (InvalidOperationException e) - { - throw new InvalidOperationException( - $"Exception in {nameof(DummyTcpServer)} created with stack: {_creationStack}", - e); - } - } - - // The following method is invoked by the RemoteCertificateValidationDelegate. - public static bool AlwaysValidServerCertificate(object sender, X509Certificate certificate, X509Chain chain, SslPolicyErrors sslPolicyErrors) - { - return true; // allow everything - } - - private class ClientState - { - private TcpClient _tcpClient; - private byte[] _receiveBuffer; - private bool _useSsl; - private SslStream _sslStream; - private bool _closed; - - public ClientState(TcpClient client) - { - _tcpClient = client; - _receiveBuffer = new byte[1024]; - _useSsl = false; - _closed = false; - } - - public ClientState(TcpClient client, EncryptionPolicy sslEncryptionPolicy) - { - _tcpClient = client; - _receiveBuffer = new byte[1024]; - _useSsl = true; - _sslStream = new SslStream(client.GetStream(), false, AlwaysValidServerCertificate, null, sslEncryptionPolicy); - _closed = false; - } - - public void Dispose() - { - if (!_closed) - { - if (_useSsl) - { - _sslStream.Dispose(); - } - - _tcpClient.Dispose(); - _closed = true; - } - } - - public TcpClient TcpClient - { - get { return _tcpClient; } - } - - public byte[] ReceiveBuffer - { - get { return _receiveBuffer; } - } - - public bool UseSsl - { - get { return _useSsl; } - } - - public bool Closed - { - get { return _closed; } - } - - public Stream Stream - { - get - { - if (_useSsl) - { - return _sslStream; - } - else - { - return _tcpClient.GetStream(); - } - } - } - } - } -} diff --git a/src/libraries/System.Net.Security/tests/FunctionalTests/ParameterValidationTest.cs b/src/libraries/System.Net.Security/tests/FunctionalTests/ParameterValidationTest.cs index 16020420ab8f78..cf596256fd446a 100644 --- a/src/libraries/System.Net.Security/tests/FunctionalTests/ParameterValidationTest.cs +++ b/src/libraries/System.Net.Security/tests/FunctionalTests/ParameterValidationTest.cs @@ -2,37 +2,26 @@ // The .NET Foundation licenses this file to you under the MIT license. using System.Net.Sockets; -using System.Security.Cryptography.X509Certificates; using System.Threading.Tasks; using Xunit; +using Xunit.Abstractions; + namespace System.Net.Security.Tests { public class ParameterValidationTest { - // The following method is invoked by the RemoteCertificateValidationDelegate. - public bool AllowAnyServerCertificate( - object sender, - X509Certificate certificate, - X509Chain chain, - SslPolicyErrors sslPolicyErrors) - { - return true; // allow everything - } - [Fact] public async Task SslStreamConstructor_BadEncryptionPolicy_ThrowException() { - using (var _remoteServer = new DummyTcpServer( - new IPEndPoint(IPAddress.Loopback, 0), EncryptionPolicy.RequireEncryption)) - using (var client = new TcpClient()) + (NetworkStream clientStream, NetworkStream serverStream) = await TestHelper.GetConnectedTcpStreamsAsync(); + using (clientStream) + using (serverStream) { - await client.ConnectAsync(_remoteServer.RemoteEndPoint.Address, _remoteServer.RemoteEndPoint.Port); - AssertExtensions.Throws("encryptionPolicy", () => { - SslStream sslStream = new SslStream(client.GetStream(), false, AllowAnyServerCertificate, null, (EncryptionPolicy)100); + SslStream sslStream = new SslStream(clientStream, false, TestHelper.AllowAnyServerCertificate, null, (EncryptionPolicy)100); }); } } diff --git a/src/libraries/System.Net.Security/tests/FunctionalTests/ServerAllowNoEncryptionTest.cs b/src/libraries/System.Net.Security/tests/FunctionalTests/ServerAllowNoEncryptionTest.cs index d52d4ae6f70f12..8520d129d37373 100644 --- a/src/libraries/System.Net.Security/tests/FunctionalTests/ServerAllowNoEncryptionTest.cs +++ b/src/libraries/System.Net.Security/tests/FunctionalTests/ServerAllowNoEncryptionTest.cs @@ -2,9 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. using System.Net.Sockets; -using System.Net.Test.Common; using System.Security.Authentication; -using System.Security.Cryptography.X509Certificates; using System.Threading.Tasks; using Xunit; @@ -21,32 +19,24 @@ public ServerAllowNoEncryptionTest(ITestOutputHelper output) _log = output; } - // The following method is invoked by the RemoteCertificateValidationDelegate. - public bool AllowAnyServerCertificate( - object sender, - X509Certificate certificate, - X509Chain chain, - SslPolicyErrors sslPolicyErrors) - { - return true; // allow everything - } - [Fact] public async Task ServerAllowNoEncryption_ClientRequireEncryption_ConnectWithEncryption() { - using (var serverAllowNoEncryption = new DummyTcpServer( - new IPEndPoint(IPAddress.Loopback, 0), EncryptionPolicy.AllowNoEncryption)) - using (var client = new TcpClient()) + (NetworkStream clientStream, NetworkStream serverStream) = TestHelper.GetConnectedTcpStreams(); + using (clientStream) + using (serverStream) { - await client.ConnectAsync(serverAllowNoEncryption.RemoteEndPoint.Address, serverAllowNoEncryption.RemoteEndPoint.Port); - - using (var sslStream = new SslStream(client.GetStream(), false, AllowAnyServerCertificate, null, EncryptionPolicy.RequireEncryption)) + using (var client = new SslStream(clientStream, false, TestHelper.AllowAnyServerCertificate, null, EncryptionPolicy.RequireEncryption)) + using (var server = new SslStream(serverStream, false, TestHelper.AllowAnyServerCertificate, null, EncryptionPolicy.AllowNoEncryption)) { - await sslStream.AuthenticateAsClientAsync("localhost", null, SslProtocolSupport.DefaultSslProtocols, false); + await TestConfiguration.WhenAllOrAnyFailedWithTimeout( + client.AuthenticateAsClientAsync("localhost", null, SslProtocols.None, false), + server.AuthenticateAsServerAsync(TestConfiguration.ServerCertificate)); + _log.WriteLine("Client authenticated to server({0}) with encryption cipher: {1} {2}-bit strength", - serverAllowNoEncryption.RemoteEndPoint, sslStream.CipherAlgorithm, sslStream.CipherStrength); - Assert.NotEqual(CipherAlgorithmType.Null, sslStream.CipherAlgorithm); - Assert.True(sslStream.CipherStrength > 0); + clientStream.Socket.RemoteEndPoint, client.CipherAlgorithm, client.CipherStrength); + Assert.NotEqual(CipherAlgorithmType.Null, client.CipherAlgorithm); + Assert.True(client.CipherStrength > 0); } } } @@ -54,48 +44,49 @@ public async Task ServerAllowNoEncryption_ClientRequireEncryption_ConnectWithEnc [Fact] public async Task ServerAllowNoEncryption_ClientAllowNoEncryption_ConnectWithEncryption() { - using (var serverAllowNoEncryption = new DummyTcpServer( - new IPEndPoint(IPAddress.Loopback, 0), EncryptionPolicy.AllowNoEncryption)) - using (var client = new TcpClient()) + (NetworkStream clientStream, NetworkStream serverStream) = TestHelper.GetConnectedTcpStreams(); + using (clientStream) + using (serverStream) { - await client.ConnectAsync(serverAllowNoEncryption.RemoteEndPoint.Address, serverAllowNoEncryption.RemoteEndPoint.Port); - - using (var sslStream = new SslStream(client.GetStream(), false, AllowAnyServerCertificate, null, EncryptionPolicy.AllowNoEncryption)) + using (var client = new SslStream(clientStream, false, TestHelper.AllowAnyServerCertificate, null, EncryptionPolicy.AllowNoEncryption)) + using (var server = new SslStream(serverStream, false, TestHelper.AllowAnyServerCertificate, null, EncryptionPolicy.AllowNoEncryption)) { - await sslStream.AuthenticateAsClientAsync("localhost", null, SslProtocolSupport.DefaultSslProtocols, false); + await TestConfiguration.WhenAllOrAnyFailedWithTimeout( + client.AuthenticateAsClientAsync("localhost", null, SslProtocols.None, false), + server.AuthenticateAsServerAsync(TestConfiguration.ServerCertificate)); + _log.WriteLine("Client authenticated to server({0}) with encryption cipher: {1} {2}-bit strength", - serverAllowNoEncryption.RemoteEndPoint, sslStream.CipherAlgorithm, sslStream.CipherStrength); - Assert.NotEqual(CipherAlgorithmType.Null, sslStream.CipherAlgorithm); - Assert.True(sslStream.CipherStrength > 0, "Cipher strength should be greater than 0"); + clientStream.Socket.RemoteEndPoint, client.CipherAlgorithm, client.CipherStrength); + Assert.NotEqual(CipherAlgorithmType.Null, client.CipherAlgorithm); + Assert.True(client.CipherStrength > 0, "Cipher strength should be greater than 0"); } } } - [ConditionalFact(nameof(SupportsNullEncryption))] + [ConditionalFact(typeof(TestConfiguration), nameof(TestConfiguration.SupportsNullEncryption))] public async Task ServerAllowNoEncryption_ClientNoEncryption_ConnectWithNoEncryption() { - using (var serverAllowNoEncryption = new DummyTcpServer( - new IPEndPoint(IPAddress.Loopback, 0), EncryptionPolicy.AllowNoEncryption)) - using (var client = new TcpClient()) + (NetworkStream clientStream, NetworkStream serverStream) = TestHelper.GetConnectedTcpStreams(); + using (clientStream) + using (serverStream) { - await client.ConnectAsync(serverAllowNoEncryption.RemoteEndPoint.Address, serverAllowNoEncryption.RemoteEndPoint.Port); - - using (var sslStream = new SslStream(client.GetStream(), false, AllowAnyServerCertificate, null, EncryptionPolicy.NoEncryption)) + using (var client = new SslStream(clientStream, false, TestHelper.AllowAnyServerCertificate, null, EncryptionPolicy.NoEncryption)) + using (var server = new SslStream(serverStream, false, TestHelper.AllowAnyServerCertificate, null, EncryptionPolicy.AllowNoEncryption)) { #pragma warning disable SYSLIB0039 // TLS 1.0 and 1.1 are obsolete - // null encryption is not permitted with Tls13 - await sslStream.AuthenticateAsClientAsync("localhost", null, SslProtocols.Tls | SslProtocols.Tls11 | SslProtocols.Tls12, false); + await TestConfiguration.WhenAllOrAnyFailedWithTimeout( + // null encryption is not permitted with Tls13 + client.AuthenticateAsClientAsync("localhost", null, SslProtocols.Tls | SslProtocols.Tls11 | SslProtocols.Tls12, false), + server.AuthenticateAsServerAsync(TestConfiguration.ServerCertificate)); #pragma warning restore SYSLIB0039 _log.WriteLine("Client authenticated to server({0}) with encryption cipher: {1} {2}-bit strength", - serverAllowNoEncryption.RemoteEndPoint, sslStream.CipherAlgorithm, sslStream.CipherStrength); + clientStream.Socket.RemoteEndPoint, client.CipherAlgorithm, client.CipherStrength); CipherAlgorithmType expected = CipherAlgorithmType.Null; - Assert.Equal(expected, sslStream.CipherAlgorithm); - Assert.Equal(0, sslStream.CipherStrength); + Assert.Equal(expected, client.CipherAlgorithm); + Assert.Equal(0, client.CipherStrength); } } } - - private static bool SupportsNullEncryption => TestConfiguration.SupportsNullEncryption; } } diff --git a/src/libraries/System.Net.Security/tests/FunctionalTests/ServerNoEncryptionTest.cs b/src/libraries/System.Net.Security/tests/FunctionalTests/ServerNoEncryptionTest.cs index 79e546621fcf6c..8060a506891593 100644 --- a/src/libraries/System.Net.Security/tests/FunctionalTests/ServerNoEncryptionTest.cs +++ b/src/libraries/System.Net.Security/tests/FunctionalTests/ServerNoEncryptionTest.cs @@ -21,94 +21,58 @@ public ServerNoEncryptionTest(ITestOutputHelper output) _log = output; } - // The following method is invoked by the RemoteCertificateValidationDelegate. - public bool AllowAnyServerCertificate( - object sender, - X509Certificate certificate, - X509Chain chain, - SslPolicyErrors sslPolicyErrors) - { - return true; // allow everything - } - - [Fact] + [ConditionalFact(typeof(TestConfiguration), nameof(TestConfiguration.SupportsNullEncryption))] public async Task ServerNoEncryption_ClientRequireEncryption_NoConnect() { - using (var serverNoEncryption = new DummyTcpServer( - new IPEndPoint(IPAddress.Loopback, 0), EncryptionPolicy.NoEncryption)) - using (var client = new TcpClient()) + (NetworkStream clientStream, NetworkStream serverStream) = TestHelper.GetConnectedTcpStreams(); + using (clientStream) + using (serverStream) { - await client.ConnectAsync(serverNoEncryption.RemoteEndPoint.Address, serverNoEncryption.RemoteEndPoint.Port); - - using (var sslStream = new SslStream(client.GetStream(), false, AllowAnyServerCertificate, null, EncryptionPolicy.RequireEncryption)) + using (var client = new SslStream(clientStream, false, TestHelper.AllowAnyServerCertificate, null, EncryptionPolicy.RequireEncryption)) + using (var server = new SslStream(serverStream, false, TestHelper.AllowAnyServerCertificate, null, EncryptionPolicy.NoEncryption)) { + Task serverTask = server.AuthenticateAsServerAsync(TestConfiguration.ServerCertificate); await Assert.ThrowsAsync(() => - sslStream.AuthenticateAsClientAsync("localhost", null, SslProtocolSupport.DefaultSslProtocols, false)); + client.AuthenticateAsClientAsync("localhost", null, SslProtocolSupport.DefaultSslProtocols, false)); + try + { + await serverTask; + } + catch (Exception ex) + { + // serverTask will fail. Log server error in case the test fails. + _log.WriteLine(ex.ToString()); + } } } } - [ConditionalFact(nameof(SupportsNullEncryption))] - public async Task ServerNoEncryption_ClientAllowNoEncryption_ConnectWithNoEncryption() + [ConditionalTheory(typeof(TestConfiguration), nameof(TestConfiguration.SupportsNullEncryption))] + [InlineData(EncryptionPolicy.AllowNoEncryption)] + [InlineData(EncryptionPolicy.NoEncryption)] + public async Task ServerNoEncryption_ClientPermitsNoEncryption_ConnectWithNoEncryption(EncryptionPolicy policy) { - using (var serverNoEncryption = new DummyTcpServer( - new IPEndPoint(IPAddress.Loopback, 0), EncryptionPolicy.NoEncryption)) - using (var client = new TcpClient()) + (NetworkStream clientStream, NetworkStream serverStream) = TestHelper.GetConnectedTcpStreams(); + using (clientStream) + using (serverStream) { - await client.ConnectAsync(serverNoEncryption.RemoteEndPoint.Address, serverNoEncryption.RemoteEndPoint.Port); - - using (var sslStream = new SslStream(client.GetStream(), false, AllowAnyServerCertificate, null, EncryptionPolicy.AllowNoEncryption)) + using (var client = new SslStream(clientStream, false, TestHelper.AllowAnyServerCertificate, null, policy)) + using (var server = new SslStream(serverStream, false, TestHelper.AllowAnyServerCertificate, null, EncryptionPolicy.NoEncryption)) { #pragma warning disable SYSLIB0039 // TLS 1.0 and 1.1 are obsolete - await sslStream.AuthenticateAsClientAsync("localhost", null, SslProtocols.Tls | SslProtocols.Tls11 | SslProtocols.Tls12, false); -#pragma warning restore SYSLIB0039 + await TestConfiguration.WhenAllOrAnyFailedWithTimeout( + // null encryption is not permitted with Tls13 + client.AuthenticateAsClientAsync("localhost", null, SslProtocols.Tls | SslProtocols.Tls11 | SslProtocols.Tls12, false), + server.AuthenticateAsServerAsync(TestConfiguration.ServerCertificate)); +#pragma warning restore SYSLIB0039 _log.WriteLine("Client authenticated to server({0}) with encryption cipher: {1} {2}-bit strength", - serverNoEncryption.RemoteEndPoint, sslStream.CipherAlgorithm, sslStream.CipherStrength); - - CipherAlgorithmType expected = CipherAlgorithmType.Null; - Assert.Equal(expected, sslStream.CipherAlgorithm); - Assert.Equal(0, sslStream.CipherStrength); - } - } - } - - [Fact] - public async Task ServerNoEncryption_ClientNoEncryption_ConnectWithNoEncryption() - { - using (var serverNoEncryption = new DummyTcpServer( - new IPEndPoint(IPAddress.Loopback, 0), EncryptionPolicy.NoEncryption)) - using (var client = new TcpClient()) - { - await client.ConnectAsync(serverNoEncryption.RemoteEndPoint.Address, serverNoEncryption.RemoteEndPoint.Port); + serverStream.Socket.RemoteEndPoint, client.CipherAlgorithm, client.CipherStrength); - using (var sslStream = new SslStream(client.GetStream(), false, AllowAnyServerCertificate, null, EncryptionPolicy.NoEncryption)) - { - if (SupportsNullEncryption) - { -#pragma warning disable SYSLIB0039 // TLS 1.0 and 1.1 are obsolete - // null encryption is not permitted with Tls13 - await sslStream.AuthenticateAsClientAsync("localhost", null, SslProtocols.Tls | SslProtocols.Tls11 | SslProtocols.Tls12, false); -#pragma warning restore SYSLIB0039 - _log.WriteLine("Client authenticated to server({0}) with encryption cipher: {1} {2}-bit strength", - serverNoEncryption.RemoteEndPoint, sslStream.CipherAlgorithm, sslStream.CipherStrength); - - CipherAlgorithmType expected = CipherAlgorithmType.Null; - Assert.Equal(expected, sslStream.CipherAlgorithm); - Assert.Equal(0, sslStream.CipherStrength); - } - else - { - var ae = await Assert.ThrowsAsync(() => sslStream.AuthenticateAsClientAsync("localhost", null, SslProtocolSupport.DefaultSslProtocols, false)); - if (!OperatingSystem.IsWindows()) - { - Assert.IsType(ae.InnerException); - } - } + Assert.Equal(CipherAlgorithmType.Null, client.CipherAlgorithm); + Assert.Equal(0, client.CipherStrength); } } } - - private static bool SupportsNullEncryption => TestConfiguration.SupportsNullEncryption; } } diff --git a/src/libraries/System.Net.Security/tests/FunctionalTests/ServerRequireEncryptionTest.cs b/src/libraries/System.Net.Security/tests/FunctionalTests/ServerRequireEncryptionTest.cs index 6dbb32d3e055a6..f918f182caee02 100644 --- a/src/libraries/System.Net.Security/tests/FunctionalTests/ServerRequireEncryptionTest.cs +++ b/src/libraries/System.Net.Security/tests/FunctionalTests/ServerRequireEncryptionTest.cs @@ -5,7 +5,6 @@ using System.Net.Sockets; using System.Net.Test.Common; using System.Security.Authentication; -using System.Security.Cryptography.X509Certificates; using System.Threading.Tasks; using Xunit; using Xunit.Abstractions; @@ -21,32 +20,24 @@ public ServerRequireEncryptionTest(ITestOutputHelper output) _log = output; } - // The following method is invoked by the RemoteCertificateValidationDelegate. - public bool AllowAnyServerCertificate( - object sender, - X509Certificate certificate, - X509Chain chain, - SslPolicyErrors sslPolicyErrors) - { - return true; // allow everything - } - [Fact] public async Task ServerRequireEncryption_ClientRequireEncryption_ConnectWithEncryption() { - using (var serverRequireEncryption = new DummyTcpServer( - new IPEndPoint(IPAddress.Loopback, 0), EncryptionPolicy.RequireEncryption)) - using (var client = new TcpClient()) + (NetworkStream clientStream, NetworkStream serverStream) = TestHelper.GetConnectedTcpStreams(); + using (clientStream) + using (serverStream) { - await client.ConnectAsync(serverRequireEncryption.RemoteEndPoint.Address, serverRequireEncryption.RemoteEndPoint.Port); - - using (var sslStream = new SslStream(client.GetStream(), false, AllowAnyServerCertificate, null, EncryptionPolicy.RequireEncryption)) + using (var client = new SslStream(clientStream, false, TestHelper.AllowAnyServerCertificate, null, EncryptionPolicy.RequireEncryption)) + using (var server = new SslStream(serverStream)) { - await sslStream.AuthenticateAsClientAsync("localhost", null, SslProtocolSupport.DefaultSslProtocols, false); + await TestConfiguration.WhenAllOrAnyFailedWithTimeout( + client.AuthenticateAsClientAsync("localhost", null, SslProtocolSupport.DefaultSslProtocols, false), + server.AuthenticateAsServerAsync(TestConfiguration.ServerCertificate)); + _log.WriteLine("Client authenticated to server({0}) with encryption cipher: {1} {2}-bit strength", - serverRequireEncryption.RemoteEndPoint, sslStream.CipherAlgorithm, sslStream.CipherStrength); - Assert.True(sslStream.CipherAlgorithm != CipherAlgorithmType.Null, "Cipher algorithm should not be NULL"); - Assert.True(sslStream.CipherStrength > 0, "Cipher strength should be greater than 0"); + clientStream.Socket.RemoteEndPoint, client.CipherAlgorithm, client.CipherStrength); + Assert.True(client.CipherAlgorithm != CipherAlgorithmType.Null, "Cipher algorithm should not be NULL"); + Assert.True(client.CipherStrength > 0, "Cipher strength should be greater than 0"); } } } @@ -54,41 +45,51 @@ public async Task ServerRequireEncryption_ClientRequireEncryption_ConnectWithEnc [Fact] public async Task ServerRequireEncryption_ClientAllowNoEncryption_ConnectWithEncryption() { - using (var serverRequireEncryption = new DummyTcpServer( - new IPEndPoint(IPAddress.Loopback, 0), EncryptionPolicy.RequireEncryption)) - using (var client = new TcpClient()) + (NetworkStream clientStream, NetworkStream serverStream) = TestHelper.GetConnectedTcpStreams(); + using (clientStream) + using (serverStream) { - await client.ConnectAsync(serverRequireEncryption.RemoteEndPoint.Address, serverRequireEncryption.RemoteEndPoint.Port); - - using (var sslStream = new SslStream(client.GetStream(), false, AllowAnyServerCertificate, null, EncryptionPolicy.AllowNoEncryption)) + using (var client = new SslStream(clientStream, false, TestHelper.AllowAnyServerCertificate, null, EncryptionPolicy.AllowNoEncryption)) + using (var server = new SslStream(serverStream)) { - await sslStream.AuthenticateAsClientAsync("localhost", null, SslProtocolSupport.DefaultSslProtocols, false); + await TestConfiguration.WhenAllOrAnyFailedWithTimeout( + client.AuthenticateAsClientAsync("localhost", null, SslProtocolSupport.DefaultSslProtocols, false), + server.AuthenticateAsServerAsync(TestConfiguration.ServerCertificate)); + _log.WriteLine("Client authenticated to server({0}) with encryption cipher: {1} {2}-bit strength", - serverRequireEncryption.RemoteEndPoint, sslStream.CipherAlgorithm, sslStream.CipherStrength); - Assert.True(sslStream.CipherAlgorithm != CipherAlgorithmType.Null, "Cipher algorithm should not be NULL"); - Assert.True(sslStream.CipherStrength > 0, "Cipher strength should be greater than 0"); + clientStream.Socket.RemoteEndPoint, client.CipherAlgorithm, client.CipherStrength); + Assert.True(client.CipherAlgorithm != CipherAlgorithmType.Null, "Cipher algorithm should not be NULL"); + Assert.True(client.CipherStrength > 0, "Cipher strength should be greater than 0"); } } } - [ConditionalFact(nameof(SupportsNullEncryption))] + [ConditionalFact(typeof(TestConfiguration), nameof(TestConfiguration.SupportsNullEncryption))] public async Task ServerRequireEncryption_ClientNoEncryption_NoConnect() { - using (var serverRequireEncryption = new DummyTcpServer( - new IPEndPoint(IPAddress.Loopback, 0), EncryptionPolicy.RequireEncryption)) - using (var client = new TcpClient()) + (NetworkStream clientStream, NetworkStream serverStream) = TestHelper.GetConnectedTcpStreams(); + using (clientStream) + using (serverStream) { - await client.ConnectAsync(serverRequireEncryption.RemoteEndPoint.Address, serverRequireEncryption.RemoteEndPoint.Port); - using (var sslStream = new SslStream(client.GetStream(), false, AllowAnyServerCertificate, null, EncryptionPolicy.NoEncryption)) + using (var client = new SslStream(clientStream, false, TestHelper.AllowAnyServerCertificate, null, EncryptionPolicy.NoEncryption)) + using (var server = new SslStream(serverStream)) { + Task serverTask = server.AuthenticateAsServerAsync(TestConfiguration.ServerCertificate); +#pragma warning disable SYSLIB0039 // TLS 1.0 and 1.1 are obsolete await Assert.ThrowsAsync(TestConfiguration.SupportsHandshakeAlerts ? typeof(AuthenticationException) : typeof(IOException), () => -#pragma warning disable SYSLIB0039 // TLS 1.0 and 1.1 are obsolete - sslStream.AuthenticateAsClientAsync("localhost", null, SslProtocols.Tls | SslProtocols.Tls11 | SslProtocols.Tls12, false)); -#pragma warning restore SYSLIB0039 + client.AuthenticateAsClientAsync("localhost", null, SslProtocols.Tls | SslProtocols.Tls11 | SslProtocols.Tls12, false)); +#pragma warning restore SYSLIB0039 + try + { + await serverTask.WaitAsync(TestConfiguration.PassingTestTimeout); + } + catch (Exception ex) + { + // This will fail. Log server error in case test fails. + _log.WriteLine(ex.ToString()); + } } } } - - private static bool SupportsNullEncryption => TestConfiguration.SupportsNullEncryption; } } diff --git a/src/libraries/System.Net.Security/tests/FunctionalTests/System.Net.Security.Tests.csproj b/src/libraries/System.Net.Security/tests/FunctionalTests/System.Net.Security.Tests.csproj index 6fe027ca2d2804..d6f02a397f90c0 100644 --- a/src/libraries/System.Net.Security/tests/FunctionalTests/System.Net.Security.Tests.csproj +++ b/src/libraries/System.Net.Security/tests/FunctionalTests/System.Net.Security.Tests.csproj @@ -11,7 +11,6 @@ - diff --git a/src/libraries/System.Net.Security/tests/FunctionalTests/TestConfiguration.cs b/src/libraries/System.Net.Security/tests/FunctionalTests/TestConfiguration.cs index b3493381933ad2..17db97de671628 100644 --- a/src/libraries/System.Net.Security/tests/FunctionalTests/TestConfiguration.cs +++ b/src/libraries/System.Net.Security/tests/FunctionalTests/TestConfiguration.cs @@ -2,8 +2,6 @@ // The .NET Foundation licenses this file to you under the MIT license. using System.Diagnostics; -using System.IO; -using System.Security.Authentication; using System.Security.Cryptography.X509Certificates; using System.Threading.Tasks; @@ -30,6 +28,8 @@ internal static class TestConfiguration public static bool SupportsHandshakeAlerts { get { return OperatingSystem.IsLinux() || OperatingSystem.IsWindows() || OperatingSystem.IsFreeBSD(); } } public static bool SupportsRenegotiation { get { return (OperatingSystem.IsWindows() && !PlatformDetection.IsWindows7) || ((OperatingSystem.IsLinux() || OperatingSystem.IsFreeBSD()) && PlatformDetection.OpenSslVersion >= new Version(1, 1, 1)); } } + public static X509Certificate2 ServerCertificate = System.Net.Test.Common.Configuration.Certificates.GetServerCertificate(); + public static Task WhenAllOrAnyFailedWithTimeout(params Task[] tasks) => tasks.WhenAllOrAnyFailed(PassingTestTimeoutMilliseconds); diff --git a/src/libraries/System.Net.Security/tests/FunctionalTests/TestHelper.cs b/src/libraries/System.Net.Security/tests/FunctionalTests/TestHelper.cs index 68b66a1af51fd4..0a5c14df841122 100644 --- a/src/libraries/System.Net.Security/tests/FunctionalTests/TestHelper.cs +++ b/src/libraries/System.Net.Security/tests/FunctionalTests/TestHelper.cs @@ -46,6 +46,11 @@ public static class TestHelper public static readonly byte[] s_ping = Encoding.UTF8.GetBytes("PING"); public static readonly byte[] s_pong = Encoding.UTF8.GetBytes("PONG"); + public static bool AllowAnyServerCertificate(object sender, X509Certificate certificate, X509Chain chain, SslPolicyErrors sslPolicyErrors) + { + return true; + } + public static (SslStream ClientStream, SslStream ServerStream) GetConnectedSslStreams() { (Stream clientStream, Stream serverStream) = GetConnectedStreams(); @@ -79,7 +84,25 @@ internal static (NetworkStream ClientStream, NetworkStream ServerStream) GetConn return (new NetworkStream(clientSocket, ownsSocket: true), new NetworkStream(serverSocket, ownsSocket: true)); } + } + internal static async Task<(NetworkStream ClientStream, NetworkStream ServerStream)> GetConnectedTcpStreamsAsync() + { + using (Socket listener = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp)) + { + listener.Bind(new IPEndPoint(IPAddress.Loopback, 0)); + listener.Listen(1); + + var clientSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); + Task acceptTask = listener.AcceptAsync(CancellationToken.None).AsTask(); + await clientSocket.ConnectAsync(listener.LocalEndPoint).WaitAsync(TestConfiguration.PassingTestTimeout); + Socket serverSocket = await acceptTask.WaitAsync(TestConfiguration.PassingTestTimeout); + + serverSocket.NoDelay = true; + clientSocket.NoDelay = true; + + return (new NetworkStream(clientSocket, ownsSocket: true), new NetworkStream(serverSocket, ownsSocket: true)); + } } internal static void CleanupCertificates([CallerMemberName] string? testName = null) diff --git a/src/libraries/System.Net.Security/tests/FunctionalTests/TransportContextTest.cs b/src/libraries/System.Net.Security/tests/FunctionalTests/TransportContextTest.cs index 5d43c02643b54e..1255dae98a85a6 100644 --- a/src/libraries/System.Net.Security/tests/FunctionalTests/TransportContextTest.cs +++ b/src/libraries/System.Net.Security/tests/FunctionalTests/TransportContextTest.cs @@ -1,11 +1,10 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. -using System.Net.Sockets; +using System.IO; using System.Runtime.InteropServices; using System.Security.Authentication; using System.Security.Authentication.ExtendedProtection; -using System.Security.Cryptography.X509Certificates; using System.Text; using System.Threading.Tasks; using Xunit; @@ -14,30 +13,21 @@ namespace System.Net.Security.Tests { public class TransportContextTest { - // The following method is invoked by the RemoteCertificateValidationDelegate. - public bool AllowAnyServerCertificate( - object sender, - X509Certificate certificate, - X509Chain chain, - SslPolicyErrors sslPolicyErrors) - { - return true; // allow everything - } - [Fact] public async Task TransportContext_ConnectToServerWithSsl_GetExpectedChannelBindings() { - using (var testServer = new DummyTcpServer( - new IPEndPoint(IPAddress.Loopback, 0), EncryptionPolicy.RequireEncryption)) - using (var client = new TcpClient()) + (Stream clientStream, Stream serverStream) = TestHelper.GetConnectedStreams(); + using (clientStream) + using (serverStream) { - await client.ConnectAsync(testServer.RemoteEndPoint.Address, testServer.RemoteEndPoint.Port); - - using (var sslStream = new SslStream(client.GetStream(), false, AllowAnyServerCertificate, null, EncryptionPolicy.RequireEncryption)) + using (var client = new SslStream(clientStream, false, TestHelper.AllowAnyServerCertificate, null, EncryptionPolicy.RequireEncryption)) + using (var server = new SslStream(serverStream)) { - await sslStream.AuthenticateAsClientAsync("localhost", null, SslProtocols.None, false); + await TestConfiguration.WhenAllOrAnyFailedWithTimeout( + client.AuthenticateAsClientAsync("localhost", null, SslProtocols.None, false), + server.AuthenticateAsServerAsync(TestConfiguration.ServerCertificate)); - TransportContext context = sslStream.TransportContext; + TransportContext context = client.TransportContext; CheckTransportContext(context); } }