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

From: Nick Harper <[email-masked]>
Date: Wed, 1 Mar 2017 16:39:18 -0800

Does the solution I described upthread (where the client switches
exporters soon after the handshake completes, but not necessarily
immediately after) sound reasonable, or do we still need to discuss
whether we should have any support whatsoever for a
TokenBindingMessage in 0-RTT application data? If there are no
objections to the upthread solution, I'd like to work on fleshing out
the details and revising the I-D.

On Tue, Feb 28, 2017 at 5:31 PM, Andrei Popov
<[email-masked]> wrote:
>> 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.

---

From: Martin Thomson <[email-masked]>
Date: Thu, 2 Mar 2017 11:52:35 +1100

Would it help to include a clear signal about which keys are intended
to be exported and used?

On 2 March 2017 at 11:39, Nick Harper <[email-masked]> wrote:
> _______________________________________________
> Unbearable mailing list
> [email-masked]
> https://www.ietf.org/mailman/listinfo/unbearable

---

From: Andrei Popov <[email-masked]>
Date: Thu, 2 Mar 2017 00:54:58 +0000

This solution introduces a lot of complexity, but does not address the fundamental problem, which is that the client can't prove possession of the TB key in 0-RTT. So, if I have a site that requires strong protection of tokens with TB, I would disable 0-RTT application data, or at least reject requests that arrive in 0-RTT and require bound tokens to be authorized.

Cheers,

Andrei

-----Original Message-----
From: Martin Thomson [mailto:[email-masked]] 
Sent: Wednesday, March 1, 2017 4:53 PM
To: Nick Harper <[email-masked]>
Cc: Andrei Popov <[email-masked]>; IETF Tokbind WG <[email-masked]>
Subject: Re: [Unbearable] 0-RTT Token Binding: When to switch exporters?

Would it help to include a clear signal about which keys are intended to be exported and used?

---

From: Nick Harper <[email-masked]>
Date: Wed, 1 Mar 2017 17:36:47 -0800

> Would it help to include a clear signal about which keys are intended to be exported and used?

Yes, I plan to include some sort of signal so that the server doesn't
have to do trial verification. This could be defining a new set of key
types that when used in a TokenBinding struct indicate the signature
is over the early exporter, or it could be an indicator extension in
the TokenBinding struct (or maybe something else). The former has the
benefit that it is covered by the signature (unless the signature
format changes).

> This solution introduces a lot of complexity, but does not address the fundamental problem, which is that the client can't prove possession of the TB key in 0-RTT. So, if I have a site that require…

The signature over the early exporter proves that the client had
possession of the TB key sometime after the server issued the
NewSessionTicket used for starting the 0-RTT connection. Whether this
is good enough depends on the threat model of the server. Obviously a
server that is paranoid can choose to reject 0-RTT data if Token
Binding is also negotiated on the connection, and I'm fine with that.
However, a server may decide that it is not concerned with client
malware stealing a NewSessionTicket (and corresponding data to replay
a 0-RTT TokenBindingMessage), and find this proof of possession good
enough.

0-RTT data has different security properties than 0.5-RTT or
post-handshake application data in TLS 1.3, so it's reasonable for a
TokenBindingMessage sent in 0-RTT application data to have different
security properties.

---

From: Nick Harper <[email-masked]>
Date: Fri, 10 Mar 2017 12:11:29 -0800

I'd like to update the I-D to address the concern of which exporter to
use when. I know that this update will not address the recent concern
around proof of possession of the TB key in 0-RTT, and we can discuss
that concern at IETF 98 in Chicago. Below is an outline of how I plan
to handle changing exporters. Does it sound reasonable to update the
I-D now, even with the open concern around proof of possession?

Outline for changing exporters:
In early data, the client uses the early exporter.
Upon receiving an application-layer response from the server, the
client switches to the regular exporter. (The client may have some
requests that were sent after the TLS handshake completed but still
using the early exporter.)
The above switch allows a server to on a per-request basis decide that
the signature of the early exporter was not sufficient and have the
client re-send the request with the regular exporter. In http, this
can be done by the server responding with a 307 redirecting to the
same resource (optionally with an additional query param indicating
that said redirect happened).

