Subject: [TLS] More clarity on resumption and session hash

From: Eric Rescorla <[email-masked]>
Date: Mon, 25 May 2015 10:35:30 -0700

I'm updating the NSS session hash implementation to conform to the new spec
and I see that it's very clear on what happens when you have a resumption
where the original handshake did not include the extension and the new one
does (thanks David and Martin)

  o  If the original session did not use an extended master secret but
      the new ClientHello does contain the "extended_master_secret"
      extension, the server MUST NOT perform the abbreviated handshake.
      Instead, it SHOULD continue with a full handshake to negotiate a
      new session.

However, it's less clear on what happens when the original handshake
included
the extension and the new one does not:

   o  If the new ClientHello does not contain the
      "extended_master_secret" extension, the server SHOULD abort the
      handshake.  If it continues with an abbreviated handshake in order
      to interoperate with legacy peers, then the considerations in
      Section 5.4 apply.

This doesn't seem to distinguish between the two cases (original session
did and did not use the extension), but they seem different, since the
original session not using session hash is a common case (legacy) whereas
an extension->no extension transition is an anomaly. Note that the client
*is* required to send it, so I think there's a reasonably strong
argument that the server should require it.

The two main options appear to be:

    1. Fall back to a full handshake.
    2. Abort the connection

The argument for the first appears to be interop. The argument for the
second appears to be that it's likely there is an error or a mid-flight
reconfiguration on the client (which seems not good). My mild preference
is for abort but I think it's important in any case that the draft be
clear.

Similarly, the text about the client side doesn't seem to draw this
distinction:

      If the new ServerHello does not contain the
      "extended_master_secret" extension, the client SHOULD abort the
      handshake.  If it continues with an abbreviated handshake in order
      to interoperate with legacy peers, then the considerations in
      Section 5.4 apply.

Because above the server is required to provide the extension when
resuming a session where the extension was negotiated, it seems like
we should require the client to fail in that case (that's the sense
of the MUST).

I see there was some discussion on the list 3/10 but it was inconclusive.

-Ekr

---

From: Karthikeyan Bhargavan <[email-masked]>
Date: Mon, 25 May 2015 19:45:05 +0200

Right, there was discussion on this and here’s the current rationale.

If the original handshake used the extended master secret,
then even if the resumption handshake does not, it is still protected
by the key derivation in the original handshake.

The only situation when I can see this happening is when the resumption handshake goes to different
endpoints than the original handshake (e.g. in WPA), but maybe someone on the list knows better whether the following is a reasonable use case.

The client connects to an access point which forwards the (EAP-TLS) connection to the (Radius) server.
The server speaks TLS + extended master secret and the client and server agree upon a master secret.
The server installs the master secret at the access point, which itself does not support extended master secret.
The client can now communicate directly with the access point,  and also resume (EAP fast reauth) connections directly with access points without the need to recontact the Radius server

A similar scenario can perhaps be envisioned in cases where a server farm of front-ends directs initial connections to a powerful server that supports extended master secret, but resumption handshakes (via session tickets) can be handled by any (legacy) server.

Far fetched?
-K.

On 25 May 2015, at 19:35, Eric Rescorla <[email-masked]> wrote:

> However, it's less clear on what happens when the original handshake included
> _______________________________________________
> TLS mailing list
> [email-masked]
> https://www.ietf.org/mailman/listinfo/tls

---

From: Eric Rescorla <[email-masked]>
Date: Mon, 25 May 2015 10:52:51 -0700

This does seem pretty far-fetched... And note that if we just required a
complete handshake
at this point, that wouldn't create a total failure.

My vote would be that unless someone speaks up relatively soon, we should
require one
of the two options listed in my message (at MUST).

-Ekr

On Mon, May 25, 2015 at 10:45 AM, Karthikeyan Bhargavan <
[email-masked]> wrote:

> endpoints than the original handshake (e.g. in WPA), but maybe someone on
> the list knows better whether the following is a reasonable use case.
>
> The client can now communicate directly with the access point,  and also
> resume (EAP fast reauth) connections directly with access points without
> the need to recontact the Radius server
>
> A similar scenario can perhaps be envisioned in cases where a server farm
> of front-ends directs initial connections to a powerful server that
> supports extended master secret, but resumption handshakes (via session
> tickets) can be handled by any (legacy) server.
>
> Far fetched?
> -K.
>
>

