Subject: [Unbearable] Clarifying Token Binding behavior with renegotiation

From: Nick Harper <[email-masked]>
Date: Fri, 7 Oct 2016 16:52:56 -0700

Right now, the Token Binding documents specify how the negotiation
extension should interact with the Renegotiation Indication (RFC 5746)
extension, but it could be more clear about which EKM value to use in a
TokenBinding after a renegotiation occurs.

Section 3.3 of TBPROTO specifies that the EKM is obtained from the current
TLS connection, but RFC 5705 states that the exporter is associated with a
TLS session (more specifically, a set of SecurityParameters). If we assume
that TBPROTO means TLS session, then after a renegotiation occurs, the EKM
value changes since the SecurityParameters changed. An alternate reading is
that the EKM from the first TLS session of the TLS connection is used.

For the sake of ease of implementation on client and server, I think it
would be better if Token Binding uses this second reading, where the EKM to
sign does not change over the lifetime of the connection. I have uploaded a
pull request to tweak the language to more clearly specify this:
https://github.com/TokenBinding/Internet-Drafts/pull/72.

If the EKM value can change over the course of a connection, then the
client and server both have to check what the EKM value is each time before
using it. Both peers also have to somehow guarantee that between when they
get the EKM value and when they send or receive the message using that
value that no renegotiation has taken place. I think this is easy enough to
guarantee for HTTP/1.1 application data, but Token Binding is agnostic of
the application layer protocol. Imagine some other protocol is using Token
Binding and renegotiation, and that protocol is multiplexed (like h2). In
this case, one application thread could read the EKM value, prepare a
TokenBinding message, and send it, while another thread does a
renegotiation on the same connection between the first thread reading the
EKM value and sending the signature of it. There are probably other strange
interleavings of token-bound messages and renegotiations that I haven't
thoroughly considered, but using the same EKM for the connection solves
those problems.

Does this seem like a reasonable clarification?
Cheers,
Nick

---

From: Andrei Popov <[email-masked]>
Date: Mon, 10 Oct 2016 00:15:05 +0000

Hi Nick,

Ø  Section 3.3 of TBPROTO specifies that the EKM is obtained from the current TLS connection, but RFC 5705 states that the exporter is associated with a TLS session (more specifically, a set of SecurityParameters). If we assume that TBPROTO means TLS session, then after a renegotiation occurs, the EKM value changes since the SecurityParameters changed. An alternate reading is that the EKM from the first TLS session of the TLS connection is used.

It is true that in TLS, a session can outlast a connection, and also a connection can outlast a session. The intent in the TBPROTO I-D is that the current EKM be used, that is, the one from the latest TLS session or connection. I agree that the existing language in the I-D is over-simplified and does not fully convey this; will clarify in the next revision.

Ø  For the sake of ease of implementation on client and server, I think it would be better if Token Binding uses this second reading, where the EKM to sign does not change over the lifetime of the connection.

There are a couple of reasons I think we should use the current EKM:

1.      This ensures that a bound token is not replayed on a newly established session, even if this new session has been established on an existing TLS connection;

2.      This avoids the requirement that the client and server remember the first EKM value for each connection, so that they can keep using it after subsequent renegotiation(s).

Ø  If the EKM value can change over the course of a connection, then the client and server both have to check what the EKM value is each time before using it.

IMHO it’s a good thing when both client and server make sure the signature properly binds the token to the most current TLS secret. A lot of server apps are stateless and don’t track TLS sessions and connections, but they can always query the current EKM value from the TLS layer. Making such apps aware of more TLS context would add significant complexity.

Ø  Imagine some other protocol is using Token Binding and renegotiation, and that protocol is multiplexed (like h2). In this case, one application thread could read the EKM value, prepare a TokenBinding message, and send it, while another thread does a renegotiation on the same connection between the first thread reading the EKM value and sending the signature of it.

This complication generally exists for multiplexed protocols running over TLS<=1.2 and using EKMs; it is not specific to Token Binding.

Cheers,

Andrei

From: Unbearable [mailto:[email-masked]] On Behalf Of Nick Harper
Sent: Friday, October 7, 2016 4:53 PM
To: IETF Tokbind WG <[email-masked]>
Subject: [Unbearable] Clarifying Token Binding behavior with renegotiation

Right now, the Token Binding documents specify how the negotiation extension should interact with the Renegotiation Indication (RFC 5746) extension, but it could be more clear about which EKM value to use in a TokenBinding after a renegotiation occurs.

Section 3.3 of TBPROTO specifies that the EKM is obtained from the current TLS connection, but RFC 5705 states that the exporter is associated with a TLS session (more specifically, a set of SecurityParameters). If we assume that TBPROTO means TLS session, then after a renegotiation occurs, the EKM value changes since the SecurityParameters changed. An alternate reading is that the EKM from the first TLS session of the TLS connection is used.

For the sake of ease of implementation on client and server, I think it would be better if Token Binding uses this second reading, where the EKM to sign does not change over the lifetime of the connection. I have uploaded a pull request to tweak the language to more clearly specify this: https://github.com/TokenBinding/Internet-Drafts/pull/72.

If the EKM value can change over the course of a connection, then the client and server both have to check what the EKM value is each time before using it. Both peers also have to somehow guarantee that between when they get the EKM value and when they send or receive the message using that value that no renegotiation has taken place. I think this is easy enough to guarantee for HTTP/1.1 application data, but Token Binding is agnostic of the application layer protocol. Imagine some other protocol is using Token Binding and renegotiation, and that protocol is multiplexed (like h2). In this case, one application thread could read the EKM value, prepare a TokenBinding message, and send it, while another thread does a renegotiation on the same connection between the first thread reading the EKM value and sending the signature of it. There are probably other strange interleavings of token-bound messages and renegotiations that I haven't thoroughly considered, but using the same EKM for the connection solves those problems.

