Subject: [TLS] TLS client_version (ClientHello & PreMasterSecret)

From: Martin Rex <[email-masked]>
Date: Wed, 16 Feb 2011 17:51:57 +0100 (MET)

Does anyone remember this report (&ensuing discussion):

  http://www.ietf.org/mail-archive/web/tls/current/msg06840.html

>
> For IE 8, the scenario looks like:
>
>     IE 8<--------------> TLS server
>          --->ClientHello V1.2--->
>          <---ServerHello V1.1<---
>          ...
>          --->PreMasterSecret (v1.2)--->  (as expected)
>          ...
>          <---HelloRequest<----
>          ---->ClientHello v1.1----> (ask for an abbreviated handshake)
>          <---ServerHello V1.1<---   (not resumable, new session)
>          ...
>          --->PreMasterSecret (v1.2)---> (**)
> 
> (**) IE 8 uses the version number offered by the ClientHello in the
> initial handshaking.

The behavior of IE 8 (actually SChannel) is clearly defective for the
renegotiation handshake, because the client_version in the
PreMasterSecret does not match the ClientHello.client_version
from the same handshake.

(Just how *independent* SSL handshakes were designed to be should
 have become painfully obvious with the renegotiation vulnerability...)

According to what a colleague just told me, the behaviour that was
described for Opera (and also used by SunJSSE) results in a handshake
failure on renegotiation with IIS7:

>
> For Opera, the scenario looks like:
>
>     Opera <--------------> TLS server
>          --->ClientHello V1.2--->
>          <---ServerHello V1.1<---
>          ...
>          --->PreMasterSecret (v1.2)--->  (as expected)
>          ...
>          <---HelloRequest<----
>          ---->ClientHello v1.1----> (ask for an abbreviated handshake)
>          <---ServerHello V1.1<---   (not resumable, new session)
>          ...
>          --->PreMasterSecret (v1.1)---> (*)
>
> (*) Opera uses the version number offered by the ClientHello in the
> renegotiation handshaking.

While coping with defective clients such as described with IE8 above
has a long tradition, a server like IIS7 that chokes on _correct_
behaviours seems to be a new kid on the block.

One reason why this problem may not be immediately apparent at
Browser UIs is that newer browsers contain extremely dirty
application-level hacks to work around TLS version interop
problems, and they're caching the TLS version for which the
handshake succeeds and steer further connects to start with
that exact same version (instead of always proposing the
highest version the client implements, as the TLS spec suggests).

Has anyone else observed this interop problem with newer
SChannel-based servers on renegotiation handshakes and wondered?

-Martin

---

From: Martin Rex <[email-masked]>
Date: Wed, 16 Feb 2011 19:15:12 +0100 (MET)

While the behaviour that was described for Opera is allowed
the way I read the TLS spec, it is _not_ the recommended behaviour.

I also wrote that in my first comment to the original posting:

   http://www.ietf.org/mail-archive/web/tls/current/msg06842.html

A client that always sends the highest supported version,
will avoid this IIS7 interop problem.

For application-level reconnect fallbacks--rather than
memorizing the TLS version that was negotiated and forcing that
version in all later TLS handshakes, a client should probably
memorize the highest protocol version (known to the client) which
could be safely proposed in ClientHello.client_version to the server
on all further Handshakes (new connects, resumes, renegotiations) and
in both, ClientHello.client_version and RSA PreMasterSecret.client_version.

-Martin

> behaviours seems to be a new kid on the block.

While the behaviour above is allowed by my reading of the TLS specification,
I noted

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

---

From: Michael D'Errico <[email-masked]>
Date: Wed, 16 Feb 2011 11:11:29 -0800

> in both, ClientHello.client_version and RSA PreMasterSecret.client_version.

A problem with caching the server's highest protocol version
is that it can change as the server is upgraded.  So the time
to live of the cached data should not be too long, in order
to not have the client cause downgrade attacks on itself.

Mike

---

From: "Yngve Nysaeter Pettersen" <[email-masked]>
Date: Wed, 16 Feb 2011 20:27:54 +0100

Hi,

The reason for Opera's behavior is that a renegotiation is essentially  
treated as a Session resume, which the server may or may not accept (most  
likely not, but it might just be a rekeying event).

As I recall (this is ancient, probably from when we introduced TLS 1.0 in  
Opera 3.50 in late 1998), historically we have observed interoperability  
problems if the version in Client Hello attempting session resume was not  
the same as negotiated. Similar reasons are IIRC behind our reordering of  
the cipher suites offered to place the previously used cipher suite at the  
front.

Regarding the premaster secret RFC 5246 says

    The version number in the PreMasterSecret is the version
    offered by the client in the ClientHello.client_version