---

From: Martin Thomson <[email-masked]>
Date: Mon, 25 May 2015 22:03:05 -0700

> is for abort but I think it's important in any case that the draft be

I'd prefer the second two.  That is, unless someone can come up with a
legitimate scenario where the former is needed.

---

From: Karthikeyan Bhargavan <[email-masked]>
Date: Tue, 26 May 2015 08:17:15 +0200

The feedback we’ve been getting on the draft has been to try and preserve interoperability
with legacy clients and servers (even more than the current draft.)
Considering this goal, aborting seems harsh.

Best,
Karthik

---

From: Ilari Liusvaara <[email-masked]>
Date: Tue, 26 May 2015 10:27:24 +0300

> Considering this goal, aborting seems harsh.

Also, there are two dangerous scenarios:
- You have non-session_hash session and resume that.
- You try to use TLS-Exporter in non-session_hase session for authentication.

Based on this, it would seem to be the safest to:
- Not offer any non-session_hash sessions for resumption.
- Deny resumption (full handshake) of any non-session_hash sessions, regardless
  of client session_hash support.
- Disable TLS-Exporter in non-session_hash sessions.

The following are odd edge cases (assuming both ends are due endpoints, these
are safe):
- Resume session_hash-enabled session wihout session_hash extension
- Resume session_hash-enabled session with non-session_hash server.

I was thinking latter of those odd behaviours could occur if one performs
rolling security fix of server farm:
- Client is security fixed
- Server A is security fixed
- Client connects to A
- Client gets session_hash-enabled session.
- Client connects to B, attempting to resume.
- Servers share session DB/key, so resumption succeeds.
- Client gets resumption without session_hash extension.

-Ilari

---

From: Karthikeyan Bhargavan <[email-masked]>
Date: Tue, 26 May 2015 10:05:04 +0200

> - Disable TLS-Exporter in non-session_hash sessions.

It’s worth checking, but I believe these cases are covered in the spec.
We use SHOULD NOT for these cases; after being advised that MUST NOT is too strong for legacy interop.

> - Resume session_hash-enabled session with non-session_hash server.

Indeed these are the cases that Ekr is objecting to.
In the current draft we say SHOULD NOT for these, and Ekr suggests it should be MUST NOT.
Formally, these cases are “safe” in the sense that they are protected by the extended master secret on the first handshake.
In practice, they are a bit weird because it looks like the connection security degraded between the two handshakes.

The question is whether these could happen in practice, and I would welcome more thought son that.
-K.

---

From: Ilari Liusvaara <[email-masked]>
Date: Tue, 26 May 2015 11:42:16 +0300

> It’s worth checking, but I believe these cases are covered in the spec.

The current spec seems to say:
- F->F: SHOULD abort
- F->T: MUST NOT resume (server), SHOULD NOT attempt resume (client)
- T->F: SHOULD abort (this is a weird case)
- T->T: (nothing)

> We use SHOULD NOT for these cases; after being advised that MUST NOT is too strong for legacy interop.

AFAICT, the first two still give interop, just with reduced performance
(full handshakes instead of resumptions).

The third breaks protocols that use TLS-Exporter, including just for keying,
which is seemingly not affected by THS unless one resumes (one can't expect
any security from bad connection).

> In practice, they are a bit weird because it looks like the connection security degraded between the two handshakes.

AFAICT, if these can actually happen in practice, aborting does create
interop problems.

> The question is whether these could happen in practice, and I would welcome more thought son that.

Could the scenario I gave (quoted below) happen in practice (it causes
resumption of session_hash-enabled session with non-session_hash server)?

-Ilari

---

From: Ilari Liusvaara <[email-masked]>
Date: Tue, 26 May 2015 19:56:02 +0300

