Subject: [quicwg/base-drafts] Bound 0-to-1-RTT Transition (#2466)

From: Mike Bishop <[email-masked]>
Date: Thu, 14 Feb 2019 22:11:10 +0000 (UTC)

Taking a stab at @DavidSchinazi's suggested alternative.  In Tokyo, we agreed that flow control and stream IDs advertised in the server's 1-RTT packets and transport parameters don't apply to the client's 0-RTT data.

This makes two changes:
- The client was already prohibited from sending more 0-RTT packets after reaching 1-RTT ([TLS 4.9](https://quicwg.org/base-drafts/draft-ietf-quic-tls.html#rfc.section.4.9), "Though an endpoint might retain older keys, new data MUST be sent at the highest
currently-available encryption level.")  This adds a requirement on the server to drop 0-RTT packets with higher packet numbers than the first 1-RTT packet number from the client.
- Any increases to flow control or stream limits the server sends don't apply to 0-RTT traffic; servers SHOULD enforce the remembered values until at least one 1-RTT packet has been received.

This isn't perfect, as a malicious client could send a high numbered 1-RTT packet to unlock the flow control and save lower packet numbers for 0-RTT traffic which exceeds the initial limits, but it helps.  From discussion on the PR, it sounds like more aggressive enforcement than this is problematic for servers in multiple implementations.

Fixes #2458.
Fixes #2360.
You can view, comment on, or merge this pull request online at:

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

-- Commit Summary --

  * Simpler restriction on staying in 0-RTT
  * Stream counts, too

-- File Changes --

    M draft-ietf-quic-transport.md (15)

-- Patch Links --

https://github.com/quicwg/base-drafts/pull/2466.patch
https://github.com/quicwg/base-drafts/pull/2466.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/2466

---

From: Martin Thomson <[email-masked]>
Date: Thu, 14 Feb 2019 14:27:16 -0800

martinthomson commented on this pull request.

More fundamentally than the objection below (which is minor), this unnecessarily creates lots of special cases.  Maybe that is what we're looking for here, but I would rather say that transport parameters that can apply to 0-RTT need to be remembered, with a requirement to demonstrate that they don't apply before they can be forgotten/changed.

> @@ -2631,7 +2641,10 @@ number 0.  Subsequent packets sent in the same packet number space MUST increase
 the packet number by at least one.
 
 0-RTT and 1-RTT data exist in the same packet number space to make loss recovery
-algorithms easier to implement between the two packet types.
+algorithms easier to implement between the two packet types.  However, a client
+MUST NOT continue sending 0-RTT packets after beginning to use 1-RTT packets.
+Servers MUST drop 0-RTT packets with greater packet numbers than the lowest
+packet number they have received in a 1-RTT packet.

I don't like the drop requirement.  The client is violating the rules, and for no good reason.  The server can punish clients who act in this way.

-- 
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/2466#pullrequestreview-204003139

---

From: Mike Bishop <[email-masked]>
Date: Thu, 14 Feb 2019 14:35:40 -0800

I'm not clear what you mean by "a requirement to demonstrate that they don't apply before they can be forgotten/changed"?  Do you just mean the stronger statement of checking that 0-RTT data doesn't exceed the limits?  I agree that #2461 is a stronger statement, but it's also more complex to verify -- you basically have to tag the processing of every data packet that arrives in 0-RTT and apply special logic to it.

It's entirely possible that we spec #2461 and people implement #2466 as a good-enough way of achieving the requirement.  :-)

-- 
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/2466#issuecomment-463830354

---

From: Mike Bishop <[email-masked]>
Date: Thu, 14 Feb 2019 14:36:10 -0800

MikeBishop commented on this pull request.

Fair enough.  We can PV on this.

-- 
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/2466#discussion_r257041327

---

From: Martin Thomson <[email-masked]>
Date: Thu, 14 Feb 2019 14:39:03 -0800

> It's entirely possible that we spec #2461 and people implement #2466 as a good-enough way of achieving the requirement. :-)

That's OK.  Because #2461 establishes the right expectations for new transport parameters, whereas this doesn't.

If the complaint about #2461 is the complexity of enforcement, given that it is a MAY-strength requirement, I fail to see what the fuss is all about.

-- 
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/2466#issuecomment-463831514

---

From: David Schinazi <[email-masked]>
Date: Thu, 14 Feb 2019 16:21:59 -0800

DavidSchinazi commented on this pull request.

Good point, I also prefer closing the connection to what I had initially proposed.

-- 
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/2466#discussion_r257065469

---

From: David Schinazi <[email-masked]>
Date: Thu, 14 Feb 2019 16:24:11 -0800

I prefer this over #2461. The fuss is about adding a complex enforcement requirement that no servers will implement. It makes the document harder to read without helping implementors.

-- 
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/2466#issuecomment-463857797

---

From: Kazuho Oku <[email-masked]>
Date: Thu, 14 Feb 2019 17:10:39 -0800

What @martinthomson says.

I think we can consider rephrasing the following sentence in #2461 to also suggest the possibility of using PN to detect misuse of 0-RTT packets.

> A server MAY treat a violation of remembered limits as a connection error of an appropriate type (for instance, a FLOW_CONTROL_ERROR for exceeding stream data limits)."

But other than that, #2461 is better.

Note also that the detecting 0-RTT misuse based on PN is weaker than the one based on frame-types. This is because when the PN-based defense cannot detect an attack that replays an 0-RTT connection _that the attacker has created_. In such an attack, an attacker can send a 1-RTT packet using a large PN, then after that send 0-RTT packets with smaller packet numbers.

-- 
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/2466#issuecomment-463867507

---

From: Kazuho Oku <[email-masked]>
Date: Thu, 14 Feb 2019 17:11:55 -0800

@DavidSchinazi 
> The fuss is about adding a complex enforcement requirement that no servers will implement.

I disagree. Having permitted list of frame-types per each epoch is a sensible way of implementing a QUIC stack. In such case, you would not have PATH_RESPONSE permitted for 0-RTT packets, as an example.

-- 
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/2466#issuecomment-463867726

---

From: David Schinazi <[email-masked]>
Date: Thu, 14 Feb 2019 17:24:24 -0800

@kazuho Limiting the list of frame types allowed in 0-RTT makes sense to me. It's not what #2461  does though

-- 
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/2466#issuecomment-463870275

---

From: Kazuho Oku <[email-masked]>
Date: Fri, 15 Feb 2019 01:41:22 +0000 (UTC)

@DavidSchinazi 
> Limiting the list of frame types allowed in 0-RTT makes sense to me. It's not what #2461 does though

My understanding is that it implies that. See https://github.com/quicwg/base-drafts/pull/2461#issuecomment-463392078. Or are you suggesting to reconsider the conclusion for #2360?

-- 
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/2466#issuecomment-463873799

---

From: MikkelFJ <[email-masked]>
Date: Thu, 14 Feb 2019 23:50:25 -0800

> Having permitted list of frame-types per each epoch is a sensible way of implementing a QUIC stack.

Agreed. The can check that list when implementing and there are no frames that suddenly sneak in unattended. When you add a frame you need to think about the context. For example, what does a KEYS_ACTIVE mean 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/2466#issuecomment-463941385

---

From: David Schinazi <[email-masked]>
Date: Fri, 15 Feb 2019 15:21:16 -0800

@kazuho I'm not suggesting to change the conclusion for #2360, I'd just prefer to not add non-mandatory server checks that no one will implement

-- 
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/2466#issuecomment-464243677

---

From: Kazuho Oku <[email-masked]>
Date: Fri, 15 Feb 2019 16:04:21 -0800

@DavidSchinazi Spec-wise, my view is that we should recommend (or at least state that it's possible for) servers can enforce TP-values of previous TLS connection for 0-RTT packets, because not doing so means that the threat model of 0-RTT in QUIC will be different from that of TLS 1.3.

TLS 1.3 uses `max_early_data_size` field of NewSessionTicket message to cap the amount of application data the client is allowed to send in 0-RTT. And we have already built things around it. For example, [RFC 8470 section 3](https://tools.ietf.org/html/rfc8470#section-3) states, quote: _A server can limit the amount of early data with the "max_early_data_size" field of the "early_data" TLS extension.  This can be used to avoid committing an arbitrary amount of memory for requests that it might defer until the handshake completes._

Unless we provide a mechanism to replace the function that replaces `max_early_data_size` in QUIC, not only HTTP but every application protocol will be required to have different security considerations for using 0-RTT of TLS 1.3 and QUIC.

And implementation-wise, I think H2O/quicly might implement this due to the following reasons:
* H2O/quicly buffers requests that were deemed to early, instead of forwarding 425 to the client. Therefore we have memory pressure caused by 0-RTT stream data. That needs to be capped.
* It is after the HEADERS frame for the 0-RTT request is read out from the receive buffer that H2O receives a 425 from upstream. That means that we cannot rely on transport-level back pressure to avoid the peer sending additional data.

My understanding is that this type of implementation (i.e. buffering requests deemed to early, reading out HEADERS frame from receive buffer) is something we expect to see, and therefore it'd be unsurprising to see others also enforcing the limit.

-- 
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/2466#issuecomment-464255236