Subject: [TLS] TLSextSNI - initial SSL 2.0 Hello and session resume

From: [email-masked] (Martin Rex)
Date: Fri, 11 Jan 2013 14:40:18 +0100 (CET)

Dear TLS-fanciers,

I've recently added TLS extension SNI to our TLS implementation,
and have encountered unexpected client behaviour on my server
resulting in session resumption failures (per rfc6066):

excerpt from the last paragraph on the bottom of page 7, rfc6066:

   http://tools.ietf.org/html/rfc6066#page-7

                                                    The client SHOULD
   include the same server_name extension in the session resumption
   request as it did in the full handshake that established the session.
   A server that implements this extension MUST NOT accept the request
   to resume the session if the server_name extension contains a
   different name.  Instead, it proceeds with a full handshake to
   establish a new session.

The cause was an "unusual" Web Browser distributed by our IT department,
which has SSL 2.0 enabled in that browser.

The effect of this configuration is, that the browser starts every
initial handshake with an SSL 2.0 CLIENT-HELLO, offering TLS,
which will result result in a TLSv1.0 full handshake.  Since there
is no room for TLS extensions in a SSL 2.0 CLIENT-HELLO, the session
is marked as being established without SNI.

On the very next handshake, the browser proposed to resume that session,
which per TLS spec requires a TLS ClientHello including the session ID.
Now that Brower's TLS implementation appears to blindly insert the
whole chore of TLS extensions into *ANY* TLSv1.0 ClientHello, including
TLS extension SNI, and this causes the my server, based on the requirement
quoted above, to reject the resumption request and require a full handshake
instead ... which requires a new connection ... which appears to
result in another SSL 2.0 CLIENT-HELLO to be used ...

... wash, rinse, repeat.

To make a long story short: it seriously impairs performance.

Now I am wondering what the desired behaviour is -- and whatever the
desired behaviour for this scenario will be, that this information
will be posted as a caveat / clarification throught the errata process
for rfc6066.

To be fair, the very same session resumption failure will be possible
with pure SSLv3 and TLS handshakes if a client does not follow the SHOULD,
it is not limited to SSL 2.0 CLIENT-HELLO.

The combination of "client SHOULD" with "the server MUST NOT resume"
may have not been a very good idea.

Am I really the first to notice??  I had commited my code update into
our internal development tree friday before X-mas, and the collegues
reported the warning messages in the servers trace file this tuesday.

Suggestions?

-Martin

---

From: Wan-Teh Chang <[email-masked]>
Date: Sun, 13 Jan 2013 07:43:56 -0800

On Fri, Jan 11, 2013 at 5:40 AM, Martin Rex <[email-masked]> wrote:
> instead

Hi Martin,

I understand your description of the problem up to this point.

> ... which requires a new connection ... which appears to

But I don't understand why your server or the browser requires a new
connection. Your server and the browser should be able to complete a
full handshake from the TLSv1.0 ClientHello, and once that full
handshake succeeds, a new TLSv1.0 ClientHello, if any, to resume the
new session should be able to succeed.

Why does that not happen?

Thanks,
Wan-Teh

---

From: [email-masked] (Martin Rex)
Date: Mon, 14 Jan 2013 21:06:22 +0100 (CET)

Wan-Teh Chang wrote:
>
> Martin Rex <[email-masked]> wrote:
> >

While it is correct (as I admitted in my followup message to the list),
that I could have avoided a new connection, and unless the client side
TLS session cache management isn't fundamentally braindead, it would
purge the TLS session for which the server refused the resumption from
the client-side session cache, and sessions derived from the failed
resume full handshake would be established with the correct server
name and therefore not exhibit the "wash, rinse, repeat" failure cycle.

Btw. The particular browser in this scenario was doing the fallback
reconnect just fine.  (The browser will have to, or otherwise experience
connectivity problems with Extensions-intolerant TLS servers.)

