Subject: [TLS] I-D Action: draft-ietf-tls-downgrade-scsv-01.txt

From: [email-masked]
Date: Mon, 10 Nov 2014 12:07:55 -0800

A New Internet-Draft is available from the on-line Internet-Drafts directories.
 This draft is a work item of the Transport Layer Security Working Group of the IETF.

        Title           : TLS Fallback Signaling Cipher Suite Value (SCSV) for Preventing Protocol Downgrade Attacks
        Authors         : Bodo Moeller
                          Adam Langley
	Filename        : draft-ietf-tls-downgrade-scsv-01.txt
	Pages           : 8
	Date            : 2014-11-10

Abstract:
   This document defines a Signaling Cipher Suite Value (SCSV) that
   prevents protocol downgrade attacks on the Transport Layer Security
   (TLS) protocol.  It updates RFC 2246, RFC 4346, and RFC 5246.

The IETF datatracker status page for this draft is:
https://datatracker.ietf.org/doc/draft-ietf-tls-downgrade-scsv/

There's also a htmlized version available at:
http://tools.ietf.org/html/draft-ietf-tls-downgrade-scsv-01

A diff from the previous version is available at:
http://www.ietf.org/rfcdiff?url2=draft-ietf-tls-downgrade-scsv-01

Please note that it may take a couple of minutes from the time of submission
until the htmlized version and diff are available at tools.ietf.org.

Internet-Drafts are also available by anonymous FTP at:
ftp://ftp.ietf.org/internet-drafts/

---

From: Florian Weimer <[email-masked]>
Date: Tue, 11 Nov 2014 14:44:22 +0100

> 	Filename        : draft-ietf-tls-downgrade-scsv-01.txt

Section 3 still does not mention which version to put into the 
inappropriate_fallback alert message.  For interoperability reasons, the 
TLS version from ClientHello.client_version has to be used (even if the 
version negotiation has not been completed because the server might opt 
to bail out early out of the handshake code).

-- 
Florian Weimer / Red Hat Product Security

---

From: Bodo Moeller <[email-masked]>
Date: Tue, 11 Nov 2014 16:52:21 +0100

Florian Weimer <[email-masked]>:

> inappropriate_fallback alert message.

Good point; it can't hurt to be completely explicit about this.

Proposed new wording:

o If TLS_FALLBACK_SCSV appears in ClientHello.cipher_suites and the highest
protocol version supported by the server is higher than the version
indicated in ClientHello.client_version, the server MUST respond with a
fatal inappropriate_fallback alert *(unless it responds with a fatal
protocol_version alert because the version indicated in
ClientHello.client_version is unsupported). The record layer version number
MUST be set to ClientHello.cipher_suites for this alert (as it would for
the Server Hello message if the server was continuing the handshake)*.

Bodo

---

From: Florian Weimer <[email-masked]>
Date: Tue, 11 Nov 2014 18:13:29 +0100

On 11/11/2014 04:52 PM, Bodo Moeller wrote:
> Florian Weimer <[email-masked] <mailto:[email-masked]>>:
>
>     o If TLS_FALLBACK_SCSV appears in ClientHello.cipher_suites and the
>     highest protocol version supported by the server is higher than the
>     version indicated in ClientHello.client_version, the server MUST
>     respond with a fatal inappropriate_fallback alert *(unless it
>     responds with a fatal protocol_version alert because the version
>     indicated in ClientHello.client_version is unsupported). The record
>     layer version number MUST be set to ClientHello.cipher_suites for
>     this alert (as it would for the Server Hello message if the server
>     was continuing the handshake)*.

The final ClientHello.cipher_suites should be ClientHello.client_version.

---

From: Martin Thomson <[email-masked]>
Date: Tue, 11 Nov 2014 11:24:53 -0800

On 11 November 2014 07:52, Bodo Moeller <[email-masked]> wrote:
> The record layer version number MUST be set to ClientHello.cipher_suites for
> this alert (as it would for the Server Hello message if the server was
> continuing the handshake).

I think that you mean ClientHello.client_version for the record layer.

---

From: Bodo Moeller <[email-masked]>
Date: Tue, 11 Nov 2014 20:41:23 +0100