In the TokenBinding struct for any Token Binding whose signature is of
the early exporter, the client includes an Extension with
ExtensionType early_exporter(TBD) and 0-length extension_data to
indicate that the server should verify the signature using the early
exporter instead of the normal exporter.

---

From: Eric Rescorla <[email-masked]>
Date: Mon, 20 Mar 2017 09:56:24 -0700

I'm not quite sure I understand the reasoning here, so let me try to walk
through it.

The HTTP stack tells the TLS stack to initiate a connection and starts
streaming
requests down to the TLS stack. At this point, it can only use the 0-RTT
exporter,
so it has to do that. At some point in this process, the client receives
the 1-RTT
Finished and can then switch to the 1-RTT exporter, but the serves has no
way
of knowing at which point that is.

In the current rule, the client MUST switch when it sees app data from the
server,
so if the server receives a HTTP request from the client that is
semantically
dependent on some HTTP response from the server, then it knows that the
client should have switched at this point. However, ISTM that SFIN must
have appeared prior to the any such application layer message, so requiring
the client to switch on SFIN would make the switch happen slightly earlier
and give the server the same guarantees. What's the argument for not
requiring
that instead, given that it's tied to the state of the TLS stack rather
than the
HTTP stack.

-Ekr

On Fri, Mar 10, 2017 at 12:11 PM, Nick Harper <[email-masked]> wrote:

> >> This solution introduces a lot of complexity, but does not address the
> fundamental problem, which is that the client can't prove possession of the
> TB key in 0-RTT. So, if I have a site that requires strong protection of
> tokens with TB, I would disable 0-RTT application data, or at least reject
> requests that arrive in 0-RTT and require bound tokens to be authorized.
> >

---

From: Nick Harper <[email-masked]>
Date: Mon, 20 Mar 2017 12:18:05 -0700

On Mon, Mar 20, 2017 at 9:56 AM, Eric Rescorla <[email-masked]> wrote:
> so it has to do that. At some point in this process, the client receives the
> 1-RTT

As the client's HTTP stack is streaming requests down to the TLS stack
(expecting that they be sent as 0-RTT data), a few things could
happen:
- The TLS stack could have received the server's Finished, so the TLS
stack decides to finish the handshake and send all future data
streamed from the HTTP stack post-handshake. If the HTTP stack starts
preparing the request just before the TLS stack receives the server's
Finished, the HTTP stack will generate a Token-Binding header using
the 0-RTT exporter, and then stream it to the TLS stack which sends it
post-handshake. We could try to assume that the TLS stack will fail
any requests to stream data once the handshake is complete and require
the HTTP stack to call a different function to send non-0-RTT data.
However, this runs into another problem.
- The TLS stack can choose how to fragment messages. When the HTTP
stack streams a request (which contains a Token-Binding header) to be
sent over 0-RTT, the TLS stack could fragment the HTTP request in a
way that splits the Token-Binding header between TLS records, and puts
half of it in 0-RTT data and the other half in post-handshake
application data. (Or, if the "stream early data" function call
returns an error if the HTTP stack tries to send 0-RTT data after the
handshake is complete, the HTTP stack is now stuck with half of a
request sent and a field it needs to change but has already sent half
of.)
- This split of a Token-Binding header across 0-RTT and non-0-RTT data
could also be caused by the TLS stack hitting the max early data size
required by the server.
- In QUIC, even if the HTTP/QUIC/TLS stack provides some way to
guarantee that an HTTP request will end up entirely in 0-RTT data, a
packet containing part of the Token-Binding header could get lost
until after the TLS handshake is complete, at which point QUIC will
retransmit it under the new keys. Given this possibility of
retransmission, how is the server to know which exporter to enforce
use of?
> In the current rule, the client MUST switch when it sees app data from the

I assume you're referring to paragraph two of section 2.1.1 of
draft-ietf-tokbind-tls13-0rtt-01? Now that I re-read that, it does not
convey what I meant it to mean. I think what I meant to say is that
after a client receives an application-layer response from the server,
it must use the exporter_secret for all future token bindings in
application messages that are in response to the received
application-layer message from the server.

