SSLv3/TLS Sniffer (Proxy Server)

Documentation Page



This page explains the SSLv3/TLS protocol and also describes some implementation details in the code.

SSLv3/TLS

Specifications

The specification of the TLS protocol can be found at http://www.ietf.org/rfc/rfc2246.txt?number=2246

The specification of the SSLv3 protocol can be found at http://home.netscape.com/eng/ssl3/draft302.txt
 

Differences between SSLv3 and TLS

SSLv3 is the very similar to TLS with a few minor differences, among which are

  1. the version number of TLS is 3.1 and SSL is 3.0
  2. slightly different MAC schemes
  3. different pseudorandom functions
  4. additional alert codes in TLS
  5. TLS does not support Fortezza while SSLv3 does
  6. SSLv3 has additional client certificate types for ephemeral Diffie Hellman and Fortezza schemes that TLS does not
  7. hashes calculated differently over the certificate verify handshake message
  8. different calculation of the master secret
  9. padding lengths. In SSLv3, the padding length is the minimum required to obtain a multiple of the cipher's block length while TLS allows any padding length that results in a multiple of the block length
None of these differences affect how the sniffer parses the packets, so I was not too concerned with them.
 

Sample output

I have some sample output which are taken from the etrade web site and the barclaycard website. The etrade one has a chain of 2 certificates while the barclaycard one has a chain of 3 certificates.
etrade's sample output
barclaycard sample output

Netscape has some sample traces that try to explain the protocol but it's basically a packet dump with each byte displayed as an integer. It's rather hard to read and understand what's going on compared to the sniffer.
http://home.netscape.com/eng/ssl3/traces/index.html
 

Overview of TLS

Microsoft has published a chapter from William Stalling's book Cryptography and Network Security (2nd Ed.) that has a great overview of the TLS and SSLv3 protocols. It can be located here.
 

Implementation Details

I learnt some things about the TLS protocol in programming this sniffer that were not very clear in the specification for TLS or that were added on later as internet drafts.

One of the first is that in making TLS connections to a proxy, a CONNECT message is first sent so that the proxy can redirect the connections. More details of this is found in the internet draft Upgrading to TLS within HTTP/1.1 by the IETF. Note: this is no longer found on the IETF page, but I located a copy and am replicating it on my page.

Appendix E of the TLS specifications states that all client applications that wish to remain backward compatible with SSLv2 have to send a SSLv2 client hello to the server with the protocol version 3.0 or 3.1. This is buried at the end of the RFC and it took me some time to realise that the garbled first message that the sniffer was receiving from browsers were actually SSLv2 packets. Once I discovered this, I ran my sniffer on a couple of sites to test their SSL versions and found to my dismay that Wells Fargo still used SSLv2 on their internet banking pages.
You can determine the version by running the sniffer and examining the packet contents. If the sniffer is unable to parse the messages properly and the first byte of the packets are -128 or some negative number followed by some set of numbers which includes the protocol version, then it is probably running SSLv2.
In OpenSSL, the right set of functions to use are found in ssl23.h for backward compatibility with SSLv2.

There are differences in how the server hello message and subsequent messages up to server hello done are sent by the TLS server that the the connection is being set up. Netscape Enterprise servers encapsulate all the messages that it is sending into one large packet with a single TLS record header. i.e., the server hello comes together with certificate, server hello done messages in a single packet. This is contrasted to Apache Stronghold, which sends each individual packet in its own TLS record header. I was caught unaware because I was testing my code on an Apache server and was surprised that the sniffer was missing messages when I ran it on other Netscape servers. There is nothing in the specification that requires either format, but I had to perform several hacks because I had initially set it up nicely to handle only the Stronghold format.

Larger messages tend to get fragmented and the socket layer handed it to the sniffer fragmented. Hence, sniffer had to be able to reassemble them. In particular, this only happens with the application data packets and the certificate packets because the other packets are rather small. Each certificate in the certificate message is roughly about 640 bytes and anything more than 2 certificates would fragment the message. I did not realise that this would occur because I assumed that TCP would handle the fragmentation, but this was a bad assumption, and I had to introduce more ugly code to keep track of the state so that these cases would be handled properly. I am not particularly pleased with the way I handled the certificate message because I assumed that the sniffer would never get a chain of more than about 50 certificates, which is probably a reasonable assumption, but is not a perfect solution. Given time to rewrite the code, I would probably have done a much nicer job of this now that I know of all the little but important details that escaped my notice initially.

I included cipher suites in the sniffer that were the specifications for elliptic curve cryptography, which I found in an internet draft. I am unable to locate the internet draft again because it has already expired.

Back To Main Page