Subject: [TLS] TLSv1.3 Cookies

From: Matt Caswell <[email-masked]>
Date: Wed, 13 Sep 2017 15:53:46 +0100

I am looking at trying to implement the TLSv1.3 stateless cookie
mechanism (in order to be able to support QUIC stateless retries).

I am not clear how cookies are supposed to interact with early_data.
Consider the scenario where a server is operating statelessly. Because
there is no state each ClientHello looks like the first one it ever
saw. The server only knows that a particular ClientHello is actually a
ClientHello2 following an HRR because of the state held in the cookie.

What happens when a client attempts to send early data to such a
server? The server will process the ClientHello and determine that
there is no cookie, sends back an HRR and then forgets all of its
state and waits for the next ClientHello. However what it actually
gets next is early_data. It does not know that that early data
followed an earlier ClientHello (because it is stateless) so it does
not know to skip the records. It just looks like illegal records so,
presumably, it will respond with an alert.

Should a stateless server silently drop any records that it doesn't understand?

I am also unclear what protects against cookies being replayed. If an
attacker wishes to perform an amplification attack on a particular IP
it awaits a legitimate ClientHello with a cookie coming from that IP
and records it. It then replays that ClientHello with cookie to the
server many times. The cookie looks valid to the server and it
responds with its ServerHello, full Certificate chain etc back to the
original IP. What have I missed here?

Thanks

Matt

---

From: Ilari Liusvaara <[email-masked]>
Date: Wed, 13 Sep 2017 18:09:29 +0300

> ClientHello2 following an HRR because of the state held in the cookie.

Looking at the definitions of Cookie and EarlyData extensions, those
two are mutually exclusive. That is, there can be three kinds of
ClientHello messages:

1) Contains neither Cookie nor EarlyData.
2) Contains an EarlyData, but not Cookie.
3) Contains a Cookie, but not EarlyData.

(This exclusivity arises because Cookie can only be present in a retry,
but EarlyData is stripped out for retry).
 
> presumably, it will respond with an alert.

Yes, if one receives a ClientHello with both Cookie and EarlyData, one
can reply with a fatal alert, because that is not supposed to happen.

There is worse edge case with client key share tho: If a ClientHello
that contains a Cookie does not contain suitable key share, that is an
irrecoverable error, and the only thing server can do is to send a
fatal alert (and hope the client somehow retries the connection setup).

> Should a stateless server silently drop any records that it doesn't understand?

No, records should not be dropped for non-transistent problems, as
doing this causes difficult-to-debug timeouts (the client will retry,
and the retry will be dropped again, repeat until client gives up).

In stateless operation, errors are sent back only once, not
retransmitted if lost.

> original IP. What have I missed here?

The attacker is likely able to inject packets, but not capture packets
(the usual "no BCP38 compliance" case).

-Ilari

---

From: "Short, Todd" <[email-masked]>
Date: Wed, 13 Sep 2017 15:11:29 +0000

One comment below.
--
-Todd Short
// [email-masked]<mailto:[email-masked]>
// "One if by land, two if by sea, three if by the Internet."

On Sep 13, 2017, at 10:53 AM, Matt Caswell <[email-masked]<mailto:[email-masked]>> wrote:

In this case, the client must have previously connected to the server, so it knows what parameters the server supports, and should only use those, preventing an HRR from being generated.

If the client were to send a ClientHello with unsupported server parameters and early data, I would consider this a client error, and an alert should be generated.

Thanks

Matt

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

---

From: Eric Rescorla <[email-masked]>
Date: Wed, 13 Sep 2017 08:12:56 -0700

> presumably, it will respond with an alert.

It seems like there are three cases here:

1. TLS over TCP -- you won't do this statelessly, and so you can know to
dump
early data.
2. DTLS -- you can be stateless, but you don't terminate connections on
decrypt
error, so you just discard the packets as you would any other bogus packet.
3. QUIC -- the data looks like an unknown connection (you have dumped the
conn_id)
so you silently discard.

> original IP. What have I missed here?

Yes. Cookies aren't generally intended to stop that kind of amplification,
they're just designed to prevent blind attacks on IPs you're not on-path
for. Note that QUIC has an additional defense here of requiring that
that ClientInitial be a certain minimum size. Note that if you are on-path
you can still get a lot of amplification even with TCP at the cost of
sending SYN, ACK, ClientHello...

-Ekr

> [email-masked]

---

From: Matt Caswell <[email-masked]>
Date: Wed, 13 Sep 2017 16:24:37 +0100

