>
> The 0-RTT API in NSS allows a server to detect this transition.  The
> problem that I think David was referring to is that the specific
> instant of the transition is lost when the multiple layers of stack
> that sit on top of TLS get involved.
>

To David's second paragraph, if we eventually authenticate the early data
as strongly as 1-RTT data, then there is no problem with long requests.
I.e., if the client starts a long PUT request that doesn't finish until
after the handshake is done, then the connection could be broken by the
server stack mid-request if it is able to figure out that the early data
was replayed. It appears this will be the case because the handshake
context for 0-RTT includes the ClientHello, which includes the early data,
so the client {Finished} will cover it. (Not clear on the value of 0-RTT to
long PUT requests, but you provide a more likely example below.)

If an HTTP client sends a request that relies on HPACK state that was
> established during 0-RTT, is it a 0-RTT request?  I'm going to go with
> probably not.
>

For the above reason, the HPACK state should be strongly authenticated by
this point, at which point it's no longer 0-RTT data.

Since the authentication status of early data may vary over the course of
the connection from "unknown/possibly replayed" to either "replayed" or
"authentic", maybe we should classify it by its status at the time we go to
use it. Which suggests the following terrible API for the server:

read(max) will return either a string of fully-authenticated data up to max
bytes, or EAGAIN if none is available (with possibly some side-band
mechanism for indicating that data of unknown authenticity is available)

read_sketchy(max) will return possibly-sketchy data up to max bytes, or 0
if there is no more such data (at which point the caller should switch to
regular read), or EAGAIN if the entire ClientHello hasn't yet been received.

If the server doesn't care about early data, or waits long enough for the
handshake to complete, all data will have been elevated to authentic or the
connection broken, depending on what happened with client {Finished}.

On the client side, one option is for the early data to be specified prior
to or alongside handshake initiation, with some indication by the stack of
whether it was written or not. (I suggest all-or-none.) This precludes
question on the part of the client as to which data might have been sent
0-RTT and which must have been sent 1-RTT.

One of the nice things about the above API is that a simple server wanting
to process early data ASAP can do the same thing every time:

poll for read
try:
  r = read_sketchy()
  if r: do_something_with_early_data(r)
catch EAGAIN: noop
try:
  r = read()
  if r: do_something(r)
  else: terminate_connection
catch EAGAIN: noop

Another nice thing is that at the moment you receive a single byte from
read() you know a priori that every byte of early data you processed was
authentic.

Do we want to support the case in which 0-RTT failure means the client can
send entirely different data? If so, then the above isn't general enough,
but the client API could offer an option to say "don't resend this data if
0-RTT fails" with some flag set on this condition or (for event systems) a
callback registered to do something more interesting.

The above API also doesn't support the case in which the server wants to
treat 0-RTT data entirely different from 1-RTT data, which would suggest a
side-band/two channel API. Is this interesting to anyone? I'm not sure I
can see any use for purposely ignoring post-hoc authentication of early
data.

Kyle
_______________________________________________
TLS mailing list
TLS@ietf.org
https://www.ietf.org/mailman/listinfo/tls

Reply via email to