.NET 6 SslStream connection fails: "Received an unexpected EOF or 0 bytes from the transport stream"

1.4k Views Asked by At

I can successfully connect to a company server using openssl:

openssl s_client -connect {ip_address}:{tcp_port} -cert client.pem -key client.key -CAfile ca.cer

The output shows the negotiated protocol is TLS 1.2.

I'd like to implement this connection in C#. Here is my current attempt. Note that I provide the client's certificate and private key, but I does not check the server certificate:

var clientPrivateKey = RSA.Create();
clientPrivateKey.ImportFromPem(File.ReadAllText("client.key"));
var clientCertificate = new X509Certificate2("client.pem").CopyWithPrivateKey(clientPrivateKey);
var clientCertificates = new X509Certificate2Collection(clientCertificate);

using (var tcpClient = new TcpClient(ipAddress, tcpPort))
using (var sslStream = new SslStream(tcpClient.GetStream()))
{
  sslStream.AuthenticateAsClient(new SslClientAuthenticationOptions
  {
    AllowRenegotiation = true,
    EnabledSslProtocols = SslProtocols.Tls12 | SslProtocols.Tls13,
    CertificateRevocationCheckMode = X509RevocationMode.NoCheck,
    ClientCertificates = clientCertificates,
    TargetHost = ipAddress, // ???
    RemoteCertificateValidationCallback = (_, _, _, _) => true
  });
}

Unfortunately sslStream.AuthenticateAsClient throws this error:

Received an unexpected EOF or 0 bytes from the transport stream. (System.IO.IOException)

I have read everything about this problem on MSDN, StackOverflow etc. Some observations:

Although the openssl command line says the protocol is TLS 1.2, I tried other values, and also tried not setting the EnabledSslProtocols value, but nothing helped. I also tried changing or omitting AllowRenegotiation and CertificateRevocationCheckMode, but that did not help either.

The TargetHost value cannot be null, but I don't know what it should be. I tried an empty string, the CN from the server's certificate, even the server's IP address, but nothing helped. Interestingly, the openssl command line above says Can't use SSL_get_servername, which is suspicious but I don't know what it means exactly.

-- Thank you for your help in advance!


UPDATE: I checked the traffic using tcpdump. In case of the C# code, there is a SYN/SYN-ACK/ACK, a FIN-ACK/ACK initiated by the server at 5 seconds, and a Client Hello from the client at 30 seconds. The client not only waits for 30 seconds, but also tries to use TLS 1.0, whatever settings I use.

0

There are 0 best solutions below