> can reply with a fatal alert, because that is not supposed to happen.

That isn't quite the scenario I was talking about. Rather your case
(2) above in a server which is operating statelessly, i.e. the client
has attempted to send early_data but has not provided a valid cookie
yet. The early_data when it arrives will look like bad packets, even
though (from the client perspective) it was valid to send them.

It kind of suggests that stateless operation is incompatible with
early_data, i.e. a server should not advertise early_data support in
its tickets if it is going to operate statelessly (because stateless
operation implies an HRR which implies no early_data). There is still
an edge case where a server's configuration has changed (i.e. it used
to operate statefully but now operates statelessly) - in that case a
client might have a valid ticket advertising early_data support which
the server will choke on when it actually receives that early_data.

> fatal alert (and hope the client somehow retries the connection setup).

Well, yes - if it contains a cookie then there must have been an HRR -
so this is a legitimate fatal error.

Matt

---

From: Matt Caswell <[email-masked]>
Date: Wed, 13 Sep 2017 16:32:24 +0100

On 13 September 2017 at 16:11, Short, Todd <[email-masked]> wrote:
> // [email-masked]
> On Sep 13, 2017, at 10:53 AM, Matt Caswell <[email-masked]> wrote:
>
> In this case, the client must have previously connected to the server, so it
> knows what parameters the server supports, and should only use those,
> preventing an HRR from being generated.

Well, that's not the case with a cookie. The server may choose to
request a cookie even though all the rest of the parameters are ok
can't it?

Also what is acceptable to the server may change over time. The ticket
may now be invalid because the configuration has changed etc.

A client may also not know what groups are acceptable to a server even
though it has a ticket, e.g. in the first handshake client sends an
X25519 key_share, server responds with an HRR requesting P-256 and
then the handshake continues to completion. The server is not
obligated to provide supported_groups in its EE message - and even if
it did the client is not obligated to remember it. Therefore it is
perfectly valid in the second handshake for the client to send an
X25519 key_share again along with early_data.

Matt

---

From: Matt Caswell <[email-masked]>
Date: Wed, 13 Sep 2017 16:40:08 +0100

> 3. QUIC -- the data looks like an unknown connection (you have dumped the

Right - well that's the case right now - I guess we don't know how
this feature might be used for in the future?

So in case (3) should this be documented somewhere - either in the
TLSv1.3 spec or the QUIC spec? Perhaps the TLSv1.3 spec should just
state that protocols using the cookie feature should specify how
early_data is to be handled - and then leave it up to QUIC/DTLS to
define the behaviour in each of their cases.

> sending SYN, ACK, ClientHello...

Ok - that makes sense. Perhaps this is worth a note somewhere (not
sure where it would fit).

Matt

---

From: Eric Rescorla <[email-masked]>
Date: Wed, 13 Sep 2017 08:58:23 -0700

> this feature might be used for in the future?

True...

> TLSv1.3 spec or the QUIC spec?

I think it should go in the QUIC spec, because it's QUIC's responsibility
to provide
the transport abstraction to TLS.

> Perhaps the TLSv1.3 spec should just

Generally, I'd prefer to keep this in the other specs, because these are
issues
that arise principally when TLS is embedded in other specs.... If someone
has
a PR, I can take a look, though.

> sure where it would fit).

I filed:
https://github.com/tlswg/tls13-spec/issues/1079

---

From: Ilari Liusvaara <[email-masked]>
Date: Wed, 13 Sep 2017 19:08:45 +0300

> though (from the client perspective) it was valid to send them.

If you really got some transport that uses TLS on something where
stateless operation makes sense (so not TCP) that transports the 0-RTT
TLS data in-band (so not QUIC), just throw any initial records starting
with 0x17 into trash.

AFAIK, QUIC does not use TLS 0-RTT data, it uses 0-RTT exporters to
derive encryption keys for data, that is sent outside TLS. So in
that case, TLS would see two consequtive ClientHello messages if the
first gets rejected.

-Ilari

---

From: Matt Caswell <[email-masked]>
Date: Wed, 13 Sep 2017 17:19:45 +0100

> that case, TLS would see two consequtive ClientHello messages if the

Ah! Right - yes that is a good point. I was looking at this from the
perspective of the need to support QUIC. I had missed that subtlety -
thanks. There is still a theoretical issue if something other than
TLS/TCP or TLS/QUIC wants to do this. But given there is no actual
known use case for that then I guess we can cross that bridge when we
come to it.

Matt