>
> [...], the server MUST respond with a fatal inappropriate_fallback alert *(unless
> it responds with a fatal protocol_version alert because the version
> indicated in ClientHello.client_version is unsupported). The record layer
> version number MUST be set to ClientHello.cipher_suites for this alert (as
> it would for the Server Hello message if the server was continuing the
> handshake)*.
>
>
Thanks to Yngve, Florian, and Martin for the correction -- of course, that
version number must be set to ClientHello.client_version; I have fixed my
working copy accordingly.

Bodo

---

From: [email-masked] (Martin Rex)
Date: Tue, 11 Nov 2014 20:41:59 +0100 (CET)

> I think that you mean ClientHello.client_version for the record layer.

ClientHello.cipher_suites as written by Bodo and echoed by Florian
does not make any sense to me (not only because a list of integers
can not possibly fit into a single integer.

But I do _not_ think that a MUST for ClientHello.client_version
would be appropriate for an fatal alert that is sent instead
of ServerHello.  For alerts that early in the handshake a server
may for simplicity reuse the record layer protocol that was used
for the in coming ClientHello.

-Martin

---

From: Martin Thomson <[email-masked]>
Date: Tue, 11 Nov 2014 11:50:52 -0800

> for the in coming ClientHello.

I think that's reasonable.  I think that we sometimes echo the record
layer protocol version, depending on how far we are through the
handshake processing.  I can see why you wouldn't want to dictate this
so strongly.

---

From: Bodo Moeller <[email-masked]>
Date: Tue, 11 Nov 2014 20:52:36 +0100

> for the in coming ClientHello.

God point.  If the record-layer version number differs from
ClientHello.client_version, the client should really be ready to accept
both version numbers. So what about the following?

[...]  The record layer version number for this alert MUST be set to either
ClientHello.client_version (as it would for the Server Hello message if the
server was continuing the handshake), or to the record layer version number
used by the client.

Bodo

---

From: [email-masked] (Martin Rex)
Date: Thu, 13 Nov 2014 22:36:13 +0100 (CET)

> server was continuing the handshake), or to the record layer version number

I thought you were looking for simplicity and ease-of-implementation.
I believe you should get rid of the MUST.

we're talking about the text on page 3 of your I-D, right?

   o  If TLS_FALLBACK_SCSV appears in ClientHello.cipher_suites and the
      highest protocol version supported by the server is higher than
      the version indicated in ClientHello.client_version, the server
-     MUST respond with a fatal inappropriate_fallback alert (unless it
-     responds with a fatal protocol_version alert because the version
-     indicated in ClientHello.client_version is unsupported).  The
-     record layer versio
- 2000
- n number for this alert MUST be set to either
-      ClientHello.client_version (as it would for the Server Hello
-      message if the server was continuing the handshake), or to the
-      record layer version number used by the client.
+     MUST respond with a fatal inappropriate_fallback alert.  There
+     has not been a protocol version negotiated at this point of the
+     TLS handshake, so the inappropriate_fallback alert, like any
+     other fatal alert this early during the handshake, should use
+     a record layer protocol_version that the client can reasonably
+     be expected to understand, such as the record layer protocol_version
+     that carried the client's ClientHello handshake message or the
+     ClientHello.client_version.

I have a serious problem with the text in the parentheses in your current
version (from above, re-flowed):

-     (unless it responds with a fatal protocol_version alert because the
-      version indicated in ClientHello.client_version is unsupported).

This text (a) is ignorant about how the SSL&TLS version negotiation is
supposed to work and (b) gives a blessing to version-intolerant servers.

It hurts to see such text in a proposal whose purpose is to ask servers
to mitigate dangerous client behaviour.  Client behaviour that was invented
to compensate for the failure of TLS servers to properly negotiate SSL&TLS
protocol versions in combination with server's protocol version intolerance.

-Martin

---

From: Bodo Moeller <[email-masked]>
Date: Thu, 13 Nov 2014 23:08:04 +0100

Martin Rex <[email-masked]>:

>
> -     [...]  The
> -     record layer version number for this alert MUST be set to either
> +     [...]  There

Hm. What else would the client "reasonably be expected to understand"? Your
proposed wording sounds very vague.

> supposed to work and (b) gives a blessing to version-intolerant servers.