The performance problem that worries me is created by the TLS full
handshake, rather than the necessesity having to establish a new
network connection.  TLS full handshakes, in particular with newer
2048-bit RSA server certs, hit a TLS server *much* harder than
connection failures.

The other problem is that clients will be requesting inconsistent
semantics when proposing TLS session resumption in combination with
a server_name in TLS extension SNI that is different from the server
name than what was used to establish the connection for which session
resumption is proposed.  That is a defect in the TLS client that
may appear to be acceptable to an implementor based on a defective
client requirement (SHOULD, where a MUST is necessary) in rfc6066.

-Martin

---

From: [email-masked] (Martin Rex)
Date: Wed, 23 Jan 2013 00:44:42 +0100 (CET)

I change the code and did some more testing.

I now believe that TLS extension SNI is mis-specified.

> connectivity problems with Extensions-intolerant TLS servers.)

After reproducing the issue in my "testbed", I realized that the
Web-browsers fallback upon the handshake failure didn't happen
as expected (I got broken images).

> 2048-bit RSA server certs, hit a TLS server *much* harder than

The full-handshake is what worries me most. 
I changed the code to make a full handshake whenever the server_name
in the ClientHello resumption proposal does not match the server_name
in from the initial handshake that created the session. For this particular
(pretty common Web-Browser), when SSL 2.0 is activated, it results
in 4 full handshakes and 3 useless sessions in the servers TLS
session cache.

This is silly, because it works with a single session when the server
continues to ignore TLS extension SNI (purposely or due to not
implementing it).

So I've changed the code again, and I will now essentially ignore the
server_name on session resumption, resulting in the same behaviour
as before implementing TLS extension SNI.

One of the several problems of TLS ext SNI is that rfc3546 did not 
specify what the server should do on session resumption, and one of
the _options_ that rfc3546 appears to offer is sending an unrecognized_name
alert, either as Warning or Fatal:

   If the server understood the client hello extension but does not
   recognize the server name, it SHOULD send an "unrecognized_name"
   alert (which MAY be fatal).

While rfc6066 tries to be more clear about the session resumption scenario,
it is actually specifying the wrong thing to do:

   When the server is deciding whether or not to accept a request to
   resume a session, the contents of a server_name extension MAY be used
   in the lookup of the session in the session cache.  The client SHOULD
   include the same server_name extension in the session resumption
   request as it did in the full handshake that established the session.
   A server that implements this extension MUST NOT accept the request
   to resume the session if the server_name extension contains a
   different name.  Instead, it proceeds with a full handshake to
   establish a new session.  When resuming a session, the server MUST
   NOT include a server_name extension in the server hello.

Rather than prohibiting a session resume on a server_name mismatch,
which by itself is irrelevant (and not backwards-compatible), it
should instead have referred to the _server_credential_.
In the specific case when the particular server credential/cert
associated with a cached session differs from the server credential/cert
that would be used when performing a full handshake, the session resume
should be denied and a full handshake performed instead.

In my TLS server implementation, the TLS stack itself is not aware of
which credentials are in use by a particular server/service, the management
of credentials is performed by the middleware on top of the TLS stack,
and the TLS session cache is bound to the credentials, rather than being
a global resource.  And if one specific credential is administratively
changed all further connections will use the new credential which has
its own session cache, independent from earlier incarnations of the
credential.  So for my implementation, the desire not to resume a
TLS session when a full handshake would result in the use of a
different (server) credential is already an implied side-effect of
my credential and session cache management, a comparison of
server_name values is irrelevant, and might impair interop or
performance.

> client requirement (SHOULD, where a MUST is necessary) in rfc6066.

While I consider the behaviour of that particular Web Browser on my
personal scorecard, the problem affects only servers that try to
implement TLS extension SNI _as_specified_.  Ignoring backwards
compatibility and ignoring a significant installed base both seem
not very reasonable, so I'm choosing a middle ground between the
three of (rfc3546, rfc4366, rfc6066).  Being anal about the exact
wording of rfc6066 about comparing server_name on session resumption
would be counter-productive to interop.

-Martin