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

Bound 0-to-1-RTT Transition #2466

Closed
wants to merge 2 commits into from
Closed

Bound 0-to-1-RTT Transition #2466

wants to merge 2 commits into from

Conversation

MikeBishop
Copy link
Contributor

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, "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.

@MikeBishop MikeBishop added design An issue that affects the design of the protocol; resolution requires consensus. -transport labels Feb 14, 2019
Copy link
Member

@martinthomson martinthomson left a comment

Choose a reason for hiding this comment

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

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.

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.
Copy link
Member

Choose a reason for hiding this comment

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

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.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Fair enough. We can PV on this.

Copy link
Contributor

Choose a reason for hiding this comment

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

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

Copy link
Contributor

Choose a reason for hiding this comment

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

Nooo: an attacker can replay old 0-RTT packets with higher packet numbers and force a close. The packets MUST be dropped.

However, I don't like the explicit drop requirement. It should happen automatically when the 0-RTT key is dropped. No reason for the server to keep track of packet numbers if the key drop is precise.

Copy link
Contributor

Choose a reason for hiding this comment

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

An attacker can't replay any packets except Initial with a higher packet number, unless the attacker has the keys(in which case, you have bigger problems).

@MikeBishop
Copy link
Contributor Author

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. :-)

@martinthomson
Copy link
Member

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.

@DavidSchinazi
Copy link
Contributor

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.

@kazuho
Copy link
Member

kazuho commented Feb 15, 2019

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.

@kazuho
Copy link
Member

kazuho commented Feb 15, 2019

@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.

@DavidSchinazi
Copy link
Contributor

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

@kazuho
Copy link
Member

kazuho commented Feb 15, 2019

@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 #2461 (comment). Or are you suggesting to reconsider the conclusion for #2360?

@mikkelfj
Copy link
Contributor

mikkelfj commented Feb 15, 2019

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

Agreed. Then you 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?

@DavidSchinazi
Copy link
Contributor

@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

@kazuho
Copy link
Member

kazuho commented Feb 16, 2019

@DavidSchinazi Spec-wise, my view is that we should recommend (or at least state that it's possible that) servers 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 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.

@janaiyengar
Copy link
Contributor

@MikeBishop @DavidSchinazi : Should we close this one in favor of #2461?

@DavidSchinazi
Copy link
Contributor

@janaiyengar That works for me.

@MikeBishop
Copy link
Contributor Author

I think where we've landed is that #2461 contains the principles and this has the recommended server enforcement mechanism. I'd like to see the enforcement in that PR spelled out more explicitly, but I agree that we want the principles there.

@MikeBishop MikeBishop closed this Apr 18, 2019
@martinthomson martinthomson deleted the transport/0-to-1-rtt branch April 30, 2019 22:55
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
-transport design An issue that affects the design of the protocol; resolution requires consensus.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Client MUST use 1-RTT packets if it reads 1-RTT packets 0-RTT flow control limits can't be increased
7 participants