Essentially, the problem I'm trying to work around is that there is a
non-zero amount of time between the HTTP stack building a request
(specifically, the part of that where it builds the Token-Binding
header) and the HTTP stack sending that request to the TLS stack. (If
the HTTP stack is streaming the request to the TLS stack as the
request is being generated, this end time is when the last byte of the
HTTP request hits the TLS stack.) During this time, the TLS handshake
could have completed. If a client starts building an HTTP request
after it has seen application data from the server, then we can
guarantee that the client will be able to use the 1-RTT exporter.
However, the client could start building an HTTP request before it has
seen application data (and before the TLS stack has seen a Finished
message from the server), but send that after the client's TLS stack
sends its Finished message. This is the case that I want to allow.

> that instead, given that it's tied to the state of the TLS stack rather than
> the
> HTTP stack.
>
> -Ekr

---

From: Eric Rescorla <[email-masked]>
Date: Mon, 20 Mar 2017 16:12:35 -0700

> retransmission, how is the server to know which exporter to enforce

I feel like this text argues for why you need to have a "which exporter was
used"
flag, right?

> application-layer message from the server.

Do we really want to allow inversions? E.g., I send request A with the 1-RTT
token binding and request B afterwards w the 0-RTT token binding? Becase
this text would allow this.

> sends its Finished message. This is the case that I want to allow.

This does seem reasonable. Note that it's not directly observable by the
server when you do this one way or the other. Let me think if there's a
way to write this that relies less on request/response semantics.

Perhaps:
Any HTTP requests which the client initiates after sending its Finished
MUST...?

-Ekr

> than

---

From: Nick Harper <[email-masked]>
Date: Mon, 20 Mar 2017 16:32:02 -0700

> I feel like this text argues for why you need to have a "which exporter was

This is more an argument for allowing the client to continue using the
early_exporter_secret for a short time after exchanging Finished
messages. But if the protocol has any point where the client might be
able to use multiple exporters, then it's probably a good idea to have
the "which exporter was used" flag.
> this text would allow this.

Probably not. If we can't guarantee that the order in which a client
starts building HTTP requests matches the order they're sent on the
wire, then there's not an obvious way for the server to enforce that
requirement.
> Any HTTP requests which the client initiates after sending its Finished
Something like that could work. A client initiating a request could
mean putting it on the wire, or starting to build the request, and I'd
like some clarity that it's the latter.

How's this:
All HTTP requests which the client starts processing to send after the
client sends its Finished message MUST use the exporter_secret for
their token bindings.

---

From: Eric Rescorla <[email-masked]>
Date: Mon, 20 Mar 2017 17:37:43 -0700

> client sends its Finished message MUST use the exporter_secret for

This LGTM.

-Ekr

---

From: Martin Thomson <[email-masked]>
Date: Tue, 21 Mar 2017 13:23:09 +1100

> client sends its Finished message MUST use the exporter_secret for

How would a server verify this?

---

From: Eric Rescorla <[email-masked]>
Date: Tue, 21 Mar 2017 05:23:55 -0700

> How would a server verify this?

I don't believe it can. It can verify some violations (effectively those
that Nick's
role detected) at the HTTP layer.

-Ekr

---

From: Andrei Popov <[email-masked]>
Date: Tue, 21 Mar 2017 17:07:23 +0000

The rules for the switch from 0-RTT EKM to the proper EKM are becoming fairly complex and hard-to-enforce.
On the other hand, the use of 0-RTT EKM, generally, makes bound tokens replayable.

I think that a server that cares enough about token replay to enable TB (and verify extra signatures) should not accept 0-RTT (at least with those clients that offer TB).

Cheers,

Andrei

From: Eric Rescorla [mailto:[email-masked]]
Sent: Tuesday, March 21, 2017 5:24 AM
To: Martin Thomson <[email-masked]>
Cc: Nick Harper <[email-masked]>; Andrei Popov <[email-masked]>; IETF Tokbind WG <[email-masked]>
Subject: Re: [Unbearable] 0-RTT Token Binding: When to switch exporters?

