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 following: - 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. -Ilari _______________________________________________ TLS mailing list TLS@ietf.org https://www.ietf.org/mailman/listinfo/tls