Subject: [TLS] Version negotiation, take two

From: David Benjamin <[email-masked]>
Date: Thu, 08 Sep 2016 16:04:23 +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:
https://github.com/tlswg/tls13-spec/pull/632

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%:
https://blog.qualys.com/ssllabs/2016/08/02/tls-version-intolerance-in-ssl-pulse

(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
tests.)

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.

Thanks,

David

---

From: "Short, Todd" <[email-masked]>
Date: Thu, 8 Sep 2016 18:27:49 +0000

We already have a useless field in the record header; the record_version is fixed to { 3, 1 }; and this is not a coincidence.
I think it would be better to maintain a 1.2-compatible version negotiation for backwards compatibility, and have a more robust and expressive version negotiation option. Now would be the time to do it.
--
-Todd Short
// [email-masked]<mailto:[email-masked]>
// "One if by land, two if by sea, three if by the Internet."

On Sep 8, 2016, at 12:04 PM, David Benjamin <[email-masked]<mailto:[email-masked]>> wrote:

Hi folks,

EKR wrote up some text for moving version negotiation to an extension:
https://github.com/tlswg/tls13-spec/pull/632<https://urldefense.proofpoint.com/v2/url?u=https-3A__github.com_tlswg_tls13-2Dspec_pull_632&d=DQMFaQ&c=96ZbZZcaMF4w0F4jpN6LZg&r=QBEcQsqoUDdk1Q26CzlzNPPUkKYWIh1LYsiHAwmtRik&m=X-0L9PRkXf7K_CpAiDi6ldM0ih6EM7it43_XJISkgbY&s=fCNNhmCZPHLsW70DqP-eY42xLYXw7VoNlcGFxxclzhU&e=>

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%:
https://blog.qualys.com/ssllabs/2016/08/02/tls-version-intolerance-in-ssl-pulse<https://urldefense.proofpoint.com/v2/url?u=https-3A__blog.qualys.com_ssllabs_2016_08_02_tls-2Dversion-2Dintolerance-2Din-2Dssl-2Dpulse&d=DQMFaQ&c=96ZbZZcaMF4w0F4jpN6LZg&r=QBEcQsqoUDdk1Q26CzlzNPPUkKYWIh1LYsiHAwmtRik&m=X-0L9PRkXf7K_CpAiDi6ldM0ih6EM7it43_XJISkgbY&s=3BBgAzG_3OoX8D2qjnRLgfpNqVc2-FnuFp2RZc0Vh2M&e=>

(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 tests.)

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<https://urldefense.proofpoint.com/v2/url?u=https-3A__bugs.launchpad.net_ubuntu_-2Bsource_openssl_-2Bbug_1256576_comments_4&d=DQMFaQ&c=96ZbZZcaMF4w0F4jpN6LZg&r=QBEcQsqoUDdk1Q26CzlzNPPUkKYWIh1LYsiHAwmtRik&m=X-0L9PRkXf7K_CpAiDi6ldM0ih6EM7it43_XJISkgbY&s=hvA2qSwecmuUYK2wCsG4PwXECtYXm5aKMN1yDHMIV50&e=> )

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.

Thanks,

David
_______________________________________________
TLS mailing list
[email-masked]<mailto:[email-masked]>
https://www.ietf.org/mailman/listinfo/tls

---

From: Xiaoyin Liu <[email-masked]>
Date: Thu, 8 Sep 2016 20:04:34 +0000

I support this proposal.

Xiaoyin

From: David Benjamin<mailto:[email-masked]>
Sent: Thursday, September 8, 2016 12:09 PM
To: [email-masked]<mailto:[email-masked]>
Subject: [TLS] Version negotiation, take two

Hi folks,

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

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%:
https://blog.qualys.com/ssllabs/2016/08/02/tls-version-intolerance-in-ssl-pulse

(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 tests.)

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.

Thanks,

David

---

From: Hannes Tschofenig <[email-masked]>
Date: Fri, 9 Sep 2016 16:07:17 +0200

I like this approach.

