Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Permit 0-RTT after Retry and VN #1514

Merged
merged 9 commits into from
Jul 31, 2018
Merged

Permit 0-RTT after Retry and VN #1514

merged 9 commits into from
Jul 31, 2018

Conversation

martinthomson
Copy link
Member

After the discussion on #1507, I've been convinced that there is no real
value in preventing a client from attempting 0-RTT after a Retry. And,
it would seem like Version Negotiation has essentially the same
properties, so excluding it would be inconsistent.

This allows this, explores the consequences for packet numbers (don't
reset them!), and updates the recovery text to include Version
Negotiation.

Closes #1507.

(Note the target of this PR. Two pieces of work are in flight here. Don't just merge and walk away or something could get lost.)

@@ -770,6 +776,28 @@ are in a different packet number space to other packets (see
{{packet-numbers}}).


### 0-RTT Packet Numbers {#retry-0rtt-pn}

Packet numbers for 0-RTT protected packets use the same space as 0-RTT protected
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

"as 0-RTT protected" -> "as 1-RTT protected"?

If the client has a token received in a NEW_TOKEN frame on a previous connection
to what it believes to be the same server, it can include that value in the
Token field of its Initial packet.
If the client has an token received in a NEW_TOKEN frame on a previous
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

a token

packets to the connection ID provided by the server. A client that sends
additional 0-RTT packets MUST NOT reset the packet number to 0 after a Retry
packet, see {{retry-0rtt-pn}}.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

sugg: A server MAY reject a redirected 0-RTT attempt because the DCID does not match the 0-RTT token.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not sure that I understand the suggestion.

Copy link
Contributor

@mikkelfj mikkelfj Jul 6, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Me neither - the thought was to use the dcid given in the retry - which could lead to a target that does not accept the tokens. But dcid cannot change from when tokens were forged.

address or network interface. Reusing a token on different network paths would
allow activity to be linked between paths (see {{migration-linkability}}). A
client needs to start the connection process over if it migrates prior to
completing the handshake.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Redundant explanation using both "correlate" and "linked" in separate sentences.

If the client has a token received in a NEW_TOKEN frame on a previous connection
to what it believes to be the same server, it can include that value in the
Token field of its Initial packet.
If the client has an token received in a NEW_TOKEN frame on a previous
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

a?

After a client receives a Retry or Version Negotiation packet, it MAY attempt to
send data in 0-RTT packets after it sends a new Initial packet. However, a
client MUST NOT reset the packet number it uses for 0-RTT packets. The keys
used to protect 0-RTT keys are not guaranteed to change as a result of
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Technically, I don't think there's even a mechanism the 0-RTT keys could be changed via Retry, so I'd say "not likely to change"?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I struggled with finding the right words, but I have a plan now. They won't change unless the cryptographic handshake does. (And I will leave unsaid the reasons why it might not - we have reason to believe that Retry will never cause a change and VN might, but that detail is elsewhere and if we follow the justification rabbit-hole to the end we'll be singing about oysters in no time.)

Copy link
Contributor

@MikeBishop MikeBishop left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I eventually figured out what you actually meant, but it didn't click for me reading the text the first time. If it's not just me, perhaps more/different explanation is in order.

The key point is that if the CID doesn't change, the 0-RTT packets from before and after the Retry can both be accepted and processed as part of the connection, either via buffering or reordering. So you have to resend all that data, but can't reuse those packet numbers.

NOT be treated as an acknowledgment for the Initial, but it MAY be used for an
RTT measurement.
Either packet indicates that the Initial was received but not processed. Either
packet cannot be treated as an acknowledgment for the Initial, but they MAY be
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

"Either ... cannot" feels awkward. Maybe "Neither packet can be...."?

Token field of its Initial packet.
If the client has a token received in a NEW_TOKEN frame on a previous
connection to what it believes to be the same server, it can include that value
in the Token field of its Initial packet.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This paragraph looks like a rewrap to a shorter line length than the rest of the document. The original layout appears to be fine.

connections to be identified as coming from the same endpoint (see also
{{migration-linkability}}). A client MUST NOT reuse a token if it believes that
its point of network attachment has changed; that is, if there is a change in
its local IP address or network interface. A client MUST start the connection
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I know you didn't change this text, but this seems to preclude clients keeping a cache of tokens and the associated network connections. For example, a mobile device that went to Wi-Fi could keep the cellular token in expectation that it will be on cellular again. Perhaps the better prohibition is that you MUST NOT use the token on a different network than where you received it?


After a client receives a Retry or Version Negotiation packet, it MAY attempt to
send data in 0-RTT packets after it sends a new Initial packet. However, a
client MUST NOT reset the packet number it uses for 0-RTT packets. The keys
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If the CID doesn't change, reordering or caching could cause the first flight of 0-RTT packets to remain valid after the new Initial lands. So unless the CID changes (and maybe even if it does, if the server is trying too hard), you have to assume those packets are still outstanding but potentially lost. Maybe we should frame this in terms of fast retransmit?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I realize now the source of the confusion. You are concerned about the case where maybe all this 0-RTT is received (and can be processed). I'm more concerned about catastrophic compromise of packet protection. I think that the nonce reuse thing is more urgent.

@@ -1311,6 +1339,10 @@ Version Negotiation packet.
A client MUST ignore a Version Negotiation packet that lists the client's chosen
version.

A client MAY attempt 0-RTT after receiving a Version Negotiation packet. A
client that sends additional 0-RTT packets MUST NOT reset the packet number to 0
after a Retry packet, see {{retry-0rtt-pn}}.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since this section is about Version Negotiation packets, the mention of Retry packets seems a non sequitur. It's fine to reset the 0-RTT packet number space after a VN packet, because the previous 0-RTT packets will be of a version unknown to the server and therefore will just be discarded (or rather, will trigger more VN packets).

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's not OK to reset the packet numbers, because you just created a two-time pad. The same key and nonce, with different inputs (the version number). That's disastrous.

The mention of Retry is a mistake though.

Copy link
Contributor

@MikeBishop MikeBishop left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Regardless of urgency, I think this covers both cases a little better. It might still be worth mentioning that the previous flight of 0-RTT packets could still be consumed by the server, so the client needs to consider that data as having been sent (and therefore can't change it).

@mikkelfj
Copy link
Contributor

mikkelfj commented Jul 6, 2018

I think it does not matter if the packet got to a server - but it might have gotten to an attacker.

@quicwg quicwg deleted a comment from mikkelfj Jul 6, 2018
packets.

After a client receives a Retry or Version Negotiation packet, 0-RTT packets are
likely to be lost or discarded by the server, especially if the server changes
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

s/likely to be/likely to have been/


After a client receives a Retry or Version Negotiation packet, 0-RTT packets are
likely to be lost or discarded by the server, especially if the server changes
its connection ID with a Retry packet. A client MAY attempt to send data in
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

s/send data/resend data/

A client SHOULD NOT reuse a token. Reusing a token could allow different
connections to be identified as coming from the same endpoint (see also
{{migration-linkability}}). A client MUST NOT reuse a token if it believes that
its point of network attachment has changed since it was last used; that is, if
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This seems too strong -- see my comment on the other PR.

After the discussion on #1507, I've been convinced that there is no real
value in preventing a client from attempting 0-RTT after a Retry.  And,
it would seem like Version Negotiation has essentially the same
properties, so excluding it would be inconsistent.

This allows this, explores the consequences for packet numbers (don't
reset them!), and updates the recovery text to include Version
Negotiation.

Closes #1507.

After a client receives a Retry or Version Negotiation packet, 0-RTT packets are
likely to have been lost or discarded by the server, especially if the server
changes its connection ID with a Retry packet. A client MAY attempt to resend
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The text after "especially if ..." seems to imply that 0-RTT packets might not have been lost in case the client receives a Version Negotiation packet.

I am not sure if that is true.

My understanding is that a Version Negotiation packet is sent by a server only if the client offers a version unknown to the server. In such case, all the 0-RTT packets would have been lost, because the format of the 0-RTT packets are version specific, and those would have been unprocessible by the server.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, this is right. In order of likelihood that packets are unusable:

  1. VN with unsupported version
  2. Retry w/ connection ID change
  3. Retry w/o connection ID change or VN with preferred alternative version

I don't know why I missed that. Reworded.

Copy link
Contributor

@ianswett ianswett left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@martinthomson martinthomson changed the base branch from move-retry to master July 31, 2018 05:13
@martinthomson martinthomson merged commit cd6b76e into master Jul 31, 2018
@martinthomson martinthomson deleted the allow-retry-0rtt branch July 31, 2018 05:14
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

7 participants