Sunday, November 27, 2011

A handshake_failure on ClientHello and TLS vulnerability

Recently, while integrating web services between two servers, we had a situation with TLS handshake when our server acted as client. In order to establish a TLS session with a server, the client would first send ClientHello message. The server immediately terminated the handshake with the alert handshake_failure. The solution involved a bit of guesswork on our side since there was no support on the server side who could debug on their side and provide some feedback. Following log snippet shows the situation (line #32) with debug enabled (on Tomcat/JBoss).
Studying the debug, we realized that perhaps the cipher suites used (line #21) to start the handshake were not negotiated by the server. In TLS, the handshake_failure alert is only used when no common cipher can be negotiated [5]. The developers of the server sent us a web service client project in SOAPUI to prove that their web services are up and running and could be tested remotely using SOAPUI using transport level security. Enabling the SSL debug in SOAPUI, we found that the cipher suite used was indeed different and was also a superset of the cipher suite our HTTPS client used to start the negotiation. Indeed, cipher suite sent for negotiation is composed with lowest common denominator in mind with with 40 bit encryption as shown below with assumption that negotiation would bring agreement between the client and the server.
However, if the server terminates the handshake with alert handshake_failure, the server might perhaps be looking for different ciphers, compression algorithm or version since this happens in response to ClientHello. There could be a reason for such behavior. Doing a bit of digging, we found that a couple of years back a vulnerability was found in the TLS protocol that could be exploited during the renegotiation phase. When this vulnerability was detected, as a first line of defense, it was suggested to turn off the renegotiation and a solution [4] was proposed to fix the problem in the protocol. Our server used a version of Java with the fix which is listed on JSSE Reference Guide.

Our suspicion was that perhaps the other server was not set up for renegotiation. So, we changed our HTTPS client code to use the cipher suite that incorporated much larger suite as follows.
This cipher suite was accepted by the server. In fact, it was SSL_RSA_WITH_RC4_128_MD5 that was picked up by the server.
  1. JSSE Reference Guide 
  2. Authentication Gap in TLS negotiation
  3. Understanding the TLS Renegotiation Attack
  4. RFC 5746 - TLS Renegotiation Extension 
  5. SSL and TLS Designing and Building Secure Systems, Eric Rescorla

No comments:

Post a Comment