Re: [TLS] Application layer interactions and API guidance

Ilari Liusvaara <ilariliusvaara@welho.com> Wed, 12 October 2016 08:11 UTC

Return-Path: <ilariliusvaara@welho.com>
X-Original-To: tls@ietfa.amsl.com
Delivered-To: tls@ietfa.amsl.com
Received: from localhost (localhost [127.0.0.1]) by ietfa.amsl.com (Postfix) with ESMTP id BF5CC12949E for <tls@ietfa.amsl.com>; Wed, 12 Oct 2016 01:11:57 -0700 (PDT)
X-Virus-Scanned: amavisd-new at amsl.com
X-Spam-Flag: NO
X-Spam-Score: -4.896
X-Spam-Level:
X-Spam-Status: No, score=-4.896 tagged_above=-999 required=5 tests=[BAYES_00=-1.9, RCVD_IN_DNSWL_NONE=-0.0001, RP_MATCHES_RCVD=-2.996] autolearn=ham autolearn_force=no
Received: from mail.ietf.org ([4.31.198.44]) by localhost (ietfa.amsl.com [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id huWG4kLHj7_Q for <tls@ietfa.amsl.com>; Wed, 12 Oct 2016 01:11:55 -0700 (PDT)
Received: from welho-filter3.welho.com (welho-filter3.welho.com [83.102.41.25]) by ietfa.amsl.com (Postfix) with ESMTP id F3D2E1294A2 for <tls@ietf.org>; Wed, 12 Oct 2016 01:11:54 -0700 (PDT)
Received: from localhost (localhost [127.0.0.1]) by welho-filter3.welho.com (Postfix) with ESMTP id 01BC1136F6; Wed, 12 Oct 2016 11:11:53 +0300 (EEST)
X-Virus-Scanned: Debian amavisd-new at pp.htv.fi
Received: from welho-smtp1.welho.com ([IPv6:::ffff:83.102.41.84]) by localhost (welho-filter3.welho.com [::ffff:83.102.41.25]) (amavisd-new, port 10024) with ESMTP id BE6AIg_RrI1e; Wed, 12 Oct 2016 11:11:52 +0300 (EEST)
Received: from LK-Perkele-V2 (87-100-237-87.bb.dnainternet.fi [87.100.237.87]) (using TLSv1 with cipher ECDHE-RSA-AES256-SHA (256/256 bits)) (No client certificate requested) by welho-smtp1.welho.com (Postfix) with ESMTPSA id 868BC28B; Wed, 12 Oct 2016 11:11:52 +0300 (EEST)
Date: Wed, 12 Oct 2016 11:11:45 +0300
From: Ilari Liusvaara <ilariliusvaara@welho.com>
To: Kyle Rose <krose@krose.org>
Message-ID: <20161012081145.GA16436@LK-Perkele-V2.elisa-laajakaista.fi>
References: <CACsn0cnpEq_00R37WZOm39dg9dXKSkpNjGt3FWg0uLgTEkwtRw@mail.gmail.com> <20161007220028.GA10288@LK-Perkele-V2.elisa-laajakaista.fi> <CABcZeBNU0HVqkZm6zb63xZzf4+ZQjXb8CacuYH77Fe_=dfFPhw@mail.gmail.com> <20161008142247.GB11416@LK-Perkele-V2.elisa-laajakaista.fi> <CACdeXiK1Wdnd2UaUdPJ6sL-LSW8oQbWyetUJ+3bUQEZY45ax5w@mail.gmail.com> <CAF8qwaDQqceewkg5XoN+8iiHtNO=J9YHH_aRS5+k_4fKTJvfeA@mail.gmail.com> <CACsn0ckz72rhSCQTYRvmWB6n_tdvB5E-V7ssV6qjGO6=qsXY+w@mail.gmail.com> <CAJU8_nWttdcOX=wHOqouZEpFyP3Tok0xTDCzvMrBunkSW9kO+w@mail.gmail.com> <CABkgnnV6YY_GEFKe2C+k67RcJjoPBJoWx1Crat_TMkvB8E-r_Q@mail.gmail.com> <CAJU8_nWtf1sgZ5jQs6zyjU5CotXq42WiYRFpMVU0qbvyy-pGFA@mail.gmail.com>
MIME-Version: 1.0
Content-Type: text/plain; charset="utf-8"
Content-Disposition: inline
In-Reply-To: <CAJU8_nWtf1sgZ5jQs6zyjU5CotXq42WiYRFpMVU0qbvyy-pGFA@mail.gmail.com>
User-Agent: Mutt/1.5.23 (2014-03-12)
Sender: ilariliusvaara@welho.com
Archived-At: <https://mailarchive.ietf.org/arch/msg/tls/hWPG9F3_a4xLOvR0KYNmFP4EONo>
Cc: "tls@ietf.org" <tls@ietf.org>
Subject: Re: [TLS] Application layer interactions and API guidance
X-BeenThere: tls@ietf.org
X-Mailman-Version: 2.1.17
Precedence: list
List-Id: "This is the mailing list for the Transport Layer Security working group of the IETF." <tls.ietf.org>
List-Unsubscribe: <https://www.ietf.org/mailman/options/tls>, <mailto:tls-request@ietf.org?subject=unsubscribe>
List-Archive: <https://mailarchive.ietf.org/arch/browse/tls/>
List-Post: <mailto:tls@ietf.org>
List-Help: <mailto:tls-request@ietf.org?subject=help>
List-Subscribe: <https://www.ietf.org/mailman/listinfo/tls>, <mailto:tls-request@ietf.org?subject=subscribe>
X-List-Received-Date: Wed, 12 Oct 2016 08:11:58 -0000

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