Subject: Re: [Unbearable] 0-RTT Token Binding: When to switch exporters?

From: Nick Harper <[email-masked]>
Date: Tue, 7 Feb 2017 16:35:56 -0800

I've been thinking about this approach for a while (and what it would take
to implement it), and I've come to the conclusion that requiring switching
exporters to match the switch of encryption keys is infeasible enough that
it won't get implemented.

Instead, I propose that if a server accepts the client's 0-RTT data, then
the client uses the 0-RTT exporter for the entirety of the connection, and
otherwise the client uses the exporter as already specified in TBPROTO.
This still has decent security properties.

First, consider a server that is uncomfortable enough with the early
exporter that it does not want to accept any token bindings that use that
exporter. This server rejects all early data on connections where the
client tries to negotiate token binding, and falls back on using the
existing exporter in TBPROTO with no early data.

Next, consider a server that does accept some requests sent in early data
with a token binding that used the early exporter (the only choice in a
request in early data). For this request, since the server accepted it, it
has decided that the early exporter provides enough security to verify the
binding (otherwise this server would be in the above category). If the
early exporter was good enough for this server on a request sent in early
data, then surely that server would accept the same request (with the same
token binding) when sent under the forward-secure encryption keys.

A server accepting early data should accept any request sent in early data.
The server can't sniff the early data to reject it if it contains a request
it doesn't like (e.g. a POST request), because the early data could contain
multiple requests (e.g. in the case of HTTP/2), and the server MUST process
the ClientHello and immediately send the ServerHello - it cannot wait to
process all of the client's early data. It follows that if a server will
accept a token-bound request in early data, then it will accept any
token-bound request in early data, meaning that the server finds the early
exporter used for the token binding acceptable no matter the request. If
the server is fine with the early exporter for every request, then it
should accept the early exporter when it is used for requests not sent in
early data as well. In other words, if the server does not want to allow
the early exporter to be used for token bindings on some requests, then the
only logical thing for that server to do is always reject early data if
token binding is negotiated.

On Fri, Jan 13, 2017 at 2:18 PM, Andrei Popov <[email-masked]>
wrote:

> Ø  Another way to move the change in exporters out of the client's
> control would be to do it at a time that is implicit in the protocol. An
> obvious choice would be switch exporters when the client switches from
> sending early data to sending data post-handshake.
>
> I think this type of approach is better.
>
>
>
> Cheers,
>
>
>
> Andrei
>
>
>
> *From:* Unbearable [mailto:[email-masked]] *On Behalf Of *Nick
> Harper
> *Sent:* Friday, January 13, 2017 12:30 PM
> *To:* IETF Tokbind WG <[email-masked]>
> *Subject:* [Unbearable] 0-RTT Token Binding: When to switch exporters?
>
>
>
> The current tokbind 0-RTT draft has the TLS 1.3 early exporter value used
> in the TokenBinding.signature for the entirety of the connection. One point
> of discussion that came up in Seoul was that we shouldn't use the 0-RTT
> exporter for too long. I agree that we shouldn't use it for too long, but I
> can't remember (or figure out from the meeting notes) if the reason is just
> because we prefer the crypto properties of the normal exporter, or are we
> also trying to prevent an attacker from being able to use the 0-RTT
> exporter indefinitely?
>
>
>
> For the first case, the switch from the 0-RTT exporter to the normal
> exporter can be client-initiated. One possible design would be to have the
> client send an extension in the TokenBinding indicating that all future
> TokenBindings will use the normal exporter. This would function similar to
> the ratcheting idea (from section 4.1 of the I-D), but the ratchet doesn't
> take effect until this indicator extension is sent (before it's sent the
> server would accept both exporters). This would likely be done in
> combination with the idea of defining new key types to indicate that the
> 0-RTT exporter is in use so the server doesn't do trial verification.
>
>
>
> If we want to move the switch from 0-RTT exporter to normal exporter out
> of the client's control (so that an attacker can't keep using the 0-RTT
> exporter indefinitely), a different solution is needed. One possible idea
> is to have the server send a message that conceptually means "all future
> TokenBindings must not use the 0-RTT exporter". Right now, Token Binding
> doesn't have any server-to-client messages, so this would require defining
> application-specific messages. Another way to move the change in exporters
> out of the client's control would be to do it at a time that is implicit in
> the protocol. An obvious choice would be switch exporters when the client
> switches from sending early data to sending data post-handshake.
>

---

From: Nick Harper <[email-masked]>
Date: Mon, 27 Feb 2017 14:42:43 -0800

Hearing no objections to this approach, I'll update the I-D for Chicago.

On Tue, Feb 7, 2017 at 4:35 PM, Nick Harper <[email-masked]> wrote:

> A server accepting early data should accept any request sent in early
> data. The server can't sniff the early data to reject it if it contains a
> request it doesn't like (e.g. a POST request), because the early data could
> contain multiple requests (e.g. in the case of HTTP/2), and the server MUST
> process the ClientHello and immediately send the ServerHello - it cannot
> wait to process all of the client's early data. It follows that if a server
> will accept a token-bound request in early data, then it will accept any

---

From: Andrei Popov <[email-masked]>
Date: Tue, 28 Feb 2017 18:46:35 +0000

Hi Nick,

Ø  Instead, I propose that if a server accepts the client's 0-RTT data, then the client uses the 0-RTT exporter for the entirety of the connection, and otherwise the client uses the exporter as already specified in TBPROTO. This still has decent security properties.
My understanding is that an attacker who has a stolen bound token and TLS “Early Secret” (but not the corresponding TB private key), can successfully replay this token, alongside the attacker’s HTTP request, to a server that allows TLS 1.3 0-RTT. This type of replay is possible from multiple machines, for as long as the server is willing to accept 0-RTT connections based on the same TLS “Early Secret”. Is this correct?

And this is of course in addition to a network attacker being able to replay a legitimate client’s request without change (no stealing of tokens or secrets required), unless the server takes extraordinary steps to prevent 0-RTT replay.

Ø  A server accepting early data should accept any request sent in early data. The server can't sniff the early data to reject it if it contains a request it doesn't like (e.g. a POST request), because the early data could contain multiple requests (e.g. in the case of HTTP/2), and the server MUST process the ClientHello and immediately send the ServerHello - it cannot wait to process all of the client's early data.
From the fact that the server sends the ServerHello after processing ClientHello, it does not follow that the server will accept every request sent as early data. The server can very well reject certain requests and/or terminate the handshake at any stage.

Cheers,

Andrei

---

From: Nick Harper <[email-masked]>
Date: Tue, 28 Feb 2017 11:52:45 -0800

On Tue, Feb 28, 2017 at 10:46 AM, Andrei Popov <[email-masked]>
wrote:

> Hi Nick,
>
>
>
> Ø  Instead, I propose that if a server accepts the client's 0-RTT data,
> then the client uses the 0-RTT exporter for the entirety of the connection,
> and otherwise the client uses the exporter as already specified in TBPROTO.
> My understanding is that an attacker who has a stolen bound token and TLS
> “Early Secret” (but not the corresponding TB private key), can successfully
> replay this token, alongside the attacker’s HTTP request, to a server that
> allows TLS 1.3 0-RTT. This type of replay is possible from multiple
> machines, for as long as the server is willing to accept 0-RTT connections
> based on the same TLS “Early Secret”. Is this correct?
>
>
>
> And this is of course in addition to a network attacker being able to
> replay a legitimate client’s request without change (no stealing of tokens
> or secrets required), unless the server takes extraordinary steps to
> prevent 0-RTT replay.
>

The attacker needs more than just the TLS "Early Secret". The attacker
needs the resumption PSK (effectively the Early Secret), but also the
ClientHello used for a 0-RTT connection and the Sec-Token-Binding header
sent on that 0-RTT connection. The attacker can then replay the stolen
bound token from that connection with the Sec-Token-Binding header on a new
connection that uses the same ClientHello, and an attacker-chosen HTTP
request. This replay is possible for as long as the server will accept that
specific ClientHello (which can be shorter than how long that server will
accept that resumption PSK, because the ClientHello includes the ticket age
when sending early data, and section 4.2.7 of tls13 says that the server
MUST validate that the ticket age is in a small tolerance of the time since
it was issued). I believe this is covered in section 6.2 of
https://tools.ietf.org/html/draft-ietf-tokbind-tls13-0rtt-00, and would be
happy to expand on that section to make things clearer. This is all in
addition to a network attacker being able to replay a 0-RTT request without
changing it.

This replay of a Sec-Token-Binding header for a 0-RTT request exists
regardless of when the client switches from the 0-RTT exporter to the
normal exporter (assuming that the server will accept the combination of
0-RTT + TB at all).

>
>
> Ø  A server accepting early data should accept any request sent in early
> wait to process all of the client's early data.
>
> From the fact that the server sends the ServerHello after processing
> ClientHello, it does not follow that the server will accept every request
> sent as early data. The server can very well reject certain requests and/or
> terminate the handshake at any stage.
>

The server chooses whether or not to accept early data before it reads that
early data. This is the fact that I use to conclude that the server will
accept in early data any request. The server certainly could terminate the
handshake at any stage, but then it doesn't matter how we would do Token
Binding on that connection, because the connection is no more. TLS 1.3
doesn't provide any mechanism for a server to say "I don't like that that
request was sent in early data, please send it again now that the handshake
is complete", and I'm not aware of any application layer specs (e.g. HTTP)
that have such a mechanism. That's how I reached the conclusion that the
server won't reject some requests sent in early data.

---

