Windows .NET client app connects successfully to Java server and initiates TLSv1.2 handshake. Packet capture at server shows:
C>S Client Hello S>C Server Hello, Certificate, Server Key Exchange, Certificate Request, Server Hello Done C>S Certificate, Client Key Exchange, Certificate Verify, Change Cipher Spec, Encrypted Handshake Message S>C Change Cipher Spec *FAILS HERE*
On server, no ACK is received for the Change Cipher Spec packet, resulting in multiple TCP retransmissions.
On client, the application does not appear to receive this packet, the following exception is logged:
System.IO.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.. ---> System.Net.Sockets.SocketException (10060): 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. at System.Net.Sockets.NetworkStream.Read(Byte[] buffer, Int32 offset, Int32 size) --- End of inner exception stack trace --- at System.Net.Sockets.NetworkStream.Read(Byte[] buffer, Int32 offset, Int32 size) at System.Net.FixedSizeReader.ReadPacket(Stream transport, Byte[] buffer, Int32 offset, Int32 count) at System.Net.Security.SslStream.StartReceiveBlob(Byte[] buffer, AsyncProtocolRequest asyncRequest) at System.Net.Security.SslStream.CheckCompletionBeforeNextReceive(ProtocolToken message, AsyncProtocolRequest asyncRequest) at System.Net.Security.SslStream.StartSendBlob(Byte[] incoming, Int32 count, AsyncProtocolRequest asyncRequest) at System.Net.Security.SslStream.ProcessReceivedBlob(Byte[] buffer, Int32 count, AsyncProtocolRequest asyncRequest) at System.Net.Security.SslStream.StartReadFrame(Byte[] buffer, Int32 readBytes, AsyncProtocolRequest asyncRequest) at System.Net.Security.SslStream.StartReceiveBlob(Byte[] buffer, AsyncProtocolRequest asyncRequest) at System.Net.Security.SslStream.CheckCompletionBeforeNextReceive(ProtocolToken message, AsyncProtocolRequest asyncRequest) at System.Net.Security.SslStream.StartSendBlob(Byte[] incoming, Int32 count, AsyncProtocolRequest asyncRequest) at System.Net.Security.SslStream.ForceAuthentication(Boolean receiveFirst, Byte[] buffer, AsyncProtocolRequest asyncRequest) at System.Net.Security.SslStream.ProcessAuthentication(LazyAsyncResult lazyResult, CancellationToken cancellationToken) at System.Net.Security.SslStream.AuthenticateAsClient(SslClientAuthenticationOptions sslClientAuthenticationOptions) at System.Net.Security.SslStream.AuthenticateAsClient(String targetHost, X509CertificateCollection clientCertificates, SslProtocols enabledSslProtocols, Boolean checkCertificateRevocation) ...
The server eventually times out the connection (set to 25 seconds). The rest of the handshake seems right: a shared cipher suite is selected, the client presents a valid certificate to the server, etc.
Why isn't the client reading and acknowledging this packet successfully?
Note: this was working about three months ago. Changes: the client renewed their client certificate (issued from same CA with same parameters)
We have validated that the client certificate is installed as expected, server is trusted, client and server have mutually supported cipher suites.