Elephants should be here, not in rooms |
[foreword: I revised this several times expanding my thoughts and worked on getting packet sizes and counts correct, but it's quite possible I've made some mistakes in the process.]
I was recently thinking about Quic, the combined TLS and Transport protocol that Google initially designed to streamline session start up and a wish list of other improvements to better target web traffic needs. The motivation is mainly latency and the number of round trips needed to start flowing the underlying HTTP traffic. While Quic certainly does that and is an improvement with the strict layering with TCP, looking at this from an outside perspective (I am no TLS expert), the biggest source of latency at startup seems to be sending the server certificates themselves. I looked at my certs and the full chain pem file (ie, my cert plus the signer's cert) are about 3500 bytes. I tried gzip'ing them and it made some difference, but was still about 2500 bytes all said and done, but TLS doesn't seem to be doing that. So that's a minimum of three MTU sized packets just for the credentials and one MTUish sized packet for the ClientHello. While the cert packets are sent in parallel given the congestion window like TCP, they are still MTU sized packets which have the latency that Google was trying to get rid of. One curious thing I noticed is that Wireshark seemingly said that it was using IP fragmentation which if true is really a Bad Thing. I sure hope that Wireshark got that wrong.
If I understand Quic correctly, basically they got rid of the the TCP handshake and used the TLS handshake instead since it's a 3 way handshake too. So the flow goes sort of like this:
- DNS A/AAA Lookup ->
- DNS Response A/AAAA <-
- ClientHello+Padding ->
- ServerHello+QuicHandshake1 (cert) <-
- QuicHandshake2 (cert cont) <-
- QuicHandshake3 (cert cont) <-
- QuickHandshake (finish) ->
So in all the server is sending ~3 MTU sized packets. This is on the assumption they are sending pem which might not be a good assumption as they could be sending the straight binary X.509, but from the looks of it on Wireshark it looks like they're just sending PEM. I'm assuming that the ClientHello is small, but I read that there are issues with reflection attacks so they are relatively large. Assuming that I read that right it's about 1200 bytes for the client and server Hello, so all told 4 ~MTU sized packets and small client finished handshake packet. So in bytes, we have about 1300+1500+1500+1000+100 which is ~5400 bytes.
Getting Rid of Certificates using DNS
What occurs to me is that if they weren't using certificates it could be much more compact. The rule for the reflection attack is that the server should send no more than 3 times the ClientHello packet size. Suppose instead of using certificates we used something like DANE (RFC 6698) or a DKIM (RFC 4871) selector like method:
- DNS A/AAAA Lookup ->
- [ DNS TLSA Lookup -> ]
- DNS A/AAAA Response <-
- ClientHello+Padding ->
- ServerHello+QuicHandshake <-
- [ DNS TLSA Response <- ]
- QuicHandshake (finish) ->
DNS Implications
Using DNS as a trust root is a much more natural way to think about authentication: domains are what we are used to either trusting or not. Certificates created an alternative trust anchor and frankly that trust anchor is pretty self-serving for a whole lot of certificate vendors. It would obviate the need for that side channel trust anchor and get it on the authority of the domain itself directly. Gone would be the need to constantly renew certificates with all of the hassle. Gone would be the need to pay for them. Gone would be the issue of having dozens of certificate roots. Gone would be the risk of one of those roots being compromised. Gone would be a business model that was predicated on 40 year old assumptions of the need for offline verification which is obviously not needed for an online transport layer protocol.
Another implication is wildcards. Certificates have the ability to have wildcards in the name space, so that foo.example.com and bar.example.com can have one certificate with *.example.com. DNS has wildcards too, but whether they would meet the security properties needed is very questionable as I'm pretty sure that there is a lot of agreement that DNS wildcards are messed up to begin with. If they don't, you'd have to enumerate each subdomain's DANE records. I'm willing to bet that DANE addresses this, but haven't seen it specifically in my skim of it.
Another implication is that a lot of clients rely on upstream resolvers which is a thorny issue when authentication is involve. However, my experience is that browsers either implement their own stub resolver, or rely on a OS stub resolver. Given ecommerce, etc, my feeling is that trying to eek out some sort of CPU performance benefit is generally a bad tradeoff and that browsers can and should actually authenticate each transaction before storing it in a local cache. RSA/ECDSA verifies are extremely cheap these days, and besides browsers are already doing those verifies for certificates.
TLS Implications
An Alternative for Certificates
While certificates require 3 packets to transmit, it is not inevitable that they must be sent each time a session is started. A client could in principle send the fingerprint(s) of certificates that it has cached for the domain in the ClientHello and the ServerHello could then reply with the chosen certificate fingerprint if it has possession of its key. That too would cut the exchange down to 3 packets instead of the 5. The downside is that it would require buy in from the TLS community to implement the new protocol extension. Additionally, the ClientHello would still be required to be an MTU'ish sized packet since the client wouldn't necessarily know whether the server supports that extension or not.