Subject: [quicwg/base-drafts] Separate key/secret availability from usage (#1654)

From: Martin Thomson <[email-masked]>
Date: Sun, 12 Aug 2018 23:13:13 -0700

As we discovered, conflating these two signals creates problems.  The
only problem we're aware of is at the server when it consumes 0-RTT, but
it's serious enough that some clarification is in order.

This makes it clear that there are two events of interest, then expands
on the particular problem scenario.

Closes #1651.
You can view, comment on, or merge this pull request online at:

  https://github.com/quicwg/base-drafts/pull/1654

-- Commit Summary --

  * Separate key/secret availability from usage

-- File Changes --

    M draft-ietf-quic-tls.md (28)

-- Patch Links --

https://github.com/quicwg/base-drafts/pull/1654.patch
https://github.com/quicwg/base-drafts/pull/1654.diff

-- 
You are receiving this because you are subscribed to this thread.
Reply to this email directly or view it on GitHub:
https://github.com/quicwg/base-drafts/pull/1654

---

From: MikkelFJ <[email-masked]>
Date: Mon, 13 Aug 2018 00:36:30 -0700

mikkelfj commented on this pull request.

> -CRYPTO frame in Handshake encryption) may send STREAM data (in 1-RTT
-encryption). However, if the Finished is lost, the client would have to
-retransmit the Finished, in which case it would use Handshake encryption.
-
+Although TLS only uses one encryption level at a time, QUIC may use more than
+one level. For instance, after sending its Finished message (using a CRYPTO
+frame at the Handshake encryption level) an endpoint can send STREAM data (in
+1-RTT encryption). If the Finished message is lost, the endpoint uses the
+Handshake encryption level to retransmit the lost message.
+
+In particular, server implementations need to be able to read packets at the
+Handshake encryption level before the final TLS handshake message at the 0-RTT
+encryption level (EndOfEarlyData) is available.  Though the content of CRYPTO
+frames at the Handshake encryption level cannot be forwarded to TLS before
+EndOfEarlyData is processed, the client could send ACK frames that the server
+needs to process in order to detect lost Handshake packets.

I am not sufficiently familiar with the handshake process to really have an opinion here. But while I understand most of the text, the last paragraph seems very dense,

-- 
You are receiving this because you are subscribed to this thread.
Reply to this email directly or view it on GitHub:
https://github.com/quicwg/base-drafts/pull/1654#pullrequestreview-145541125

---

From: Christian Huitema <[email-masked]>
Date: Mon, 13 Aug 2018 10:08:38 -0700

huitema approved this pull request.

I think this text is better than the previous one. 

I suggest adding a paragraph about the need for reordering before submission to TLS. It is somewhat redundant, and I would understand that editors decide to do without. But I think it is important to hammer this point, as it is an important part of the design.

Looks good. You may or may not want to hammer the point about ordering. Something like this:

Proper operation of TLS requires that handshake octets be delivered to the TLS receiver in the order in which they were produced by the sender but QUIC can only guarantee ordering within an encryption level. Due to possible reordering and losses it is possible that encryption level 1 messages sent in 0-RTT packets arrive after level 2 messages sent in Handshake packets. QUIC receivers need to make sure that handshake messages are only submitted to TLS when TLS is ready to accept messages at that encryption level.

-- 
You are receiving this because you are subscribed to this thread.
Reply to this email directly or view it on GitHub:
https://github.com/quicwg/base-drafts/pull/1654#pullrequestreview-145746786

---

From: Martin Thomson <[email-masked]>
Date: Mon, 13 Aug 2018 17:18:44 -0700

@martinthomson pushed 1 commit.

ab5c19f  More text

-- 
You are receiving this because you are subscribed to this thread.
View it on GitHub:
https://github.com/quicwg/base-drafts/pull/1654/files/3dcfe95aa68d372b6717bf58db2d09e0e7175bc1..ab5c19ffdbd00874eaa0bc7394699314a32900c6

---

From: Martin Thomson <[email-masked]>
Date: Mon, 13 Aug 2018 17:19:15 -0700

martinthomson commented on this pull request.

Encryption levels are strictly ordered, so isn't it possible that QUIC can guarantee ordering in what it delivers to TLS?

The point you are making is well taken though; packets might arrive out of order and QUIC is responsible for ensuring that they are delivered to TLS in the correct order.

Take a look at the text I've added.  I think that hammers the point home hard enough.

-- 
You are receiving this because you are subscribed to this thread.
Reply to this email directly or view it on GitHub:
https://github.com/quicwg/base-drafts/pull/1654#discussion_r209797878

---

From: Christian Huitema <[email-masked]>
Date: Mon, 13 Aug 2018 18:16:37 -0700

huitema commented on this pull request.

There is no requirement that QUIC guarantees ordering. In fact, it will deliver data from different streams in different order than they were received -- this is essential to avoid head of line blocking. The only guaranteed ordering is within a stream, or within a crypto stream.

Your paragraph develops the need for QUIC to handle the different Crypto contexts in parallel. That's fine, but in my mind that's not the same requirement as delivery of crypto-stream in specified order. In fact, just ordering them is not sufficient, because the QUIC implementation does not actually know how long a particular crypto stream is. There is no end mark. So how does it logically deduce that level N is now done, and that it is OK to proceed with N+1?

-- 
You are receiving this because you are subscribed to this thread.
Reply to this email directly or view it on GitHub:
https://github.com/quicwg/base-drafts/pull/1654#discussion_r209805055

---

From: Kazuho Oku <[email-masked]>
Date: Mon, 13 Aug 2018 18:23:49 -0700

kazuho commented on this pull request.

@huitema 
> In fact, just ordering them is not sufficient, because the QUIC implementation does not actually know how long a particular crypto stream is. There is no end mark. So how does it logically deduce that level N is now done, and that it is OK to proceed with N+1?

IIUC our assumption is that the TLS stack will somehow notify the QUIC stack what the current read epoch is, and that the QUIC stack will only supply the contents of CRYPTO frames received in that epoch.

In my view, the following sentence in the PR implies that.

_Though the content of CRYPTO frames at the Handshake encryption level cannot be forwarded to TLS before EndOfEarlyData is processed, the client could send ACK frames that the server needs to process in order to detect lost Handshake packets._

Or is it the case that you are uncomfortable with the text dealing with how to handle TLS messages?

-- 
You are receiving this because you are subscribed to this thread.
Reply to this email directly or view it on GitHub:
https://github.com/quicwg/base-drafts/pull/1654#discussion_r209805903

---

From: Christian Huitema <[email-masked]>
Date: Mon, 13 Aug 2018 18:32:34 -0700

I may be suffering from excess of caution, after spending some time debugging the out of order EOED issue. But yes, the explicit mention of out of order EOED and need to reorder is there, so I guess I the text is fine.

-- 
You are receiving this because you are subscribed to this thread.
Reply to this email directly or view it on GitHub:
https://github.com/quicwg/base-drafts/pull/1654#discussion_r209806927

---

From: Nick Banks <[email-masked]>
Date: Mon, 13 Aug 2018 18:44:41 -0700

nibanks commented on this pull request.

One of the reasons I opened #1592 was to make it easier to know when one part of the CRYPTO stream ended and another started. It also ordering easier and more explicit, IMO. But everyone seemed to disagree at the time.

-- 
You are receiving this because you are subscribed to this thread.
Reply to this email directly or view it on GitHub:
https://github.com/quicwg/base-drafts/pull/1654#discussion_r209808215

---

From: Kazuho Oku <[email-masked]>
Date: Mon, 13 Aug 2018 19:17:11 -0700

@nibanks FWIW, I still prefer the current approach above #1592.

By having different crypto streams at every epoch, TLS stacks can check if the TLS messages were delivered using the correct epoch. The verification is crucial for TLS.

If we allow single "stream" (i.e. flow of octets) span across multiple epochs, it becomes much harder to have that kind of enforcement in the API design, and I would assume that at least some of the QUIC implementations will fail to implement correct verification (consider the fact that most of us failed to notice NSTs sent using a cleartext packet).

-- 
You are receiving this because you are subscribed to this thread.
Reply to this email directly or view it on GitHub:
https://github.com/quicwg/base-drafts/pull/1654#discussion_r209811992

---

From: Mike Bishop <[email-masked]>
Date: Tue, 14 Aug 2018 15:50:43 +0000 (UTC)

MikeBishop commented on this pull request.

> @@ -457,7 +457,11 @@ Although TLS only uses one encryption level at a time, QUIC may use more than
 one level. For instance, after sending its Finished message (using a CRYPTO
 frame at the Handshake encryption level) an endpoint can send STREAM data (in
 1-RTT encryption). If the Finished message is lost, the endpoint uses the