From: Andrei Popov <[email-masked]>
Date: Tue, 28 Feb 2017 20:55:34 +0000

Ø  The attacker needs more than just the TLS "Early Secret". The attacker needs the resumption PSK (effectively the Early Secret), but also the ClientHello used for a 0-RTT connection and the Sec-Token-Binding header sent on that 0-RTT connection.
Correct, the ClientHello is also needed. Not sure this makes things significantly better, but it is an additional piece the attacker needs. I guess we’re referring to the same attack, but disagreeing on whether “this still has decent security properties”☺.

Ø  TLS 1.3 doesn't provide any mechanism for a server to say "I don't like that that request was sent in early data, please send it again now that the handshake is complete", and I'm not aware of any application layer specs (e.g. HTTP) that have such a mechanism. That's how I reached the conclusion that the server won't reject some requests sent in early data.
HTTP allows the server to reject individual requests, therefore I disagree with the above logic. E.g. an HTTP server could reject a security-sensitive request authenticated by a replayable token, but accept other requests.

It seems that the right thing to do is not allow Token Binding messages until exporter_secret is available.

Cheers,

Andrei

---

From: Nick Harper <[email-masked]>
Date: Tue, 28 Feb 2017 13:52:50 -0800

On Tue, Feb 28, 2017 at 12:55 PM, Andrei Popov
<[email-masked]> wrote:
> Correct, the ClientHello is also needed. Not sure this makes things
> significantly better, but it is an additional piece the attacker needs. I
> guess we’re referring to the same attack, but disagreeing on whether “this
> still has decent security properties”J.

Yes, it sounds like we're talking about the same attack, and the
additional piece of the ClientHello (in addition to the resumption
PSK) doesn't change its feasibility that much. If we do any form of
0-RTT Token Binding, this attack will exist in some form. It is the
major difference between 0-RTT Token Binding and regular Token
Binding. My comment about "decent security properties" was that always
using the 0-RTT exporter (if there is a token binding sent and
accepted in early data) has decent security properties compared to
using the 0-RTT exporter only for token bindings sent in early data.
> until exporter_secret is available.

That restriction would effectively mean that Token Binding can't be
used with 0-RTT.

---

From: Nick Harper <[email-masked]>
Date: Tue, 28 Feb 2017 14:46:32 -0800

Here's a solution that I think would handle the case of an HTTP server
rejecting a request because it doesn't like the strength of the
exporter used for Token Binding:

- On requests sent in early data, the client uses the early exporter
(it's the only option).
- For requests sent after the handshake has completed, the client MAY
continue to use the early exporter.
- Once the client has received a response from the server, it SHOULD
switch to using the (not early) exporter for new requests on that
connection (requests that the client has already started to build but
haven't sent yet can continue using the early exporter, per the
previous point).
- A server that receives a token-bound request using the early
exporter MAY request that the client re-send the request using the
(not early) exporter. This signal would be application-specific; for
HTTP this could be done by sending a 307 status code with the Location
header pointing to the same URI. A client that implements the SHOULD
in the previous point will switch exporters by the time it re-sends
the request.

This solves the implementation problems of requiring the exporter to
match which data its sent in, and I think it offers a reasonable
solution for a server to reject a request because of exporter strength
and have the client retry it with the regular exporter. This is only
an outline of a solution and still has details that would need to be
worked out. In particular, the client needs to indicate in its
TokenBinding struct which exporter it used or the server has to do
trial verification.

---

From: Andrei Popov <[email-masked]>
Date: Tue, 28 Feb 2017 23:34:55 +0000

>> It seems that the right thing to do is not allow Token Binding 
>> messages until exporter_secret is available.
>

More precisely, this would mean that TB (and bound tokens) cannot be sent as part of 0-RTT data. TB (and bound tokens) could still be used after the server's response, as soon as exporter_secret is available.

---

From: Nick Harper <[email-masked]>
Date: Tue, 28 Feb 2017 17:01:03 -0800

> More precisely, this would mean that TB (and bound tokens) cannot be sent as part of 0-RTT data. TB (and bound tokens) could still be used after the server's response, as soon as exporter_secret is…

The purpose of draft-ietf-tokbind-tls13-0rtt is to allow sending a
bound token (along with a TokenBinding struct to verify the binding)
in 0-RTT data, which that option doesn't allow.

For HTTP, that option would mean a client resuming a connection and
sending 0-RTT data can only send in 0-RTT data requests that have no
cookies (or other potentially bound tokens), which is a very limited
use case.

---

From: Andrei Popov <[email-masked]>
Date: Wed, 1 Mar 2017 01:31:34 +0000

> For HTTP, that option would mean a client resuming a connection and sending 0-RTT data can only send in 0-RTT data requests that have no cookies (or other potentially bound tokens), which is a very limited use case.
Agreed, this is indeed a limited use-case. But so is 0-RTT application data, if one attempts to use it securely.