Subject: [TLS] 0-RTT, server Application Data, and client Finished

From: David Benjamin <[email-masked]>
Date: Wed, 27 Jan 2016 00:46:13 +0000

It's possible I'm reading the draft wrong, so this thread may be a very
short one.

(t here is in units of RTT, so t=0 is when the client sends ClientHello and
t=0.5 is when the server receives ClientHello and sends ServerHello, t=1 is
when the client receives ServerHello, etc.)

Looking at the Zero-RTT exchange here:
https://tlswg.github.io/tls13-spec/#rfc.section.6.2.2

Is the intention that the client, even in the successful 0-RTT case, send
two Finished messages (one at t=0 and one at t=1) and that the server not
send application data until receiving the second of these at t=1.5? If so,
does this not defeat the purpose of 0-RTT? Although the client now eagerly
sends at t=0, it will not see the response until t=2, which is no better
than the resumption case (in TLS 1.2 or 1.3) where the client doesn't send
until t=1.

David

---

From: Martin Thomson <[email-masked]>
Date: Wed, 27 Jan 2016 12:28:23 +1100

This is in part why I created: https://github.com/tlswg/tls13-spec/pull/402

My understanding is that the server is able to send any data that does
not depend on client authentication at t=0.5 and any data that depends
on client authentication at either t=0.5 if it successfully consumes
the client authentication in the 0-RTT flight, or t=1.5 failing that.

On 27 January 2016 at 11:46, David Benjamin <[email-masked]> wrote:
> _______________________________________________
> TLS mailing list
> [email-masked]
> https://www.ietf.org/mailman/listinfo/tls
>

---

From: David Benjamin <[email-masked]>
Date: Wed, 27 Jan 2016 01:58:40 +0000

On Tue, Jan 26, 2016 at 8:28 PM Martin Thomson <[email-masked]>
wrote:

> This is in part why I created:
> https://github.com/tlswg/tls13-spec/pull/402

Ah, great. And indeed there is a paragraph I missed:
"""
At this point, the handshake is complete, and the client and server may
exchange application layer data. Application data MUST NOT be sent prior to
sending the Finished message. Note that while the server may send
application data prior to receiving the client’s Authentication messages,
any data sent at that point is of course being sent to an unauthenticated
peer.
"""

In addition to the diagram, there's also some text in 6.3.4.3 which
somewhat contradicts this (that's the paragraph I was going off of in
writing this mail):
"""
[...] Once a side has sent its Finished message and received and validated
the Finished message from its peer, it may begin to send and receive
application data over the connection. This data will be protected under
keys derived from the ephemeral secret (see Section 7).
"""

> the client authentication in the 0-RTT flight, or t=1.5 failing that.

This seems unnecessarily complicated and invites all the context-switching
problems of mid-stream client auth in even more situations.

If the server needs to send a CertificateRequest (i.e. the client
mispredicted the 0-RTT Certificate/CertificateVerify) but otherwise has a
0-RTT hit, have it reject 0-RTT altogether. The 0-RTT is already all but
useless because the first authenticated byte of the response is delayed to
t=1.5. We should just say that 0-RTT accept + CertificateRequest is
forbidden.

If one really wants to, a la mid-stream[*] auth, send unauthenticated bytes
at t=0.5 and then authenticated bytes at t=1.5, one could just as easily
use mid-stream auth itself. The server accepts the 0-RTT without a
CertificateRequest and, at t=0.5, sends the unauthenticated bytes followed
by a mid-stream CertificateRequest. At t=1, the client processes the
unauthenticated bytes, sees a mid-stream CertificateRequest, authenticates,
which the server receives at t=1.5, sends authenticated bytes, received by
the client at t=2. The same data arrives at the same times and we don't
increase the state-space.

David

[*] Mid-stream auth is a serious regression, and I am not endorsing it in
any way. But supposing it exists for the purposes of this thread...

---

From: Martin Thomson <[email-masked]>
Date: Wed, 27 Jan 2016 13:11:56 +1100

> t=1.5. We should just say that 0-RTT accept + CertificateRequest is

I believe that is a choice that an implementation could make, rather
than have a stipulation in a spec.  You are free to simplify in your
implementation as much as you like.

Refusing 0-RTT and delaying the "completion" of a handshake if you
find that you need to send a CertificateRequest (either because you
don't have 0-RTT client auth or the 0-RTT client auth is
bad/indecipherable) is a pretty good choice.  I might even be happy to
recommend it to others.  But do you have a security property you are
looking to preserve?  Because otherwise, I think that I might take the
optimization.

---

From: David Benjamin <[email-masked]>
Date: Wed, 27 Jan 2016 03:11:05 +0000

> looking to preserve?  Because otherwise, I think that I might take the