On 09/08/2016 06:04 PM, David Benjamin wrote:
> 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.
>
> 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.
>
> 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%:
> 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 tests.)
>
> 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.
> [email-masked]

---

From: Benjamin Kaduk <[email-masked]>
Date: Tue, 13 Sep 2016 11:07:33 -0500

This is the best proposal I've seen given the deployment constraints
imposed by reality.  Perhaps it could be tweaked to improve it slightly,
but I support merging this version.

-Ben

On 09/08/2016 11:04 AM, David Benjamin wrote:
> <https://urldefense.proofpoint.com/v2/url?u=https-3A__github.com_tlswg_tls13-2Dspec_pull_632&d=DQMFaQ&c=96ZbZZcaMF4w0F4jpN6LZg&r=sssDLkeEEBWNIXmTsdpw8TZ3tAJx-Job4p1unc7rOhM&m=aarB3I3r_Kn7FPWJq9AJd1ivPK1niUnkupGujPoRKpk&s=1euqoGMgrdBFwR2KiZey_Du1pzwHcBTJJgTNL0Ynvo0&e=>
>
> 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.
>
> 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.
>
> 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%:
> <https://urldefense.proofpoint.com/v2/url?u=https-3A__blog.qualys.com_ssllabs_2016_08_02_tls-2Dversion-2Dintolerance-2Din-2Dssl-2Dpulse&d=DQMFaQ&c=96ZbZZcaMF4w0F4jpN6LZg&r=sssDLkeEEBWNIXmTsdpw8TZ3tAJx-Job4p1unc7rOhM&m=aarB3I3r_Kn7FPWJq9AJd1ivPK1niUnkupGujPoRKpk&s=6ziW12EZ1iGkM2bN_6ooRy7CV9SPp0CVFv4hX7bpYSw&e=>
>
> browsers early. The rest appears to be noise from transient errors
> which crop up in large tests.)
>
> 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
> <https://urldefense.proofpoint.com/v2/url?u=https-3A__bugs.launchpad.net_ubuntu_-2Bsource_openssl_-2Bbug_1256576_comments_4&d=DQMFaQ&c=96ZbZZcaMF4w0F4jpN6LZg&r=sssDLkeEEBWNIXmTsdpw8TZ3tAJx-Job4p1unc7rOhM&m=aarB3I3r_Kn7FPWJq9AJd1ivPK1niUnkupGujPoRKpk&s=tBAuUGE2Q0PBvobD02Z-2PhxBDD1DP7dGKm1M6YxIQM&e=>
> )
>
> 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.
>
> Thanks,
>
> David
>
>

---

From: Kyle Rose <[email-masked]>
Date: Tue, 13 Sep 2016 12:30:08 -0400

> 2. We should fix broken servers

There's also:

3. Implementors will find a way to screw this up, too.

But if you follow through with your plan to have Chrome randomly add a
really high version to the list to smoke out servers that fail when they
see unsupported versions, it's plausible version intolerance could be in
the noise next time around.

If you time-limit that behavior for a particular version of Chrome (say, to
a few months), you could even have it randomly add the next version or
current version + 2 to the list to detect and report on selective
next-version intolerance. I'd say this kind of failure mode is unlikely,
but... Murphy's Law.

Kyle

---

From: Sean Turner <[email-masked]>
Date: Tue, 13 Sep 2016 13:18:34 -0400

All,

There appears to be an emerging consensus here to adopt the change proposed by this PR.  Please indicate whether you are unwilling (and why) to accept this change by September 16th.

J&S

> On Sep 08, 2016, at 12:04, David Benjamin <[email-masked]> wrote:
> 
> Hi folks,
>

---

From: Hubert Kario <[email-masked]>
Date: Wed, 14 Sep 2016 11:56:34 +0200

First, I don't think that the argument that the current version scheme doesn't 
lend itself to future-proofing is correct. Just as with GREASE, browsers can 
send much higher version than they really support if they do that on a time 
limited basis.

Second, while the "joint" which handles new extensions IDs doesn't seem to be 
rusting, it's not the case with lists in particular extensions. SNI being the 
prime example where sending anything but a single host name value will most 
likely lead to your client hello being either misinterpreted or rejected.

