[TLS] Version negotiation, take two

David Benjamin <davidben@chromium.org> Thu, 08 September 2016 16:08 UTC

Return-Path: <davidben@google.com>
X-Original-To: tls@ietfa.amsl.com
Delivered-To: tls@ietfa.amsl.com
Received: from localhost (localhost []) by ietfa.amsl.com (Postfix) with ESMTP id 8FC9512B2F6 for <tls@ietfa.amsl.com>; Thu, 8 Sep 2016 09:08:49 -0700 (PDT)
X-Virus-Scanned: amavisd-new at amsl.com
X-Spam-Flag: NO
X-Spam-Score: -4.207
X-Spam-Status: No, score=-4.207 tagged_above=-999 required=5 tests=[BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, HEADER_FROM_DIFFERENT_DOMAINS=0.001, HTML_MESSAGE=0.001, RCVD_IN_DNSWL_LOW=-0.7, RP_MATCHES_RCVD=-1.508, SPF_PASS=-0.001] autolearn=ham autolearn_force=no
Authentication-Results: ietfa.amsl.com (amavisd-new); dkim=pass (1024-bit key) header.d=chromium.org
Received: from mail.ietf.org ([]) by localhost (ietfa.amsl.com []) (amavisd-new, port 10024) with ESMTP id rsdlPtg_0b0B for <tls@ietfa.amsl.com>; Thu, 8 Sep 2016 09:08:47 -0700 (PDT)
Received: from mail-it0-x22e.google.com (mail-it0-x22e.google.com [IPv6:2607:f8b0:4001:c0b::22e]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by ietfa.amsl.com (Postfix) with ESMTPS id 6930D12B30E for <tls@ietf.org>; Thu, 8 Sep 2016 09:04:35 -0700 (PDT)
Received: by mail-it0-x22e.google.com with SMTP id i184so265431193itf.1 for <tls@ietf.org>; Thu, 08 Sep 2016 09:04:35 -0700 (PDT)
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=chromium.org; s=google; h=mime-version:from:date:message-id:subject:to; bh=DXEzClN6VPPhMibX7WHU0/nFo3vvKW8xscGjiw0/V2U=; b=ACL8/MXYNjBpQz/JrlcLFpi1TE9d/Y8hCtxfUWZZkshlvfSGi7BZ0AC/pwNIwwAr1c 42Qpy3K9At3CH2pfPrMxzB1/en/w9FXK7lKKHKhOiHjrnTYANiShcDD+MLAG1av/OKGG sBU2CtQ2TI9lSmknUVyHlx4Du8OF+zJvHzhP8=
X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:mime-version:from:date:message-id:subject:to; bh=DXEzClN6VPPhMibX7WHU0/nFo3vvKW8xscGjiw0/V2U=; b=SiRLgsdHXZZdl2V2JnlsCJFCFfXYYehjE6wtxyHNi1GYU/SiMNqra7cBQlHJn30X90 qXJEFa3oXHXyK5HE/Svonx/zUjcEnTDINGpNCRwuglWRBZ1c+WXv0cv92sZVX3V9Z15U qVH8ZY4qv6b+V+1vTBNIwuzlgfQemLuWgfE0UM7piHrORYwN4xCYsmNVo7rlymLTny66 ApcOljZ4sFNA6wDxsyMcInYT+LnH78OyLE6uiQ6kdVb5vAUalx4RYR2XquxKD9oIE0VK VG5+3kwCBup6GUgx7hF1QfE9oBjlLdoBUbvlkB7/JtbSj/MizIduZV8DwKmpeXYI+ox7 6j0g==
X-Gm-Message-State: AE9vXwOs1knKj0gk4/a3VGJyDnRFUmAciJ2c6+lfYmGLFxgz7RJVCKOpeFMLuRpFCzu9KSUG7k4rAKybkaved54Q
X-Received: by with SMTP id o125mr16534005itc.7.1473350674292; Thu, 08 Sep 2016 09:04:34 -0700 (PDT)
MIME-Version: 1.0
From: David Benjamin <davidben@chromium.org>
Date: Thu, 08 Sep 2016 16:04:23 +0000
Message-ID: <CAF8qwaA86yytg29QOD_N7ARimh9QcNGU_nnr_OrxqCrvrk2MBg@mail.gmail.com>
To: "tls@ietf.org" <tls@ietf.org>
Content-Type: multipart/alternative; boundary="001a114abf70928b58053c012f9f"
Archived-At: <https://mailarchive.ietf.org/arch/msg/tls/hd-QpaRaEojL9RItZfiCyN8TgCc>
Subject: [TLS] Version negotiation, take two
X-BeenThere: tls@ietf.org
X-Mailman-Version: 2.1.17
Precedence: list
List-Id: "This is the mailing list for the Transport Layer Security working group of the IETF." <tls.ietf.org>
List-Unsubscribe: <https://www.ietf.org/mailman/options/tls>, <mailto:tls-request@ietf.org?subject=unsubscribe>
List-Archive: <https://mailarchive.ietf.org/arch/browse/tls/>
List-Post: <mailto:tls@ietf.org>
List-Help: <mailto:tls-request@ietf.org?subject=help>
List-Subscribe: <https://www.ietf.org/mailman/listinfo/tls>, <mailto:tls-request@ietf.org?subject=subscribe>
X-List-Received-Date: Thu, 08 Sep 2016 16:08:49 -0000

Hi folks,

I’d like to revisit the question of version negotiation.

EKR wrote up some text for moving version negotiation to an extension:

I would like us to adopt this proposal.

In Berlin, this really got framed as a pragmatic question: the current
version negotiation has a lot of intolerance and so let’s work around that.
So, understandably, this seemed like a “let’s adopt a hack forever”
proposal. I think that framing is wrong. The intolerance situation is
serious, but I think there’s also a strong argument that the current scheme
isn’t very good.

The current scheme is very simple. The client advertises a maximum version
and the server selects based on that. This is the only piece of TLS
negotiation which works this way. Elsewhere (extensions, cipher suites,
signature algorithms), one side offers a list and the other side picks out
of it. I think it’s clear now that strategy is more robust: every time
we’ve bumped version numbers, we’ve had intolerance problems and this time
is no exception (see below). By contrast, we regularly introduce new cipher
suites, extensions, etc., and while we do see the occasional failure, they
are much rarer and typically within the level of breakage that clients can
tolerate and deal with by reaching out to affected servers. Moreover, lists
lend themselves to future-proofing via draft-davidben-tls-grease-00 in a
way the current scheme does not.

An additional benefit is lists make it much easier to roll out
prototype/draft versions. Currently, we are using a hack where the client
offers {3, 4} but also includes a draft version number in an extension.
This does work, but requires servers process that extension in perpetuity
or at least until all draft version clients go away.  With a list, it’s
trivial to offer a draft version by just including it. This is the strategy
HTTP/2 used (via ALPN) and it worked well.

Despite all of the above, it probably wouldn’t be worth fixing version
negotiation in 1.3 except for intolerance. Unfortunately, this fourth time,
it’s the same story as before. A probe of Alexa top million sites with
BoringSSL’s TLS 1.3 code (the Go version), shows 1.63% of TLS-capable hosts
reject a TLS 1.3 ClientHello. Note these are top sites and traffic is
top-heavy, so we can expect much higher usage-weighted numbers. Qualys SSL
Pulse reports 3.6%:

(Ignore the drop in the graph. We’ve long fixed the ClientHello
record-layer at {3, 1}. TLS 1.3 only codified existing practice here.) If
instead we use a TLS 1.3 ClientHello with version TLS 1.2, the breakage
drops to 0.017%. (Some of this is an NSS signature algorithms bug, fixed
last year, which we hope to clear by deploying RSA-PSS in browsers early.
The rest appears to be noise from transient errors which crop up in large

These numbers are *far* too high for clients to accept as damage, which
means that they (at least browsers) will be forced to do fallback. This
represents a security risk (cf. POODLE) as well as hides serious interop
problems. The situation is even worse for non-browser clients, which may be
unable to deploy at all (Ubuntu 12.04, despite shipping an OpenSSL release
with TLS 1.2, had to disable it on the client.
https://bugs.launchpad.net/ubuntu/+source/openssl/+bug/1256576/comments/4 )

The major arguments against this change seem to be:

1. It’s inelegant to have two mechanisms.
2. We should fix broken servers

The first is true, but as with other changes, EKR’s PR replaces the 1.2
mechanism with one for 1.3, so we’ll just have one going forward. The
second would be nice, but as a practical matter, I spend a lot of time
trying to get those servers fixed and it doesn’t work very well here.
Better is simply to move to a situation where once those servers upgrade
they will be correctly behaving forever (instead of just handling 1.3
correctly and breaking with 1.4). This change does that.