---

From: Nick Harper <[email-masked]>
Date: Mon, 10 Oct 2016 11:06:41 -0700

On Sun, Oct 9, 2016 at 5:15 PM, Andrei Popov <[email-masked]>
wrote:

> 1.      This ensures that a bound token is not replayed on a newly
> established session, even if this new session has been established on an
> existing TLS connection;
>
This replay could only happen on an existing TLS connection. For this to
happen, an attacker has to be able to read and write to the TLS stream both
before and after renegotiation occurs. (Before to get the TokenBinding to
replay, and after to replay the TokenBinding with whatever bound tokens and
message the attacker wanted.) If the attacker has these capabilities, the
attacker could just replay the TokenBinding from after the renegotiation,
so it doesn't matter that they use the same EKM value.

> 2.      This avoids the requirement that the client and server remember
> the first EKM value for each connection, so that they can keep using it
> after subsequent renegotiation(s).
>
The server needs to remember the EKM across renegotiation regardless of
whether the same EKM is used for the whole connection or a new EKM is used
after renegotiation. Consider the following example with HTTP/1.1:

1. C->S: GET /foo HTTP/1.1
2. S->C: HelloRequest
3. C<->S: ClientHello, ServerHello, client auth, ChangeCipherSpec, Finished
4. S->C: HTTP/1.1 200 OK

In #1, the client makes a request for a protected resource. When starting
to process this request, the server needs a client certificate and sends a
HelloRequest (#2) to start renegotiation. #3 has the renegotiation, with
the server requesting and the client providing a certificate. Finally, in
#4, the server replies to the request from #1, with the reply possibly
dependent on the cert in #3.

With Token Binding, the request in #1 might have a bound token. The server
has to remember this request until at least #3 to process it (since the
response could depend on the cert in #3), but when processing it, it also
has to verify the Token Binding, using the EKM from before renegotiation.
The way that makes the most sense to me for processing this request is that
after #3, the server processes the request it received in #1 to generate
the response in #4, which means remembering the EKM from #1 to verify the
signature. Perhaps it is possible that the server verifies the Token
Binding in #1 and then processes the rest of the request later, but this
requires keeping track of some other state across renegotiation, and to me
sounds more complicated than using the same EKM.

>
>
> Ø  If the EKM value can change over the course of a connection, then the
> using it.
> IMHO it’s a good thing when both client and server make sure the signature
> properly binds the token to the most current TLS secret. A lot of server
> apps are stateless and don’t track TLS sessions and connections, but they
> can always query the current EKM value from the TLS layer. Making such apps
> aware of more TLS context would add significant complexity.
>

If an app is able to query the current EKM value from the TLS layer, it
presumably has access to something like OpenSSL's SSL struct (which stores
all state for the TLS connection). Once the TLS handshake is complete, the
app could store alongside the SSL struct the EKM value for Token Binding
(the app probably has an object that owns the SSL struct and manages its
lifetime, that object can handle getting the EKM once the handshake is
complete). The app itself doesn't need to be more aware of TLS context, and
this doesn't add very much complexity.

Requiring a lookup of the EKM on each request is expensive and adds more
complexity than using the same EKM for the whole connection. If an app is
using the Windows TLS stack, each time it queries the EKM, another IPC is
required (this was a reason for not putting some of the context for the
Token Binding signature in the EKM context value and instead hashing that
context with the EKM). This also makes client implementations more
complicated. Right now, my client implementation caches Token Binding
signatures by TB key and type. If I had to look up the EKM on each request,
the cache design would be significantly more complicated, or the cache
would be lost entirely and we'd be re-signing on each request and lose all
benefits of any HTTP header compression from signatures being the same.

Overall, I think that using the same EKM for the whole connection (instead
of the EKM for the most recent session) is easier and simpler to implement,
and is just as secure.

-Nick

---

From: Andrei Popov <[email-masked]>
Date: Wed, 12 Oct 2016 19:17:29 +0000

Ø  For this to happen, an attacker has to be able to read and write to the TLS stream both before and after renegotiation occurs. (Before to get the TokenBinding to replay, and after to replay the TokenBinding with whatever bound tokens and message the attacker wanted.) If the attacker has these capabilities, the attacker could just replay the TokenBinding from after the renegotiation, so it doesn't matter that they use the same EKM value.
Not necessarily: let’s say the initial TLS session is MITM’ed and the attacker A transparently passes messages between C and S. In the process, A gains access to the TB message and the token from this initial TLS session.
With your proposal in place, now A can trigger renegotiation with S and present the same token and the same TB message, and impersonate C from a different machine, without access to the TB key securely stored by C.
If the latest EKM is required after renegotiation (as it currently is, albeit admittedly the language is flawed), A needs to generate a new signature after renegotiation, using the latest EKM, and A can’t do it without access to the TB key.

Ø  The server needs to remember the EKM across renegotiation regardless of whether the same EKM is used for the whole connection or a new EKM is used after renegotiation. Consider the following example with HTTP/1.1:…
As you note yourself, the binding can be verified at step 1, so remembering multiple EKMs vs. verifying TBs as they arrive is an implementation choice. I see no reason for the TB spec to lock an implementation into one choice.

Ø  Requiring a lookup of the EKM on each request is expensive and adds more complexity than using the same EKM for the whole connection.
Again, you’re assuming that the server application has a notion of “connection”, whereas many of them are designed to only understand “request”.

Ø  If an app is using the Windows TLS stack, each time it queries the EKM, another IPC is required (this was a reason for not putting some of the context for the Token Binding signature in the EKM context value and instead hashing that context with the EKM).
Thanks for thinking about Windows☺. On Windows, HTTP middleware caches the current EKM, so there is no need to do IPC for each request.