On Mon, Mar 20, 2017 at 7:23 PM, Martin Thomson <[email-masked]<mailto:[email-masked]>> wrote:

I don't believe it can. It can verify some violations (effectively those that Nick's
role detected) at the HTTP layer.

-Ekr

---

From: Nick Harper <[email-masked]>
Date: Tue, 21 Mar 2017 12:00:26 -0700

> fairly complex and hard-to-enforce.

We can make these rules much simpler if we use the 0-RTT exporter for
all token bindings on a connection where the server accepted 0-RTT
data.
> I think that a server that cares enough about token replay to enable TB (and
> verify extra signatures) should not accept 0-RTT (at least with those
> clients that offer TB).

This depends on what the server's threat model is, and there are
servers that will choose to enable both TB and 0-RTT on the same
connection and accept the slightly weaker security properties.

There are two kinds of replay to consider with 0-RTT TB:

First is a network attacker retransmitting a ClientHello and early
data, i.e. repeating the exact same application message. This replay
problem exists without TB. A server that chooses to enable 0-RTT has
already mitigated this replay by e.g. including a nonce in requests so
that a replayed request is idempotent or otherwise deciding that the
0-RTT replay is acceptable.

Second replay of a TokenBinding message on a new connection (where the
exporter is the same). This involves client malware, which can just as
easily do private key operations to generate new TokenBinding messages
to use on new connections. In TBPROTO, this is also possible, but it
can only be done for active connections. With 0-RTT, the attacker can
do this for connections that will be created up to 7 days in the
future.

If a server's threat model does not include client malware, i.e. the
server is only using Token Binding to protect against attacks like XSS
(e.g. to protect cookies without the HttpOnly flag set, or OAuth
tokens), then enabling both TB and 0-RTT is perfectly reasonable.
Depending on the server's policies, even if client malware is in its
threat model it still could find the 7 day window acceptable.

---

From: Andrei Popov <[email-masked]>
Date: Tue, 21 Mar 2017 20:25:58 +0000

Hi Nick,

> Second replay of a TokenBinding message on a new connection (where the exporter is the same). This involves client malware, which can just as easily do private key operations to generate new TokenBinding messages to use on new connections. In TBPROTO, this is also possible, but it can only be done for active connections. With 0-RTT, the attacker can do this for connections that will be created up to 7 days in the future.

A basic property of Token Binding is that malware can't export the token and successfully use it from another machine, as long as it cannot also export the TB key. This is a useful property, because it means that once the client malware is removed, the attack is immediately stopped. This property is not present when Token Binding is used in combination with 0-RTT, because it may be possible for the malware to export the TLS 1.3 resumption secret.

> If a server's threat model does not include client malware, i.e. the server is only using Token Binding to protect against attacks like XSS (e.g. to protect cookies without the HttpOnly flag set, or OAuth tokens), then enabling both TB and 0-RTT is perfectly reasonable.
> Depending on the server's policies, even if client malware is in its threat model it still could find the 7 day window acceptable.

Yes, I can easily imagine servers with such policies:). 
If the WG decides to allow the use of TB in combination with 0-RTT, then we should at least provide a way for the client to negotiate replayable/0-RTT TB option separately. This would allow a client to opt out of "replayable TB", while avoiding reauthentication on every connection. A server that receives a TLS 1.3 ClientHello advertising "proper TB" (and not "replayable TB") would either not negotiate Token Binding, or reject 0-RTT resumption with this client (and instead do a full handshake).

A different client would be able to offer both "proper TB" and "replayable TB". Such a client would use the 0-RTT exporter throughout all 0-RTT connections, simplifying the rules... Would this work for you, Nick?

Cheers,

Andrei

---

From: Nick Harper <[email-masked]>
Date: Tue, 21 Mar 2017 17:19:38 -0700

On Tue, Mar 21, 2017 at 13:26 Andrei Popov <[email-masked]>
wrote:

> easily do private key operations to generate new TokenBinding messages to
> use on new connections. In TBPROTO, this is also possible, but it can only
> be done for active connections. With 0-RTT, the attacker can do this for
> connections that will be created up to 7 days in the future.
>
> A basic property of Token Binding is that malware can't export the token
> and successfully use it from another machine, as long as it cannot also
> export the TB key. This is a useful property, because it means that once
> the client malware is removed, the attack is immediately stopped. This
> property is not present when Token Binding is used in combination with
> 0-RTT, because it may be possible for the malware to export the TLS 1.3
> resumption secret.
>
> (e.g. to protect cookies without the HttpOnly flag set, or OAuth tokens),
> then enabling both TB and 0-RTT is perfectly reasonable.
> If the WG decides to allow the use of TB in combination with 0-RTT, then
> we should at least provide a way for the client to negotiate
> replayable/0-RTT TB option separately. This would allow a client to opt out
> of "replayable TB", while avoiding reauthentication on every connection. A
> server that receives a TLS 1.3 ClientHello advertising "proper TB" (and not
> "replayable TB") would either not negotiate Token Binding, or reject 0-RTT
> resumption with this client (and instead do a full handshake).
>
> A different client would be able to offer both "proper TB" and "replayable
> TB". Such a client would use the 0-RTT exporter throughout all 0-RTT
> connections, simplifying the rules... Would this work for you, Nick?
>

I agree that both the client and the server should be able to opt out of
"replayable TB" and be able to do "proper TB" or 0-RTT as they wish. I'd be
happy with providing a way for negotiating "replayable TB" separately from
"proper TB" and using the 0-RTT exporter for the entirety of 0-RTT
connections. I'm also ok with switching exporters for "replayable TB" if
the WG prefers that.

If we need to, I could propose a new TLS extension to negotiate "replayable
TB", which the client and server can use to negotiate that separately from
"proper TB". However, I think we can design it so that extension isn't
needed.

