On Tue, Oct 11, 2016 at 09:41:55PM -0400, Kyle Rose wrote:
> >
> > 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.)

I have actually seen one service where partially received PUT requests
had "side effects". Fortunately, not a replay problem in that case,
since application would reject replays anyway.

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

For when 0-RTT has become boring enough for me to implement, I would
think the server-side interface I put in would be something like the

- ServerSession::getReplayable0RttReader(alp_list) -> ZRttReader
- ZRttReader::getAlpn() -> String
- ZRttReader::dataAvailable() -> size
- ZRttReader implements Read

If there is no replayable 0RTT reader given when ClientHello is
received, or if the ALP of the 0-RTT does not match any in alp_list,
the 0-RTT is rejected. Otherwise it is accepted and the data stream is
received via the ZRttReader. Then regular 1-RTT data will be returned by
the usual Read interface of ServerSession.

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

In the interface above, not caring about 0-RTT gets 0-RTT rejected. And
waiting just causes the connection to freeze up.
> 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.

The interface I envision has client write all the 0-RTT data and
explicitly signal the end of data, with a callback if server rejects,
so the application can abort the flight early (the stack just black-
holes the data after error).

And of course some critical thingy in which normally blocks 0-RTT
sending has name suggestive of replayability.

The reason for waiting for application to ACK the 0-RTT error is that
the thing is MT-safe, so one has to prepare for races..
> 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.

Well, one always knows that for any received data, one who sent it
possesses the PSK secret and it can't be tampered with without the
PSK secret.

However, receiving any 1-RTT data after 0-RTT data does not imply that
the 0-RTT data was not replayed!
> 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.

There's the case where ALP mismatches (and unfortunately, due to how
ALPN and 0-RTT interact, mismatches can happen in cases other than
just that 0-RTT is fundamentially impossible).

In that case, the data is obviously different. Then there are also
things like the planned 0-RTT tokbind, where the data sent on 0-RTT
failure is different from the original data.

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

I regard post-hoc authentication as quite dangerous. At least in
some applications it is a deadly security mistake.


TLS mailing list

Reply via email to