Well, actually I ended up with that text because I copied from the TLS RFCs
-- see the definition of the protocol_version alert:

"The protocol version the client has attempted to negotiate is recognized,
but not supported. (For example, old protocol versions might be avoided for
security reasons). This message is always fatal."

The above wording is *not* meant to encourage servers to send a
protocol_version alert if client_version is too high (new), which I think
is what you got from it. It merely recognizes that servers may be sending a
protocol_version alert if client_version is too low (old). I hadn't thought
of the other interpretation -- the intention here was simply to be clear
that previous current protocol_version behavior is still allowed, and not
overridden by a requirement to always send inappropriate_fallback.

If you read it in its actual context ("If TLS_FALLBACK_SCSV appears in
ClientHello.cipher_suites and the highest protocol version supported by the
server is higher than the version indicated in ClientHello.client_version,
..."), I think that's entirely clear in draft-ietf-tls-downgrade-scsv-02:
if the highest protocol version supported by the client is higher than
ClientHello.client_version and ClientHello.client_version is unsupported by
the server, then clearly client_version is too old. That has nothing to do
with version-intolerance.

Bodo

---

From: [email-masked] (Martin Rex)
Date: Fri, 14 Nov 2014 00:19:54 +0100 (CET)

> proposed wording sounds very vague.

It is vague on purpose, because it is supposed to be non-normative.
Why would you want to inconvenience existing implementations
(where the record level protocol version for an alert might get determined
at the record protocol layer, and _not_ in function (as function parameter)
that triggers the alert response, such as:

   ssl3_send_alert(s,SSL3_AL_FATAL,SSL_AD_INAPPROPRIATE_FALLBACK);

> security reasons). This message is always fatal."

Which looks very much like an bug in the TLS RFCs.
No, we don't need to be bug-for-bug compatible.

> is what you got from it.

Non-obvious intentions of the author do not matter here.
The wording clearly suggests that it would be OK for servers for too high
as well.

Consider the following scenario:

 - server that has TLSv1.0 and SSLv3 disabled (Win2012 ADFS?)
 - middlebox in the path that kills TLSv1.2 connections
 - Client that starts with record.pv={3,3}+ClientHello.client_version={3,3}
   observes a connection closure (caused by the middlebox) and
   retries with  record.pv={3,1}+ClientHello.client_version={3,1}+FB_SCSV
   (MSIE 8 on Win7 with TLSv1.0+TLSv1.1+TLSv1.2 enabled)

I can see three possible server responses, and which one do you think
would be best in helping the client to decide how to continue (and why):

 (1) server sees the FB_SCSV and responds with fatal invalid_fallback alert
 (2) server sees ClientHello.client_version={3,1} and responds with
     fatal protocol_version alert
 (3) server continues handshake with ServerHello.server_version={3,2}

-Martin

---

From: Bodo Moeller <[email-masked]>
Date: Fri, 14 Nov 2014 06:38:07 +0100

> The wording clearly suggests that it would be OK for servers for too high

As I subsequently explained, it doesn't if you don't take it out of
context. The context is that the version is low.

That wording in the TLS RFCs indeed appears to encourage version-intolerant
behavior and should be fixed. However, for this I-D, I'm not worried.

---

From: Bodo Moeller <[email-masked]>
Date: Fri, 14 Nov 2014 07:13:49 +0100

Martin Rex <[email-masked]>:

>> +     [...] the inappropriate_fallback alert, like any
> >> +     be expected to understand, [...]
>

> [...] Your proposed wording sounds very vague.
>

>    ssl3_send_alert(s,SSL3_AL_FATAL,SSL_AD_INAPPROPRIATE_FALLBACK);

In that case, I think we should be saying nothing in the server behavior
section at all (after all, alerts sent by the client in response to the
Client Hello aren't new). Rather, the client server behavior section should
point out that clients that want to detect the inappropriate_fallback alert
must be prepared to see any record-layer protocol version.

Florian, I'd put in explicit guidance on the record-layer protocol version
to use with the inappropriate_fallback alert at your request. What do you
think about explicitly asking the client to tolerate any version (as the
TLS RFC does for the Client Hello record version) vs. explicitly telling
the server what to use?

Bodo

---

From: Florian Weimer <[email-masked]>
Date: Fri, 14 Nov 2014 07:23:34 +0100

On 11/14/2014 07:13 AM, Bodo Moeller wrote:
> Florian, I'd put in explicit guidance on the record-layer protocol
> version to use with the inappropriate_fallback alert at your request.
> What do you think about explicitly asking the client to tolerate any
> version (as the TLS RFC does for the Client Hello record version) vs.
> explicitly telling the server what to use?

I think this would be rather misleading because at least OpenSSL is not 
version-tolerant here, in the sense that the application will see a 
different error, and not one that reflects the inappropriate_fallback 
alert, if there is an unexpected version number in the alert message.

---

From: Bodo Moeller <[email-masked]>
Date: Fri, 14 Nov 2014 09:12:52 +0100

> I think [the former] would be rather misleading because at least OpenSSL
> is not version-tolerant here, in the sense that the application will see a

Thanks for your comment.

Right, I just wouldn't want to use OpenSSL behavior that might not be ideal
as an excuse to be unreasonably strict in the spec.

But then I think that stating explicit requirements for the server as
draft-ietf-tls-downgrade-scsv-02 does ("The record layer version number for
this alert MUST be set to ...") is not unreasonable in this case: the main
point of this alert is to provide an explicit signal from the server back
to the client *if* the server would normally be willing to negotiate that
protocol version. We're not requiring the server to use a record-layer
protocol version that it doesn't support at all. Server implementations can
first determine the protocol version to use, and *then* look for the SCSV
to check if they should proceed with the handshake: even if the handshake
will be aborted, they'll have the protocol version before they send the
alert.

So I believe that draft-ietf-tls-downgrade-scsv-02 addresses all comments
(cf. slide 5 in
http://www.ietf.org/proceedings/91/slides/slides-91-tls-0.pdf). Joe, Sean,
can we proceed?

Bodo

---

From: Florian Weimer <[email-masked]>
Date: Fri, 14 Nov 2014 13:07:17 +0100

On 11/14/2014 09:12 AM, Bodo Moeller wrote:

> Right, I just wouldn't want to use OpenSSL behavior that might not be
> ideal as an excuse to be unreasonably strict in the spec.

You are finalizing the specification after the implementation.  I don't 
think there is value in *not* documenting existing interoperability 
requirements.

> Server
> implementations can first determine the protocol version to use, and
> *then* look for the SCSV to check if they should proceed with the
> handshake: even if the handshake will be aborted, they'll have the
> protocol version before they send the alert.

Agreed.

---

From: [email-masked] (Martin Rex)
Date: Fri, 14 Nov 2014 18:11:13 +0100 (CET)

>> protocol version before they send the alert.

This is ignoring the actual problem and passing the buck to implementors.

Keep in mind that there is the general IETF rule

"Be liberal in what you accept, be conservative in what you send",

and we know that there are several "scanners" / "probers" out there,
not just broken TLS implementations, and any kind of guidance should
cover-it-all, rather than leaving undefined behaviour.

The SSL alert response of the server should avoid using a protocol
version at the record layer which
   (a) the server potentially does not even implement and
   (b) which the peer can not reasonably be expected to understand.

(a) may often rule out ClientHello.client_version, not just for
    TLS probers / scanners, but also early adopter clients
    (like bleeding edge web browsers) talking to installed base servers

(b) makes the record_version that the client used at the record layer
    for the record carrying the ClientHello a reasonably safe bet.

but there still is the possibility that a scanner/prober or defective
client uses a protocol version at the record layer that the server
doesn't implement (or which doesn't even exist, mind you that TLSv1.2
requires servers to accept {0x03, 0xXX} at the record layer for the
initial ClientHello), and depending on the design of the existing
server code, the record layer may not want to use an invalid or
unknown protocol value at all, and rather fallback to a truely safe bet
(which I think would be {0x03, 0x00}, inspite of the specific alert
this document is newly defining isn't described in the SSLv3 spec.
(because the latter argument applies to *ALL* existing protocols,
 SSLv3 through TLSv1.2 and is therefore not applicable).

Personally, I would use the record version of the record which carried
the initial ClientHello, because independent of what it is, if the
client used it for ClientHello, it must be OK to use for the response
in the sense of "best effort".

{0x03, 0x00} while being a theoretical and fully spec-compliant "safe bet"
that no reasonable TLS implementation ought to choke on, may cause
choking in less reasonable implementations that started with {0x03, 0x01}
or above.

-Martin

---

From: Ben Laurie <[email-masked]>
Date: Fri, 14 Nov 2014 17:27:28 +0000

> "Be liberal in what you accept, be conservative in what you send",

This "rule" is terrible for security and absolutely should not be followed.

---

From: [email-masked] (Martin Rex)
Date: Fri, 14 Nov 2014 18:31:53 +0100 (CET)

Ben Laurie wrote:
> Martin Rex <[email-masked]> wrote:
> 

You seem to have missed it, but what we were discussing here
is a guidance for the server which protocol version the server should
use at the record layer when returning the fatal invalid_fallback
alert to the client.

The protocol_version that that the server uses will *NOT* affect the
fatal failure of the handshake (for the server), but may affect the
behaviour of the client and the comprehensibility of the error message
that the client produces, so this is *EXACTLY* the kind of situation
where the general IETF rule applies.

-Martin

---

From: Watson Ladd <[email-masked]>
Date: Fri, 14 Nov 2014 09:42:22 -0800

> use at the record layer when returning the fatal invalid_fallback

I'm confused. The record layers in all versions of TLS are the same,
except for the version number, until encryption is turned on, and we
have a version negotiation mechanism. Why shouldn't the server send
the alert using the version that version negotiation would produce?

Sincerely,
Watson Ladd

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

-- 
"Those who would give up Essential Liberty to purchase a little
Temporary Safety deserve neither  Liberty nor Safety."
-- Benjamin Franklin

---

From: [email-masked] (Martin Rex)
Date: Fri, 14 Nov 2014 19:52:50 +0100 (CET)

> the alert using the version that version negotiation would produce?

There never is a version negotiated in this situation.

Actually, the "protocol version negotiation" is a little weird in TLS,
because the client never "offers" protocol versions to choose from,
but only indicates the highest protocol version that it supports (or
more appropriately, the highest protocol version that it is willing
to use), and the server does whatever the server feels like.

There are a number of unreasonable TLS clients that send

  record.pv = {3,3} + ClientHello.client_version = {3,3}

even when they are configured to use allow other protocol versions,
and a server that does _not_ support TLSv1.2 (or has it administratively
disabled) has two options here:

  (a) fail the handshake with a fatal protocol_version alert

  (b) successfully continue the handshake with the highest protocol
      version that the server supports and has enabled.

(a) is technically spec-compliant behaviour for pre-TLSv1.2 servers,
and it is nowhere clear that pre-TLSv1.2 server implementers will
take into accound broken TLSv1.2 clients ahead of time and do (b) 
from the beginning.

Creating specification with ambiguities or undefined behaviour,
pushing the buck to implementors, is never a good idea.
Especially if one knows that implementors have previously failed
time and time again, and when providing more elaborate guidance is easy.

-Martin

---

From: Bodo Moeller <[email-masked]>
Date: Fri, 14 Nov 2014 23:56:48 +0100

> pushing the buck to implementors, is never a good idea.

Now I am thoroughly confused by what you're saying. A bit earlier you
argued *against* specifying a MUST for the record-layer version number to
be used with the inappropriate_fallback alert (as it appears in
draft-ietf-tls-downgrade-scsv-02), proposing instead a wording that you
said was "vague on purpose". I can't reconcile that with what you're saying
here. The only constant theme I can make out is that whatever you're saying
at a given time is undoubtedly right.

(For the record, I'm still happy with what draft-ietf-tls-downgrade-scsv-02
says.)

Bodo

---

From: [email-masked] (Martin Rex)
Date: Sat, 15 Nov 2014 05:23:06 +0100 (CET)

> at a given time is undoubtedly right.

Giving a implementors a guidance by describing the issue at hand
calling for reasonable trade-offs and and recommending, but not mandating
certain behaviour, promotes interop.

Using imperatives where this isn't necessary is not only squarly in
conflict with rfc2119, it will also result in interop failures, because
it gives (some) implementors poor excuses for why their code aborts or
fails interop in a neither useful nor reasonable fashion.

-Martin