Ø  Right now, my client implementation caches Token Binding signatures by TB key and type.
This sounds like a bug: EKM should be part of the cache index, because it’s part of the data being signed by a particular signature.

Cheers,

Andrei

---

From: Nick Harper <[email-masked]>
Date: Wed, 12 Oct 2016 14:34:54 -0700

On Wed, Oct 12, 2016 at 12:17 PM, Andrei Popov <[email-masked]>
wrote:

> Ø  For this to happen, an attacker has to be able to read and write to
> the TLS stream both before and after renegotiation occurs. (Before to get
> the TokenBinding to replay, and after to replay the TokenBinding with
> whatever bound tokens and message the attacker wanted.) If the attacker has
> these capabilities, the attacker could just replay the TokenBinding from
> after the renegotiation, so it doesn't matter that they use the same EKM
> value.
>
> Not necessarily: let’s say the initial TLS session is MITM’ed and the
> attacker A transparently passes messages between C and S. In the process, A
> gains access to the TB message and the token from this initial TLS session.
>
> With your proposal in place, now A can trigger renegotiation with S and
> present the same token and the same TB message, and impersonate C from a
> different machine, without access to the TB key securely stored by C.
>
> If the latest EKM is required after renegotiation (as it currently is,
> albeit admittedly the language is flawed), A needs to generate a new
> signature after renegotiation, using the latest EKM, and A can’t do it
> without access to the TB key.
>

I'm assuming that the MITM attacker A sits somewhere on the network path
between C and S, that the TLS connection is between C and S (i.e. A is not
terminating TLS, since otherwise that would break the TB), and that A
somehow has the capability to read and write to the TLS connection (so that
it can send/receive renegotiation messages). If this is the case, then A
can hijack the connection and send whatever application data it wants over
the existing connection (using the TB message and token it has from
earlier), and drop all traffic to/from C (or send a TCP RST to C if it
wants to). Which EKM is used post-renegotiation doesn't affect what A can
do in this attack.

In TLS 1.3, the EKM doesn't change after post-handshake auth (it also
doesn't cover client certs). Using the same EKM for the whole TLS
connection in 1.2 is analogous to the EKM in 1.3. I don't see any security
benefits to using the new EKM.

>
>
> Ø  The server needs to remember the EKM across renegotiation regardless
> of whether the same EKM is used for the whole connection or a new EKM is
> used after renegotiation. Consider the following example with HTTP/1.1:…
>
> As you note yourself, the binding can be verified at step 1, so
> remembering multiple EKMs vs. verifying TBs as they arrive is an
> implementation choice. I see no reason for the TB spec to lock an
> implementation into one choice.
>

This change doesn't prevent a server from verifying TBs before renego if it
wishes - it can verify before or after. This also doesn't require that a
server remember multiple EKMs, it requires that it only remember one. Most
likely, the server will have cached the EKM to use (instead of getting it
from the TLS stack each time), and it's easier to cache just the first one
than it is to cache the current one.

>
>
> Ø  Requiring a lookup of the EKM on each request is expensive and adds
> more complexity than using the same EKM for the whole connection.
>
> Again, you’re assuming that the server application has a notion of
> “connection”, whereas many of them are designed to only understand
> “request”.
>

At some point in the server stack, it's aware of the connection. I agree
that at some level of the server application stack, it just understands a
"request". However, to process a request with Token Binding, it needs some
amount of information from the connection (e.g. the EKM in the signature to
verify). Whatever provides that information to the application that only
understands "request" is aware of the connection, and can provide the first
EKM.

>
>
> Thanks for thinking about WindowsJ. On Windows, HTTP middleware caches
> the current EKM, so there is no need to do IPC for each request.
>

I'm assuming then that the Windows HTTP middleware is aware of
renegotiation so that it can update its cached EKM value after
renegotiation occurs. A simpler caching logic to implement is to cache the
first EKM from the connection. Applications that only need an EKM for Token
Binding will find it easier to implement an EKM cache that caches only the
first value, instead of implementing a cache that is aware of renegotiation
and updates/invalidates when renegotiation happens.

The complication with multiplexed protocols and TLS <= 1.2 isn't due to the
use of EKM, it's due to the use of renegotiation (which is why HTTP/2
forbids renegotiation). If Token Binding is going to work with generic
application protocols (which is the case as the drafts are currently set
up) and with renegotiation, then it needs to specify how this problem
should be handled. One possible way is to say that certain combinations
aren't allowed, but it needs to say something to solve this problem. Using
one EKM for the whole connection is another way to solve this problem for
the generic case.

Right now, I see no security benefit to using the post-renegotiation EKM
(instead of the first EKM of the connection), and I see something that is
harder to implement. My preference would be to completely forbid
renegotiation with Token Binding, but it sounds like you have uses for it.
Instead, I think this proposal provides what you need and also keeps things
simple for implementations.

---

From: Brian Campbell <[email-masked]>
Date: Thu, 13 Oct 2016 13:53:29 -0600

Given the current intent of the draft, where renegotiation is allowed and
the EKM is from the current or most recent TLS session/connection, how is a
server expected to handle things when renegotiation happens? In some
(many/all?) cases, for a period of time around renegotiation the server
can't know for sure if a TB message was prepared with the before EKM or the
after EKM. To work reliably it seems like the server would need to retain
both EKM values for a short but not entirely determinate period of time and
check the TB signature over both. That seems cumbersome. Nick's proposal
addresses that issue (though I'm not sure if it's the *right* thing to do
or not). Disallowing renegotiation with Token Binding would also address it
(but Andrei has stated a need for it). But I agree that the draft(s) should
say something to solve this problem or provide guidance.

