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

Separate key/secret availability from usage #1654

Merged
merged 3 commits into from
Aug 14, 2018
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
31 changes: 21 additions & 10 deletions draft-ietf-quic-tls.md
Original file line number Diff line number Diff line change
Expand Up @@ -440,23 +440,34 @@ Important:

### Encryption Level Changes

At each change of encryption level in either direction, TLS provides QUIC with
the new level and the encryption keys. These events are not asynchronous; they
always occur immediately after TLS is provided with new handshake octets, or
after TLS produces handshake octets.
As keys for new encryption levels become available, TLS provides QUIC with those
keys. Separately, as TLS starts using keys at a given encryption level, TLS
indicates to QUIC that it is now reading or writing with keys at that encryption
level. These events are not asynchronous; they always occur immediately after
TLS is provided with new handshake octets, or after TLS produces handshake
octets.
Copy link
Contributor

Choose a reason for hiding this comment

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

But doesn't the production of new handshake octets also occur immediately after TLS is provided with new incoming octets? I suspect we could condense that statement.

Copy link
Member

Choose a reason for hiding this comment

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

That's not always the case. People sometimes offload public key crypto to different devices (even to different continents when private key leakage is a concern).

Copy link
Contributor

Choose a reason for hiding this comment

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

@kazuho that may be so, but isn't TLS / QUIC currently stating that all interaction is synchronous?


If 0-RTT is possible, it is ready after the client sends a TLS ClientHello
message or the server receives that message. After providing a QUIC client with
the first handshake octets, the TLS stack might signal the change to 0-RTT
keys. On the server, after receiving handshake octets that contain a ClientHello
message, a TLS server might signal that 0-RTT keys are available.

Note that although TLS only uses one encryption level at a time, QUIC may use
more than one level. For instance, after sending its Finished message (using a
CRYPTO frame in Handshake encryption) may send STREAM data (in 1-RTT
encryption). However, if the Finished is lost, the client would have to
retransmit the Finished, in which case it would use Handshake encryption.

Although TLS only uses one encryption level at a time, QUIC may use more than
one level. For instance, after sending its Finished message (using a CRYPTO
frame at the Handshake encryption level) an endpoint can send STREAM data (in
1-RTT encryption). If the Finished message is lost, the endpoint uses the
Copy link
Contributor

Choose a reason for hiding this comment

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

It might actually be more instructive to talk about CRYPTO frames at different levels. Maybe the 1-RTT data could be a New Session Ticket in a CRYPTO frame?

Handshake encryption level to retransmit the lost message. Reordering or loss
of packets can mean that QUIC will need to handle packets at multiple encryption
levels. During the handshake, this means potentially handling packets at higher
and lower encryption levels than the current encryption level used by TLS.

In particular, server implementations need to be able to read packets at the
Handshake encryption level before the final TLS handshake message at the 0-RTT
encryption level (EndOfEarlyData) is available. Though the content of CRYPTO
frames at the Handshake encryption level cannot be forwarded to TLS before
EndOfEarlyData is processed, the client could send ACK frames that the server
needs to process in order to detect lost Handshake packets.

Copy link
Contributor

Choose a reason for hiding this comment

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

I am not sufficiently familiar with the handshake process to really have an opinion here. But while I understand most of the text, the last paragraph seems very dense,

Copy link
Contributor

@huitema huitema Aug 13, 2018

Choose a reason for hiding this comment

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

Looks good. You may or may not want to hammer the point about ordering. Something like this:

Proper operation of TLS requires delivery of handshake octets to the TLS receiver in the order in which they were produced by the sender, but QUIC can only guarantee ordering within an encryption level. Due to possible reordering and losses it is possible that encryption level 1 messages sent in 0-RTT packets arrive after level 2 messages sent in Handshake packets. QUIC implementations need to make sure that handshake messages are only submitted to TLS when TLS is ready to accept messages at that encryption level.

Copy link
Member Author

Choose a reason for hiding this comment

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

Encryption levels are strictly ordered, so isn't it possible that QUIC can guarantee ordering in what it delivers to TLS?

The point you are making is well taken though; packets might arrive out of order and QUIC is responsible for ensuring that they are delivered to TLS in the correct order.

Take a look at the text I've added. I think that hammers the point home hard enough.

Copy link
Contributor

Choose a reason for hiding this comment

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

There is no requirement that QUIC guarantees ordering. In fact, it will deliver data from different streams in different order than they were received -- this is essential to avoid head of line blocking. The only guaranteed ordering is within a stream, or within a crypto stream.

Your paragraph develops the need for QUIC to handle the different Crypto contexts in parallel. That's fine, but in my mind that's not the same requirement as delivery of crypto-stream in specified order. In fact, just ordering them is not sufficient, because the QUIC implementation does not actually know how long a particular crypto stream is. There is no end mark. So how does it logically deduce that level N is now done, and that it is OK to proceed with N+1?

Copy link
Member

Choose a reason for hiding this comment

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

@huitema

In fact, just ordering them is not sufficient, because the QUIC implementation does not actually know how long a particular crypto stream is. There is no end mark. So how does it logically deduce that level N is now done, and that it is OK to proceed with N+1?

IIUC our assumption is that the TLS stack will somehow notify the QUIC stack what the current read epoch is, and that the QUIC stack will only supply the contents of CRYPTO frames received in that epoch.

In my view, the following sentence in the PR implies that.

Though the content of CRYPTO frames at the Handshake encryption level cannot be forwarded to TLS before EndOfEarlyData is processed, the client could send ACK frames that the server needs to process in order to detect lost Handshake packets.

Or is it the case that you are uncomfortable with the text dealing with how to handle TLS messages?

Copy link
Contributor

Choose a reason for hiding this comment

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

I may be suffering from excess of caution, after spending some time debugging the out of order EOED issue. But yes, the explicit mention of out of order EOED and need to reorder is there, so I guess I the text is fine.

Copy link
Member

@nibanks nibanks Aug 14, 2018

Choose a reason for hiding this comment

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

One of the reasons I opened #1592 was to make it easier to know when one part of the CRYPTO stream ended and another started. It also made ordering easier and more explicit, IMO. But everyone seemed to disagree at the time.

Copy link
Member

Choose a reason for hiding this comment

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

@nibanks FWIW, I still prefer the current approach above #1592.

By having different crypto streams at every epoch, TLS stacks can check if the TLS messages were delivered using the correct epoch. The verification is crucial for TLS.

If we allow single "stream" (i.e. flow of octets) span across multiple epochs, it becomes much harder to have that kind of enforcement in the API design, and I would assume that at least some of the QUIC implementations will fail to implement correct verification (consider the fact that most of us failed to notice NSTs sent using a cleartext packet).


### TLS Interface Summary
Expand Down