Subject: Re: [quicwg/base-drafts] Allow CONNECTION_CLOSE in 0-RTT (#3440)

From: Martin Thomson <[email-masked]>
Date: Tue, 03 Mar 2020 15:39:24 -0800

@martinthomson pushed 1 commit.

7ac257f124012d5afdc07f423ad770511f2ccf5c  Closes #3430

-- 
You are receiving this because you are subscribed to this thread.
View it on GitHub:
https://github.com/quicwg/base-drafts/pull/3440/files/032b88e613631aa31d1d9f3e1ab58ce722cc876a..7ac257f124012d5afdc07f423ad770511f2ccf5c

---

From: Martin Thomson <[email-masked]>
Date: Tue, 03 Mar 2020 15:41:35 -0800

@kazuho, can you check the recent changes here?

-- 
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/3440#issuecomment-594228488

---

From: Kazuho Oku <[email-masked]>
Date: Tue, 03 Mar 2020 16:02:17 -0800

kazuho commented on this pull request.

LGTM modulo the points below.

-- CRYPTO frames and CONNECTION_CLOSE frames signaling errors at the QUIC layer
-  (type 0x1c) MAY appear in packets of any encryption level except 0-RTT.
+- CONNECTION_CLOSE frames signaling errors at the QUIC layer (type 0x1c) MAY
+  appear in any packet number space. CONNECTION_CLOSE frames signaling
+  application errors (type 0x1d) MAY appear in every packet number space other
+  than Initial.

I think we should forbid CONNECTION_CLOSE (0x1d) from being used in Handshake packets. It is the responsibility of an encrypted transport encrypted *and authenticated* channel to the application. Handshake packets do not provide that.

Consider the case of a pot protocol that returns a boolean indicating if it is a coffee pot or a tea pot. Such an application protocol can use application close to indicate that boolean. But can a coffee pot send that boolean in a Handshake packet? Definitely not! Because somebody from Britain might spoof a Handshake packet that tells the client that it is in fact a tea pot.

> +  the client has Handshake keys.  Under these circumstances, a server SHOULD
+  send a CONNECTION_CLOSE frame in both Handshake and Initial packets to ensure
+  that at least one of them is processable by the client.
+
+* A client that sends CONNECTION_CLOSE in a 0-RTT packet cannot be assured of
+  the server has accepted 0-RTT and so sending a CONNECTION_CLOSE frame in an
+  Initial packet makes it more likely that the server can receive the close
+  signal, even if the application error code might not be received.
+
+* Prior to confirming the handshake, a peer might be unable to process 1-RTT
+  packets, so an endpoint SHOULD send CONNECTION_CLOSE in both Handshake and
+  1-RTT packets.  A server SHOULD also send CONNECTION_CLOSE in an Initial
+  packet.
+
+An CONNECTION_CLOSE of type 0x1d MUST be replaced by a CONNECTION_CLOSE of type
+0x1c when sending the frame in Initial packets. Otherwise, information about

"Initial or Handshake packets" due to the reason stated above.

-: A CONNECTION_CLOSE frame of type 0x1c can appear in Initial, Handshake, and
-1-RTT packets, whereas a CONNECTION_CLOSE of type 0x1d can only appear in a
-1-RTT packet.
+: A CONNECTION_CLOSE frame of type 0x1d cannot appear in Initial packets.

Initial or Handshake

> @@ -5680,10 +5693,10 @@ Reason Phrase:
   This SHOULD be a UTF-8 encoded string {{!RFC3629}}.
 
 The application-specific variant of CONNECTION_CLOSE (type 0x1d) can only be
-sent using an 1-RTT packet ({{QUIC-TLS}}, Section 4).  When an application
-wishes to abandon a connection during the handshake, an endpoint can send a
-CONNECTION_CLOSE frame (type 0x1c) with an error code of 0x15a ("user_canceled"
-alert; see {{?TLS13}}) in an Initial or a Handshake packet.
+sent using 0-RTT or 1-RTT packets ({{QUIC-TLS}}, Section 4).  When an

Good to know that the sentence here forbids CONNECTION_CLOSE (0x1d) being used in Handshake packets. Maybe it's the case that we changed here, but not the other places (that I have pointed out).

-- 
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/3440#pullrequestreview-368410473

---

From: Martin Thomson <[email-masked]>
Date: Tue, 03 Mar 2020 16:07:54 -0800

martinthomson commented on this pull request.

That is good reasoning.  I will do that.

-- 
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/3440#discussion_r387369170

---

From: Martin Thomson <[email-masked]>
Date: Tue, 03 Mar 2020 16:11:35 -0800

Well that was a mistake, but now I don't have to fix it :)

-- 
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/3440#discussion_r387370293

---

From: Martin Thomson <[email-masked]>
Date: Tue, 03 Mar 2020 16:13:44 -0800

64923744854a0835ae0948828f6495a1dc4acd58  Forbid application close in Handshake too

-- 
You are receiving this because you are subscribed to this thread.
View it on GitHub:
https://github.com/quicwg/base-drafts/pull/3440/files/7ac257f124012d5afdc07f423ad770511f2ccf5c..64923744854a0835ae0948828f6495a1dc4acd58

---

From: Jana Iyengar <[email-masked]>
Date: Tue, 03 Mar 2020 16:38:56 -0800

janaiyengar commented on this pull request.

A few suggestions, but overall looks good!

> @@ -415,12 +415,18 @@ A QUIC client starts TLS by requesting TLS handshake bytes from TLS.  The client
 acquires handshake bytes before sending its first packet.  A QUIC server starts
 the process by providing TLS with the client's handshake bytes.
 
-At any time, the TLS stack at an endpoint will have a current sending encryption
-level and receiving encryption level. Each encryption level is associated with a
-different flow of bytes, which is reliably transmitted to the peer in CRYPTO
-frames. When TLS provides handshake bytes to be sent, they are appended to the
-current flow and any packet that includes the CRYPTO frame is protected using
-keys from the corresponding encryption level.
+At any time, the TLS stack at an endpoint will have a current sending
+encryption level and receiving encryption level. Encryption levels correspond
+roughly to packet number spaces and determine the packet type and keys that are
+used for protecting data.
+
+Each encryption level is associated with a different flow of bytes, which is
+reliably transmitted to the peer in CRYPTO frames. When TLS provides handshake
+bytes to be sent, they are appended to the current flow and any packet that

```suggestion
bytes to be sent, they are appended to the current flow. Any packet that
```

> +encryption level and receiving encryption level. Encryption levels correspond
+roughly to packet number spaces and determine the packet type and keys that are
+used for protecting data.

```suggestion
encryption level and receiving encryption level. Encryption levels determine
the packet type and keys that are used for protecting data.
```

(moved this below to be more precise.)

> +0-RTT, Handshake, and 1-RTT packets. CRYPTO frames are carried in just three of
+these levels, omitting the 0-RTT level.

```suggestion
0-RTT, Handshake, and 1-RTT packets. CRYPTO frames are carried in just three of
these levels, omitting the 0-RTT level. These four levels correspond to three packet
number spaces: Initial and Handshake encrypted packets use their own separate
spaces, and 0-RTT and 1-RTT encrypted packets use one other space. 
```

> @@ -1364,12 +1364,11 @@ by the frames that are typically contained in those packets. So, for instance
 the first packet is of type Initial, with packet number 0, and contains a CRYPTO
 frame carrying the ClientHello.
 
-Note that multiple QUIC packets -- even of different encryption levels -- may be
+Note that multiple QUIC packets -- even of different packet types -- can be

Take-it-or-leave-it suggestion: It seems useful to say here that different encryption levels can be coalesced. Perhaps retain this old text here?

>  coalesced into a single UDP datagram (see {{packet-coalesce}}), and so this
 handshake may consist of as few as 4 UDP datagrams, or any number more. For
-instance, the server's first flight contains packets from the Initial encryption
-level (obfuscation), the Handshake level, and "0.5-RTT data" from the server at
-the 1-RTT encryption level.
+instance, the server's first flight contains Initial packets (obfuscation),

```suggestion
instance, the server's first flight contains Initial packets,
```

>  coalesced into a single UDP datagram (see {{packet-coalesce}}), and so this
 handshake may consist of as few as 4 UDP datagrams, or any number more. For
-instance, the server's first flight contains packets from the Initial encryption
-level (obfuscation), the Handshake level, and "0.5-RTT data" from the server at
-the 1-RTT encryption level.
+instance, the server's first flight contains Initial packets (obfuscation),
+Handshake packets, and "0.5-RTT data" in packets with a short header.

```suggestion
Handshake packets, and "0.5-RTT data" in 1-RTT packets with a short header.
```

+0x1c when sending the frame in Initial packets. Otherwise, information about
+the application state might be revealed. Endpoints MUST clear the value of the
+Reason Phrase field and SHOULD use the APPLICATION_ERROR code when converting
+to a CONNECTION_CLOSE of type 0x1c.

```suggestion
Sending a CONNECTION_CLOSE of type 0x1d in an Initial packet might reveal application
state to third parties. To avoid this leakage, a CONNECTION_CLOSE of type 0x1d MUST
be replaced by a CONNECTION_CLOSE of type 0x1c when sending the frame in Initial
packets. Endpoints MUST clear the value of the Reason Phrase field and SHOULD use
the APPLICATION_ERROR code when converting to a CONNECTION_CLOSE of type 0x1c.
```

-A client will always know whether the server has Handshake keys (see
-{{discard-initial}}), but it is possible that a server does not know whether the
-client has Handshake keys.  Under these circumstances, a server SHOULD send a
-CONNECTION_CLOSE frame in both Handshake and Initial packets to ensure that at
-least one of them is processable by the client.  Similarly, a peer might be
-unable to read 1-RTT packets, so an endpoint SHOULD send CONNECTION_CLOSE in
-Handshake and 1-RTT packets prior to confirming the handshake.  These packets
-can be coalesced into a single UDP datagram; see {{packet-coalesce}}.
+CONNECTION_CLOSE frames sent in multiple packets can be coalesced into a single

```suggestion
CONNECTION_CLOSE frames sent in multiple packets types can be coalesced into a single
```

-- 
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/3440#pullrequestreview-368409255

---

From: Jana Iyengar <[email-masked]>
Date: Tue, 03 Mar 2020 16:41:28 -0800

> +A CONNECTION_CLOSE of type 0x1d MUST be replaced by a CONNECTION_CLOSE of type
+0x1c when sending the frame in Initial or Handshake packets. Otherwise,
+information about the application state might be revealed. Endpoints MUST clear
+the value of the Reason Phrase field and SHOULD use the APPLICATION_ERROR code
+when converting to a CONNECTION_CLOSE of type 0x1c.

```suggestion

-- 
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/3440#pullrequestreview-368427856

---

From: Kazuho Oku <[email-masked]>
Date: Tue, 03 Mar 2020 17:50:47 -0800

LGTM modulo the editorial concern below (sorry to report things one by one).

-Some frames are prohibited in different encryption levels, others cannot be
-sent. The rules here generalize those of TLS, in that frames associated with
-establishing the connection can usually appear at any encryption level, whereas
-those associated with transferring data can only appear in the 0-RTT and 1-RTT
-encryption levels:
+Some frames are prohibited in different packet number spaces. The rules here
+generalize those of TLS, in that frames associated with establishing the
+connection can usually appear in packets in any packet number space, whereas
+those associated with transferring data can only appear in the application
+packet number space:

Looking at [section 12.3 of the transport draft](https://quicwg.org/base-drafts/draft-ietf-quic-transport.html#section-12.3), I think the term we use is "application data (packet number) space"?

This comment applies to "application packet number space" used elsewhere in this PR too.

-- 
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/3440#pullrequestreview-368453839

---

From: Martin Thomson <[email-masked]>
Date: Tue, 03 Mar 2020 18:51:30 -0800

198883f45dca18bee33a3a5f32e3550a4e11926d  Jana's editorial suggestions

-- 
You are receiving this because you are subscribed to this thread.
View it on GitHub:
https://github.com/quicwg/base-drafts/pull/3440/files/64923744854a0835ae0948828f6495a1dc4acd58..198883f45dca18bee33a3a5f32e3550a4e11926d

---

From: Martin Thomson <[email-masked]>
Date: Tue, 03 Mar 2020 18:52:13 -0800

152a5ba309fbed00aea7d3997a23cae8b173d943  More of Jana's suggestions, reworded

-- 
You are receiving this because you are subscribed to this thread.
View it on GitHub:
https://github.com/quicwg/base-drafts/pull/3440/files/198883f45dca18bee33a3a5f32e3550a4e11926d..152a5ba309fbed00aea7d3997a23cae8b173d943

---

From: Martin Thomson <[email-masked]>
Date: Tue, 03 Mar 2020 18:58:52 -0800

8fdeb9dafd0bf6ccb5261d41489e77d8ac7691d3  Sloppy

-- 
You are receiving this because you are subscribed to this thread.
View it on GitHub:
https://github.com/quicwg/base-drafts/pull/3440/files/152a5ba309fbed00aea7d3997a23cae8b173d943..8fdeb9dafd0bf6ccb5261d41489e77d8ac7691d3

---

From: Kazuho Oku <[email-masked]>
Date: Tue, 03 Mar 2020 19:12:32 -0800

Two places to change to "application data".

+  application errors (type 0x1d) MUST only appear in the Application packet
+  number space.

"application data packet number space"

> -|:--------------------|:-----------------|:----------|
-| Initial             | Initial secrets  | Initial   |
-| 0-RTT Protected     | 0-RTT            | 0/1-RTT   |
-| Handshake           | Handshake        | Handshake |
-| Retry               | N/A              | N/A       |
-| Version Negotiation | N/A              | N/A       |
-| Short Header        | 1-RTT            | 0/1-RTT   |
-{: #packet-types-levels title="Encryption Levels by Packet Type"}
+indicate which keys were used to protect a given packet, as shown in
+{{packet-types-keys}}. When packets of different types need to be sent,
+endpoints SHOULD use coalesced packets to send them in the same UDP datagram.
+
+| Packet Type         | Encryption Keys | PN Space    |
+|:--------------------|:----------------|:------------|
+| Initial             | Initial secrets | Initial     |
+| 0-RTT Protected     | 0-RTT           | Application |

"Application data"

-- 
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/3440#pullrequestreview-368479093

---

From: Martin Thomson <[email-masked]>
Date: Tue, 03 Mar 2020 19:33:51 -0800

bbe18d7579293ebfb2e9c6c34d9a42c026ba9331  Consistency over brevity

-- 
You are receiving this because you are subscribed to this thread.
View it on GitHub:
https://github.com/quicwg/base-drafts/pull/3440/files/8fdeb9dafd0bf6ccb5261d41489e77d8ac7691d3..bbe18d7579293ebfb2e9c6c34d9a42c026ba9331

---

From: ekr <[email-masked]>
Date: Sat, 07 Mar 2020 15:00:07 -0800

ekr commented on this pull request.

-- CONNECTION_CLOSE frames signaling application errors (type 0x1d) MUST only be
-  sent in packets at the 1-RTT encryption level.
+- ACK frames MAY appear in any packet number space, but can only acknowledge
+  packets which appeared in that packet number space.

This text is weird in light of the following graf that says that ACK is not permitted in 0-RTT. I would add a parenthetical "(however, as noted below, it is not possible for ACK frames to be sent in 0-RTT)"

-- 
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/3440#pullrequestreview-370793486

---

From: Martin Thomson <[email-masked]>
Date: Sun, 08 Mar 2020 22:07:43 -0700

a5f6205bf3eca9b2caba25c3582d3ec6c355d2e1  Apply suggestion from @ekr

-- 
You are receiving this because you are subscribed to this thread.
View it on GitHub:
https://github.com/quicwg/base-drafts/pull/3440/files/bbe18d7579293ebfb2e9c6c34d9a42c026ba9331..a5f6205bf3eca9b2caba25c3582d3ec6c355d2e1

---

From: Martin Thomson <[email-masked]>
Date: Sun, 08 Mar 2020 23:00:24 -0700

da24edbf0d4b53be01670f741d0b8858d9601a66  Line length fixed

-- 
You are receiving this because you are subscribed to this thread.
View it on GitHub:
https://github.com/quicwg/base-drafts/pull/3440/files/a5f6205bf3eca9b2caba25c3582d3ec6c355d2e1..da24edbf0d4b53be01670f741d0b8858d9601a66

---

From: David Schinazi <[email-masked]>
Date: Mon, 09 Mar 2020 16:53:31 -0700

DavidSchinazi approved this pull request.

-- 
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/3440#pullrequestreview-371601104

---

From: ianswett <[email-masked]>
Date: Tue, 10 Mar 2020 22:36:51 -0700

ianswett commented on this pull request.

> @@ -415,12 +416,20 @@ A QUIC client starts TLS by requesting TLS handshake bytes from TLS.  The client
 
+encryption level and receiving encryption level. Encryption levels determine
+the packet type and keys that are used for protecting data.

Flow is a non-obvious word choice, maybe sequence of bytes?

```suggestion
Each encryption level is associated with a different sequence of bytes, which is
```

-- 
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/3440#pullrequestreview-372485718

---

From: Martin Thomson <[email-masked]>
Date: Tue, 10 Mar 2020 22:39:27 -0700

df917e429b2005071135d858ad1264864be6d5fe  Update draft-ietf-quic-tls.md

-- 
You are receiving this because you are subscribed to this thread.
View it on GitHub:
https://github.com/quicwg/base-drafts/pull/3440/files/da24edbf0d4b53be01670f741d0b8858d9601a66..df917e429b2005071135d858ad1264864be6d5fe

---

From: Kazuho Oku <[email-masked]>
Date: Wed, 11 Mar 2020 01:40:49 -0700

kazuho approved this pull request.

-- 
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/3440#pullrequestreview-372559562

---

From: MikkelFJ <[email-masked]>
Date: Thu, 12 Mar 2020 09:18:25 -0700

mikkelfj commented on this pull request.

> @@ -2497,16 +2496,34 @@ handshake is confirmed (see Section 4.1.2 of {{QUIC-TLS}}), an endpoint MUST
 send any CONNECTION_CLOSE frames in a 1-RTT packet.  However, prior to
 confirming the handshake, it is possible that more advanced packet protection
 keys are not available to the peer, so the frame MAY be replicated in a packet

"replicated" is not accurate as it suggest the same error code can be used in both places.

-- 
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/3440#pullrequestreview-373703052

---

From: Martin Thomson <[email-masked]>
Date: Thu, 12 Mar 2020 16:34:04 -0700

1d110798aec3e1661f8a41da278888c6ef7a9749  Don't replicate, just send another

-- 
You are receiving this because you are subscribed to this thread.
View it on GitHub:
https://github.com/quicwg/base-drafts/pull/3440/files/df917e429b2005071135d858ad1264864be6d5fe..1d110798aec3e1661f8a41da278888c6ef7a9749

---

From: Jana Iyengar <[email-masked]>
Date: Fri, 20 Mar 2020 14:58:12 -0700

Merged #3440 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/3440#event-3151028728