From: Tomas Weinfurt Date: Thu, 7 May 2020 20:46:43 +0000 (-0700) Subject: improve handling of handshake failure (#35549) X-Git-Tag: submit/tizen/20210909.063632~8114 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=3058899348decccabcf758be6a586c87dc1f0c9a;p=platform%2Fupstream%2Fdotnet%2Fruntime.git improve handling of handshake failure (#35549) * improve handling of handshake failure * more cleanup * remove console reference * add quotes around parameter * enable ServerAsyncAuthenticate_MismatchProtocols_Fails * cleanup ssl2 test * fix http2 * feedback from review * add back two missing empty lines Co-authored-by: Tomas Weinfurt --- diff --git a/src/libraries/System.Net.Security/src/Resources/Strings.resx b/src/libraries/System.Net.Security/src/Resources/Strings.resx index 7270ea8..8af05eb 100644 --- a/src/libraries/System.Net.Security/src/Resources/Strings.resx +++ b/src/libraries/System.Net.Security/src/Resources/Strings.resx @@ -212,6 +212,9 @@ Authentication failed because the remote party has closed the transport stream. + + Authentication failed because the remote party sent a TLS alert: '{0}'. + Authentication failed on the remote side (the stream might still be available for additional authentication attempts). diff --git a/src/libraries/System.Net.Security/src/System.Net.Security.csproj b/src/libraries/System.Net.Security/src/System.Net.Security.csproj index 868fadd..067df9b 100644 --- a/src/libraries/System.Net.Security/src/System.Net.Security.csproj +++ b/src/libraries/System.Net.Security/src/System.Net.Security.csproj @@ -34,6 +34,7 @@ + diff --git a/src/libraries/System.Net.Security/src/System/Net/Security/SecureChannel.cs b/src/libraries/System.Net.Security/src/System/Net/Security/SecureChannel.cs index 82aab9f..b770ef2 100644 --- a/src/libraries/System.Net.Security/src/System/Net/Security/SecureChannel.cs +++ b/src/libraries/System.Net.Security/src/System/Net/Security/SecureChannel.cs @@ -625,7 +625,7 @@ namespace System.Net.Security // // Acquire Server Side Certificate information and set it on the class. // - private bool AcquireServerCredentials(ref byte[]? thumbPrint, ReadOnlySpan clientHello) + private bool AcquireServerCredentials(ref byte[]? thumbPrint) { if (NetEventSource.IsEnabled) NetEventSource.Enter(this); @@ -639,13 +639,13 @@ namespace System.Net.Security // with .NET Framework), and if neither is set we fall back to using ServerCertificate. if (_sslAuthenticationOptions.ServerCertSelectionDelegate != null) { - string? serverIdentity = SniHelper.GetServerName(clientHello); - localCertificate = _sslAuthenticationOptions.ServerCertSelectionDelegate(serverIdentity); - + localCertificate = _sslAuthenticationOptions.ServerCertSelectionDelegate(_sslAuthenticationOptions.TargetHost); if (localCertificate == null) { throw new AuthenticationException(SR.net_ssl_io_no_server_cert); } + if (NetEventSource.IsEnabled) + NetEventSource.Info(this, "Use delegate selected Cert"); } else if (_sslAuthenticationOptions.CertSelectionDelegate != null) { @@ -784,7 +784,7 @@ namespace System.Net.Security if (_refreshCredentialNeeded) { cachedCreds = _sslAuthenticationOptions.IsServer - ? AcquireServerCredentials(ref thumbPrint, inputBuffer) + ? AcquireServerCredentials(ref thumbPrint) : AcquireClientCredentials(ref thumbPrint); } diff --git a/src/libraries/System.Net.Security/src/System/Net/Security/SniHelper.cs b/src/libraries/System.Net.Security/src/System/Net/Security/SniHelper.cs index ffbf730..db68218 100644 --- a/src/libraries/System.Net.Security/src/System/Net/Security/SniHelper.cs +++ b/src/libraries/System.Net.Security/src/System/Net/Security/SniHelper.cs @@ -26,13 +26,13 @@ namespace System.Net.Security // opaque fragment[SSLPlaintext.length]; // } SSLPlaintext; const int ContentTypeOffset = 0; - const int ProtocolVersionOffset = ContentTypeOffset + sizeof(ContentType); + const int ProtocolVersionOffset = ContentTypeOffset + sizeof(TlsContentType); const int LengthOffset = ProtocolVersionOffset + ProtocolVersionSize; const int HandshakeOffset = LengthOffset + sizeof(ushort); // SSL v2's ContentType has 0x80 bit set. // We do not care about SSL v2 here because it does not support client hello extensions - if (sslPlainText.Length < HandshakeOffset || (ContentType)sslPlainText[ContentTypeOffset] != ContentType.Handshake) + if (sslPlainText.Length < HandshakeOffset || (TlsContentType)sslPlainText[ContentTypeOffset] != TlsContentType.Handshake) { return null; } @@ -62,10 +62,10 @@ namespace System.Net.Security // } body; // } Handshake; const int HandshakeTypeOffset = 0; - const int ClientHelloLengthOffset = HandshakeTypeOffset + sizeof(HandshakeType); + const int ClientHelloLengthOffset = HandshakeTypeOffset + sizeof(TlsHandshakeType); const int ClientHelloOffset = ClientHelloLengthOffset + UInt24Size; - if (sslHandshake.Length < ClientHelloOffset || (HandshakeType)sslHandshake[HandshakeTypeOffset] != HandshakeType.ClientHello) + if (sslHandshake.Length < ClientHelloOffset || (TlsHandshakeType)sslHandshake[HandshakeTypeOffset] != TlsHandshakeType.ClientHello) { return null; } @@ -363,16 +363,6 @@ namespace System.Net.Security return Encoding.GetEncoding("utf-8", new EncoderExceptionFallback(), new DecoderExceptionFallback()); } - private enum ContentType : byte - { - Handshake = 0x16 - } - - private enum HandshakeType : byte - { - ClientHello = 0x01 - } - private enum ExtensionType : ushort { ServerName = 0x00 diff --git a/src/libraries/System.Net.Security/src/System/Net/Security/SslStream.Implementation.cs b/src/libraries/System.Net.Security/src/System/Net/Security/SslStream.Implementation.cs index 600163b..d9ff52d 100644 --- a/src/libraries/System.Net.Security/src/System/Net/Security/SslStream.Implementation.cs +++ b/src/libraries/System.Net.Security/src/System/Net/Security/SslStream.Implementation.cs @@ -34,14 +34,8 @@ namespace System.Net.Security // This is set on the first packet to figure out the framing style. private Framing _framing = Framing.Unknown; - // SSL3/TLS protocol frames definitions. - private enum FrameType : byte - { - ChangeCipherSpec = 20, - Alert = 21, - Handshake = 22, - AppData = 23 - } + private TlsAlertDescription _lastAlertDescription; + private TlsFrameHandshakeInfo _lastFrame; private readonly object _handshakeLock = new object(); private volatile TaskCompletionSource? _handshakeWaiter; @@ -274,7 +268,6 @@ namespace System.Net.Security { // get ready to receive first frame _handshakeBuffer = new ArrayBuffer(InitialHandshakeBufferSize); - _framing = Framing.Unknown; } while (!handshakeCompleted) @@ -288,6 +281,19 @@ namespace System.Net.Security if (message.Failed) { + if (_lastFrame.Header.Type == TlsContentType.Handshake && message.Size == 0) + { + // If we failed without OS sending out alert, inject one here to be consistent across platforms. + byte[] alert = TlsFrameHelper.CreateAlertFrame(_lastFrame.Header.Version, TlsAlertDescription.ProtocolVersion); + await adapter.WriteAsync(alert, 0, alert.Length).ConfigureAwait(false); + } + else if (_lastFrame.Header.Type == TlsContentType.Alert && _lastAlertDescription != TlsAlertDescription.CloseNotify && + message.Status.ErrorCode == SecurityStatusPalErrorCode.IllegalMessage) + { + // Improve generic message and show details if we failed because of TLS Alert. + throw new AuthenticationException(SR.Format(SR.net_auth_tls_alert, _lastAlertDescription.ToString()), message.GetException()); + } + throw new AuthenticationException(SR.net_auth_SSPI, message.GetException()); } else if (message.Status.ErrorCode == SecurityStatusPalErrorCode.OK) @@ -346,17 +352,49 @@ namespace System.Net.Security _framing = DetectFraming(_handshakeBuffer.ActiveReadOnlySpan); } - int frameSize = GetFrameSize(_handshakeBuffer.ActiveReadOnlySpan); - if (frameSize < 0) + if (_framing == Framing.BeforeSSL3) + { +#pragma warning disable 0618 + _lastFrame.Header.Version = SslProtocols.Ssl2; +#pragma warning restore 0618 + _lastFrame.Header.Length = GetFrameSize(_handshakeBuffer.ActiveReadOnlySpan); + } + else + { + TlsFrameHelper.TryGetFrameHeader(_handshakeBuffer.ActiveReadOnlySpan, ref _lastFrame.Header); + } + + if (_lastFrame.Header.Length < 0) { throw new IOException(SR.net_frame_read_size); } + // Header length is content only so we must add header size as well. + int frameSize = _lastFrame.Header.Length + TlsFrameHelper.HeaderSize; if (_handshakeBuffer.ActiveLength < frameSize) { await FillHandshakeBufferAsync(adapter, frameSize).ConfigureAwait(false); } + // At this point, we have at least one TLS frame. + if (_lastFrame.Header.Type == TlsContentType.Alert) + { + TlsAlertLevel level = 0; + if (TlsFrameHelper.TryGetAlertInfo(_handshakeBuffer.ActiveReadOnlySpan, ref level, ref _lastAlertDescription)) + { + if (NetEventSource.IsEnabled && _lastAlertDescription != TlsAlertDescription.CloseNotify) NetEventSource.Fail(this, $"Received TLS alert {_lastAlertDescription}"); + } + } + else if (_lastFrame.Header.Type == TlsContentType.Handshake) + { + if (_handshakeBuffer.ActiveReadOnlySpan[TlsFrameHelper.HeaderSize] == (byte)TlsHandshakeType.ClientHello && + _sslAuthenticationOptions!.ServerCertSelectionDelegate != null) + { + // Process SNI from Client Hello message + TlsFrameHelper.TryGetHandshakeInfo(_handshakeBuffer.ActiveReadOnlySpan, ref _lastFrame); + _sslAuthenticationOptions.TargetHost = _lastFrame.TargetName; + } + } return ProcessBlob(frameSize); } @@ -372,23 +410,24 @@ namespace System.Net.Security _handshakeBuffer.Discard(frameSize); // Often more TLS messages fit into same packet. Get as many complete frames as we can. - while (_handshakeBuffer.ActiveLength > SecureChannel.ReadHeaderSize) + while (_handshakeBuffer.ActiveLength > TlsFrameHelper.HeaderSize) { - ReadOnlySpan remainingData = _handshakeBuffer.ActiveReadOnlySpan; - if (remainingData[0] >= (int)FrameType.AppData) + TlsFrameHeader nextHeader = default; + + if (!TlsFrameHelper.TryGetFrameHeader(_handshakeBuffer.ActiveReadOnlySpan, ref nextHeader)) { break; } - frameSize = GetFrameSize(remainingData); - if (_handshakeBuffer.ActiveLength >= frameSize) + frameSize = nextHeader.Length + TlsFrameHelper.HeaderSize; + if (nextHeader.Type == TlsContentType.AppData || frameSize > _handshakeBuffer.ActiveLength) { - chunkSize += frameSize; - _handshakeBuffer.Discard(frameSize); - continue; + // We don't have full frame left or we already have app data which needs to be processed by decrypt. + break; } - break; + chunkSize += frameSize; + _handshakeBuffer.Discard(frameSize); } return _context!.NextMessage(availableData.Slice(0, chunkSize)); @@ -645,7 +684,7 @@ namespace System.Net.Security Debug.Assert(_internalBufferCount >= SecureChannel.ReadHeaderSize); // Parse the frame header to determine the payload size (which includes the header size). - int payloadBytes = GetFrameSize(_internalBuffer.AsSpan(_internalOffset)); + int payloadBytes = TlsFrameHelper.GetFrameSize(_internalBuffer.AsSpan(_internalOffset)); if (payloadBytes < 0) { throw new IOException(SR.net_frame_read_size); @@ -913,6 +952,7 @@ namespace System.Net.Security Buffer.BlockCopy(saved, 0, buffer, 0, copyCount); } } + return buffer; } @@ -1003,8 +1043,8 @@ namespace System.Net.Security } // If the first byte is SSL3 HandShake, then check if we have a SSLv3 Type3 client hello. - if (bytes[0] == (byte)FrameType.Handshake || bytes[0] == (byte)FrameType.AppData - || bytes[0] == (byte)FrameType.Alert) + if (bytes[0] == (byte)TlsContentType.Handshake || bytes[0] == (byte)TlsContentType.AppData + || bytes[0] == (byte)TlsContentType.Alert) { if (bytes.Length < 3) { diff --git a/src/libraries/System.Net.Security/src/System/Net/Security/SslStreamPal.OSX.cs b/src/libraries/System.Net.Security/src/System/Net/Security/SslStreamPal.OSX.cs index b72e549..3cf26e7 100644 --- a/src/libraries/System.Net.Security/src/System/Net/Security/SslStreamPal.OSX.cs +++ b/src/libraries/System.Net.Security/src/System/Net/Security/SslStreamPal.OSX.cs @@ -237,9 +237,8 @@ namespace System.Net.Security sslContext = new SafeDeleteSslContext((credential as SafeFreeSslCredentials)!, sslAuthenticationOptions); context = sslContext; - if (!string.IsNullOrEmpty(sslAuthenticationOptions.TargetHost)) + if (!string.IsNullOrEmpty(sslAuthenticationOptions.TargetHost) && !sslAuthenticationOptions.IsServer) { - Debug.Assert(!sslAuthenticationOptions.IsServer, "targetName should not be set for server-side handshakes"); Interop.AppleCrypto.SslSetTargetName(sslContext.SslContext, sslAuthenticationOptions.TargetHost); } diff --git a/src/libraries/System.Net.Security/src/System/Net/Security/TlsFrameHelper.cs b/src/libraries/System.Net.Security/src/System/Net/Security/TlsFrameHelper.cs new file mode 100644 index 0000000..ec18be1 --- /dev/null +++ b/src/libraries/System.Net.Security/src/System/Net/Security/TlsFrameHelper.cs @@ -0,0 +1,235 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System.Diagnostics; +using System.Security.Authentication; + +namespace System.Net.Security +{ + // SSL3/TLS protocol frames definitions. + internal enum TlsContentType : byte + { + ChangeCipherSpec = 20, + Alert = 21, + Handshake = 22, + AppData = 23 + } + + internal enum TlsHandshakeType : byte + { + HelloRequest = 0, + ClientHello = 1, + ServerHello = 2, + NewSessionTicket = 4, + EndOfEarlyData = 5, + EncryptedExtensions = 8, + Certificate = 11, + ServerKeyExchange = 12, + CertificateRequest = 13, + ServerHelloDone = 14, + CertificateVerify = 15, + ClientKeyExchange = 16, + Finished = 20, + KeyEpdate = 24, + MessageHash = 254 + } + + internal enum TlsAlertLevel : byte + { + Warning = 1, + Fatal = 2, + } + + internal enum TlsAlertDescription : byte + { + CloseNotify = 0, // warning + UnexpectedMessage = 10, // error + BadRecordMac = 20, // error + DecryptionFailed = 21, // reserved + RecordOverflow = 22, // error + DecompressionFail = 30, // error + HandshakeFailure = 40, // error + BadCertificate = 42, // warning or error + UnsupportedCert = 43, // warning or error + CertificateRevoked = 44, // warning or error + CertificateExpired = 45, // warning or error + CertificateUnknown = 46, // warning or error + IllegalParameter = 47, // error + UnknownCA = 48, // error + AccessDenied = 49, // error + DecodeError = 50, // error + DecryptError = 51, // error + ExportRestriction = 60, // reserved + ProtocolVersion = 70, // error + InsuffientSecurity = 71, // error + InternalError = 80, // error + UserCanceled = 90, // warning or error + NoRenegotiation = 100, // warning + UnsupportedExt = 110, // error + } + + internal struct TlsFrameHeader + { + public TlsContentType Type; + public SslProtocols Version; + public int Length; + } + + internal struct TlsFrameHandshakeInfo + { + public TlsFrameHeader Header; + public TlsHandshakeType HandshakeType; + public SslProtocols SupportedVersions; + public string? TargetName; + } + + internal class TlsFrameHelper + { + public const int HeaderSize = 5; + + private static byte[] s_protocolMismatch13 = new byte[] { (byte)TlsContentType.Alert, 3, 4, 0, 2, 2, 70 }; + private static byte[] s_protocolMismatch12 = new byte[] { (byte)TlsContentType.Alert, 3, 3, 0, 2, 2, 70 }; + private static byte[] s_protocolMismatch11 = new byte[] { (byte)TlsContentType.Alert, 3, 2, 0, 2, 2, 70 }; + private static byte[] s_protocolMismatch10 = new byte[] { (byte)TlsContentType.Alert, 3, 1, 0, 2, 2, 70 }; + + public static bool TryGetFrameHeader(ReadOnlySpan frame, ref TlsFrameHeader header) + { + bool result = frame.Length > 4; + + if (frame.Length >= 1) + { + header.Type = (TlsContentType)frame[0]; + + if (frame.Length >= 3) + { + // SSLv3, TLS or later + if (frame[1] == 3) + { + if (frame.Length > 4) + { + header.Length = ((frame[3] << 8) | frame[4]); + } + + switch (frame[2]) + { + case 4: + header.Version = SslProtocols.Tls13; + break; + case 3: + header.Version = SslProtocols.Tls12; + break; + case 2: + header.Version = SslProtocols.Tls11; + break; + case 1: + header.Version = SslProtocols.Tls; + break; + case 0: +#pragma warning disable 0618 + header.Version = SslProtocols.Ssl3; +#pragma warning restore 0618 + break; + default: + header.Version = SslProtocols.None; + break; + } + } + else + { + header.Length = -1; + header.Version = SslProtocols.None; + } + } + } + + return result; + } + + // Returns frame size e.g. header + content + public static int GetFrameSize(ReadOnlySpan frame) + { + if (frame.Length < 5 || frame[1] < 3) + { + return - 1; + } + + return ((frame[3] << 8) | frame[4]) + HeaderSize; + } + + public static bool TryGetHandshakeInfo(ReadOnlySpan frame, ref TlsFrameHandshakeInfo info) + { + if (frame.Length < 6 || frame[0] != (byte)TlsContentType.Handshake) + { + return false; + } + + // This will not fail since we have enough data. + bool gotHeader = TryGetFrameHeader(frame, ref info.Header); + Debug.Assert(gotHeader); + + info.SupportedVersions = info.Header.Version; + + info.HandshakeType = (TlsHandshakeType)frame[5]; + + if (info.HandshakeType == TlsHandshakeType.ClientHello) + { + info.TargetName = SniHelper.GetServerName(frame); + } + + return true; + } + + public static bool TryGetAlertInfo(ReadOnlySpan frame, ref TlsAlertLevel level, ref TlsAlertDescription description) + { + if (frame.Length < 7 || frame[0] != (byte)TlsContentType.Alert) + { + return false; + } + + level = (TlsAlertLevel)frame[5]; + description = (TlsAlertDescription)frame[6]; + + return true; + } + + private static byte[] CreateProtocolVersionAlert(SslProtocols version) => + version switch + { + SslProtocols.Tls13 => s_protocolMismatch13, + SslProtocols.Tls12 => s_protocolMismatch12, + SslProtocols.Tls11 => s_protocolMismatch11, + SslProtocols.Tls => s_protocolMismatch10, + _ => Array.Empty(), + }; + + public static byte[] CreateAlertFrame(SslProtocols version, TlsAlertDescription reason) + { + if (reason == TlsAlertDescription.ProtocolVersion) + { + return CreateProtocolVersionAlert(version); + } + else if ((int)version > (int)SslProtocols.Tls) + { + // Create TLS1.2 alert + byte[] buffer = new byte[] { (byte)TlsContentType.Alert, 3, 3, 0, 2, 2, (byte)reason }; + switch (version) + { + case SslProtocols.Tls13: + buffer[2] = 4; + break; + case SslProtocols.Tls11: + buffer[2] = 2; + break; + case SslProtocols.Tls: + buffer[2] = 1; + break; + } + + return buffer; + } + + return Array.Empty(); + } + } +} diff --git a/src/libraries/System.Net.Security/tests/FunctionalTests/ClientAsyncAuthenticateTest.cs b/src/libraries/System.Net.Security/tests/FunctionalTests/ClientAsyncAuthenticateTest.cs index 69c9673..5c22719 100644 --- a/src/libraries/System.Net.Security/tests/FunctionalTests/ClientAsyncAuthenticateTest.cs +++ b/src/libraries/System.Net.Security/tests/FunctionalTests/ClientAsyncAuthenticateTest.cs @@ -44,11 +44,7 @@ namespace System.Net.Security.Tests public async Task ClientAsyncAuthenticate_ServerNoEncryption_NoConnect() { // Don't use Tls13 since we are trying to use NullEncryption - Type expectedExceptionType = TestConfiguration.SupportsHandshakeAlerts && TestConfiguration.SupportsNullEncryption ? - typeof(AuthenticationException) : - typeof(IOException); - - await Assert.ThrowsAsync(expectedExceptionType, + await Assert.ThrowsAsync( () => ClientAsyncSslHelper( EncryptionPolicy.NoEncryption, SslProtocolSupport.DefaultSslProtocols, SslProtocols.Tls | SslProtocols.Tls11 | SslProtocols.Tls12 )); @@ -120,12 +116,12 @@ namespace System.Net.Security.Tests 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, TestConfiguration.SupportsVersionAlerts ? typeof(AuthenticationException) : typeof(IOException) }; - yield return new object[] { SslProtocols.Tls, SslProtocols.Tls12, TestConfiguration.SupportsVersionAlerts ? typeof(AuthenticationException) : typeof(IOException) }; + 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, TestConfiguration.SupportsVersionAlerts ? typeof(AuthenticationException) : typeof(IOException) }; + yield return new object[] { SslProtocols.Tls11, SslProtocols.Tls12, typeof(AuthenticationException) }; } #region Helpers diff --git a/src/libraries/System.Net.Security/tests/FunctionalTests/ClientDefaultEncryptionTest.cs b/src/libraries/System.Net.Security/tests/FunctionalTests/ClientDefaultEncryptionTest.cs index 4a57ca9..ed3a2c6 100644 --- a/src/libraries/System.Net.Security/tests/FunctionalTests/ClientDefaultEncryptionTest.cs +++ b/src/libraries/System.Net.Security/tests/FunctionalTests/ClientDefaultEncryptionTest.cs @@ -84,7 +84,7 @@ namespace System.Net.Security.Tests using (var sslStream = new SslStream(client.GetStream(), false, AllowAnyServerCertificate, null)) { - await Assert.ThrowsAsync(TestConfiguration.SupportsHandshakeAlerts ? typeof(AuthenticationException) : typeof(IOException), () => + await Assert.ThrowsAsync(() => sslStream.AuthenticateAsClientAsync("localhost", null, SslProtocolSupport.DefaultSslProtocols, false)); } } diff --git a/src/libraries/System.Net.Security/tests/FunctionalTests/ServerAsyncAuthenticateTest.cs b/src/libraries/System.Net.Security/tests/FunctionalTests/ServerAsyncAuthenticateTest.cs index 5ecb21d..9bf0afb 100644 --- a/src/libraries/System.Net.Security/tests/FunctionalTests/ServerAsyncAuthenticateTest.cs +++ b/src/libraries/System.Net.Security/tests/FunctionalTests/ServerAsyncAuthenticateTest.cs @@ -44,7 +44,6 @@ namespace System.Net.Security.Tests [Theory] [MemberData(nameof(ProtocolMismatchData))] - [ActiveIssue("https://github.com/dotnet/runtime/issues/29642")] public async Task ServerAsyncAuthenticate_MismatchProtocols_Fails( SslProtocols serverProtocol, SslProtocols clientProtocol, @@ -80,10 +79,10 @@ namespace System.Net.Security.Tests #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, TestConfiguration.SupportsVersionAlerts ? typeof(AuthenticationException) : typeof(TimeoutException) }; + yield return new object[] { SslProtocols.Tls11, SslProtocols.Tls, typeof(AuthenticationException) }; yield return new object[] { SslProtocols.Tls11, SslProtocols.Tls12, typeof(AuthenticationException) }; - yield return new object[] { SslProtocols.Tls12, SslProtocols.Tls, TestConfiguration.SupportsVersionAlerts ? typeof(AuthenticationException) : typeof(TimeoutException) }; - yield return new object[] { SslProtocols.Tls12, SslProtocols.Tls11, TestConfiguration.SupportsVersionAlerts ? typeof(AuthenticationException) : typeof(TimeoutException) }; + yield return new object[] { SslProtocols.Tls12, SslProtocols.Tls, typeof(AuthenticationException) }; + yield return new object[] { SslProtocols.Tls12, SslProtocols.Tls11, typeof(AuthenticationException) }; } #region Helpers diff --git a/src/libraries/System.Net.Security/tests/FunctionalTests/ServerNoEncryptionTest.cs b/src/libraries/System.Net.Security/tests/FunctionalTests/ServerNoEncryptionTest.cs index 65efb78..d062fac 100644 --- a/src/libraries/System.Net.Security/tests/FunctionalTests/ServerNoEncryptionTest.cs +++ b/src/libraries/System.Net.Security/tests/FunctionalTests/ServerNoEncryptionTest.cs @@ -43,7 +43,7 @@ namespace System.Net.Security.Tests using (var sslStream = new SslStream(client.GetStream(), false, AllowAnyServerCertificate, null, EncryptionPolicy.RequireEncryption)) { - await Assert.ThrowsAsync(TestConfiguration.SupportsHandshakeAlerts ? typeof(AuthenticationException) : typeof(IOException), () => + await Assert.ThrowsAsync(() => sslStream.AuthenticateAsClientAsync("localhost", null, SslProtocolSupport.DefaultSslProtocols, false)); } } diff --git a/src/libraries/System.Net.Security/tests/FunctionalTests/SslStreamSniTest.cs b/src/libraries/System.Net.Security/tests/FunctionalTests/SslStreamSniTest.cs index a546241..b98a9ea 100644 --- a/src/libraries/System.Net.Security/tests/FunctionalTests/SslStreamSniTest.cs +++ b/src/libraries/System.Net.Security/tests/FunctionalTests/SslStreamSniTest.cs @@ -3,6 +3,7 @@ // See the LICENSE file in the project root for more information. using System.Collections.Generic; +using System.IO; using System.Net.Test.Common; using System.Security.Authentication; using System.Security.Cryptography.X509Certificates; @@ -201,9 +202,7 @@ namespace System.Net.Security.Tests private async Task WithVirtualConnection(Func serverClientConnection, RemoteCertificateValidationCallback clientCertValidate) { - VirtualNetwork vn = new VirtualNetwork(); - using (VirtualNetworkStream serverStream = new VirtualNetworkStream(vn, isServer: true), - clientStream = new VirtualNetworkStream(vn, isServer: false)) + (Stream clientStream, Stream serverStream) = TestHelper.GetConnectedStreams(); using (SslStream server = new SslStream(serverStream, leaveInnerStreamOpen: false), client = new SslStream(clientStream, leaveInnerStreamOpen: false, clientCertValidate)) { diff --git a/src/libraries/System.Net.Security/tests/FunctionalTests/SslStreamSystemDefaultsTest.cs b/src/libraries/System.Net.Security/tests/FunctionalTests/SslStreamSystemDefaultsTest.cs index 4943401..bc704fa 100644 --- a/src/libraries/System.Net.Security/tests/FunctionalTests/SslStreamSystemDefaultsTest.cs +++ b/src/libraries/System.Net.Security/tests/FunctionalTests/SslStreamSystemDefaultsTest.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +using System.IO; using System.Net.Http; using System.Net.Test.Common; using System.Security.Cryptography.X509Certificates; @@ -21,10 +22,7 @@ namespace System.Net.Security.Tests public SslStreamSystemDefaultTest() { - var network = new VirtualNetwork(); - var clientNet = new VirtualNetworkStream(network, isServer:false); - var serverNet = new VirtualNetworkStream(network, isServer: true); - + (Stream clientNet, Stream serverNet) = TestHelper.GetConnectedTcpStreams(); _clientStream = new SslStream(clientNet, false, ClientCertCallback); _serverStream = new SslStream(serverNet, false, ServerCertCallback); } 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 8a245e8..4ad9475 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 @@ -66,6 +66,8 @@ Link="ProductionCode\Common\System\Threading\Tasks\TaskToApm.cs" /> + diff --git a/src/libraries/System.Net.Security/tests/FunctionalTests/TestConfiguration.cs b/src/libraries/System.Net.Security/tests/FunctionalTests/TestConfiguration.cs index 9769590..577d2ce 100644 --- a/src/libraries/System.Net.Security/tests/FunctionalTests/TestConfiguration.cs +++ b/src/libraries/System.Net.Security/tests/FunctionalTests/TestConfiguration.cs @@ -32,9 +32,7 @@ namespace System.Net.Security.Tests public static bool SupportsHandshakeAlerts { get { return RuntimeInformation.IsOSPlatform(OSPlatform.Linux) || RuntimeInformation.IsOSPlatform(OSPlatform.Windows); } } - public static bool SupportsAlpnAlerts { get { return RuntimeInformation.IsOSPlatform(OSPlatform.Windows) || (RuntimeInformation.IsOSPlatform(OSPlatform.Linux) && PlatformDetection.OpenSslVersion.CompareTo(new Version(1,1,0)) >= 0); } } - - public static bool SupportsVersionAlerts { get { return RuntimeInformation.IsOSPlatform(OSPlatform.Linux) && PlatformDetection.OpenSslVersion.CompareTo(new Version(1,1,0)) >= 0; } } + public static bool SupportsAlpnAlerts { get { return RuntimeInformation.IsOSPlatform(OSPlatform.Windows) || (RuntimeInformation.IsOSPlatform(OSPlatform.Linux) && PlatformDetection.OpenSslVersion.CompareTo(new Version(1,0,2)) >= 0); } } public static Task WhenAllOrAnyFailedWithTimeout(params Task[] tasks) => tasks.WhenAllOrAnyFailed(PassingTestTimeoutMilliseconds);