On Wed, Oct 12, 2016 at 3:34 PM, Nick Harper <[email-masked]> wrote:

>
>
> On Wed, Oct 12, 2016 at 12:17 PM, Andrei Popov <[email-masked]
> > wrote:
>
> This change doesn't prevent a server from verifying TBs before renego if
> it wishes - it can verify before or after. This also doesn't require that a
> The complication with multiplexed protocols and TLS <= 1.2 isn't due to
> the use of EKM, it's due to the use of renegotiation (which is why HTTP/2
> _______________________________________________
> Unbearable mailing list
> [email-masked]
> https://www.ietf.org/mailman/listinfo/unbearable
>
>

---

From: Andrei Popov <[email-masked]>
Date: Thu, 13 Oct 2016 20:56:06 +0000

Ø  Given the current intent of the draft, where renegotiation is allowed and the EKM is from the current or most recent TLS session/connection, how is a server expected to handle things when renegotiation happens? In some (many/all?) cases, for a period of time around renegotiation the server can't know for sure if a TB message was prepared with the before EKM or the after EKM.
I’m not aware of a situation where the server can’t know for sure.

1.       TLS handshake is complete. The client sends the first TB message as part of the first application_data record of this TLS session or connection.

2.       The server validates the TB message, using the current session/connection’s EKM. If validation succeeds, continue to step 3.

3.       The server processes the rest of the application_data, determines that e.g. client auth is required, and triggers renegotiation. Go to step 1.

Cheers,

Andrei

---

From: Brian Campbell <[email-masked]>
Date: Thu, 13 Oct 2016 15:29:51 -0600

What if, for example, the client were to initiate renegotiation after step
1 and before 2?

On Thu, Oct 13, 2016 at 2:56 PM, Andrei Popov <[email-masked]>
wrote:

> Ø  Given the current intent of the draft, where renegotiation is allowed
> and the EKM is from the current or most recent TLS session/connection, how
> is a server expected to handle things when renegotiation happens? In some
> after EKM.
> 1.       TLS handshake is complete. The client sends the first TB message
> as part of the first application_data record of this TLS session or
> connection.
>
> 2.       The server validates the TB message, using the current
> session/connection’s EKM. If validation succeeds, continue to step 3.
>
> 3.       The server processes the rest of the application_data,
> determines that e.g. client auth is required, and triggers renegotiation.
> Go to step 1.
>
>
>
> Cheers,
>
>
>
> Andrei
>

---

From: Andrei Popov <[email-masked]>
Date: Thu, 13 Oct 2016 21:55:17 +0000

1.5   The client sends a ClientHello to renegotiate.

3.       The server processes the rest of the application_data and possibly sends a response.

4.       The server processes the renegotiation ClientHello. An HTTP server will likely have client-initiated renegotiation disabled, but if not, it will perform the handshake. Go to step 1.

A TLS server always knows what TLS session/connection a given application_data message belongs to, otherwise it would not be able to decrypt this application_data in the first place.
And application_data carries the TB message.

From: Brian Campbell [mailto:[email-masked]]
Sent: Thursday, October 13, 2016 2:30 PM
To: Andrei Popov <[email-masked]>
Cc: Nick Harper <[email-masked]>; IETF Tokbind WG <[email-masked]>
Subject: Re: [Unbearable] Clarifying Token Binding behavior with renegotiation

What if, for example, the client were to initiate renegotiation after step 1 and before 2?

On Thu, Oct 13, 2016 at 2:56 PM, Andrei Popov <[email-masked]<mailto:[email-masked]>> wrote:

>  Given the current intent of the draft, where renegotiation is allowed and the EKM is from the current or most recent TLS session/connection, how is a server expected to handle things when renegotiation happens? In some (many/all?) cases, for a period of time around renegotiation the server can't know for sure if a TB message was prepared with the before EKM or the after EKM.

Cheers,

Andrei

---

From: Nick Harper <[email-masked]>
Date: Thu, 13 Oct 2016 16:12:15 -0700

On Thu, Oct 13, 2016 at 2:55 PM, Andrei Popov <[email-masked]>
wrote:
>
> A TLS server always knows what TLS session/connection a given
> application_data message belongs to, otherwise it would not be able to
> decrypt this application_data in the first place.
>

Does the application always know what TLS session/SecurityParameters an
application_data message belongs to? I imagine the application only has an
interface like SSL_read to read application data from the TLS stack, and
when processing the TB message, it makes another call to the TLS stack some
time delta later to get the EKM. The SSL_read interface only provides a
sequence of bytes, not some identifier for the TLS session that the
application could use when querying for the EKM later.

I'm thinking of something like what Brian mentioned:
0. Client and Server establish a TLS connection
1. Client sends some app data with a TB
2. Client sends a ClientHello to start renegotiation
3. Server reads app data sent by Client from TLS connection
4. Server's TLS stack continues the TLS renegotiation handshake
5. Meanwhile, the server's application stack processes the app data,
including verifying the TB signature of the EKM.

In step 5, the application stack queries the TLS stack for the EKM. If step
4's handshake has finished before the application queries for the EKM, the
application will get the new EKM when it wants the old EKM. (Or the
application might query the TLS stack for the EKM during renegotiation,
which the TLS stack might not support.) Obviously this is dependent on how
the TLS stack is implemented and what interfaces it provides to the
application.

This is all assuming that there's a well-defined way to identify a
TokenBindingMessage as belonging to a particular set of application_data
TLS messages, that all of those application_data messages ended up on the
same side of the ChangeCipherSpec message, and that ChangeCipherSpec is the
correct point to use (instead of e.g. Finished) to indicate that
renegotiation has completed and the new EKM instead of the old EKM should
be used.