Why do you say it's an optimization? They're exactly the same except the
simplified one reduces to normal 0-RTT + mid-stream CertificateRequest (a
combination that's possible with or without my restriction) and the other
is a brand new handshake flow to worry about.

Original:
t = 0  Client sends ClientHello to server with 0-RTT data.
t = 0.5 Server acks 0-RTT in ServerHello, adds a CertificateRequest in the
middle, sends Finished (and messages in between).
t = 0.5 Server sends unauthenticated application data.
t = 1 Client receives CertificateRequest, sends Certificate,
CertificateVerify, Finished
t = 1 Client receives unauthenticated application data
t = 1.5 Server receives Certificate, etc., sends authenticated application
data.
t = 2 Client receives authenticated application data.

Simplified:
t = 0  Client sends ClientHello to server with 0-RTT data.
t = 0.5 Server acks 0-RTT ServerHello, sends Finished (and messages in
between)
t = 0.5 Server sends mid-stream CertificateRequest
t = 0.5 Server sends unauthenticated application data
t = 1 Client sends Finished
t = 1 Client receives mid-stream CertificateRequest, sends mid-stream
Certificate, CertificateVerify
t = 1 Client receives unauthenticated application data
t = 1.5 Server receives mid-stream Certificate, etc., sends authenticated
application data.
t = 2 Client receives authenticated application data.

I believe all that changes is CertificateRequest now comes after Finished
on the server and Finished comes before Certificate on the client.

But this way we cut down on the state space. Even if servers are sensible
enough to act this way, clients must still accept it if it's in the
protocol. That's more cases that everyone must write tests for (BoringSSL
has a pretty extensive battery of tests and I intend to continue this
practice) and think about in analyzing the protocol.

David

---

From: Martin Thomson <[email-masked]>
Date: Wed, 27 Jan 2016 14:32:32 +1100

On 27 January 2016 at 14:11, David Benjamin <[email-masked]> wrote:
> combination that's possible with or without my restriction) and the other is
> a brand new handshake flow to worry about.

I get your point, but I don't see that as a simplification.  In my
mind, post-handshake client authentication doesn't happen.  Or, I
don't see it being commonplace.

---

From: Bill Cox <[email-masked]>
Date: Wed, 27 Jan 2016 06:12:38 -0800

> don't see it being commonplace.

The use case described to me was for a higher level of authentication, such
as when accessing a source-code repository at work, similar to proving that
you still possess a security key now and then.  I am not sure why FIDO does
not fit this use case better, though.  I have a feeling this is a legacy
use case of client certificates, and is being included to avoid having to
transition a lot of legacy client-cert based systems to FIDO.

The CertificateVerify message is still listed as an option in the 0-RTT
client's first flight at t = 0.  Is this a mistake?  I have not heard that
anyone wants to do this, as there is no possibility of a traditional
proof-of-possession in the first flight.  However, with QUIC-like strike
registers, a reasonably accurate timestamp in the handshake, and a secure
clock on the client, you can approximate a proof-of-possession.  This seems
like a lot of trouble for a first-flight CertificateVerify, but if someone
wants to do this, it could stay in the spec.  If CertficateVerify is to
remain in the 0-RTT first flight, there needs to be some way to provide a
timestamp in the handshake hash.  Is there a way to do this now?  The TLS
1.2 timestamp in the client random seems to have been removed.

Bill

---

From: Watson Ladd <[email-masked]>
Date: Wed, 27 Jan 2016 07:09:01 -0800

On Wed, Jan 27, 2016 at 6:12 AM, Bill Cox <[email-masked]> wrote:
> not fit this use case better, though.  I have a feeling this is a legacy use
> case of client certificates, and is being included to avoid having to

All certificate based authentication over HTTP is currently done by
renegotiation, when the client chooses to access a protected resource
a Renegotiation Request is sent, leading to the client certificate
being provided in the second handshake. It's true that FIDO will be a
better solution (currently unfinished), but when changing TLS stacks
to work with TLS 1.3 we need to support this case, without requiring
changes to application code below this.

> 1.2 timestamp in the client random seems to have been removed.

All 0-RTT data is replayable, but I don't see what replaying a
authenticated replayable connection gets you.

-- 
"Man is born free, but everywhere he is in chains".
--Rousseau.

---

From: Bill Cox <[email-masked]>
Date: Wed, 27 Jan 2016 08:13:11 -0800

> changes to application code below this.

Thanks for the explanation.  That makes sense.

> authenticated replayable connection gets you.

I do not either.  However, a 0-RTT CertificateVerify from the client is not
as secure as a regular CertificateVerify.  I doubt anyone has a use case
for it in the near-term, and with FIDO coming in the future, I would
recommend removing it from the 0-RTT first-flight diagram.