On Tuesday, 13 September 2016 13:18:34 CEST Sean Turner wrote:
> All,
> 
> There appears to be an emerging consensus here to adopt the change proposed
> by this PR.  Please indicate whether you are unwilling (and why) to accept
> this change by September 16th.
> 
> J&S
> 
> > that. So, understandably, this seemed like a “let’s adopt a hack forever”
> > serious, but I think there’s also a strong argument that the current
> > scheme isn’t very good.
> > 
> > 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
> > occasional failure, they are much rarer and typically within the level of
> > breakage that clients can tolerate and deal with by reaching out to
> > trivial to offer a draft version by just including it. This is the
> > strategy HTTP/2 used (via ALPN) and it worked well.
> > 

-- 
Regards,
Hubert Kario
Senior Quality Engineer, QE BaseOS Security team
Web: www.cz.redhat.com
Red Hat Czech s.r.o., Purkyňova 99/71, 612 45, Brno, Czech Republic

---

From: Benjamin Kaduk <[email-masked]>
Date: Wed, 14 Sep 2016 10:21:35 -0500

> send much higher version than they really support if they do that on a time 

David had previously convinced me that it doesn't actually work very
well, but I forget the reasoning he used to do so. :(

> likely lead to your client hello being either misinterpreted or rejected.

But people will ~always be sending multiple elements in the list in the
version-negotiation extension -- you can't just send TLS 1.3; you also
send 1.2 for the near future.  And if browsers are grease-ing from the
beginning, I don't really see this one rusting.

-Ben

---

From: David Benjamin <[email-masked]>
Date: Wed, 14 Sep 2016 16:17:50 +0000

On Wed, Sep 14, 2016 at 11:46 AM Benjamin Kaduk <[email-masked]> wrote:

> David had previously convinced me that it doesn't actually work very well,
> but I forget the reasoning he used to do so. :(
>

Right, this was suggested at Berlin but is not very realistic.

First it requires that clients do so with very careful precautions
(time-limited, server-side field trials, etc.). There cannot be
fake-TLS-1.4 clients by the time real-TLS-1.4 is to exist. If enough
implementations mess up, we lose. With a list, any library can freely
implement this without depending on extra infrastructure.

Second, even if we were to advertise TLS 1.4 when we really mean TLS 1.3,
we still cannot deploy TLS 1.3 as-is without a TLS 1.2 fallback.
Version-intolerant servers will continue to get deployed unnoticed. We need
to get to a quiet point where the extension point works before we can start
meaningfully applying GREASE. All GREASE does is try to exercise
rarely-exercised extension point.

Because I am unreasonably amused by this metaphor, if the joint has
completely rusted shut already, we won't be able to get the GREASE in
there. It needs to have some mobility left.

> version-negotiation extension -- you can't just send TLS 1.3; you also send
> 1.2 for the near future.  And if browsers are grease-ing from the

Right, SNI should just never have been an extension point. We have
multi-valued lists elsewhere and they've worked fine. I can only speak to
Chrome's experience, but we add cipher suites without worry. We
successfully deployed X25519. RSA-PSS is going through the release process
now. (We expect breakage from an old NSS bug, but probes of top sites
suggest it will be tolerable.) TLS 1.3 adds even more lists. We're already
assuming lists work.

Yes, we find list intolerance too---servers which only look at the second
byte in a cipher suite, servers which forgot a default in their NamedGroup
switch-case, servers which get confused on unknown HashAlgorithms, servers
which require the final extension non-empty---but this is dramatically less
than version intolerance. It's usually within tolerable levels that we
needn't resort to fallbacks.

The proposal switches from something which we know does not work to
something new. Perhaps this new one will break too, but it is very similar
to things that have worked before, and I am hopeful that GREASE will help.

David

---

From: Hubert Kario <[email-masked]>
Date: Wed, 14 Sep 2016 18:39:43 +0200

> to things that have worked before, and I am hopeful that GREASE will help.

Was the option to do "one extension point = specific TLS version supported" 
discussed too? What arguments are there against it?

---

From: Andrei Popov <[email-masked]>
Date: Wed, 14 Sep 2016 17:39:59 +0000

Do you mean a TLS extension code point per TLS version?
One argument against this was that this makes it difficult to express the client's prioritization of TLS versions, but IMHO arguably the server should not care.

Cheers,

Andrei

-----Original Message-----
From: TLS [mailto:[email-masked]] On Behalf Of Hubert Kario
Sent: Wednesday, September 14, 2016 9:40 AM
To: David Benjamin <[email-masked]>
Cc: [email-masked]
Subject: Re: [TLS] Version negotiation, take two

On Wednesday, 14 September 2016 16:17:50 CEST David Benjamin wrote:
> Yes, we find list intolerance too---servers which only look at the 
> second byte in a cipher suite, servers which forgot a default in their 
> NamedGroup switch-case, servers which get confused on unknown 
> HashAlgorithms, servers which require the final extension 
> non-empty---but this is dramatically less than version intolerance. 
> It's usually within tolerable levels that we needn't resort to fallbacks.
> 
> something new. Perhaps this new one will break too, but it is very 
> similar to things that have worked before, and I am hopeful that GREASE will help.

---

From: Hubert Kario <[email-masked]>
Date: Wed, 14 Sep 2016 20:02:31 +0200

> Do you mean a TLS extension code point per TLS version?

yes, e.g. if extension 0x00a0 is present assume TLSv1.3 support, 0x0121, 
TLSv1.4; same way EMS and MtE works

> One argument against this was that this makes it difficult to express the
> client's prioritization of TLS versions, but IMHO arguably the server
> should not care.

I don't think we should depart from the "highest mutually supported version" 
negotiation algorithm, any kind of preference in the client list is likely to 
cause additional problems - version misnegotiation

if client will want to advertise support for TLSv1.3 and TLSv1.5 but not 
TLSv1.4 it will still be able to do that

---

From: Andrei Popov <[email-masked]>
Date: Wed, 14 Sep 2016 19:02:14 +0000

Basically, I don't feel strongly about the switch to the proposed version negotiation mechanism. But if we are going to make this change based on the theory of having only one extension point and actively defending it, then we should probably follow the theory and send a separate TLS extension per TLS version.
 
> I don't think we should depart from the "highest mutually supported version" negotiation algorithm...
Correct, but it's not clear what represents "the highest" protocol version in the world where national TLS "standards" exist. Is country X-TLS (e.g. with integrated MITM support) a higher version than TLS 1.3? The server will make a choice based on the server's preferences. In a way, the proposed version negotiation mechanism makes it slightly easier to implement servers that support country X-TLS alongside IETF TLS versions.

Cheers,

Andrei

-----Original Message-----
From: Hubert Kario [mailto:[email-masked]] 
Sent: Wednesday, September 14, 2016 11:03 AM
To: Andrei Popov <[email-masked]>
Cc: David Benjamin <[email-masked]>; [email-masked]
Subject: Re: [TLS] Version negotiation, take two

> Do you mean a TLS extension code point per TLS version?

yes, e.g. if extension 0x00a0 is present assume TLSv1.3 support, 0x0121, TLSv1.4; same way EMS and MtE works

> One argument against this was that this makes it difficult to express 
> the client's prioritization of TLS versions, but IMHO arguably the 
> server should not care.

I don't think we should depart from the "highest mutually supported version" 
negotiation algorithm, any kind of preference in the client list is likely to cause additional problems - version misnegotiation

> > second byte in a cipher suite, servers which forgot a default in 
> > their NamedGroup switch-case, servers which get confused on unknown

---

From: "Salz, Rich" <[email-masked]>
Date: Wed, 14 Sep 2016 19:08:42 +0000

Are there national TLS standards, or just national crypto-suites?

---

From: Andrei Popov <[email-masked]>
Date: Wed, 14 Sep 2016 19:15:39 +0000

Both exist. E.g. China has at least one national TLS version (and cipher suites), and Russia has cipher suites.

The line is blurred anyway, because a cipher suite (or extension) can introduce new protocol message formats, state machine changes, authentication schemes, ...

---

From: Hubert Kario <[email-masked]>
Date: Thu, 15 Sep 2016 12:22:03 +0200

On Wednesday, 14 September 2016 19:02:14 CEST Andrei Popov wrote:
> Correct, but it's not clear what represents "the highest" protocol version
> in the world where national TLS "standards" exist. Is country X-TLS (e.g.
> with integrated MITM support) a higher version than TLS 1.3? 

it means the same when I disable support for TLS 1.2 in current version of 
OpenSSL - it should negotiate TLS 1.1 as it is the highest mutually supported 
version. We don't care what the server's or client's code can do in absolute, 
we care what it is configured to do. See also: FALLBACK_SCSV handling.

> The server
> will make a choice based on the server's preferences. In a way, the
> proposed version negotiation mechanism makes it slightly easier to
> implement servers that support country X-TLS alongside IETF TLS versions.

and a list with opaque version identifiers (just int16 values) won't?

> I don't think we should depart from the "highest mutually supported version"
 negotiation algorithm, any kind of preference in the client list is
> likely to cause additional problems - version misnegotiation

---

From: Hubert Kario <[email-masked]>
Date: Thu, 15 Sep 2016 12:26:28 +0200

On Thursday, 15 September 2016 12:22:03 CEST Hubert Kario wrote:
> OpenSSL - it should negotiate TLS 1.1 as it is the highest mutually
> supported version. We don't care what the server's or client's code can do
> in absolute, we care what it is configured to do. See also: FALLBACK_SCSV
> handling.
> > The server

also, I'm not sure if it's really such a bad thing, it's certainly better than 
some Russian sites selecting TLS_RSA_WITH_AES_128_CBC_SHA but actually using 
GOST cipher...

---

From: Benjamin Kaduk <[email-masked]>
Date: Thu, 15 Sep 2016 11:51:31 -0500

> Basically, I don't feel strongly about the switch to the proposed version negotiation mechanism. But if we are going to make this change based on the theory of having only one extension point and a…

To me, the (ordered) list of client supported versions in a single
extension feels more intuitively natural, so I want to try harder to
understand the reasoning that leads you to prefer a separate extension
for each version.  Is it just that doing an additional "negotiation"
within the extension body constitutes another extension point that we
would have to actively defend, or is there something else about what a
TLS extension is philosophically supposed to indicate?

Thanks,

Ben

---

From: Hubert Kario <[email-masked]>
Date: Thu, 15 Sep 2016 20:03:03 +0200

On Thursday, 15 September 2016 11:51:31 CEST Benjamin Kaduk wrote:
> > Basically, I don't feel strongly about the switch to the proposed version
> > negotiation mechanism. But if we are going to make this change based on
> > the theory of having only one extension point and actively defending it,
> > then we should probably follow the theory and send a separate TLS
> > extension per TLS version.

the extensions joint is well greased and works

the lists inside extensions are a hit and miss, they mostly work, but then we 
have SNI in general, signature methods in past NSS versions, and if you dug 
more I wouldn't be surprised if you found half a dozen other issues just like 
it (in late October I may have actual numbers about it)

---

From: Andrei Popov <[email-masked]>
Date: Thu, 15 Sep 2016 21:35:31 +0000

> and a list with opaque version identifiers (just int16 values) won't?

A list with opaque version identifiers is the proposed mechanism. Currently the client advertises one version identifier.

---

From: Andrei Popov <[email-masked]>
Date: Thu, 15 Sep 2016 21:50:26 +0000

Ø  Is it just that doing an additional "negotiation" within the extension body constitutes another extension point that we would have to actively defend…

Yes, the proposed negotiation mechanism is based on the premise that one shall “have one joint and keep it well oiled<https://www.imperialviolet.org/2016/05/16/agility.html>”. And it’s been pointed out that the TLS extensions are the joint that hasn’t rusted solid yet.

For me, either one of the three options works (what we have currently, list of versions in an extension, or one extension per version).

Cheers,

Andrei

---

From: Vlad Krasnov <[email-masked]>
Date: Fri, 16 Sep 2016 13:21:09 -0700

I am opposed to this change.

I don’t think that version selection as an extension is such a good idea.

Some implementations out there rely on the fact that they can read the first two bytes of the client hello, and take the appropriate code path on the spot.

That allows for a very simple and stream-lined parsing of the hello, with minimal buffering.

Also note that several fields *preceding* the extensions have special values for TLS 1.3.

Delaying this decision until after all the extensions are parsed will make implementations that much more complex, memory consuming, and slower (HOL blocking), plus potentially leading to new bugs we want to avoid.

At the very least, if version is negotiated as extension it must be the very first extension advertised.

Cheers,
Vlad

> On 15 Sep 2016, at 11:03, Hubert Kario <[email-masked]> wrote:
> 
> Red Hat Czech s.r.o., Purkyňova 99/71, 612 45, Brno, Czech Republic_______________________________________________
> TLS mailing list
> [email-masked]

---

From: Andrei Popov <[email-masked]>
Date: Fri, 16 Sep 2016 20:29:45 +0000

> At the very least, if version is negotiated as extension it must be the very first extension advertised.
I don't think it's a good idea to impose extension ordering requirements. 

> Some implementations out there rely on the fact that they can read the first two bytes of the client hello, and take the appropriate code path on the spot.
Yes, these implementations (Windows TLS stack included) will need to do more elaborate/slightly slower pre-parsing if we use TLS version negotiation via TLS extension(s). Not something I like, but can be done.

Cheers,

Andrei

-----Original Message-----
From: TLS [mailto:[email-masked]] On Behalf Of Vlad Krasnov
Sent: Friday, September 16, 2016 1:21 PM
To: Hubert Kario <[email-masked]>
Cc: [email-masked]
Subject: Re: [TLS] Version negotiation, take two

Cheers,
Vlad

>>> Basically, I don't feel strongly about the switch to the proposed 
>>> version negotiation mechanism. But if we are going to make this 
>>> change based on the theory of having only one extension point and 
>>> actively defending it, then we should probably follow the theory and 
>>> send a separate TLS extension per TLS version.
>> understand the reasoning that leads you to prefer a separate 
>> extension for each version.  Is it just that doing an additional "negotiation"
>> would have to actively defend, or is there something else about what 
>> a TLS extension is philosophically supposed to indicate?
> 
> the lists inside extensions are a hit and miss, they mostly work, but 
> then we have SNI in general, signature methods in past NSS versions, 
> and if you dug more I wouldn't be surprised if you found half a dozen 
> other issues just like it (in late October I may have actual numbers 
> about it)
> 
> --
> Regards,
> Hubert Kario
> Red Hat Czech s.r.o., Purkyňova 99/71, 612 45, Brno, Czech 
> Republic_______________________________________________
> TLS mailing list
> [email-masked]

---

From: David Benjamin <[email-masked]>
Date: Sat, 17 Sep 2016 01:04:07 +0000

Agreed. If we're concerned with the order, I suppose are other options like
smuggling them in the front of the cipher list or hacky things like that.
:-) But using extensions is cleaner, and still perfectly deployable.

> Some implementations out there rely on the fact that they can read the
first two bytes of the client hello, and take the appropriate code path on
the spot.
Yes, these implementations (Windows TLS stack included) will need to do
more elaborate/slightly slower pre-parsing if we use TLS version
negotiation via TLS extension(s). Not something I like, but can be done.

TLS already does not strictly permit sniff-based implementations like this.
A handshake message may be fragmented pathologically or even interspersed
with warning alerts. It's doable if you reject such fragmentations (no one
would send a ClientHello this way...), but you need to be careful because
this fragmentation does not figure into the handshake transcript. In
particular, you cannot have an else clause in your dispatch. The dispatcher
must reject anything it can't definitively resolve rather than blindly
forward to your pre-TLS-1.3 implementation.