---

From: Martin Thomson <[email-masked]>
Date: Fri, 14 Oct 2016 12:10:13 +1100

Yes, requests that span a renegotiation can fail.  Of course, you
could arrange things so that the renegotiation is triggered after
validating the TB and avoid the problem.

I don't think we need to add extra complexity to deal with this.  If
anything this makes me more confident that removing renegotiation from
TLS 1.3 was the right choice.

On 14 October 2016 at 10:12, Nick Harper <[email-masked]> wrote:
> TokenBindingMessage as belonging to a particular set of application_data TLS
> messages, that all of those application_data messages ended up on the same
> side of the ChangeCipherSpec message, and that ChangeCipherSpec is the
> renegotiation has completed and the new EKM instead of the old EKM should be
> used.
>

---

From: Andrei Popov <[email-masked]>
Date: Fri, 14 Oct 2016 01:15:52 +0000

+ Dirk

I guess, the key question is whether we care to do proof of possession after renegotiation, or would be content using a stale EKM from the beginning of the connection.

My vote is to use the latest EKM and proper proof of possession after renegotiation; Nick appears to think that POP after renegotiation is no use and a hassle to implement.
Anyone else has an opinion?

Cheers,

Andrei

-----Original Message-----
From: Martin Thomson [mailto:[email-masked]] 
Sent: Thursday, October 13, 2016 6:10 PM
To: Nick Harper <[email-masked]>
Cc: Andrei Popov <[email-masked]>; IETF Tokbind WG <[email-masked]>; Brian Campbell <[email-masked]>
Subject: Re: [Unbearable] Clarifying Token Binding behavior with renegotiation

Yes, requests that span a renegotiation can fail.  Of course, you could arrange things so that the renegotiation is triggered after validating the TB and avoid the problem.

I don't think we need to add extra complexity to deal with this.  If anything this makes me more confident that removing renegotiation from TLS 1.3 was the right choice.

On 14 October 2016 at 10:12, Nick Harper <[email-masked]> wrote:
>> application_data message belongs to, otherwise it would not be able 
>> to decrypt this application_data in the first place.
>>
> Does the application always know what TLS session/SecurityParameters 
> an application_data message belongs to? I imagine the application only 
> has an interface like SSL_read to read application data from the TLS 
> stack, and when processing the TB message, it makes another call to 
> the TLS stack some time delta later to get the EKM. The SSL_read 
> interface only provides a sequence of bytes, not some identifier for 
> the TLS session that the application could use when querying for the EKM later.
>
> 0. Client and Server establish a TLS connection 1. Client sends some 
> app data with a TB 2. Client sends a ClientHello to start 
> renegotiation 3. Server reads app data sent by Client from TLS 
> connection 4. Server's TLS stack continues the TLS renegotiation 
> handshake 5. Meanwhile, the server's application stack processes the 
> app data, including verifying the TB signature of the EKM.
>
> In step 5, the application stack queries the TLS stack for the EKM. If 
> step 4's handshake has finished before the application queries for the 
> EKM, the application will get the new EKM when it wants the old EKM. 
> (Or the application might query the TLS stack for the EKM during 
> renegotiation, which the TLS stack might not support.) Obviously this 
> is dependent on how the TLS stack is implemented and what interfaces 
> it provides to the application.
>
> TokenBindingMessage as belonging to a particular set of 
> application_data TLS messages, that all of those application_data 
> messages ended up on the same side of the ChangeCipherSpec message, 
> and that ChangeCipherSpec is the correct point to use (instead of e.g. 
> Finished) to indicate that renegotiation has completed and the new EKM 
> instead of the old EKM should be used.
>

---

From: Nick Harper <[email-masked]>
Date: Thu, 13 Oct 2016 18:30:51 -0700

Correct, I think that using the EKM from the latest handshake provides no
additional value. I think implementation difficulty might be more than just
"a hassle" - it might be impossible to implement with OpenSSL's current
API. Additionally, it requires that an application protocol that uses both
renegotiation and Token Binding define a clear boundary between application
data pre-renegotiation and application data post-renegotiation.

On Thu, Oct 13, 2016 at 6:15 PM, Andrei Popov <[email-masked]>
wrote:

> + Dirk
>
> I guess, the key question is whether we care to do proof of possession
> after renegotiation, or would be content using a stale EKM from the
> beginning of the connection.
>
> My vote is to use the latest EKM and proper proof of possession after
> renegotiation; Nick appears to think that POP after renegotiation is no use
> and a hassle to implement.
> Cc: Andrei Popov <[email-masked]>; IETF Tokbind WG <
> [email-masked]>; Brian Campbell <[email-masked]>
> Yes, requests that span a renegotiation can fail.  Of course, you could
> arrange things so that the renegotiation is triggered after validating the
> TB and avoid the problem.
>
> anything this makes me more confident that removing renegotiation from TLS
> 1.3 was the right choice.
>

---

From: Brian Campbell <[email-masked]>
Date: Fri, 14 Oct 2016 15:57:17 -0600

There's an abstraction implied by TLS that's followed by most, if not all,
TLS implementations/APIs where the application is exposed to reading and
writing the application data and is mostly shielded from the other details
of the happens at the TLS layer like the crypto or when exactly a
renegotiation might have happened.  In principle in the messaging there is
a clear way to know what application data is associated with which master
secret / EKM, but in practice the application data is opaque to the TLS
layer and the TLS stuff is hidden from the application. I do think there's
a problem here but not sure how serious or likely it actually is. How much
is renegotiation really done? Or will be done with TB? As has been noted,
TLS 1.3 and HTTP2 are doing away with it. In my own product experience, we
did it years ago to support asking for client auth on certain resources but
it was always pretty flaky and we disabled it when the renegotiation
vulnerability came out and then never turned it back on. And what's the
impact of using the other EKM? The connection gets terminated and the
client probably tries again. Maybe one could get into a nasty cycle there.
But it might not even be a visible issue in most cases.