There, did I actually suggest something useful for TLS 1.3?  It will make
my day if so... :)

Bill

---

From: Martin Thomson <[email-masked]>
Date: Thu, 28 Jan 2016 04:45:00 +1100

> authenticated replayable connection gets you.

If the 0-RTT flight includes actions (especially non-idempotent ones)
that only apply if the authentication is correct, then you get
authenticated replayable actions.

e.g., "please pay Watson $10, my certificate authenticates this request"

---

From: Watson Ladd <[email-masked]>
Date: Wed, 27 Jan 2016 09:58:27 -0800

> e.g., "please pay Watson $10, my certificate authenticates this request"

We already know non-idempotent actions cannot be put into 0 RTT.

---

From: "Salz, Rich" <[email-masked]>
Date: Wed, 27 Jan 2016 18:00:20 +0000

s/cannot/should not/  This might help prevent problems.  Might.  I don't know if it's worth it.

---

From: Andrei Popov <[email-masked]>
Date: Wed, 27 Jan 2016 18:38:36 +0000

Ø  The CertificateVerify message is still listed as an option in the 0-RTT client's first flight at t = 0.  Is this a mistake?  I have not heard that anyone wants to do this, as there is no possibility of a traditional proof-of-possession in the first flight.
I agree with this: client auth in 0-RTT is replayable, unless the server takes extraordinary steps (QUIC-like strike registers, database of client nonces, etc.) No plans to implement, at least for now.

Cheers,

Andrei

From: TLS [mailto:[email-masked]] On Behalf Of Bill Cox
Sent: Wednesday, January 27, 2016 6:13 AM
To: Martin Thomson <[email-masked]>
Cc: [email-masked]
Subject: Re: [TLS] 0-RTT, server Application Data, and client Finished

On Tue, Jan 26, 2016 at 7:32 PM, Martin Thomson <[email-masked]<mailto:[email-masked]>> wrote:

The use case described to me was for a higher level of authentication, such as when accessing a source-code repository at work, similar to proving that you still possess a security key now and then.  I am not sure why FIDO does not fit this use case better, though.  I have a feeling this is a legacy use case of client certificates, and is being included to avoid having to transition a lot of legacy client-cert based systems to FIDO.

The CertificateVerify message is still listed as an option in the 0-RTT client's first flight at t = 0.  Is this a mistake?  I have not heard that anyone wants to do this, as there is no possibility of a traditional proof-of-possession in the first flight.  However, with QUIC-like strike registers, a reasonably accurate timestamp in the handshake, and a secure clock on the client, you can approximate a proof-of-possession.  This seems like a lot of trouble for a first-flight CertificateVerify, but if someone wants to do this, it could stay in the spec.  If CertficateVerify is to remain in the 0-RTT first flight, there needs to be some way to provide a timestamp in the handshake hash.  Is there a way to do this now?  The TLS 1.2 timestamp in the client random seems to have been removed.

Bill

---

From: Yoav Nir <[email-masked]>
Date: Wed, 27 Jan 2016 21:09:53 +0200

> On 27 Jan 2016, at 8:38 PM, Andrei Popov <[email-masked]> wrote:
> 

To clarify: by “no plans to implement”, do you mean no plans to implement 0-RTT, or no plans to implement client authentication with 0-RTT?

Thanks

Yoav

---

From: David Benjamin <[email-masked]>
Date: Wed, 27 Jan 2016 19:28:47 +0000

> don't see it being commonplace.

I certainly hope it doesn't become commonplace either! :-)

But the only cases where this flow is useful (server sends non-zero
unauthenticated bytes at t=0.5 before the authenticated bytes at t=1.5) has
all the same pitfalls of mid-stream auth (specifically that the stream's
authentication switches partway through), so I don't see what avoiding
mid-stream auth is supposed to gain.

David

---

From: Ilari Liusvaara <[email-masked]>
Date: Wed, 27 Jan 2016 21:44:17 +0200

> mid-stream auth is supposed to gain.

I don't think the two situations have the same problems:
- "Server 0-RTT" has _recipient_ identity change.
- "Dynamic reauth" has _sender_ identity change.

You have more concrete examples of things going wrong with "server
0-RTT"? Because I have major problems coming up with troublesome
cases.

-Ilari

---

From: Andrei Popov <[email-masked]>
Date: Wed, 27 Jan 2016 20:13:28 +0000

No plans to implement client auth in 0-th RTT.

Cheers,

Andrei

From: Yoav Nir [mailto:[email-masked]]
Sent: Wednesday, January 27, 2016 11:10 AM
To: Andrei Popov <[email-masked]>
Cc: Bill Cox <[email-masked]>; Martin Thomson <[email-masked]>; [email-masked]
Subject: Re: [TLS] 0-RTT, server Application Data, and client Finished

On 27 Jan 2016, at 8:38 PM, Andrei Popov <[email-masked]<mailto:[email-masked]>> wrote:

>  The CertificateVerify message is still listed as an option in the 0-RTT client's first flight at t = 0.  Is this a mistake?  I have not heard that anyone wants to do this, as there is no possibility of a traditional proof-of-possession in the first flight.

Thanks

Yoav

---

From: David Benjamin <[email-masked]>
Date: Thu, 28 Jan 2016 17:36:22 +0000

> 0-RTT"? Because I have major problems coming up with troublesome

The client also has some 0-RTT data which, in the server 0-RTT case, the
server reports was accepted and processed. That all is associated with the
first identity rather than the second. So I believe we have sender identity
change in both cases.

David

---

From: Ilari Liusvaara <[email-masked]>
Date: Thu, 28 Jan 2016 21:09:09 +0200

> first identity rather than the second. So I believe we have sender identity

The 0-RTT being sent under different identity than the application data
does involve sending identity change, but what does it have to do with
"server 0-RTT"? The client could do that (and run into trouble with
badly designed protocols) without "server 0-RTT".

-Ilari

---

From: David Benjamin <[email-masked]>
Date: Fri, 29 Jan 2016 19:55:53 +0000

> badly designed protocols) without "server 0-RTT".

Perhaps I misunderstood you. I read "dynamic reauth" in your message above
as the post-handshake auth mechanism. You said that "server 0-RTT" has
recipient identity change and "dynamic reauth" has sender identity change.
My claim is that "server 0-RTT" also has sender identity change, since that
seemed to be the question you were asking. Did you mean something else?

Yes, by forbidding CertificateRequest on 0-RTT hit, we are not removing
anything post-handshake auth can't do. That's largely my point. It is
identical in both how it works in good or bad) and how early each message
arrives (see https://www.ietf.org/mail-archive/web/tls/current/msg19159.html
for
comparison).

I hope the more reasonable protocols without legacy burdens will declare
that post-handshake auth is forbidden and only allow initial-handshake
client auth or none at all, as SPDY and HTTP/2[*] did to renego in TLS 1.2.
Yet it's not obvious CertificateRequest on a 0-RTT hit is equivalent to
post-handshake auth and should be allowed or forbidden together.

Also, although servers can choose never to do this, clients that implement
post-handshake auth (like HTTP apparently) can't. This figures into the
client API the TLS stack exposes. Despite being in the handshake, this flow
should be exposed via post-handshake auth's API. This is weird, but
handshake-negotiated properties otherwise have nice assumptions like being
constant throughout the connection, should the client's stream depend on
it. Consider ALPN. If a server wishes to pick a different ALPN value from
the 0-RTT-predicted one, it must reject 0-RTT because that data's wrong
anyway. I think the same should be true of in-handshake client auth.

Since there is zero benefit to a using this handshake flow over already
existing alternative (this handshake flow is not an optimization), I don't
see how it can be worth this (or any) complexity.

David

[*] Sadly, HTTP's legacy burdens caught up to us. Although I see
draft-thomson-http2-client-certs-01 has picked up again, so maybe HTTP/2
won't use post-handshake auth? Doesn't matter; new multiplexed protocol
without such legacy would best forbid post-handshake auth.

---

From: Ilari Liusvaara <[email-masked]>
Date: Fri, 29 Jan 2016 22:52:55 +0200

> seemed to be the question you were asking. Did you mean something else?

No, it doesn't: The server auth block comes before the data sent, and this
block authenticates the sender (which is the server).
 
> for comparison).

Also, there are some subtle attacks on TLS that only fail on client
Finished, so client auth block is needed.

> post-handshake auth and should be allowed or forbidden together.

That actually also depends on what kind of data is sent in 0-RTT. Some
protocols might be unsafe in general case, but have restricted subset
that is safe in 0-RTT.

E.g. protocol banners (e.g. HTTP/2 prelude/SETTINGS) are in general safe.
HTTP/2 also has other stuff that could be sent (e.g. preflights or
any requests with user privilege).

Or protocol could say that anything in 0-RTT is permanently locked
to authority it was sent with (including possibly anonymous authority).
IIRC, 0-RTT data is explicitly distinct from normal data.

> anyway. I think the same should be true of in-handshake client auth.

IIRC, there is no indication of assumed ALPN for 0-RTT...

Also, 0-RTT data is also separate on client side. So in-handshake
1RTT auth is quite different for client than post-handshake auth.

Also, I think there should be a way for client to request Certificate-
Request, even without valid configuration. This is needed for M2M
applications (and some interactive protocols as well).

> without such legacy would best forbid post-handshake auth.

Well, considering that they have no choice with TLS 1.2, I presume
they will also go that way with TLS 1.3.

-Ilari