which I read to mean the Client Hello of the _current_ negotiation, not  
the first on the connection, or the one used when the currently active  
session was negotiated.

We recently received a report about the version in premaster during  
renegotiation issue.

> the way I read the TLS spec, it is _not_ the recommended behaviour.

Where is this recommendation written in the TLS RFCs?

The Client Hello section says that the version in that record

     SHOULD be the latest (highest valued) version supported by the client

We use the version that we know can be safely negotiated, even though we  
store information that indicates the highest version that can be safely be  
negotiated, specifically for Renego patched servers (for unpatched servers  
the servers version is stored), and as mentioned we choose the session  
version since there have been trouble using the supported version during  
session resume.

I notice that the IE8 Hello referenced was sending negotiated version as  
the Client Hello version, not what was used in the original Client Hello  
(like Opera), while using the original connection handshake Client Hello  
version as the premaster secret version (unlike Opera).

IMO several things may have to be clarified:

   1) Should session resume Client Hellos specify negotiated or supported  
versions during _new_ connection negotiation?

   2) Should renegotiation  use the Client Hello version from the original  
Hello, or the negotiated version

   3) If the versions in the renegotiation Client Hello is different from  
the version used in the initial negotiation, which should be used.

   4) If the negotiated version is used in session resume, if the current  
connection was a session resume, should the highest supported version be  
used in the premaster secret?

I think 1) could go either way, but unless I am mistaken "everybody" is  
using negotiated version at present. And I have no idea what the current  
status is regarding tolerance for this (feature request filed for the TLS  
Prober).

The answer to 2) would probably follow the answer to 1).

The big question is what should be the answer to 3) and 4), and in any  
case here we come up against the fact that both the server and client in  
Schannel were developed by the same company and tested against each other,  
but also the that 30% of all servers do not check the premaster version  
field, and 99% of all servers have TLS 1.0 as their highest enabled  
version. Additionally, renegotiation is not used that frequently in  
deployed systems.

My opinion is that the Client Hello of the current negotiation should be  
used, since that makes the logic easier, mistakes less easy to make, and  
AFAIK unless the negotiated protocol version is vulnerable to an active  
rollback attack and MITM attack, the negotiated version will be the  
highest supported by the server, so that should not present a security  
problem or rollback possibility.

Whatever is decided, one probably have to be very careful, since changing  
 from the current system might cause interoperability problems with  
existing systems.

-- 
Sincerely,
Yngve N. Pettersen
********************************************************************
Senior Developer		     Email: [email-masked]
Opera Software ASA                   http://www.opera.com/
Phone:  +47 23 69 32 60              Fax:    +47 23 69 24 01
********************************************************************

---

From: Martin Rex <[email-masked]>
Date: Wed, 16 Feb 2011 20:57:50 +0100 (MET)

>     offered by the client in the ClientHello.client_version

Yup, this is the important information about the "client_version"
in ClientHello and RSA PreMasterSecret and applies to every
TLS handshake (and NEVER cross-handshake).

>      SHOULD be the latest (highest valued) version supported by the client

You are quoting the recommendation here.

The recommendation is to ALWAYS send the latest version supported
by the client (more precisely it is the highest version that the
client is willing to use).

In face of interop problems when sending ClientHello.client_version
with values of TLSv1.1{0x03,0x02} or TLSv1.2{0x03,0x03}, the
interoperability enhanced guidance would be something like this:

  ClientHello should be the latest (highest valued) version that the
  client implementation supports, the client app is willing to use
  and the server is now known to choke on.

If the client caches and forces the last protocol_version that
was successfully negotiated, then it is impossible, in case
that the server's TLS implementation gets upgraded, that the
client uses a better version without probing.

The client is better off if it memorizes the highest client_version
that it could safely propose, because it may allow the use of higher
protocol versions for every handshake without probing (unless the
server chokes on all protocol versions that it does not implement).

-Martin

---

From: Martin Rex <[email-masked]>
Date: Wed, 16 Feb 2011 21:20:45 +0100 (MET)

Sorry, typo (s/is now known/is not known/), fixed below:
 
    ClientHello should be the latest (highest valued) version that the
    client implementation supports, the client app is willing to use
    and the server is not known to choke on.

-Martin

---

From: Martin Rex <[email-masked]>
Date: Wed, 16 Feb 2011 23:51:53 +0100 (MET)

> to not have the client cause downgrade attacks on itself.

Agreed.  Assumptions about the servers protocol version (in)tolerance
that were determined by unprotected probing heuristics should not
be used/cached too long.

The behaviour newer Web browsers that have reconnect fallbacks
suggest that some browsers _are_ caching protocol versions for
servers and that they might be caching the negotiated rather
than the highest tolerated protocol version.

-Martin