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
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.