CVE-2014-3511 is an example of OpenSSL's 1.0.x sniff-based implementation
going wrong (OpenSSL 1.1.x is no longer sniff-based). It is a particularly
silly instance, but it's the sort of failure mode you can get.

Further, with the current trajectory, TLS 1.3 servers will need to do
version-negotiation based on extensions anyway. All the various
implementors have been using this "draft_version" extension to experiment
with TLS 1.3. (draft_version is really just a worse version of this
proposal.)
https://github.com/tlswg/tls13-spec/wiki/Implementations#version-negotiation

I don't think anyone has actually enabled client code by default yet, but
once anyone does, servers will need to process extensions for versioning
until draft TLS 1.3 clients are out of the ecosystem. This seems the worst
of both worlds. We'll have extensions in versioning and an undeployable
protocol. I think we should go for the latter and, if we must have the
former, at least do it properly.

David

Cheers,

Andrei

-----Original Message-----
From: TLS [mailto:[email-masked]] On Behalf Of Vlad Krasnov
Sent: Friday, September 16, 2016 1:21 PM
To: Hubert Kario <[email-masked]>
Cc: [email-masked]
Subject: Re: [TLS] Version negotiation, take two

Some implementations out there rely on the fact that they can read the
first two bytes of the client hello, and take the appropriate code path on
the spot.