-Handshake encryption level to retransmit the lost message.
+Handshake encryption level to retransmit the lost message.  Reordering or loss
+of packets can mean that QUIC will need to handle packets at multiple encryption
+levels.  During the handshake, this means potentially handling of packets at

"potentially handling packets" or "handling of packets", but not both.

-- 
You are receiving this because you are subscribed to this thread.
Reply to this email directly or view it on GitHub:
https://github.com/quicwg/base-drafts/pull/1654#pullrequestreview-146131206

---

From: Martin Thomson <[email-masked]>
Date: Tue, 14 Aug 2018 15:19:07 -0700

7632df3  Grammar!

-- 
You are receiving this because you are subscribed to this thread.
View it on GitHub:
https://github.com/quicwg/base-drafts/pull/1654/files/ab5c19ffdbd00874eaa0bc7394699314a32900c6..7632df337d77147dfb21d6de5edfacb3bcd6bcc1

---

From: Martin Thomson <[email-masked]>
Date: Tue, 14 Aug 2018 22:22:51 +0000 (UTC)

Merged #1654 into master.

-- 
You are receiving this because you are subscribed to this thread.
Reply to this email directly or view it on GitHub:
https://github.com/quicwg/base-drafts/pull/1654#event-1788953129

---

From: Mike Bishop <[email-masked]>
Date: Tue, 14 Aug 2018 15:40:27 -0700

Sorry, this was hanging in a draft.  Take it for what it's worth, if anything.

> @@ -440,23 +440,35 @@ Important:
 
 ### Encryption Level Changes
 
-At each change of encryption level in either direction, TLS provides QUIC with
-the new level and the encryption keys.  These events are not asynchronous; they
-always occur immediately after TLS is provided with new handshake octets, or
-after TLS produces handshake octets.
+As keys for new encryption levels become available, TLS provides QUIC with those
+keys.  Separately, as TLS starts using keys at a given encryption level, TLS
+indicates to QUIC that it is now reading or writing with keys at that encryption
+level.  These events are not asynchronous; they always occur immediately after
+TLS is provided with new handshake octets, or after TLS produces handshake
+octets.

But doesn't the production of new handshake octets also occur immediately after TLS is provided with new incoming octets?  I suspect we could condense that statement.

 If 0-RTT is possible, it is ready after the client sends a TLS ClientHello
 message or the server receives that message.  After providing a QUIC client with
 the first handshake octets, the TLS stack might signal the change to 0-RTT
 keys. On the server, after receiving handshake octets that contain a ClientHello
 message, a TLS server might signal that 0-RTT keys are available.
 
-Note that although TLS only uses one encryption level at a time, QUIC may use
-more than one level. For instance, after sending its Finished message (using a
-CRYPTO frame in Handshake encryption) may send STREAM data (in 1-RTT
-encryption). However, if the Finished is lost, the client would have to
-retransmit the Finished, in which case it would use Handshake encryption.
-
+Although TLS only uses one encryption level at a time, QUIC may use more than
+one level. For instance, after sending its Finished message (using a CRYPTO
+frame at the Handshake encryption level) an endpoint can send STREAM data (in
+1-RTT encryption). If the Finished message is lost, the endpoint uses the

It might actually be more instructive to talk about CRYPTO frames at different levels.  Maybe the 1-RTT data could be a New Session Ticket in a CRYPTO frame?

-- 
You are receiving this because you are subscribed to this thread.
Reply to this email directly or view it on GitHub:
https://github.com/quicwg/base-drafts/pull/1654#pullrequestreview-146131809

---

From: Kazuho Oku <[email-masked]>
Date: Tue, 14 Aug 2018 15:42:44 -0700

That's not always the case. People sometimes offload public key crypto to different devices (even to different continents when private key leakage is a concern).

-- 
You are receiving this because you are subscribed to this thread.
Reply to this email directly or view it on GitHub:
https://github.com/quicwg/base-drafts/pull/1654#discussion_r210126926

---

From: MikkelFJ <[email-masked]>
Date: Tue, 14 Aug 2018 22:10:19 -0700

@kazuho that may be so, but isn't TLS / QUIC currently stating that all interaction is synchronous?

-- 
You are receiving this because you are subscribed to this thread.
Reply to this email directly or view it on GitHub:
https://github.com/quicwg/base-drafts/pull/1654#discussion_r210172357