Subject: [quicwg/base-drafts] Add Advice and Rules for CONN_CLOSE in Initial and Handshake (#1786)

From: martinduke <[email-masked]>
Date: Fri, 21 Sep 2018 12:57:36 -0700

The presence of CONN_CLOSE in INITIAL and HANDSHAKE packets (and APP_CLOSE in HANDSHAKE) raises a number of questions for implementers.

If I must generate a CONN_CLOSE frame during the handshake, what context should I use? The highest one I have, or the highest that I received a packet for?

Relatedly, under what circumstances should I accept a CONN_CLOSE with old keys? I would argue we should toss any Initial Packet with CONN_CLOSE if the peer has already sent us something with Handshake keys, but it's possible to be more strict than that.

Should I accept a Handshake CONNECTION_CLOSE when we are using 1-RTT merely because I still have the Handshake keys lying around?

As far as I can tell, other frame types have no impact on the other contexts, except for a minor CRYPTO frame issue I'll handle in a different PR.

-- 
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/1786

---

From: martinduke <[email-masked]>
Date: Fri, 21 Sep 2018 13:11:47 -0700

I would recommend the following:
1) Always send CONN_CLOSE/APP_CLOSE with the strongest keys you have available.
2) If a packet contains a CONN_CLOSE in a context where you have already recevied a packet from the sender with a stronger context, drop it.

If people like this, I can write up a PR.

-- 
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/1786#issuecomment-423657304

---

From: ianswett <[email-masked]>
Date: Fri, 21 Sep 2018 13:18:58 -0700

I think 1 needs to be the strongest keys you know the peer can process?

-- 
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/1786#issuecomment-423659008

---

From: martinduke <[email-masked]>
Date: Fri, 21 Sep 2018 20:46:25 +0000 (UTC)

I don't think that works with #2. Though my rule doesn't work either. If the server needs to send one right after its first flight, it knows only that the peer processes INITIAL. The client will have HS packets from the server, so it will drop with Initial. The server might actually send 1-RTT, and this would work as well under the current rule if nothing is lost.

None of these solutions are obviously best, which is why there should be some guidance. I have to think about it some more, and would appreciate that others do so.

-- 
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/1786#issuecomment-423665660

---

From: MikkelFJ <[email-masked]>
Date: Sat, 22 Sep 2018 00:43:10 -0700

I belive at least the PR https://github.com/quicwg/base-drafts/pull/1788/files has text to reject secondary Initial packets toward the client. The server would not want to consider a connection close in an initial, but I'm not sure if this is stated explicitly.

-- 
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/1786#issuecomment-423724743

---

From: martinduke <[email-masked]>
Date: Mon, 24 Sep 2018 13:08:37 -0700

Also note that Item (1) above is explicitly stated in Section 4.9 of the quic-tls draft:

"Though an endpoint might retain older keys, new data MUST be sent at
   the highest currently-available encryption level."

The acceptance criteria are still, in my opinion, vague in the CONN_CLOSE case.

-- 
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/1786#issuecomment-424107516

---

From: Mike Bishop <[email-masked]>
Date: Wed, 26 Sep 2018 12:19:00 -0700

This is tricky, not just because you don't want an attacker to be able to inject the CC, but because all the mitigations themselves have ugly implications.

"Drop it" is a difficult directive -- if you mean drop the packet, what about other frames that you might have processed before encountering the CC frame?  Surely we're not adding a requirement that we be able to back out all interpreted frames if we encounter a frame that we don't like.

On the other hand, if you *don't* do that, then you're in an inconsistent state -- some of the frames that you've just consumed might have been attacker-generated and you've accepted them into the connection state.  Likewise if you only mean dropping the frame and continuing to process the rest of the packet.  That would argue for blowing up the connection as compromised anyway, which is exactly what would happen if you accepted the CONNECTION_CLOSE as valid.