Taking a step back, it seems there are a few options:

   - Leave things as they are and just let things fall out as they may and
   hope it's not too bad (I think this is what Martin advocated for)
   - Leave things as they are and make some mention of the possibility of
   the issue and maybe ways that could be used to deal with it (I do think
   that retaining and checking multiple EKMs for a short time around the
   renegotiation could work but is definitely a hassle)
   - Prohibit the use of TB and renegotiation together
   - Take Nick's proposal of using only the EKM from the initial handshake
   (I don't claim to fully understand the security ramifications but it's not
   clear to me that security is degraded by this)

---

From: Martin Thomson <[email-masked]>
Date: Mon, 17 Oct 2016 21:43:56 +1100

On 15 October 2016 at 08:57, Brian Campbell <[email-masked]> wrote:
> Leave things as they are and just let things fall out as they may and hope
> it's not too bad (I think this is what Martin advocated for)
> Leave things as they are and make some mention of the possibility of the
> issue and maybe ways that could be used to deal with it (I do think that
> retaining and checking multiple EKMs for a short time around the

I think that we should say use the EKM that is based on the current
MS.  I am very happy to see text that explains the hazards of
renegotiation in this context and that initiators of renegotiation
should ensure that they line their ducks up correctly (with all the
ins-and-outs, etc...).

Note: I have no problem with a server that receives a request that
triggers renegotiation checking the token BEFORE initiating
renegotiation.  That seems OK to me.  I am concerned that requiring
that the server also check afterwards is just guaranteeing failure.
And I don't think that we have a retry built in here, so that could be
a hard failure.  I hope that is not what Andrei is advocating, because
I think that I agree with his view on this.

---

From: Andrei Popov <[email-masked]>
Date: Mon, 17 Oct 2016 17:36:45 +0000

> I think that we should say use the EKM that is based on the current MS.  
Otherwise, we're effectively saying there is no proof of possession of the TB key after renegotiation.

> I am very happy to see text that explains the hazards of renegotiation in this context and that initiators of renegotiation should ensure that they line their ducks up correctly (with all the ins-and-outs, etc...).
I'll add some text to this effect in the next revision.

> Note: I have no problem with a server that receives a request that triggers renegotiation checking the token BEFORE initiating renegotiation.  That seems OK to me.
Yes, this is the idea (and this is how we've currently implemented it).

Cheers,

Andrei

---

From: Brian Campbell <[email-masked]>
Date: Wed, 19 Oct 2016 14:30:28 -0600

On Mon, Oct 17, 2016 at 11:36 AM, Andrei Popov <[email-masked]>
wrote:

> triggers renegotiation checking the token BEFORE initiating renegotiation.
> That seems OK to me.
What happens in that implementation, if the client has pipelined other
requests that have a TB message produced with the first EKM? Meaning the
request is already in flight but not yet processed when the server
initiates renegotiation.

---

From: Andrei Popov <[email-masked]>
Date: Wed, 19 Oct 2016 21:08:11 +0000

A request that has an invalid binding (as in a signature over the wrong EKM value) will fail.

From: Brian Campbell [mailto:[email-masked]]
Sent: Wednesday, October 19, 2016 1:30 PM
To: Andrei Popov <[email-masked]>
Cc: Martin Thomson <[email-masked]>; Nick Harper <[email-masked]>; Dirk Balfanz ([email-masked]) <[email-masked]>; IETF Tokbind WG <[email-masked]>
Subject: Re: [Unbearable] Clarifying Token Binding behavior with renegotiation

What happens in that implementation, if the client has pipelined other requests that have a TB message produced with the first EKM? Meaning the request is already in flight but not yet processed when the server initiates renegotiation.

---

From: Andrei Popov <[email-masked]>
Date: Wed, 19 Oct 2016 21:14:56 +0000

To elaborate a bit, in your specific example, if the TLS server is able to decrypt the pipelined messages, then the server’s EKM is still the same one the client used for the binding. And if the server is unable to decrypt the messages, it does not matter that their binding is also invalid…

From: Unbearable [mailto:[email-masked]] On Behalf Of Andrei Popov
Sent: Wednesday, October 19, 2016 2:08 PM
To: Brian Campbell <[email-masked]>
Cc: Dirk Balfanz ([email-masked]) <[email-masked]>; IETF Tokbind WG <[email-masked]>; Martin Thomson <[email-masked]>; Nick Harper <[email-masked]>
Subject: Re: [Unbearable] Clarifying Token Binding behavior with renegotiation

From: Brian Campbell [mailto:[email-masked]]
Sent: Wednesday, October 19, 2016 1:30 PM
To: Andrei Popov <[email-masked]<mailto:[email-masked]>>
Cc: Martin Thomson <[email-masked]<mailto:[email-masked]>>; Nick Harper <[email-masked]<mailto:[email-masked]>>; Dirk Balfanz ([email-masked]<mailto:[email-masked]>) <[email-masked]<mailto:[email-masked]>>; IETF Tokbind WG <[email-masked]<mailto:[email-masked]>>
Subject: Re: [Unbearable] Clarifying Token Binding behavior with renegotiation

---

From: Nick Harper <[email-masked]>
Date: Wed, 19 Oct 2016 14:23:58 -0700

I think what Brian was saying is that a client sends multiple HTTP/1.1
pipelined requests (e.g. A and B), with B sent before waiting on a reply
for A from the server. What if request A is the one that triggers
renegotiation? A token binding in B will still sign the same EKM as A. How
does the server handle the valid token binding in request B?

On Wed, Oct 19, 2016 at 2:14 PM, Andrei Popov <[email-masked]>
wrote:

> To elaborate a bit, in your specific example, if the TLS server is able to
> decrypt the pipelined messages, then the server’s EKM is still the same one
> the client used for the binding. And if the server is unable to decrypt the
> messages, it does not matter that their binding is also invalid…
>
>
>
> *From:* Unbearable [mailto:[email-masked]] *On Behalf Of *Andrei
> Popov
> *Sent:* Wednesday, October 19, 2016 2:08 PM
> *To:* Brian Campbell <[email-masked]>
> *Cc:* Dirk Balfanz ([email-masked]) <[email-masked]>; IETF
> Tokbind WG <[email-masked]>; Martin Thomson <[email-masked]>;
> Nick Harper <[email-masked]>
> *Subject:* Re: [Unbearable] Clarifying Token Binding behavior with
> renegotiation
>
>
>
> *From:* Brian Campbell [mailto:[email-masked]
> <[email-masked]>]
> *Sent:* Wednesday, October 19, 2016 1:30 PM
> *To:* Andrei Popov <[email-masked]>
> *Cc:* Martin Thomson <[email-masked]>; Nick Harper <
> [email-masked]>; Dirk Balfanz ([email-masked]) <[email-masked]>;
> IETF Tokbind WG <[email-masked]>
> *Subject:* Re: [Unbearable] Clarifying Token Binding behavior with
> renegotiation
>
>
>
>
>

---

From: Brian Campbell <[email-masked]>
Date: Wed, 19 Oct 2016 15:26:39 -0600

Yes, that's what I'm asking. Thanks for clarifying, Nick.

On Wed, Oct 19, 2016 at 3:23 PM, Nick Harper <[email-masked]> wrote:

>> To elaborate a bit, in your specific example, if the TLS server is able
>> to decrypt the pipelined messages, then the server’s EKM is still the same
>> one the client used for the binding. And if the server is unable to decrypt
>> the messages, it does not matter that their binding is also invalid…
>>
>>
>>
>> Tokbind WG <[email-masked]>; Martin Thomson <
>> [email-masked]>; Nick Harper <[email-masked]>
>> [email-masked]>; Dirk Balfanz ([email-masked]) <
>> [email-masked]>; IETF Tokbind WG <[email-masked]>
>> On Mon, Oct 17, 2016 at 11:36 AM, Andrei Popov <
>> [email-masked]> wrote:
>>
>>

---

From: Martin Thomson <[email-masked]>
Date: Thu, 20 Oct 2016 13:42:18 +1100

> messages, it does not matter that their binding is also invalid…

Isn't it the case that until ChangeCipherSpec arrives, the old read
(client write) keys are in place.  However, the server might still
have moved its master secret to the new keys.  In that case, the
client could be out of luck and those pipelined requests might fail.
But if, like in NSS, your implementation is careful to maintain the
old master secret and it knows how to look at the right one, then it
might work.  Of course, NSS looks at the server write keys so it would
fail in this case.

Of course, this is probably one of those corner cases that caused
pipelining to be a widespread failure.

---

From: Andrei Popov <[email-masked]>
Date: Thu, 20 Oct 2016 17:23:48 +0000

> Isn't it the case that until ChangeCipherSpec arrives, the old read (client write) keys are in place.
Correct, TLS 1.2 RFC says:
"If a rehandshake occurs while data is flowing on a connection,
   the communicating parties may continue to send data using the old
   CipherSpec.  However, once the ChangeCipherSpec has been sent, the
   new CipherSpec MUST be used.  The first side to send the
   ChangeCipherSpec does not know that the other side has finished
   computing the new keying material (e.g., if it has to perform a
   time-consuming public key operation).  Thus, a small window of time,
   during which the recipient must buffer the data, MAY exist."

> However, the server might still have moved its master secret to the new keys.  In that case, the client could be out of luck and those pipelined requests might fail.
The client sends application_data either before or after CCS. If sent before, the binding is to the old master secret. If sent after, the binding is to the new master secret.
The server receives application_data either before or after CCS. If received before, the binding is to the old master secret. If sent after, the binding is to the new master secret.

In other words, if the binding is to the same master secret that produced the key with which application_data is encrypted, then both message decryption and TB verification succeed.

If the binding is to one master secret, and the encryption key is a product of another master secret, then either decryption or TB verification will fail. This mismatch is indicative of an implementation bug or a token replay attack.

> I think what Brian was saying is that a client sends multiple HTTP/1.1 pipelined requests (e.g. A and B), with B sent before waiting on a reply for A from the server. What if request A is the one that triggers renegotiation? A token binding in B will still sign the same EKM as A. How does the server handle the valid token binding in request B?
Understood. 
In this case, the server receives request B before CCS, so it will successfully decrypt using old keys, and the EKM based on the old master secret will be used. It is true that the server may have calculated the new master secret before receiving CCS, but the old master secret (or the old EKM) has to be kept around until CCS, just like the old session keys have to be kept around until CCS.

Cheers,

Andrei

-----Original Message-----
From: Martin Thomson [mailto:[email-masked]] 
Sent: Wednesday, October 19, 2016 7:42 PM
To: Andrei Popov <[email-masked]>
Cc: Brian Campbell <[email-masked]>; Dirk Balfanz ([email-masked]) <[email-masked]>; IETF Tokbind WG <[email-masked]>; Nick Harper <[email-masked]>
Subject: Re: [Unbearable] Clarifying Token Binding behavior with renegotiation

On 20 October 2016 at 08:14, Andrei Popov <[email-masked]> wrote:
> To elaborate a bit, in your specific example, if the TLS server is 
> able to decrypt the pipelined messages, then the server’s EKM is still 
> the same one the client used for the binding. And if the server is 
> unable to decrypt the messages, it does not matter that their binding 
> is also invalid…

Isn't it the case that until ChangeCipherSpec arrives, the old read (client write) keys are in place.  However, the server might still have moved its master secret to the new keys.  In that case, the client could be out of luck and those pipelined requests might fail.
But if, like in NSS, your implementation is careful to maintain the old master secret and it knows how to look at the right one, then it might work.  Of course, NSS looks at the server write keys so it would fail in this case.

Of course, this is probably one of those corner cases that caused pipelining to be a widespread failure.

---

From: Nick Harper <[email-masked]>
Date: Thu, 20 Oct 2016 10:53:20 -0700

On Thu, Oct 20, 2016 at 10:23 AM, Andrei Popov <[email-masked]>
wrote:

> In this case, the server receives request B before CCS, so it will
> successfully decrypt using old keys, and the EKM based on the old master
> secret will be used. It is true that the server may have calculated the new
> master secret before receiving CCS, but the old master secret (or the old
> EKM) has to be kept around until CCS, just like the old session keys have
> to be kept around until CCS.
>
> The server needs to keep the old EKM around until it receives CCS. But,
the server could also send a Token-Bound message to the client after the
server sends CCS/Finished (and before receiving the client's CCS), so the
server has a period of time where it needs to keep track of 2 EKMs.

If limited to specific application protocols, I don't think that using the
latest EKM is intractable, but I think it is much more complicated both in
the spec and in implementation. The above example, with what Andrei
proposes, requires the server to keep track of multiple EKMs at the same
time, and have logic in place to update the cached EKMs at the appropriate
time in the renegotiation. My proposal is simpler to implement - the client
or server computes the EKM after the connection's initial handshake
completes, and then doesn't have to worry about any of this for the rest of
the connection.

---

From: Andrei Popov <[email-masked]>
Date: Thu, 20 Oct 2016 18:09:36 +0000

Ø   If limited to specific application protocols, I don't think that using the latest EKM is intractable, ...
Now that we agree this can be done, we’re back to the core of the issue: whether it is useful to prove possession of the TB key after renegotiating on the same connection. This is where Nick and I differ.

Ø  …but I think it is much more complicated both in the spec and in implementation. The above example, with what Andrei proposes, requires the server to keep track of multiple EKMs at the same time, and have logic in place to update the cached EKMs at the appropriate time in the renegotiation.
This tracking logic already exists for read/write keys in all TLS implementations that support renegotiation. The only change is to add EKM to the state. And it is one previous EKM, not multiple EKMs, and only to be cached alongside read/write keys until CSS is received (essentially, while the handshake is on-going).

Ø  My proposal is simpler to implement - the client or server computes the EKM after the connection's initial handshake completes, and then doesn't have to worry about any of this for the rest of the connection.
Nick’s proposal requires that an implementation tracks connection status and stores the first EKM of the connection for the duration of the connection, and then knows to use the stale EKM for Token Binding, but (hopefully) the current EKM for everything else…
From the TLS perspective, I don’t think it is a good idea to introduce a concept of stale EKM.

---

From: Nick Harper <[email-masked]>
Date: Thu, 20 Oct 2016 11:48:00 -0700

On Thu, Oct 20, 2016 at 11:09 AM, Andrei Popov <[email-masked]>
wrote:

> Now that we agree this can be done, we’re back to the core of the issue:
> whether it is useful to prove possession of the TB key after renegotiating
> on the same connection. This is where Nick and I differ.
>

If proving possession of the TB key after renegotiation is that important,
why not bind your tokens to the client certificate presented in
renegotiation (instead of the token binding keys)? Then we could forbid
renegotiation with Token Binding and this whole problem goes away.

>
>
> Ø  …but I think it is much more complicated both in the spec and in
> implementation. The above example, with what Andrei proposes, requires the
> server to keep track of multiple EKMs at the same time, and have logic in
> place to update the cached EKMs at the appropriate time in the
> renegotiation.
>
> This tracking logic already exists for read/write keys in all TLS
> implementations that support renegotiation. The only change is to add EKM
> to the state. And it is one previous EKM, not multiple EKMs, and only to be
> cached alongside read/write keys until CSS is received (essentially, while
> the handshake is on-going).
>

This is assuming that the TLS stack is caching the EKM. BoringSSL/OpenSSL
and NSS provide a function that calculates the EKM based on the current
connection state, so a Token Binding implementation using one of those TLS
stacks would have to duplicate that logic. A Token Binding implementation
using one of those stacks is most likely going to implement its own cache
of the EKM, and caching a single value is easier than invalidating and
caching multiple values.

>
>
> Ø  My proposal is simpler to implement - the client or server computes
> the EKM after the connection's initial handshake completes, and then
> doesn't have to worry about any of this for the rest of the connection.
>
> Nick’s proposal requires that an implementation tracks connection status
> and stores the first EKM of the connection for the duration of the
> connection, and then knows to use the stale EKM for Token Binding, but
> (hopefully) the current EKM for everything else…
>

The Token Binding implementation would store that EKM, not the TLS stack
(see above about the TLS stack only knowing how to compute an EKM based on
the current connection state). This doesn't affect other users of the EKM.

---

From: Andrei Popov <[email-masked]>
Date: Thu, 20 Oct 2016 19:16:39 +0000

Ø  If proving possession of the TB key after renegotiation is that important, why not bind your tokens to the client certificate presented in renegotiation (instead of the token binding keys)? Then we could forbid renegotiation with Token Binding and this whole problem goes away.
Because it seems more simple/less error-prone to use one type of token binding regardless of the client authentication mechanism.