TLS extensions expand the SSL/TLS protocols. The extensions have many uses, like adding more features, supporting more scalable patterns or making the protocol more secure. However, adoption has been disappointingly slow until the last few years as the reignited browser wars have kicked client vendors into action. I was unable to find recent statistics about the adoption of TLS extensions, so I went about figuring it out.
There are about 15-20 TLS extensions in specifications. Many however are rarely used, some of the most common and important extensions are:
Server Name Indication (SNI): Standardized in 2003, this extension enables browsers to send the hostname they intend to connect to, which solves the Virtual Host Problem in SSL. Without this extension every SSL certificate needs its own IP address to work. In 2005 I implemented SNI support in mod_gnutls, and in 2007 mod_ssl added support for SNI. Browser support lagged behind the servers, but is now thought to be widespread, excluding clients running on Windows XP. More: Wikipedia: Server Name Indication, RFC 6066
Session Tickets: The base SSL/TLS protocol includes Session Caching to reduce the number of expensive cryptographic operations a server needs to do if a client has previously visited it. This session caching relies upon the client sending a session ID, and the server storing data about that session. This model however is difficult to implement in a large scale server environment with many endpoints terminating SSL, as they would all need a shared caching infrastructure. Session tickets solve this by having the server give the client an encrypted ‘ticket’, which contains all of the information needed to resume the session, without the server needing an additional shared cache. Client support is widespread in Chrome and Firefox, but realistic server deployments still appear to be rare. In late 2011 I patched mod_ssl trunk to support configuration of session tickets, but the feature hasn’t been back ported to a release branch. More: Vincent Bernat: Speeding up SSL: enabling session reuse, RFC 5077
Next Protocol Negotiation (NPN): Used by the SPDY protocol to reduce round trips, this lets both the client and server agree on the protocol to run inside the encrypted connection. Without this extension, SPDY would require the use of additional round trips to upgrade from HTTP to SPDY. The extension is not yet an RFC, but has seen widespread adoption as Chrome and Firefox have both implemented support. Apache HTTP server added native support just 4 months ago. More: IETF Draft: Next Protocol Negotiation Extension
Renegotiation Indication: A TLS protocol bug was discovered in 2009 that allowed attackers to inject data into the stream read by the client. This extension was crafted to prevent this attack. A common mitigation was to disable all renegotiation once a connection was established, so the lack of this extension doesn’t necessarily indicate that a client is vulnerable, but it is a good indication of the age of the SSL/TLS stack being used by the Client. More: RFC 5746
User Agents Drive TLS Adoption
The adoption of TLS features and extensions is directly tied to the User Agent. While consumer websites and web browsers are important, I believe there has not been significant enough attention focused to Web Service API User Agents. Consumer browsers are now on much faster upgrade cycles, but many servers are not going to follow the same upgrade curves.
For this reason, I’ve collected samples from 3 different data sources:
svn.apache.org: Primary version control site for the ASF. The majority of the clients are using Subversion Clients, but there is a smaller mix of browsers and other agents.
issues.apache.org: The most browser focused site that I could easily sample. It hosts the ASF JIRA and Bugzilla which are primarily used by consumer browsers.
If someone out there could sample a popular consumer site (Google? Facebook? Yahoo?) and post the results I would be very interested in seeing them.
It seemed too difficult to modify the existing server software to log all of the information that I wanted, and because in some cases the TLS termination is done in devices like a load balancer, I decided to build a tool to decode the information from a packet capture. All of the extensions I am interested in are sent by the Client in its ClientHello message. This means I didn’t need to do any cryptographic operations to decode it, just parse the TLS packet.
I started by using the excellent dpkt library to dissect my packet captures, but quickly figured out it didn’t actually parse any of the TLS extensions. A little patching later and I had it parsing TLS extensions.
The script I wrote handles the common issues I’ve seen, but still could be improved to do TCP stream re-assembly, but in practice with all the captures I made, the TLS Client Hello messages were in a single TCP packet.
If you want to try collecting and analyzing your own samples:
git clone git://github.com/pquerna/tls-client-hello-stats.git cd tls-client-hello-stats # Let tcpdump run for awhile, press ctrl+c to stop capturing. sudo tcpdump -i eth0 -s 0 -w port443.cap port 443 python parser.py port443.cap
TLS 1.0 is the version advertised by most clients and servers. The version spread for
monitoring are about what I would expect, but I was surprised to see that
svn.apache.org was still seeing over 23% of its clients reporting SSLv3 as their highest supported version.
While not an extension,
deflate compression has to be advertised by both sides in order to support it. If used, it also imposes increased memory usage requirements on both the client and server, so I was interested in seeing if clients are advertising support for it.
OpenSSL enables the
deflate compression by default, and until recent versions it was difficult to disable. I suspect that most of the
monitoring traffic is using a default OpenSSL client library, and the more sophisticated browser user agents are explicitly disabling it. Since HTTP and SPDY both support compression inside their protocols, enabling deflate at the TLS layer would commonly lead to content being double compressed.
Number of Total Extensions Sent
It is interesting that most of the API centric clients send so few extensions. This seems to indicate potentially both the age of the TLS software stack being used, and the complexity of how it is configured by the developer.
I was disappointed to find a massive gap between consumer browsers and API consumers for SNI. This can be traced to common libraries not setting the SNI extension until recently. For example, only Python 3.2 or newer sends the SNI extension, and because ”Python 2 only receives bug fixes”, it will never be back ported for the most commonly deployed versions of the Python language.
Session Tickets seem to have a more reasonable usage by non-browser user agents, but the consumer browsers are again leading adoption.
NPN support has been driven by the adoption of SPDY in Chrome and Firefox, so it isn’t surprising that for
monitoring we see almost no support from clients.
Renegotiation Indication Support
While the Renegotiation Indication extension is sent by a significant number of clients on
issues, its use is extremely low both
monitoring. This again shows how Browsers are leading the charge in upgrading, but also since the Renegotiation attacks require a man-in-the-middle, it would generally be a lower priority for server-to-server software.
I’ve posted a gist with the raw data for my three samples, if you wanted to look at the information for a more rarely seen extensions.
I think the data I’ve seen so far says a few things:
Server Name Indication: I was hopeful that SNI could soon be used in prime time, but I believe this is still years away with the usage numbers I’ve seen.
Session Tickets: I believe it is reasonable to put effort into using Session Tickets if you have more than one server doing SSL/TLS termination. Reducing the need to use distributed Session Caching eases implementation, and should result in a generally faster user experience.
I think it is great that Browser vendors like Chrome and Firefox are driving the use of newer features and extensions in TLS. It is obvious however that because API clients are commonly built by a more diverse set of developers, and those developers are less specialized in SSL/TLS security issues, that their adoption of the newest extensions is lagging. I hope this could change quickly if HTTP/2.0 and SPDY start driving the need to use NPN, and I hope that this would get developers to upgrade their SSL/TLS stacks.