On Tue, May 26, 2015 at 04:41:37PM +0000, David Benjamin wrote:
> On Tue, May 26, 2015 at 4:42 AM Ilari Liusvaara <[email-masked]>
> wrote:
> 
> This could certainly happen with a server farm, yeah. Hopefully such a
> situation would be rather transient, and it can be mitigated by sharding
> the session cache between EMS-less and EMS-ful halves of the rollout. But
> relying on it always happening seems unrealistic, so honoring the SHOULD is
> a little risky.

IIRC, this hits MUST. That is, the client is REQUIRED to abort in this
case.
 
> I would think tls-unique and friends are still fine in this case? Though if
> we're worried about it (maybe we introduce some new extension later and
> would rather it be incorporated into the key derivation?), we could just
> say that the client should still disable tls-unique and whatnot. I.e.
> IsTLSUniqueSecure() requires that BOTH the connection and the original
> session, if any, are EMS-ful. That seems appropriately conservative and
> without risk of (transient) interop failures. Client with require interop
> need to account for that returning false anyway.

AFAIK:

If you don't resume, TLS-Unique is fine. TLS-Extractor is not.

If the original connection had EMS, then both TLS-Unique and TLS-Extractor
are fine, regardless of if resumptions do.

-Ilari

---

From: David Benjamin <[email-masked]>
Date: Tue, 26 May 2015 16:41:37 +0000

On Tue, May 26, 2015 at 4:42 AM Ilari Liusvaara <[email-masked]>
wrote:

> > Formally, these cases are “safe” in the sense that they are protected by
> the extended master secret on the first handshake.
> > In practice, they are a bit weird because it looks like the connection
> security degraded between the two handshakes.
>

For the converse case (client offers an EMS-ful session on an EMS-less
connection, draft says server SHOULD abort), I can't think of a deployment
where this could happen in practice. The analogous "server farm" case seems
less likely for a client, so aborting seems fine. Still, I don't see a need
for the abort, so I would marginally prefer either "fall back to a full
handshake" (unlike the client, the server has this option) or "just behave
as you otherwise would and inherit whatever EMS-ful => EMS-less tls-unique
considerations we adopt above".

It's slightly confusing that the text tries to specify everything with a
single menu of SHOULDs to pick and choose. It's seems there's only two
profiles to worry about: "EMS required" and "EMS optional due to interop
needs". In fact, the two SHOULDs we're talking about don't even explicitly
talk about the EMS-ful session => EMS-less resumption case. They just say
to abort period, which is mostly for the "EMS required" profile.

David

---

From: David Benjamin <[email-masked]>
Date: Tue, 26 May 2015 17:31:32 +0000

> IIRC, this hits MUST. That is, the client is REQUIRED to abort in this

I don't think it does. The text is:

   o  If the original session did not use an extended master secret but
      the new ServerHello does contain the "extended_master_secret"
      extension, the client MUST abort the handshake.

   o  If the new ServerHello does not contain the
      "extended_master_secret" extension, the client SHOULD abort the
      handshake.  If it continues with an abbreviated handshake in order
      to interoperate with legacy peers, then the considerations in
      Section 5.4 apply.

The latter applies if an EMS-less server resumes an EMS-full session. This
is what you described. The former applies if an EMS-full server resumes an
EMS-less session. That one shouldn't cause interop problems assuming all
EMS-full servers honor this MUST:

Whereas an EMS-less server may be able to parse a serialized EMS-full
session and attempt to resume it. (In the case of OpenSSL, even if the
structure version gets bumped, d2i_SSL_SESSION kindly ignores the version
field because why not[*]? Though I suppose the structure's syntax could
just get changed incompatibly to break the parse.)

David

[*] I believe the rewrite of that code in the master branch will actually
check it, but 1.0.2 and before don't.

---

From: Nico Williams <[email-masked]>
Date: Wed, 27 May 2015 12:23:30 -0500

> is for abort but I think it's important in any case that the draft be

Is a mid-flight reconfiguration of the client while reusing an old
session cache likely?

Anyways, my preference would be to fallback, since I don't see the harm.
Correct me if I'm wrong.

Nico
--

---

From: Martin Thomson <[email-masked]>
Date: Wed, 27 May 2015 10:43:16 -0700

