Subject: Re: [TLS] 0-RTT encrypted data limits

From: Hubert Kario <[email-masked]>
Date: Thu, 01 Sep 2016 12:31:49 +0200

On Wednesday, 31 August 2016 11:23:11 CEST Eric Rescorla wrote:
> On Wed, Aug 31, 2016 at 11:14 AM, Hubert Kario <[email-masked]> wrote:
> > Current draft has the following text in it:
> >     If any of these checks fail, the server MUST NOT respond
> >     with the extension and must discard all the remaining first
> >     flight data (thus falling back to 1-RTT). If the client attempts
> >     a 0-RTT handshake but the server rejects it, it will generally
> >     not have the 0-RTT record protection keys and must instead
> >     trial decrypt each record with the 1-RTT handshake keys
> >     until it finds one that decrypts properly, and then pick up
> >     the handshake from that point.
> > 
> > My understanding of that, in case client does 0-RTT but server rejects it
> > (because the PSK is too old or its time is different enough) is that the
> > server needs to keep on reading arbitrarily large amounts of data it has
> > no
> > idea what to do with
> > 
> > Why is there no limit on the amount of data that can be encrypted using
> > PSK keys (0-RTT)?
> 
> I don't think this would usefully improve things.

there's also second angle:

I'm afraid that requiring the server to keep the connection open for 
essentially arbitrary amount of time while it consumes garbage data is not 
unlike the Apache slowloris attack.
-- 
Regards,
Hubert Kario
Senior Quality Engineer, QE BaseOS Security team
Web: www.cz.redhat.com
Red Hat Czech s.r.o., Purkyňova 99/71, 612 45, Brno, Czech Republic

---

From: Eric Rescorla <[email-masked]>
Date: Thu, 1 Sep 2016 05:48:02 -0700

> unlike the Apache slowloris attack.

It's not required to. It can close the connection at any time.

-Ekr

--

---

From: Hubert Kario <[email-masked]>
Date: Thu, 01 Sep 2016 15:09:10 +0200

On Thursday, 1 September 2016 05:48:02 CEST Eric Rescorla wrote:
> > > On Wed, Aug 31, 2016 at 11:14 AM, Hubert Kario <[email-masked]>
> > 
> > wrote:
> > > > My understanding of that, in case client does 0-RTT but server rejects
> > 
> > it
> > 
> > > > (because the PSK is too old or its time is different enough) is that
> > 
> > the
> > 
> > > > server needs to keep on reading arbitrarily large amounts of data it
> > 
> > has
> > 
> > > > no
> > > > idea what to do with
> > > > 

Then how about making it explicit by including following paragraph:

    To protect against denial of service attacks, servers MAY close the 
    connection at any point when processing records with
    trial decryption, but SHOULD process at least four records before doing 
    so. This is so that server can find the second Finished message in case 
    client sent just one record of Application Data.

---

From: Ilari Liusvaara <[email-masked]>
Date: Thu, 1 Sep 2016 16:15:21 +0300

> It's not required to. It can close the connection at any time.

Should there be recommendation for clients to cut transfer and send
Finished if the client receives EncryptedExtensions without
early_data extension?

-Ilari

---

From: Eric Rescorla <[email-masked]>
Date: Thu, 1 Sep 2016 06:45:29 -0700

> Finished if the client receives EncryptedExtensions without

I thought that was implicit, but i'd take a PR that did that.

-Ekr

---

From: David Benjamin <[email-masked]>
Date: Thu, 01 Sep 2016 14:29:00 +0000

> I thought that was implicit, but i'd take a PR that did that.

(s/EncryptedExtensions/ServerHello/, but whatever.)

At this point the client must do much more than cut transfer anyway. It
probably should be phrased as starting over and retrying or so. Everything
sent has been rejected and all you thought you knew about the connection
may have changed, like ALPN. At sufficiently high layers, you should
probably just pretend you got a fresh connection and are repeating the
request (or whatever) from scratch.

In the general case, you may even need to bounce to a new connection.
Consider if our session was established with h2, we try to 0-RTT-resume it,
send 20 replayable HTTP requests across it... and only then to hear from
server, "Nope, no 0-RTT for you, try again. Oh, by the way, we're talking
http/1.1 now." At least 19 of those 20 requests must get fresh connections
anyway.

David

---

From: Ilari Liusvaara <[email-masked]>
Date: Thu, 1 Sep 2016 18:22:03 +0300

> (s/EncryptedExtensions/ServerHello/, but whatever.)

According to the table it is EncryptedExtensions (but there have been
errors in it before)...
 
> request (or whatever) from scratch.

So server is supposed to continue on 0-RTT fail, but not client?

-Ilari

---

From: Eric Rescorla <[email-masked]>
Date: Thu, 1 Sep 2016 08:25:11 -0700

> According to the table it is EncryptedExtensions (but there have been

It goes in EE, because it should be encrypted.

> So server is supposed to continue on 0-RTT fail, but not client?

There are plenty of scenarios where the client can continue. For instance,
if the server has forgotten the ticket but is otherwise unchanged.

-Ekr

---

From: David Benjamin <[email-masked]>
Date: Thu, 01 Sep 2016 15:46:20 +0000

> It goes in EE, because it should be encrypted.

Hrm. Most of the text currently says ServerHello, except for the table
which says EncryptedExtensions.

ServerHello:
https://tlswg.github.io/tls13-spec/#rfc.section.4.2.6
https://tlswg.github.io/tls13-spec/#rfc.section.2.3

EncryptedExtensions:
https://tlswg.github.io/tls13-spec/#rfc.section.10

I'm a little wary of putting something that tells you the handshake "shape"
in EncryptedExtensions. Accepting early_data comes with a host of
constraints  the client must enforce like ALPN not being allowed to change,
etc. But I think all the current constraints are with EncryptedExtensions,
so maybe it's fine?

(The failure mode for getting this wrong is a risk of serious
implementation complexity and bugs, similar to why client
EncryptedExtensions was a problem. E.g. if ALPN were in SH but early_data
in EE , there would be a window of time where we have a new ALPN but aren't
sure if it's a 0-RTT reject or fatal error. It makes things a mess.)

> if the server has forgotten the ticket but is otherwise unchanged.

Right, I mean it's a logical starting over. I imagine most cases one can
keep affinity with the old transport socket just fine, but data does likely
need to be reset. (Although in some cases you can't.)

David

---

From: Eric Rescorla <[email-masked]>
Date: Thu, 1 Sep 2016 09:01:27 -0700

On Thu, Sep 1, 2016 at 8:46 AM, David Benjamin <[email-masked]>
wrote:

>> On Thu, Sep 1, 2016 at 8:22 AM, Ilari Liusvaara <[email-masked]
>> > wrote:
>>
> I'm a little wary of putting something that tells you the handshake
> "shape" in EncryptedExtensions. Accepting early_data comes with a host of

ALPN is also in EE. My general principle was that only things that were
required
to decrypt the handshake messages should be in SH. Arguably, btw, this means
that Server.signature_algorithms should be in EE, but I chickened out.

-Ekr

---

From: Ilari Liusvaara <[email-masked]>
Date: Thu, 1 Sep 2016 19:20:41 +0300

> that Server.signature_algorithms should be in EE, but I chickened out.

What the server.signature_algorithms is about BTW? To me, it looks like
a footgun if used outside PSK mode (anonymous connections?) and not
expressive enough (what are the semantics of authentication?) if used
with PSK mode.

-Ilari

---

From: Martin Thomson <[email-masked]>
Date: Fri, 9 Sep 2016 12:45:27 +1000

> I thought that was implicit, but i'd take a PR that did that.

Note that this is something you might want to do with
HelloRetryRequest as well (my drafty implementation in NSS cuts off
0-RTT at that point as well).