Let's consider a client that supports TB and 0-RTT, but would prefer to do
"proper TB", speaking to a server that supports "replayable TB". Before the
client can make a 0-RTT connection to the server, it needs to make a 1-RTT
connection to get a PSK it can use for resumption (and 0-RTT). When it
makes this 1-RTT connection, it learns that the server supports both 0-RTT
and TB, so the client could make a note not to use that PSK for 0-RTT (only
use it for 1-RTT resumption). Let's also consider a server that when it
issued the NewSessionTicket to the client did not support TB (so the client
is going to use this NST for a 0-RTT connection), but when the client
initiates the 0-RTT connection, the server now supports TB. One option is
for the client to exclude the TB extension from its ClientHello and send
the EarlyDataIndication extension. This results in the client making a
connection without TB even though both endpoints support it. Instead, the
client should send the TB extension and the EarlyDataIndication extension.
(The early data won't contain a bound token.) The server when choosing
whether or not to accept early data will follow rules that the result of
negotiating the TB extension must be the same on the resumed connection as
on the connection where the NST was issued, and since the NST was issued on
a connection without TB, but this connection would negotiate TB, the server
rejects early data and negotiates TB. (This is the same behavior for early
data as the ALPN and SNI extensions.)

A server that supports TB and 0-RTT, but not "replayable TB" can implement
this much easier. If a ClientHello arrives with only one of the two
extensions (TB or EarlyDataIndication), it negotiates whichever is present
as normal. If both are present, the server can unconditionally reject early
data if it negotiates TB.

I realize the client scenario is a bit complicated, and I might not have
explained it well. Does this provide a clear enough signal (for both sides)
between "proper TB" and "replayable TB"?

---

From: Bill Cox <[email-masked]>
Date: Tue, 21 Mar 2017 18:20:20 -0700

I'm just now reading this thread.  A couple points: I agree with Nick that
switching exporters will hurt adoption rates of toke binding.  I think
servers should decide if they want to support 0-RTT token binding, and
accept this as part of the risk.

As for replay prevention, only about 1% of verified token binding headers
make it to our auth backend, meaning we have about a 100X reduction in
computing costs if we do replay prevention there.  TB replay prevention
belongs in the auth backend.

Bill

---

From: Denis <[email-masked]>
Date: Wed, 22 Mar 2017 09:09:36 +0100

Hi Andrei,

The text states:

    A basic property of Token Binding is that malware can't export the
    token and successfully use it from another machine,
    as long as it cannot also export the TB key.

This sentence is incorrect for two reasons:

    1° The major problem is not related to a malware, but to a specific
    piece of software voluntary installed and used by one client.

    2° There is no need to export the TB key, since one client can
    perform all the needed computations for the benefit of another client.

For example, simply protecting the TB key in a secure element (e.g. 
smart card or a HSM) is insufficient.

A basic property of the current Token Binding mechanism is that a 
specific piece of software voluntarily installed by a client can export
the token and perform all the needed computations so that the token can 
successfully be used from another machine.

As soon as someone will develop that piece of software and make it 
publicly available, everybody will be able to use it and
all the current Token Binding mechanisms will collapse.

Denis

---

From: Andrei Popov <[email-masked]>
Date: Wed, 22 Mar 2017 17:22:01 +0000

I haven’t thought through all the permutations of TLS 1.3, but it seems that you’re right and it is possible for a client to only use “proper TB” without negotiating “replayable” vs. “proper” TB options, by keeping some extra state associated with the resumption secret. If the WG decides to go ahead with 0-RTT TB, then we should at least describe the behavior of a client and server that avoids mixing TB with 0-RTT. This will be particularly important for clients and servers that care about malware enough to support TB key attestation.

Cheers,

Andrei

From: Nick Harper [mailto:[email-masked]]
Sent: Tuesday, March 21, 2017 5:20 PM
To: Andrei Popov <[email-masked]>
Cc: Eric Rescorla <[email-masked]>; IETF Tokbind WG <[email-masked]>; Martin Thomson <[email-masked]>
Subject: Re: [Unbearable] 0-RTT Token Binding: When to switch exporters?

On Tue, Mar 21, 2017 at 13:26 Andrei Popov <[email-masked]<mailto:[email-masked]>> wrote:
Hi Nick,

I agree that both the client and the server should be able to opt out of "replayable TB" and be able to do "proper TB" or 0-RTT as they wish. I'd be happy with providing a way for negotiating "replayable TB" separately from "proper TB" and using the 0-RTT exporter for the entirety of 0-RTT connections. I'm also ok with switching exporters for "replayable TB" if the WG prefers that.

If we need to, I could propose a new TLS extension to negotiate "replayable TB", which the client and server can use to negotiate that separately from "proper TB". However, I think we can design it so that extension isn't needed.

Let's consider a client that supports TB and 0-RTT, but would prefer to do "proper TB", speaking to a server that supports "replayable TB". Before the client can make a 0-RTT connection to the server, it needs to make a 1-RTT connection to get a PSK it can use for resumption (and 0-RTT). When it makes this 1-RTT connection, it learns that the server supports both 0-RTT and TB, so the client could make a note not to use that PSK for 0-RTT (only use it for 1-RTT resumption). Let's also consider a server that when it issued the NewSessionTicket to the client did not support TB (so the client is going to use this NST for a 0-RTT connection), but when the client initiates the 0-RTT connection, the server now supports TB. One option is for the client to exclude the TB extension from its ClientHello and send the EarlyDataIndication extension. This results in the client making a connection without TB even though both endpoints support it. Instead, the client should send the TB extension and the EarlyDataIndication extension. (The early data won't contain a bound token.) The server when choosing whether or not to accept early data will follow rules that the result of negotiating the TB extension must be the same on the resumed connection as on the connection where the NST was issued, and since the NST was issued on a connection without TB, but this connection would negotiate TB, the server rejects early data and negotiates TB. (This is the same behavior for early data as the ALPN and SNI extensions.)

A server that supports TB and 0-RTT, but not "replayable TB" can implement this much easier. If a ClientHello arrives with only one of the two extensions (TB or EarlyDataIndication), it negotiates whichever is present as normal. If both are present, the server can unconditionally reject early data if it negotiates TB.

I realize the client scenario is a bit complicated, and I might not have explained it well. Does this provide a clear enough signal (for both sides) between "proper TB" and "replayable TB"?

Cheers,

Andrei