> Is a mid-flight reconfiguration of the client while reusing an old

Some clients persist session caches to disk.  That means completely
new software could load old sessions.

---

From: Eric Rescorla <[email-masked]>
Date: Thu, 28 May 2015 16:23:47 -0700

I'd like to close the loop on this, since I think it would be better if
implementations
behaved identically.

It seems to me that there are two cases here:

- Interoperating with non-EMS-enabled devices, in which case we want to
  encourage refusal to resume, but we know we can't require it (hence
  SHOULD.

- Mid-flight reconfigurations/changes, etc. in which case we should be able
  to come down on one definite interpretation.

Since this second case should rarely happen, but people seem sad about
abort, I would suggest that we say MUST NOT resume and SHOULD
do a new full handshake.

-Ekr

---

From: David Benjamin <[email-masked]>
Date: Fri, 29 May 2015 18:06:38 +0000

I poked a bit more and I was mistaken about OpenSSL's d2i_SSL_SESSION
behavior: Although it does ignore the structure version, it will fail the
parse if it sees elements at the end of the structure it doesn't
understand. Presuming any EMS implementation adds an optional boolean to
the end of the serialized session, pre-EMS servers derived from OpenSSL
should simply not recognize any sessions created by post-EMS servers in any
shared session cache + rolling upgrade situation. So, at least against
those servers, having the client abort when the peer resumes an EMS-full
server without EMS should not cause issues. I don't know about other
implementations though.

If we do specify that the client MUST or even SHOULD abort in that case, I
think we should also explicitly call out that servers without EMS support
MUST NOT resume sessions created with EMS support. This is slightly weird
because EMS-less servers will necessarily predate this specification.

A client has no option to fall back to a full handshake at ServerHello, so
any cases where we want clients to abort, we need to be sure are illegal
for the server to produce. (E.g. EMS-ful resume of EMS-less session is okay
to abort because we can reasonably require that servers fall back to a full
handshake.)

David

On Thu, May 28, 2015 at 7:24 PM Eric Rescorla <[email-masked]> wrote:

> On Wed, May 27, 2015 at 10:43 AM, Martin Thomson <[email-masked]
> > wrote:
>

---

From: "Salz, Rich" <[email-masked]>
Date: Fri, 29 May 2015 18:09:07 +0000

> I poked a bit more and I was mistaken about OpenSSL's d2i_SSL_SESSION behavior: Although it does ignore the structure version, it will fail the parse if it sees elements at the end of the structure it doesn't understand.

We'd like to change this.  Allow applications to append their own data to a session is very useful.

(We is probably my employer submitting patches to OpenSSL which someone on the dev team like me will review.()

	/r$

---

From: David Benjamin <[email-masked]>
Date: Fri, 29 May 2015 18:14:29 +0000

On Fri, May 29, 2015 at 2:09 PM Salz, Rich <[email-masked]> wrote:

> parse if it sees elements at the end of the structure it doesn't understand.
>

This is somewhat tangential, but this seems a bad idea. Having applications
squat the same namespace of tag numbers as OpenSSL will break when OpenSSL
internally adds more fields to the end. If you want applications-specific
data in the session, either the application should serialize and
deserialize a wrapper structure that happens to contain a serialized
SSL_SESSION, or explicitly introduce an OCTET STRING hole to stuff opaque
application-specific data into.

David

---

From: David Benjamin <[email-masked]>
Date: Fri, 29 May 2015 18:16:13 +0000

On Fri, May 29, 2015 at 2:14 PM David Benjamin <[email-masked]>
wrote:

> This is somewhat tangential, but this seems a bad idea. Having
> applications squat the same namespace of tag numbers as OpenSSL will break
> when OpenSSL internally adds more fields to the end. If you want
> applications-specific data in the session, either the application should
> serialize and deserialize a wrapper structure that happens to contain a
> serialized SSL_SESSION, or explicitly introduce an OCTET STRING hole to
> stuff opaque application-specific data into.
>

(Not to mention the obvious bad consequences, such as the one discussed in
this thread, if an older OpenSSL happily parses an SSL_SESSION with fields
it doesn't understand from a new OpenSSL.)

David