Subject: Add application parameters to QUIC handshake and use it for H3 SETTINGS

From: Nick Harper <[email-masked]>
Date: Thu, 26 Sep 2019 17:51:48 -0700

I propose introducing application parameters to the QUIC handshake and
using this new mechanism for H3 SETTINGS instead of sending them as
the first thing in the control stream. Application parameters would
allow applications using QUIC to advertise or negotiate
application-specific parameters during the cryptographic and transport
handshake. It would guarantee that the client and server have
exchanged their application parameters once the handshake is complete.

Specifically, I’m proposing a new “application_layer_parameters”
transport parameter, which when sent by the client is a series of ALPN
identifiers with an opaque blob of application parameters per
identifier, and when sent by the server is a single opaque blob of
application parameters for the application identified in the ALPN
extension.

Negotiating or advertising features is something multiple applications
will need to do and is not a feature specific to H3. Whatever we do in
H3 will likely be copied by other applications using QUIC. By
providing a general mechanism in QUIC transport, we provide
applications with a consistent way of achieving this goal. QUIC has a
design pattern of collapsing multiple layers into one to save on round
trips (e.g. combining crypto and transport handshake); this fits in
with that pattern.

Using application parameters for H3 SETTINGS clears up some issues. H3
doesn’t need to specify that an endpoint shouldn’t wait for its peer’s
SETTINGS since they’ve already arrived. Likewise, there is no
confusion about whether SETTINGS arriving after session tickets are
bound to the session tickets; SETTINGS arrives before the tickets and
the client doesn’t need to wait for the receipt of SETTINGS to bind
them to the ticket. It also simplifies the server binding SETTINGS to
the ticket since that is done as part of binding transport parameters
to the ticket.

This also provides opportunities for future features. Since the
exchange of SETTINGS occurs before application data, a new feature
doesn’t need to be specified in a way to provide an upgrade path from
“vanilla” H3 to something including this feature, and instead be
guaranteed that the new feature can be used for the entire connection.

Without application parameters, each application that needs to
advertise or negotiate application settings needs its own mechanism to
do so. This would result in multiple transport parameters or
extensions leading to duplication of work and layering violations.
Applications could instead exchange these settings in application
data, meaning that each application needs to define the semantics of
application data received before and after the settings have been
exchanged, as H3 currently does.

There is already a demonstrated need for an application parameters
mechanism in the QUIC handshake. One example is
https://tools.ietf.org/html/draft-vvv-webtransport-quic-00 which is
currently using a “web_accepted_origins” transport parameter but could
easily use an application parameters mechanism instead.

I see two downsides to this proposal. The first is that the client’s
application parameters are sent in the clear. Application designers
will need to make a decision of how much they want to use this
functionality (they could limit what is sent by the client or only use
application parameters in the server direction). For H3, there are
only three SETTINGS, QPACK_MAX_TABLE_CAPACITY, QPACK_BLOCKED_STREAMS,
and MAX_HEADER_LIST_SIZE, which do not reveal any information about
the user or the server they are connecting to and are likely constant
per H3 implementation.

The other downside is that if too much data is put in application
parameters, it could cause the number of packets for a client or
server’s flight to go from N to N+1, which would increase the chance
of head of line blocking.

Related issues:
https://github.com/quicwg/base-drafts/issues/2790: Binding settings
into session tickets
https://github.com/quicwg/base-drafts/issues/2945: When to send the
SETTINGS frame
https://github.com/quicwg/base-drafts/issues/2783: Consider making
SETTINGS part of the control stream header
https://github.com/quicwg/base-drafts/issues/436: Move SETTINGS into
TLS Handshake

---

From: Christian Huitema <[email-masked]>
Date: Thu, 26 Sep 2019 16:45:59 -1000

> application parameters for the application identified in the ALPN

I am a tad concerned with the privacy aspects of this proposal, at least
on the client side. Currently, the settings frame is sent encrypted in
0-RTT or 1-RTT packets. With your proposal, it would be sent in
clear-text, allowing very easy fingerprinting of clients.

-- Christian Huitema

---

From: Nick Harper <[email-masked]>
Date: Thu, 26 Sep 2019 21:54:32 -0700

> clear-text, allowing very easy fingerprinting of clients.

Yes, this does provide a fingerprinting vector. Transport Parameters
also provide a fingerprinting vector with about 10 parameters that
could reasonably be used for fingerprinting, compared to the 3 we have
in H3. The nature of both of those sets of parameters is that they'd
likely fingerprint implementations but not individual clients.

In terms of the application parameters design, individual applications
can choose whether or not they want to use them in the client flight
or just the server flight. We could keep client SETTINGS in the
control stream and only put server SETTINGS in application parameters.

---

From: Mikkel Fahnøe Jørgensen <[email-masked]>
Date: Thu, 26 Sep 2019 22:55:04 -0700

Not arguing against the usefulness of such a feature, and aside from
already mentioned privacy issues:

It seems to be possible to facilitate a man-in-the-middle attack on
application parameters unless the application takes counter-measures which
would complicate matters and likely introduce delays anyway.

I also wonder how this would work with 0-RTT since it cannot be assumed
that application parameters would be remembered across connenctions.

