Skip to content

Inconsistent behavior in SslStream.AuthenticateAsClient across win/linux #81590

@CharlieEriksen

Description

@CharlieEriksen

Description

On .NET 7.0, SslStream.AuthenticateAsClient behaves differently on Windows and Linux. When TargetHost is set for the SslClientAuthenticationOptions parameter, in some cases on Linux it will lead to the connection not establishing successfully, while it does on Windows.

While this appears to be host specific and is dependent on the parameters to AuthenticateAsClient, the fact that the very same code does not function the same across OS is problematic, leading to a lot of wasted time.

On Linux, you will simply get a connection reset:

Unhandled exception. System.IO.IOException: Unable to read data from the transport connection: Connection reset by peer.
 ---> System.Net.Sockets.SocketException (104): Connection reset by peer
   at System.Net.Sockets.NetworkStream.Read(Span`1 buffer)
   --- End of inner exception stack trace ---
   at System.Net.Sockets.NetworkStream.Read(Span`1 buffer)
   at System.Net.Security.SyncReadWriteAdapter.ReadAsync(Stream stream, Memory`1 buffer, CancellationToken cancellationToken)
   at System.Net.Security.SslStream.EnsureFullTlsFrameAsync[TIOAdapter](CancellationToken cancellationToken)
   at System.Runtime.CompilerServices.PoolingAsyncValueTaskMethodBuilder`1.StateMachineBox`1.System.Threading.Tasks.Sources.IValueTaskSource<TResult>.GetResult(Int16 token)
   at System.Net.Security.SslStream.ReceiveBlobAsync[TIOAdapter](CancellationToken cancellationToken)
   at System.Net.Security.SslStream.ForceAuthenticationAsync[TIOAdapter](Boolean receiveFirst, Byte[] reAuthenticationData, CancellationToken cancellationToken)
   at System.Net.Security.SslStream.AuthenticateAsClient(SslClientAuthenticationOptions sslClientAuthenticationOptions)
   at Program.Main() in /mnt/c/Users/Charlie/RiderProjects/SslStreamTest/SslStreamTest/Program.cs:line 17

Reproduction Steps

Run this code across both Windows and Linux:

using System.Net.Security;
using System.Net.Sockets;
					
public class Program
{
    public static void Main()
    {
        TcpClient client = new TcpClient("143.166.83.22", 443);
        SslStream sslStream = new SslStream(client.GetStream(), false);

        sslStream.AuthenticateAsClient(new SslClientAuthenticationOptions(){TargetHost = "143.166.83.22",RemoteCertificateValidationCallback = (sender, x509Certificate, chain, errors) => true});
    }
}

Expected behavior

As seen on Windows: A connection is established.

Actual behavior

As seen on Linux: Connection is reset:

Unhandled exception. System.IO.IOException: Unable to read data from the transport connection: Connection reset by peer.
 ---> System.Net.Sockets.SocketException (104): Connection reset by peer
   at System.Net.Sockets.NetworkStream.Read(Span`1 buffer)
   --- End of inner exception stack trace ---
   at System.Net.Sockets.NetworkStream.Read(Span`1 buffer)
   at System.Net.Security.SyncReadWriteAdapter.ReadAsync(Stream stream, Memory`1 buffer, CancellationToken cancellationToken)
   at System.Net.Security.SslStream.EnsureFullTlsFrameAsync[TIOAdapter](CancellationToken cancellationToken)
   at System.Runtime.CompilerServices.PoolingAsyncValueTaskMethodBuilder`1.StateMachineBox`1.System.Threading.Tasks.Sources.IValueTaskSource<TResult>.GetResult(Int16 token)
   at System.Net.Security.SslStream.ReceiveBlobAsync[TIOAdapter](CancellationToken cancellationToken)
   at System.Net.Security.SslStream.ForceAuthenticationAsync[TIOAdapter](Boolean receiveFirst, Byte[] reAuthenticationData, CancellationToken cancellationToken)
   at System.Net.Security.SslStream.AuthenticateAsClient(SslClientAuthenticationOptions sslClientAuthenticationOptions)
   at Program.Main() in /mnt/c/Users/Charlie/RiderProjects/SslStreamTest/SslStreamTest/Program.cs:line 17

Regression?

No response

Known Workarounds

Not setting TargetHost can help in some cases.

Configuration

Windows:

.NET SDK:
 Version:   7.0.102
 Commit:    4bbdd14480

Runtime Environment:
 OS Name:     Windows
 OS Version:  10.0.22000
 OS Platform: Windows
 RID:         win10-x64
 Base Path:   C:\Program Files\dotnet\sdk\7.0.102\

Host:
  Version:      7.0.2
  Architecture: x64
  Commit:       d037e070eb

.NET SDKs installed:
  6.0.402 [C:\Program Files\dotnet\sdk]
  7.0.102 [C:\Program Files\dotnet\sdk]

Linux, wsl:

.NET SDK:
 Version:   7.0.102
 Commit:    4bbdd14480

Runtime Environment:
 OS Name:     ubuntu
 OS Version:  20.04
 OS Platform: Linux
 RID:         ubuntu.20.04-x64
 Base Path:   /usr/share/dotnet/sdk/7.0.102/

Host:
  Version:      7.0.2
  Architecture: x64
  Commit:       d037e070eb

.NET SDKs installed:
  7.0.102 [/usr/share/dotnet/sdk]

Other information

No response

Metadata

Metadata

Assignees

No one assigned

    Labels

    area-System.Net.Securitygood first issueIssue should be easy to implement, good for first-time contributorshelp wanted[up-for-grabs] Good issue for external contributors

    Type

    No type

    Projects

    No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions