Subject: [TLS] checking on an scsv point

From: Stephen Farrell <[email-masked]>
Date: Tue, 17 Feb 2015 22:25:39 +0000

Hiya,

In going over the threads on this I think there was one point of
Martin's where it wasn't clear to me that the WG considered his
proposal. That might be because it was raised just before the
holidays and was part of a mega-thread and fairly deeply embedded
in a longer message. Anyway, I asked Martin if he could describe
it better and he did (see below) so I'd like to just check that
the WG don't in fact want this.

If you do not want to make this change, silence if fine, but if
you would implement this in your TLS stack then please say so in
the next few days. (Pretty please: let's not side-track - I'm
really only looking for "yes, I'd implement that in my TLS
code" responses, or silence:-)

I figure it's not likely that the WG will want this, but if
there's a groundswell for doing it, we can handle the process
stuff, so don't worry about that.

Thanks,
S.

What I've been asking for time and time again is allowing (adding)
an additional/alternative server behaviour, which a TLS (server)
implementer will be _allowed_ to implement instead of a fatal
handshake failure.

The most simplistic alternative server behaviour would be for
the server to continue the handshake successfully, using

ServerHello.server_version = (ClientHello.client_version + 1)

i.e. negotiating a _higher_ TLS version instead of aborting the
TLS handshake with a fatal error.

A client (and this affects only the clients that assert the
FALLBACK_SCSV) will be able to recognize that the server supports a
higher TLS protocol version than what the TLS client proposed in
ClientHello.client_version, and it will be left to that client to
decide whether the resulting TLS session properties are OK, or wether
the client want to take chances, establishing a new connection,
starting a new handshake and proposing other/additional TLS protocol
features in ClientHello that it might have omitted (for whatever
reason) in the last ClientHello.

This alternative behaviour is better, because it provides actual
*interoperability* between TLS client and TLS server -- and in many
cases the same or reasonably secure TLS session properties without
the need for complex heuristics and a whole new connection establishment
and handshake through the entire application protocol stack
(such as HTTP CONNECT proxy traversals or the stuff before STARTTLS).

Keep in mind that I'm NOT asking to make early adopter servers(!)
non-compliant.  Admittedly, I don't know what exactly the early
adopting clients will currently do when they receive

   ServerHello.server_version = (ClientHello.client_version + 1)

---

From: Martin Thomson <[email-masked]>
Date: Wed, 18 Feb 2015 09:35:33 +1100

FWIW, I just checked and an NSS client would fail the handshake if a
server did this.  We'd probably need new configuration to avoid the
"upgrade attack" if this were permitted.

On 18 February 2015 at 09:25, Stephen Farrell <[email-masked]> wrote:
> _______________________________________________
> TLS mailing list
> [email-masked]
> https://www.ietf.org/mailman/listinfo/tls

---

From: [email-masked] (Martin Rex)
Date: Wed, 18 Feb 2015 00:10:46 +0100 (CET)

> "upgrade attack" if this were permitted.

This NSS behaviour is not necessarily a problem.  The more "interesting"
question is what the app callers above NSS, that have asked NSS to
include FALLBACK_SCSV, will do in response to that behaviour of NSS,
or more specifically, will they do the same that they would do in
response of a fatal invalid_downgrade alert.

But that is a question for the apps on top rather than for NSS.

Ultimately, of course, I would prefer for a TLS client implementation that
asserts FALLBACK_SCSV, to not fail if the ServerHello comes back with
  ServerHello.server_version = (ClientHello.client_version) because
the semantics of FALLBACK_SCSV clearly is
  "I do support protocol version (ClientHello.client_version+1) and I
   really would prefer to use that instead of ClientHello.client_version."

-Martin

---

From: Henrik Grubbström <[email-masked]>
Date: Wed, 18 Feb 2015 00:19:37 +0100

On Tue, Feb 17, 2015 at 11:25 PM, Stephen Farrell
<[email-masked]> wrote:
[...]
> (such as HTTP CONNECT proxy traversals or the stuff before STARTTLS).

I consider breaking the obviously broken intervening proxy a feature,
as it obviously is broken enough that plain recent TLS doesn't work
with it (as otherwise the downgrade wouldn't have been needed), as it
would make it obvious to the system maintainer that something is
wrong. Hiding broken code behind workarounds like the suggested is
almost never a good idea.

I also fail to see how you can call this less complex and without new
connection establishment, as for the FALLBACK_SCSV to have been
asserted there will already have been a reconnect.

> adopting clients will currently do when they receive

Yes, this will break (probably most) early adopters, as good practice
in applications (especially those involving crypto) is to validate
that all parameters are within the expected range, and it isn't
allowed for a server to bump the protocol version above what the
client requested. I suspect the most common failure is a
protocol_version alert.

-- 
Henrik Grubbström                                       [email-masked]
Roxen Internet Software AB                              [email-masked]

---

From: David Benjamin <[email-masked]>
Date: Tue, 17 Feb 2015 23:46:06 +0000

> But that is a question for the apps on top rather than for NSS.

Chrome will not treat those the same in either NSS or BoringSSL ports.

It'll look like either a generic protocol error or a bad ServerHello
version (not sure which on NSS, but it doesn't matter), both of which
continue the fallback chain. An inappropriate_fallback alert terminates the
fallback chain and restores the original attempt's error code. (So the
error code is reported as if there were no version fallback.)

I don't really care for adding complexity to support this, either in
BoringSSL's server bits or Chrome. I'm especially uninterested in accepting
a client_version+1 ServerHello. It opens up questions with
client_version-conditioned extensions (signature_algorithms) and isn't a
secure version negotiation. FALLBACK_SCSV implies I support
client_version+1 but doesn't imply that I do NOT support client_version+2.

David

---

From: Martin Thomson <[email-masked]>
Date: Wed, 18 Feb 2015 10:49:39 +1100

> But that is a question for the apps on top rather than for NSS.

I have access to one of those as well.  That implementation would
consider the failure to be *another* sign of version intolerance,
triggering further fallback.  If the pattern of version+1 responses
continues, and I expect it to, it will reset any version intolerance
state after exhausting all the options.

Of course, that implementation is about to disable fallback, so the
window of applicability is extremely narrow in that case.

---

From: [email-masked] (Martin Rex)
Date: Wed, 18 Feb 2015 01:16:06 +0100 (CET)

> asserted there will already have been a reconnect.

Just using a connection established with
(ClientHello.client_version+1) will be less complexity for
clients (that implement this alternative behaviour properly)
because the app will not have to establish a new connection
and go through the entire app-level protocol preparations again
(HTTP CONNECT proxy and/or STARTTLS prologue)

> Yes, this will break (probably most) early adopters,

In which way does it "break" early adopters.
The fatal alert will unconditionally result in complete interop
failure on the established connection.  The "worst" that could possibly
happen is a "different kind of complete interop failure" but an interop
failure is an interop failure is an interop failure.  So really, making
it worse for the current handshake is factually impossible.

>
> as good practice in applications (especially those involving crypto)
> is to validate that all parameters are within the expected range,
> and it isn't allowed for a server to bump the protocol version above
> what the client requested.

It was the CLIENT(!!) who asserted the FALLBACK_SCSV in the first
place, complaining loudly that it would really like to use a higher
TLS protocol version that what the client placed into
ClientHello.client_version, so this reasoning is bogus here.

>
> I suspect the most common failure is a protocol_version alert.

The whole proposal started because the client believes that the
protocol options that the server negotiates would be options that
the client rather does not want.  So what kind of alert the client
sends if it wants to abort the current handshake and start a new one,
doesn't really matter for the server here.

What matters is that the server does not have to take the blame for
the handshake failure.  This will be left to the client, who started
the FALLBACK_SCSV dance.  For this particular connection, the server
has the necessary state to make this handshake failure "soft"
(i.e. not stand out in the traces), when the client aborts in response
to the servers selection of
  ServerHello.server_version = (ClientHello.client_version+1)

so I really don't mind such a client behaviour.

Servers not implementing the alternative approach do not have to bother
about this outcome.

-Martin

---

From: [email-masked] (Martin Rex)
Date: Wed, 18 Feb 2015 01:28:04 +0100 (CET)

Martin Thomson wrote:
> Martin Rex <[email-masked]> wrote:
>>

You mean that this client will fallback further _down_, rather than
upwards as the server suggests?

I assume this is mostly because the App does the heuristics here
and has little information to do its heuristics (it probably doesn't
have the ServerHello to look at).  But that should be an easy
fix to the app heuristics.

> window of applicability is extremely narrow in that case.

Then the exact semantics of the FALLBACK_SCSV and the server response
to it will become a non-issue for that App, I believe.

-Martin

---

From: Martin Thomson <[email-masked]>
Date: Wed, 18 Feb 2015 11:36:17 +1100

> In which way does it "break" early adopters.

I suspect that not generating the alert will cause early adopters to
fall back more.  If a long series of fallbacks resets any fallback
state before failing completely (like Firefox), then that's not a
terminal condition.  In fact, it produces the same net result, albeit
more slowly, for those.  Not sure about other implementations though.

David's concern about burying the original reason doesn't bother me
much, but it does apply.

---

From: Martin Thomson <[email-masked]>
Date: Wed, 18 Feb 2015 11:39:54 +1100

> upwards as the server suggests?

Indeed.  I expect that to be a common response.

> fix to the app heuristics.

I'm largely talking about apps that don't change here, because if they
were to change, then I'd be arguing for disabling fallback.  It's
actually fairly easy to make the change, because the app is usually
well aware of the fact that it is performing a fallback when it does.
What is needed is a signal to the TLS stack that it should accept a
higher version in the ServerHello.

---

From: [email-masked] (Martin Rex)
Date: Wed, 18 Feb 2015 01:48:26 +0100 (CET)

Martin Thomson wrote:
[ Charset UTF-8 unsupported, converting... ]
> higher version in the ServerHello.

But isn't that signal _already_ there: the request for the FALLBACK_SCSV.
How does the App signal that the FALLBACK_SCSV should be included?

-Martin

---

From: Martin Thomson <[email-masked]>
Date: Wed, 18 Feb 2015 11:55:07 +1100

> But isn't that signal _already_ there: the request for the FALLBACK_SCSV.

Well, we were talking about the legacy case, where the request to
include the SCSV doesn't implicitly include permission to negotiate
version.max + 1.  TLS stacks that care about backward compatibility as
deeply as NSS does will want another signal to avoid the overload of
semantics.

> How does the App signal that the FALLBACK_SCSV should be included?

In the APIs I've seen (NSS + OpenSSL), the app configures the stack
with a reduced range of versions and they explicitly turn on the SCSV
with a separate option.