On 27 September 2019 at 06.55.02, Nick Harper (
nharper=[email-masked]) wrote:

---

From: Ian Swett <[email-masked]>
Date: Fri, 27 Sep 2019 09:29:34 -0400

I agree that there is a privacy concern on the client side, but I don't
believe adding HTTP/3 SETTINGS makes it meaningfully worse than the
existing design.  As Nick said, the existing 10 transport params are likely
to have a lot more variability among implementations.  If we think that's a
real problem, then I think we'd do best to solve the general issue that
client transport params aren't encrypted.

I like this because it fits better with the overall design of QUIC where
we've combined transport, crypto and application handshake into one
optimized step.  I also think it'll make implementations simpler and it'll
be more likely QPACK will be used on early requests.

> that application parameters would be remembered across connenctions.

When connecting with 0-RTT, you must remember past transport params and use
those until the new transport parameters arrive.

---

From: Lucas Pardue <[email-masked]>
Date: Fri, 27 Sep 2019 14:44:22 +0100

> exchanged, as H3 currently does.
HTTP/3 defines rules for processing its application parameter messages:
SETTINGS frames MUST NOT contain duplicate settings, a receiver MAY treat
this as a connection error with an application error code.

If SETTINGS were to move to QUIC handshake, would you expect that a
receiver of such a bogus message would generate a CONNECTION_CLOSE of type
0x1d? I'm guessing the checks would take place after ALPN selection had
taken place (at the server).

---

From: Roberto Peon <[email-masked]>
Date: Fri, 27 Sep 2019 17:11:36 +0000

My preference would be to have a facility that would allow an application to ensure that some limited/constant-size data is in every packet that it sends until it gets an ACK.

This would allow control messages to be sent reliably, but avoid the HoL blocking issues.
The real issue that, I believe, we’re trying to solve here is to ensure that the first packet has everything in it that is needed for interpretation/settings, etc.

I also believe that this could be of use in a number of other HoL-prevention things.

It is my opinion that this is a QUICv2 feature, if it becomes something we’d want at all.
-=R

From: QUIC <[email-masked]> on behalf of Mikkel Fahnøe Jørgensen <[email-masked]>
Date: Thursday, September 26, 2019 at 10:55 PM
To: Christian Huitema <[email-masked]>, Nick Harper <nharper=[email-masked]>
Cc: IETF QUIC WG <[email-masked]>
Subject: Re: Add application parameters to QUIC handshake and use it for H3 SETTINGS

Not arguing against the usefulness of such a feature, and aside from already mentioned privacy issues:

It seems to be possible to facilitate a man-in-the-middle attack on application parameters unless the application takes counter-measures which would complicate matters and likely introduce delays anyway.

I also wonder how this would work with 0-RTT since it cannot be assumed that application parameters would be remembered across connenctions.

On 27 September 2019 at 06.55.02, Nick Harper (nharper=[email-masked]<mailto:nharper=[email-masked]>) wrote:

---

From: Nick Harper <[email-masked]>
Date: Fri, 27 Sep 2019 11:50:11 -0700

> The real issue that, I believe, we’re trying to solve here is to ensure that the first packet has everything in it that is needed for interpretation/settings, etc.
That sounds like a good way to phrase the problem. I'd clarify it by
saying the problem we're trying to solve is to ensure that when we
send the first application data packet (i.e. 0- or 1-RTT encrypted) we
have everything negotiated that we need.

> It seems to be possible to facilitate a man-in-the-middle attack on application parameters unless the application takes counter-measures which would complicate matters and likely introduce delays a…
A man in the middle wouldn't be able to tamper with application
parameters without causing the handshake to fail - this is the same as
transport parameters. (If they are tampered with, the two endpoints
will have different TLS handshake transcripts, thus derive different
keys and Finished messages.)

> I also wonder how this would work with 0-RTT since it cannot be assumed that application parameters would be remembered across connenctions.
Each application would still need to define how it handles 0-RTT
(likely to remember the server's previous application parameters, like
we currently do for transport parameters and H3 settings), with the
default assumption being that an application does not support 0-RTT.

---

From: Ted Hardie <[email-masked]>
Date: Fri, 27 Sep 2019 12:12:45 -0700

Hi Nick,

Two points in addition to the privacy issue already raised make me concur
with Roberto that this should be v2 or later.  The first is this:

"Negotiating or advertising features is something multiple applicationswill
need to do and is not a feature specific to H3."

Absolutely true, but there is also a fairly large variability in how
applications do this.  If we design something now that works for H3, it may
very well be sub-optimal or useless for later application targets.  Getting
something general enough to handle DNS, WEBRTC,  SMTP, plus the various
flavors of IoT protocols I've heard as targets hoping to move to QUIC is
going to take time and care, and it will block completion of v1.

The second is this:

*The other downside is that if too much data is put in application
parameters, it could cause the number of packets for a client or server’s
flight to go from N to N+1, which would increase the chance of head of line
blocking.

Depending on what counts as application parameters, this could be more than
N+1.  Someone running NETCONF over QUIC, for example, would be using a
fairly verbose syntax in which each parameter is a full URN.

regards,

Ted Hardie