That allows for a very simple and stream-lined parsing of the hello, with
minimal buffering.

Also note that several fields *preceding* the extensions have special
values for TLS 1.3.

Delaying this decision until after all the extensions are parsed will make
implementations that much more complex, memory consuming, and slower (HOL
blocking), plus potentially leading to new bugs we want to avoid.

At the very least, if version is negotiated as extension it must be the
very first extension advertised.

Cheers,
Vlad

---

From: Hubert Kario <[email-masked]>
Date: Mon, 19 Sep 2016 12:42:32 +0200

On Saturday, 17 September 2016 01:04:07 CEST David Benjamin wrote:
> :

I don't see how that prevents streaming implementation - warning alerts is 
something you can handle in the dispatcher (though I'm not sure why it's 
something you should worry /before/ the first client hello received), then to 
the specific implementation you pass the buffer with current record and the 
socket, the first of which may be empty if the record boundary landed right 
after the client_version
 
> https://github.com/tlswg/tls13-spec/wiki/Implementations#version-negotiation

for experimental implementations memory usage is not such a big problem, it's 
not the case for everybody

> former, at least do it properly.

hmm, what if we did define both mechanisms? so that clients that worry about 
compatibility with the broken servers can advertise TLSv1.3 through extension 
while ones that don't, advertise through client_version?

similar to how secure renegotiation indication works

---

From: Vlad Krasnov <[email-masked]>
Date: Tue, 20 Sep 2016 11:31:15 -0700

Another concern here is that in order to reduce memory footprint, some implementations will probably introduce bugs by trying to optimize and infer the version by observing the cipher-suits in client hello instead waiting for the extension.

Cheers,
Vlad

> On 19 Sep 2016, at 03:42, Hubert Kario <[email-masked]> wrote:
> 
>> On Fri, Sep 16, 2016 at 4:29 PM Andrei Popov <[email-masked] <mailto:[email-masked]>>
>> 
>> wrote:
>> https://github.com/tlswg/tls13-spec/wiki/Implementations#version-negotiation <https://github.com/tlswg/tls13-spec/wiki/Implementations#version-negotiation>
> 
> Web: www.cz.redhat.com <http://www.cz.redhat.com/>

---

From: Joseph Salowey <[email-masked]>
Date: Tue, 20 Sep 2016 17:08:40 -0700

It looks like we have enough consensus to move to an extension based
version negotiation mechanism so we're asking the author to merge in this
pull request.  We can have further refinement of the details, but its
important for us to get a complete view of the spec at this point.

Cheers,

J&S

On Mon, Sep 19, 2016 at 3:42 AM, Hubert Kario <[email-masked]> wrote:

> > On Fri, Sep 16, 2016 at 4:29 PM Andrei Popov <[email-masked]
> >
> >
> > wrote: