AuthenticateAsClient: System.IO.IOException: Received an unexpected EOF or 0 bytes from the transport stream

Bret picture Bret · Aug 20, 2014 · Viewed 15.6k times · Source

Due to Heartbleed, our Gateway Server was updated and this problem presented itself.

Due to POODLE, SSLv3 is no longer supported.

  • Note, the problem is only present on Win7+ boxes; WinXP boxes work without issue (same code, different OS = problem); granted WinXP is no longer a valid OS, just wanted to make note of functionality.

Client application (.NET 2.0) sits on a Windows 7 (or 8) box. Server runs within a DMZ behind a Gateway Server. Just to note, I found that this problem is no longer present on .NET 4.0+ - however due to legacy code, I do not have the luxury of updating.

Gateway Server is a pass through box on which Apache HTTP Server with SSL run. Its location is outside the DMZ, and it is used to access the Server which is inside the DMZ. Versions of software running on the Gateway server are Apache/2.2.25 (Win32), mod_jk/1.2.39, mod_ssl/2.2.25, OpenSSL/1.0.1g

Here is the code used on the Client application (with an exorbitant amount of logging added) ... note, 'serverName' typically contains a value such as "https://some.url.com"

private bool ConnectAndAuthenicate(string serverName, out TcpClient client, out SslStream sslStream)
{
    client = null;
    sslStream = null;
    try
    {
        client = new TcpClient(serverName, 443); // Create a TCP/IP client; ctor attempts connection
        Log("ConnectAndAuthenicate: Client CONNECTED"));

        sslStream = new SslStream(client.GetStream(), false, ValidateServerCertificate, null);
        Log("ConnectAndAuthenicate: SSL Stream CREATED"));
    }
    catch (Exception x)
    {
        Log("ConnectAndAuthenicate: EXCEPTION >> CONNECTING to server: {0}", x.ToString()));

        if (x is SocketException)
        {
            SocketException s = x as SocketException;
            Log("ConnectAndAuthenicate: EXCEPTION >> CONNECTING to server: Socket.ErrorCode: {0}", s.ErrorCode));
        }
        if (client != null) { client.Close(); client = null; }
        if (sslStream != null) { sslStream.Close(); sslStream = null; }
    }

    if (sslStream == null) return false;

    try
    {
        sslStream.ReadTimeout = 10000; // wait 10 seconds for a response ...
        Log("ConnectAndAuthenicate: AuthenticateAsClient CALLED ({0})", serverName));
        sslStream.AuthenticateAsClient(serverName);
        Log("ConnectAndAuthenicate: AuthenticateAsClient COMPLETED SUCCESSFULLY"));
        return true;
    }
    catch (Exception x)
    {
        Log("ConnectAndAuthenicate: EXCEPTION >> AuthenticateAsClient: {0}", x.ToString()));
        client.Close(); client = null;
        sslStream.Close(); sslStream = null;
    }
    return false;
}

Note - answers posted pertaining to ServicePointManager have absolutely no effect on the outcome of this application.

Every time that AuthenicateAsClient() is called when application is run on Win 7+ box, the exception occurs - if application is run on WinXP box, code works properly without exceptions.

Any ideas for solutions are very welcome.

Answer

Bret picture Bret · Aug 21, 2014

Following the trail of setting the ServicePointManager.SecurityProtocol static ctor with a SecurityProtocolType, I found mention of another enum called SslPolicy -- further research found that AuthenicateAsClient has an overload that takes SslPolicy as an argument.

Changing this line in the above code fixed this problem:

sslStream.AuthenticateAsClient(serverName, null, SslPolicy.Tls, false);