Subject: Re: [quicwg/base-drafts] Idempotency and replay (#4393)

From: Mike Bishop <[email-masked]>
Date: Tue, 01 Dec 2020 15:14:13 -0800

-tls, Section 4.6.2 says:

> When 0-RTT is rejected, all connection characteristics that the client assumed might be incorrect. This includes the choice of application protocol, transport parameters, and any application configuration. The client therefore MUST reset the state of all streams, including application state bound to those streams.

That means that the data which was previously sent is not re-sent by the stack; it's up to the application to re-establish state from scratch.  Do you think this language needs to be more explicit?

-- 
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/issues/4393#issuecomment-736879678

---

From: Jana Iyengar <[email-masked]>
Date: Tue, 01 Dec 2020 15:18:17 -0800

What @MikeBishop said. I've suggested a change to the PR to address @kazuho's other concern (`if permitted` vs. `MUST NOT unless requested`).

-- 
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/issues/4393#issuecomment-736882630

---

From: Nick Banks <[email-masked]>
Date: Tue, 01 Dec 2020 15:23:04 -0800

> The client therefore MUST reset the state of all streams

1. The `client` here has to be the app layer, right? It **cannot** be QUIC because of the need for an application specific error code.
2. Is this **MUST** absolutely necessary? It assumes the application protocol is sending data in 0-RTT that's dependent on the previous "connection characteristics", but that's not absolutely necessary.

-- 
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/issues/4393#issuecomment-736884433

---

From: Kazuho Oku <[email-masked]>
Date: Tue, 01 Dec 2020 21:05:29 -0800

@MikeBishop The text that you quote talks about the behavior of the transport. It also implies that from the viewpoint of the application, the stream opened in 0-RTT will continue to flow using 1-RTT packets.

My point is that such assumption is different from RFC 8446 that states that the stack "MUST NOT automatically resend 0-RTT data if it is rejected by the server unless instructed by the application," because in QUIC-TLS we do not have such a requirement (asking applications to specify if streams opened during 0-RTT MUST be closed unless instructed by the application). As @nibanks says, we do not even know how that can be achieved.

To summarize, the 0-RTT requirements of QUIC-TLS is different from RFC 8446, and QUIC-TLS is defining it's own rules.

-- 
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/issues/4393#issuecomment-736992575

---

From: Martin Thomson <[email-masked]>
Date: Mon, 07 Dec 2020 02:14:42 -0800

@nibanks:

> When informed of 0-RTT rejection, they have the option of aborting any stream data they had queued (and allowed the use of 0-RTT). This would result in the corresponding STREAM_RESET/STOP_SENDING frames being sent to the peer in 1-RTT. I the app doesn't abort, then we'd immediately retransmit the stream data in a 1-RTT packet the first chance we got. Should we not be doing this? 

Yes, you should not do this.  Take the case where 0-RTT is rejected because the stream limit is reduced.  If your application sends on 10 streams and is only permitted to send on 5 with the updated transport parameters, those frames will be sent and cause various errors.  The only response that is completely safe is to tell the application that everything it did was undone and that the connection has been reverted to a pristine state.

> To summarize, the 0-RTT requirements of QUIC-TLS is different from RFC 8446, and QUIC-TLS is defining it's own rules.

I think here that they are not as different as you imply.  What is different here is that QUIC has a split between QUIC-stuff and app-stuff that we are being clearer about.  TLS just sort of says "data" without qualification, which is OK because TLS with TCP only really has to deal with data (and EOED), assuming that you don't have other record types in 0-RTT (which is maybe possible, but likely a terrible idea).

However, if you consider the Section 8 text to apply to *application data*, then we're entirely consistent.  TLS doesn't say "idempotent is OK", it's quite a bit more nuanced than that.  What we're doing is building on that, not redefining 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/issues/4393#issuecomment-739818940

---

From: Nick Banks <[email-masked]>
Date: Mon, 07 Dec 2020 07:47:04 -0800

@martinthomson we don't resend the old data blindly. We will use the new transport parameters and generate new 0-RTT packets accordingly. Going back to a pristine state seems kind of catastrophic. You're saying we have to essentially force all application protocols to just start over completely? I can think of several examples where it doesn't matter what the server's TP change to, the application data could just be resent as is (limited by new FC as needed): for example, the client's initial state or settings.

-- 
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/issues/4393#issuecomment-740001071

---

From: Martin Thomson <[email-masked]>
Date: Mon, 07 Dec 2020 15:38:40 -0800

If you think that you can do better, then fine.  But the number of ways in which this could be broken are numerous: different ALPN, different stream limits, different flow control, and all sorts of things.  I'd say you are more likely to get catastrophic results by trying to retain state.

Separately, it sounds like you are accepting data for which you don't have flow control credit, for which you are also tempting fate when it comes to deadlocks.

-- 
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/issues/4393#issuecomment-740247901

---

From: Nick Banks <[email-masked]>
Date: Mon, 07 Dec 2020 16:22:32 -0800

> But the number of ways in which this could be broken are numerous: different ALPN, different stream limits, different flow control, and all sorts of things.

Can you explain how different ALPNs would work? My TLS understanding is probably lacking here. I don't understand that one. If you're doing/trying 0-RTT that means the client is using a single ALPN, right? If the connection continues, but 0-RTT is rejected, it'd still have to be that ALPN right?

> Separately, it sounds like you are accepting data for which you don't have flow control credit, for which you are also tempting fate when it comes to deadlocks.

If by this, you mean accepting data on the sender side, in preparation to send it, before the receiver has indicated enough FC window to accept it, then yes, we do allow the app to queue as much data up for send as it has available. As far as "tempting fate" I'd have to strongly disagree. This is a very common pattern **necessary** to "keep the pipe full" for performance. If I had to go ask the app for more data every time I got a window update from the peer, perf would tank.

Still, even with all these things changing, I don't see any current transport parameter or TLS setting that might change as a result of rejected 0-RTT that would prevent an application layer message saying something like "I support app feature X" being immediately retransmitting in 1-RTT by the transport (if the FC windows allow). For this reason, I don't think we MUST require applications to abandon everything and start over. We can strongly recommend and warn of possible issues. And as I mentioned before I don't know how you'd even enforce that must.

-- 
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/issues/4393#issuecomment-740263792

---

From: Martin Thomson <[email-masked]>
Date: Mon, 07 Dec 2020 16:39:42 -0800

> Can you explain how different ALPNs would work? 

A client can offer multiple protocols in the ALPN extension.  It should, because if it misrepresents its preferences, then that exposes it to downgrade attacks.  However, if it previously used one protocol and the server chooses a different protocol, the server has to reject 0-RTT.  But the server does have that choice.  At that point anything the client did in 0-RTT is completely invalid because it's a different protocol.

> necessary to "keep the pipe full" for performance

I realize that, just noting the deadlock risk.  I'm sure that it's OK if it's just message payloads.  Probably.

> I don't think we MUST require applications to abandon everything and start over

I never said that.  I said that what you are doing is risky.  Rejecting 0-RTT invalidates every assumption the client has made about what it can and can't do, starting from the application protocol.  When you optimize in the way you have, you are making a bet about what stays the same.  I just wanted to ensure that you  understood the consequences of that bet.

-- 
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/issues/4393#issuecomment-740270390

---

From: Nick Banks <[email-masked]>
Date: Mon, 07 Dec 2020 16:47:42 -0800

So, even when doing 0-RTT the client is still expected/allowed to offer multiple ALPNS?

As far as the MUST I thought someone pointed to text that essentially already stated that. I wasn't trying to put words in your mouth. I'm sorry if it came off that way. As to the risks involved, I totally agree there be dragons 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/issues/4393#issuecomment-740273134

---

From: Martin Thomson <[email-masked]>
Date: Mon, 07 Dec 2020 16:50:36 -0800

Yes, if the client supports multiple protocols, it needs to include them always.  If a better option than what was previously used becomes viable (e.g., the server might support h5), then using that is preferable to continue use of a less-preferred option.  Even if that less-preferred option allows 0-RTT.

The 0-RTT use is just once; the new protocol is potentially forever (especially if the reason for preferring the new protocol is that the old protocol has a security flaw).

-- 
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/issues/4393#issuecomment-740274047

---

From: Nick Banks <[email-masked]>
Date: Mon, 07 Dec 2020 16:52:16 -0800

Ok. Thanks @martinthomson. That makes sense. I'll need to add a test case for this, and make sure we support this appropriately.

-- 
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/issues/4393#issuecomment-740274608

---

From: Jana Iyengar <[email-masked]>
Date: Mon, 07 Dec 2020 22:08:27 -0800

There is a MUST, see @MikeBishop 's [comment above](https://github.com/quicwg/base-drafts/issues/4393#issuecomment-736879678).

@martinthomson: Is there clarification text that can help with your [response to @kazuho 's comment](https://github.com/quicwg/base-drafts/issues/4393#issuecomment-739818940)?

-- 
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/issues/4393#issuecomment-740401427

---

From: Kazuho Oku <[email-masked]>
Date: Mon, 07 Dec 2020 22:11:50 -0800

@martinthomson 
> However, if you consider the Section 8 text to apply to application data, then we're entirely consistent. TLS doesn't say "idempotent is OK", it's quite a bit more nuanced than that. What we're doing is building on that, not redefining it.

Thank you for elaborating. I think I misused the word "redefine." QUIC is using 0-RTT in a specific way that is permitted by TLS. Specifically, QUIC stacks are assumed to automatically resend 0-RTT data using 1-RTT keys, rather than delegating the decision to the application. If necessary, we can point that out as the difference.

-- 
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/issues/4393#issuecomment-740402823

---

From: Martin Thomson <[email-masked]>
Date: Tue, 08 Dec 2020 00:10:09 -0800

I think that there is a lot of commentary that might go along with these documents.  Particular when it comes to understanding how things like 0-RTT and its interactions with transport state, loss recovery, and other things.  I fear that if we get into too much detail in specifications it will be hard to get right and much harder to wade through to get the important stuff.  I'm content leaving this to commentary.

-- 
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/issues/4393#issuecomment-740457217

---

From: mirjak <[email-masked]>
Date: Tue, 08 Dec 2020 01:47:50 -0800

Is there anything more we want to say in the applicability statement though? E.g. impact on ALPN seems to need clarification...

-- 
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/issues/4393#issuecomment-740510625

---

From: Martin Thomson <[email-masked]>
Date: Wed, 09 Dec 2020 20:49:57 -0800

Closed #4393 via #4394.

-- 
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/issues/4393#event-4093158830

---

From: Martin Thomson <[email-masked]>
Date: Wed, 09 Dec 2020 20:50:24 -0800

Keeping open as agreed.

-- 
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/issues/4393#issuecomment-742237777

---

From: Martin Thomson <[email-masked]>
Date: Thu, 10 Dec 2020 04:50:25 +0000 (UTC)

Reopened #4393.

-- 
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/issues/4393#event-4093159620

---

From: MikkelFJ <[email-masked]>
Date: Sun, 20 Dec 2020 15:21:28 -0800

I did not follow the development on this issue an PR closely, but I came back here as I had the following thought:

If the application is able to protect itself against replay attacks, for example using entangled quantum effects, or something more mondane like a server side state, then 0-RTT does not have to be idempotent. Requiring it to be idempotent would prevent an application from managing side-effects intelligently.

It appears to me that the now merged PR indeed does remove the idempotency requirement, but at the same time this issue seems to suggest that there needs to be a requirement that is stronger that idempotency, which goes against the application that is able to handle this (along with a suitable application profile).

quote
> which goes further than idempotency and strongly recommends that only safe methods be used.

-- 
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/issues/4393#issuecomment-748685835

---

From: Martin Thomson <[email-masked]>
Date: Sun, 20 Dec 2020 15:27:09 -0800

Right.  The problem is that the client can't know what the server is doing.  So it can't commit to anything more than what is recommended without assuming some risk.

This text doesn't prevent an application protocol from defining signals that would allow a client to do something riskier.  The only normative text to this effect is:

> A client therefore MUST NOT use 0-RTT for application data unless specifically requested by the application that is in use.

-- 
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/issues/4393#issuecomment-748686502

---

From: MikkelFJ <[email-masked]>
Date: Sun, 20 Dec 2020 15:37:32 -0800

OK, so client in this context is the transport client. It basically cannot even do idempotent things without adult supervision, but with supervision, it can do more.

-- 
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/issues/4393#issuecomment-748687947