Perhaps the most robust would be to require a first scan of any packet received at a lower encryption level than the highest ever seen (and always, for Initials) and reject the packet without processing any frames if illegal frame types are found.  (This is actually a compelling argument for making complex variable-length frames have an explicit length field, so they're easy to skip in this pass.)

Unless we do that, I'm inclined to think you don't fully trust a CONNECTION_CLOSE in Initial packets (perhaps not ever, or perhaps only after a short timeout to see if other Initials arrive), and you always trust and process a CONNECTION_CLOSE or APPLICATION_CLOSE from any other encryption level if you can validate the 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/issues/1786#issuecomment-424837812

---

From: MikkelFJ <[email-masked]>
Date: Wed, 26 Sep 2018 19:55:44 +0000 (UTC)

Actually, from memory, there is (or used to be) some text that states that a single packet MUST be valid before changing any state of the connection. That is a hard requirement that I'd like to get rid of, since it requires two passes over the frame list.

-- 
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/1786#issuecomment-424848523

---

From: MikkelFJ <[email-masked]>
Date: Wed, 26 Sep 2018 13:37:40 -0700

```
8.1.  Packet Processing and Acknowledgment

   A packet MUST NOT be acknowledged until packet protection has been
   successfully removed and all frames contained in the packet have been
   processed.  Any stream state transitions triggered by the frame MUST
   have occurred.  For STREAM frames, this means the data has been
   enqueued in preparation to be received by the application protocol,
   but it does not require that data is delivered and consumed.
```
I think this is the text I were referring to. It only speaks of ACK

-- 
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/1786#issuecomment-424861281

---

From: Ryan Hamilton <[email-masked]>
Date: Thu, 27 Sep 2018 12:33:44 -0700

It's a bit unclear to me what's special about CONNECTION_CLOSE on the receive side here. If I am prepared to, for example, process a STREAM frame in a packet, why would I not process a CONNECTION_CLOSE 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/issues/1786#issuecomment-425216176

---

From: ianswett <[email-masked]>
Date: Thu, 27 Sep 2018 12:39:23 -0700

I think Ryan's right.  If I'm processing a packet at an encryption level, then there are many ways to close the connection, including an invalid frame in an encryption level, etc.

So I think we're stuck with "Send CONNECITION_CLOSE with the highest keys you know the peer can decrypt."  And try to drop the Initial keys as soon as possible.  Unfortunately, that's currently not that fast at the moment.

-- 
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/1786#issuecomment-425217730

---

From: martinduke <[email-masked]>
Date: Thu, 27 Sep 2018 12:51:23 -0700

I would very much like to close the hole where Initial packets injected at arbitrarily long times after the handshake are able to bring the connection down, for obvious reasons.

The editor's draft says that we can choose to silently drop Initial packets with invalid frames, which IMO  is the correct response once we have handshake keys.

STREAM packets are only in app-key-protected packets, so that's not an informative example.  I keep old keys around essentially just to ack stuff and help the peer account for its packets -- you can't accept additional CRYPTO frames, and my point is you shouldn't accept a CONN_CLOSE that can bring down the connection.

-- 
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/1786#issuecomment-425220858

---

From: MikkelFJ <[email-masked]>
Date: Thu, 27 Sep 2018 13:18:08 -0700

The TLS mapping says
```
If the packet is from a previously installed encryption level, it MUST not contain data which extends past the end of previously received data in that flow. Implementations MUST treat any violations of this requirement as a connection error of type PROTOCOL_VIOLATION.
```
but since the initial encryption level is not strong, a man on the side could inject data to force a PROTOCOL_VIOLATION.

-- 
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/1786#issuecomment-425228655

---

From: ianswett <[email-masked]>
Date: Thu, 27 Sep 2018 13:20:08 -0700

I think this comes down to whether we require support implicit ACK of Initial packets.  If we do, we can close some of these holes.  If we don't, I can't see how to close these holes, since you need to keep ACKing the peer's Initial packets because you can't guarantee they have received previous ACKs and there's no other way to ACK those packets.

-- 
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/1786#issuecomment-425229222

---

From: MikkelFJ <[email-masked]>
Date: Thu, 27 Sep 2018 13:22:06 -0700

What is the problem with ignoring all communication with old levels once you have a handshake?
I'm not sure where key updates go, but it can be on lower crypto level I presume

-- 
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/1786#issuecomment-425229790

---

From: MikkelFJ <[email-masked]>
Date: Thu, 27 Sep 2018 13:22:38 -0700

One you have a handshake, it knows the peer also has it, that 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/issues/1786#issuecomment-425229964

---

From: ianswett <[email-masked]>
Date: Thu, 27 Sep 2018 13:23:16 -0700

There is no problem I'm aware of, but previously we have not required 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/1786#issuecomment-425230129

---

From: martinduke <[email-masked]>
Date: Thu, 27 Sep 2018 13:23:50 -0700

@mikkelfj Good find; I think that's a poor design.

@ianswett I think that when the context has been superseded, we should ACK otherwise legal packets and drop all others. "Legal packets" would only include ACK frames and CRYPTO frames with previously received offsets.

-- 
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/1786#issuecomment-425230304

---

From: martinduke <[email-masked]>
Date: Thu, 27 Sep 2018 13:32:01 -0700

I would recommend the following changes.

1) Update Sec 4.1.1 of the TLS draft (@mikkelfj 's find above) to allow quietly dropping the packet when CRYPTO overruns.
2) Silently drop packets with CONN_CLOSE if we have received a higher encryption level from the peer.
3) When closing the connection, send CONNECTION_CLOSE with the latest keys you have. If you haven't received a packet with those keys yet, also send with the previous keys.

If people are comfortable with that, I'll file a PR.

-- 
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/1786#issuecomment-425232570

---

From: MikkelFJ <[email-masked]>
Date: Thu, 27 Sep 2018 13:33:56 -0700

Is 2. necessary if you already ignore old levels?

-- 
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/1786#issuecomment-425233031

---

From: martinduke <[email-masked]>
Date: Thu, 27 Sep 2018 13:40:55 -0700

@mikkelfj There is nothing stopping you from dropping the context entirely, no, though if you do it too early the handshake can deadlock. For example, if the ACK of client finished is dropped several times, most implementations will free the handshake keys and we cannot finish the handshake.

The point of this issue is that I want to hang around to repeat acks if needed, but not leave myself open to injections of bogus stuff.

-- 
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/1786#issuecomment-425235039

---

From: MikkelFJ <[email-masked]>
Date: Thu, 27 Sep 2018 13:42:36 -0700

I mean after you see a higher level from peer. After that I can see the point of ACK or retransmission if you are also happy with that level, and if you are not, you don't transmit on that level.

Unless you want to ACK a level you are not ready to deal with yet.

-- 
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/1786#issuecomment-425235490

---

From: martinduke <[email-masked]>
Date: Thu, 27 Sep 2018 13:58:01 -0700

There are dumb but compliant ways to implement an end host and weird corner cases.

For example, the client's initial ACK could be lost, causing retransmission of server hello, even though handshake packets make it through.

etc.

-- 
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/1786#issuecomment-425240808

---

From: MikkelFJ <[email-masked]>
Date: Thu, 27 Sep 2018 14:04:44 -0700

"An endpoint SHOULD cancel pending retransmissions once it has received and processed a valid packet on a higher crypto level. An endpoint MUST ignore any packet received on a crypto level lower than the highest crypto level of any packet that it has received and processed". Or something. It's late...

-- 
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/1786#issuecomment-425242703

---

From: martinduke <[email-masked]>
Date: Thu, 27 Sep 2018 14:10:30 -0700

In my example, we've received Handshake packets from the server, but the server may need us to process another Initial packet.

Your text is veering into the idea of implicit acks, which is a worthy but wider discussion. It also doesn't really work for clients retransmitting their FINISHED. The server has app keys, and that demonstrates nothing about receipt of FINISHED.

-- 
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/1786#issuecomment-425244332

---

From: MikkelFJ <[email-masked]>
Date: Thu, 27 Sep 2018 14:18:54 -0700

But the server wouldn't process the level above FINISHED before processing FINISHED, would it? Since it cannot trust the handshake until then.

-- 
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/1786#issuecomment-425246586

---

From: martinduke <[email-masked]>
Date: Thu, 27 Sep 2018 14:23:31 -0700

If the FINISHED is lost, the server could still send 1-RTT data in response to a 0-RTT request. Your rule would abort retransmission of FINISHED, leading to all sorts of problems.

-- 
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/1786#issuecomment-425247779

---

From: MikkelFJ <[email-masked]>
Date: Thu, 27 Sep 2018 14:29:04 -0700

Correct, I am confusing crypto levels with packet number levels. If we modify the text to PN levels it might work, but I can see that gremlins might be hiding.

-- 
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/1786#issuecomment-425249193

---

From: Martin Thomson <[email-masked]>
Date: Thu, 27 Sep 2018 15:42:56 -0700

> Update Sec 4.1.1 of the TLS draft (@mikkelfj 's find above) to allow quietly dropping the packet when CRYPTO overruns.

Seems reasonable, as a MAY.

> Silently drop packets with CONN_CLOSE if we have received a higher encryption level from the peer.

Mostly OK, but you might have already processed some frames when you hit the CONNECTION_CLOSE.  We'd need to address that.

> When closing the connection, send CONNECTION_CLOSE with the latest keys you have. If you haven't received a packet with those keys yet, also send with the previous keys.

Send with the keys you know that your peer has.  That is, if you have received X, send with X.  You might already be sending with X+1, but it isn't always guaranteed that your peer has X+1.  For instance, the server might be sending Handshake packets, but the client might not have processed all of the Initial yet.

-- 
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/1786#issuecomment-425265494

---

From: martinduke <[email-masked]>
Date: Thu, 27 Sep 2018 17:36:59 -0700

> Mostly OK, but you might have already processed some frames when you hit the CONNECTION_CLOSE. We'd need to address that.

Yes, there are some unpleasant corner cases there.

> Send with the keys you know that your peer has. That is, if you have received X, send with X. You might already be sending with X+1, but it isn't always guaranteed that your peer has X+1. For insta…

This doesn't work with the second item. If I've received context X while having sent X+1, this rule would force me to send CONN_CLOSE in X. If X+1 arrives first, the receiver would ignore X.

-- 
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/1786#issuecomment-425284178

---

From: martinduke <[email-masked]>
Date: Thu, 27 Sep 2018 18:08:19 -0700

What's really motivating this is INITIAL, and HANDSHAKE packets introduce a lot of complications due to the late client FINISHED and relatively early application data.  So let's separate the cases

So, rules for sending CONN_CLOSE:
- if you've received 1-RTT packets, use that, else
- if you've received HANDSHAKE, use that, else
- if you've sent HANDSHAKE but received only INITIAL, send in both in a coalesced packet, else
- send in INITIAL

for receiving
- If it comes in INITIAL, and you have received HANDSHAKE, drop, else*
- accept it.

* I don't think there's a "what else have I processed" problem here. The spoofed packet could contain
(1) an ACK of the Hello message, which is already implicit in the receipt of handshake packets
(2) old crypto data, which triggers an ACK but is otherwise fine - what happens if we ACK an unsent packet? we might want to reverse the decision to ACK, I guess
(3) New crypto data, which we should ignore given we've already moved on to handshake

-- 
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/1786#issuecomment-425288534

---

From: ianswett <[email-masked]>
Date: Thu, 27 Sep 2018 18:24:55 -0700

If the Initial arrives with frame types that aren't valid in the Initial, you're going to have to decide how to handle it.  This could easily happen after you receive a valid frame.  But even if the STREAM frame is the only thing in the invalid Initial, it's effect would be to close the connection, correct?

By reading your 3 items, it seems like at some point we should mostly ignore Initial packets, but send an ACK?

I think the sender text is fairly straightforward, but we have 3 options I'm aware of on the receiver side:
1) Require implicit ACKs.
2) Instruct the receiver to ACK Initial encryption after receiving Handshake, but not process them.
3) Decide we don't care about injection attacks.

-- 
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/1786#issuecomment-425291149

---

From: martinduke <[email-masked]>
Date: Thu, 27 Sep 2018 18:48:45 -0700

I think you're convincing me to generalize this issue into "Don't tear down the connection due to a Initial Packet if you're already at Handshake or later". We'll always be vulnerable to injection, but by carefully wording it we can limit that vulnerablity to 1.5 RTTs.

That is much simpler guidance and avoids opening all the issues that this discussion has brought up..

-- 
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/1786#issuecomment-425294726

---

From: Ryan Hamilton <[email-masked]>
Date: Thu, 27 Sep 2018 20:41:44 -0700

That guidance is confusing to me. We end up in this special realm where we accept initial packets, but only if they don't close the connection? My sense is that there are no "good" reasons that a receiver would need to process an initial packet other than to ACK them. Is that right? If so, it sure seems like a cleaner solution to this problem is Ian's option 1: Implicit ACKs. Drop initial keys ASAP and then we need no special handling for this case.

But perhaps the situation is more subtle than I'm thinking 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/issues/1786#issuecomment-425311632

---

From: Kazuho Oku <[email-masked]>
Date: Fri, 28 Sep 2018 01:33:24 -0700

@ianswett 
> 1. Require implicit ACKs.
> 2. Instruct the receiver to ACK Initial encryption after receiving Handshake, but not process them.
> 3. Decide we don't care about injection attacks.

IIRC the discussion during the handshake redesign process was that we should not care about injection attacks, though the design allows stacks to implement countermeasures (see [TLS Handshake Messsages on QUIC; section 3.4](https://docs.google.com/document/d/1fRsJqPinJl8N3b-bflDRV6auojfJLkxddT93j6SwHY8/edit)).

For a middlebox, the easiest way of disrupting a handshake is to send a crafted Initial in response to the client's first flight. We do require the endpoints to implement protection for that. So I do not think there is a reason to care about injection attacks happening at a later moment.

-- 
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/1786#issuecomment-425363631

---

From: MikkelFJ <[email-masked]>
Date: Fri, 28 Sep 2018 01:40:27 -0700

Well, the specs says that you MUST terminate the connection. You can't countermeasure that without not being QUIC.

I don't really care about implicit ACKs when seen as an optimization, but as a way to protect the connection it is the only thing that makes sense. All the other stop gaps are complex and deals with single cases. As @martinduke has pointed out, there are also issues with implicit acks, but I would be surprised if they can't be ironed out - for example by considered PN spaces instead of crypto level as I suggested earlier.

I'm also wondering if the FINISHED could be sent as the first frame on the 1-RTT crypto 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/issues/1786#issuecomment-425365465

---

From: Kazuho Oku <[email-masked]>
Date: Fri, 28 Sep 2018 02:23:20 -0700

> Well, the specs says that you MUST terminate the connection. You can't countermeasure that without not being QUIC.

You cannot process packets once you drop the keys, meaning that you would never see the CONNECTION_CLOSE packet, or anything else that might disrupt the handshake. Therefore, what an endpoint that is cautious of detecting attacks should do is drop the Initial key at the earliest moment. I simply do not see why we need to handle CONNECTION_CLOSE differently than other frames that we might see in a Initial packet that arrives at a later moment.

And in regard to the philosophical question of if ignoring a Initial packet that you detected and found a CONNECTION_CLOSE frame is against the spec., my argument would be that stacks are allowed to do whatever they want in these circumstances. In my view, it is the same as having a packet filter that drops suspicious TCP packets.

-- 
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/1786#issuecomment-425377046

---

From: martinduke <[email-masked]>
Date: Fri, 28 Sep 2018 14:18:29 -0700

@ianswett Personally, I'm reluctant to cross the implicit ACK bridge. Messing with the ack and retransmission logic, at this point, could result in unforeseen consequences in the handshake. I would much rather restrict the weirdness to error cases in the just after the Initial phase, which is unlikely to be exercised often.

@kazuho I want to clarify an important distinction here. There is nothing we can do about injection attacks in the first 1.5 RTTs, and that is not the objection here. There is a further vulnerability, after handshake keys are employed, until we dispose of the keys. I am trying to close that hole without driving people to run their timers too short.

You may be right that people will do it anyway. But I'd like to spec to be consistent with best practice.

Do people think this is discussion is far enough along that they'd like to see a PR?

-- 
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/1786#issuecomment-425568975

---

From: Kazuho Oku <[email-masked]>
Date: Sun, 30 Sep 2018 02:24:34 -0700

@martinduke My point is that it is IMO meaningless to have a rule specific to processing  aCONNECTION_CLOSE frame when any other frame (or a malformed payload) can cause the handshake to fail.

OTOH, I am not against clarifying how an endpoint should send CONNECTION_CLOSE during the handshake. In fact, it is essential, because we allow the peer to drop it's keys at it's own discretion. Unless we describe the correct way of sending a CONNECTION_CLOSE frame, the peer might fail to decode the packet that contains CONNECTION_CLOSE.

Having that said, the most straightforward rule for sending CONNECTION_CLOSE would be to send the frame in *all* epochs for which the endpoint possesses the write keys. This is basically the contraposition of the receiver being allowed to drop the read keys at any point.

-- 
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/1786#issuecomment-425707186

---

From: ianswett <[email-masked]>
Date: Sun, 30 Sep 2018 17:22:58 -0700

I'm happy clarifying what the sender should do and leaving the receiver side fairly flexible.  I'm not sure all epochs are necessary.  Possibly "in the highest epoch the sender knows the peer can process and one higher if the peer may be able to process it." or something along those lines?

-- 
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/1786#issuecomment-425763501

---

From: Kazuho Oku <[email-masked]>
Date: Sun, 30 Sep 2018 18:02:28 -0700

@ianswett 
> I'm not sure all epochs are necessary. Possibly "in the highest epoch the sender knows the peer can process and one higher if the peer may be able to process it." or something along those lines?

Yeah. The problem here is that the rule to determine "the highest epoch the peer can process" is complex and specific to TLS 1.3. IIRC that is one of the reasons we favored the explicit-ACK approach instead of the implicit- approach.

Anyways, the requirement here is that we need to at least state that the endpoints MUST send CONNECTION_CLOSE protected by a key that the peers established, if such key is available. Otherwise, peers trying to do their best against Initial packet injection attacks would not recognize the frame.

Perhaps stating something like the following might suffice; that for sending CONNECTION_CLOSE during handshake, an endpoint
* uses the Initial packet if it does not know the Handshake write key
* uses the Handshake packet if it has received a Handshake packet
* uses both the Initial packet and the Handshake packet if it has not received a Handshake packet but it knows the Handshake write key

The downside of the rule will be that the peers might not be able to drop Handshake keys as aggressively as the Initial keys. But IIUC that's fine from security perspective because Handshake packets are protected by the key agreement.

-- 
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/1786#issuecomment-425766045