user1538717
user1538717

Reputation:

SslStream.Read results in IOException

I'm trying to use SslStream to connect to a website to pass a request, but I'm getting the following IOException:

Unable to read data from the transport connection: A connection attempt failed because the connected party did not properly respond after a period of time, or established connection failed because connected host has failed to respond.

In order to make testing this more efficient i created a standalone program and copied the client code example code from here: http://msdn.microsoft.com/en-us/library/system.net.security.sslstream(v=vs.110).aspx and then passed in the request based on the other party's API.

            string Request = "The Request";
            TcpClient client = new TcpClient();
            client.ReceiveTimeout = 10000; //10 seconds
            SslStream sslStream;
            string server = "ssl.website.com";
            client.Connect(server, 12345);
            sslStream = new SslStream(client.GetStream(), false, new RemoteCertificateValidationCallback(ValidateServerCertificate), null );

            sslStream.AuthenticateAsClient(server,null, SslProtocols.Tls12, false);

            StringBuilder messageData = new StringBuilder();
            byte[] len = BitConverter.GetBytes(SslClient.GetLen(Request));

            messageData.AppendLine("Writing length of data " + SslClient.GetLen(Request).ToString());
            sslStream.Write(len);
            byte[] msg = Encoding.UTF8.GetBytes(Request);

            sslStream.Write(msg);
            sslStream.Flush();

            byte[] buffer = new byte[2048];

            messageData.AppendLine("Writing data " + System.Text.Encoding.UTF8.GetString(msg));
            messageData.AppendLine("Is Authenticated? " + sslStream.IsAuthenticated.ToString());
            int bytes = -1;

            try
            {
                do
                {
                    bytes = sslStream.Read(buffer, 0, buffer.Length);

                    Decoder decoder = Encoding.UTF8.GetDecoder();
                    char[] chars = new char[decoder.GetCharCount(buffer, 0, bytes)];
                    decoder.GetChars(buffer, 0, bytes, chars, 0);
                    messageData.AppendLine(chars.ToString());

                    if (messageData.ToString().IndexOf("<EOF>") != -1)
                    {
                        break;
                    }

                } while (bytes != 0);
            }
            catch(Exception ex)
            {
                messageData.AppendLine(ex.Message);
            }

            return messageData.ToString();
        }


        public static bool ValidateServerCertificate(
              object sender,
              X509Certificate certificate,
              X509Chain chain,
              SslPolicyErrors sslPolicyErrors)
        {
            if (sslPolicyErrors == SslPolicyErrors.None)
                return true;
            return false;
        }

        public static Int16 GetLen(string Request)
        {
            return Convert.ToInt16(Encoding.UTF8.GetBytes(Request).Length);

        }

The part where it's failing is sslStream.Read(buffer, 0, buffer.Length). This never returns and is where the IOException is coming from.

The people i'm trying to connect to say that the SSL handshake is failing, but I don't see any indication of that on our end. It always makes it to sslStread.Read and then fails. They've said sometimes they are receiving the request and sending the response, but I haven't yet seen a response returned.

Thanks

Upvotes: 0

Views: 1423

Answers (1)

user1538717
user1538717

Reputation:

After some testing sessions with the partner it turned out to be a simple bug in my code. The length bytes had to be flipped to the network byte order. I did this using IPAddress.HostToNetworkOrder

            byte[] len = BitConverter.GetBytes(IPAddress.HostToNetworkOrder(SslClient.GetLen(Request)));

            messageData.AppendLine("Writing length of data " + SslClient.GetLen(Request).ToString());
            sslStream.Write(len);

Upvotes: 0

Related Questions