Subject: Re: Version negotiation: the bare minimum?

From: Lucas Pardue <[email-masked]>
Date: Mon, 12 Apr 2021 20:44:21 +0100

Hi Watson and Christian,

Thanks for your input on the topic of QUIC Version Negotiation. The thread
has fizzled out a bit. The QUIC Version Negotiation interim meeting is next
week (Wednesday April 20, 21:00 UTC), it would be great if you could add
some further concrete ideas to the discussion. In particular, if you're
describing an alternative to what the VN draft has today, there is value in
us hearing it out because it might help the QUIC WG make progress in this
area.

Kind regards
Lucas
QUIC WG Co-chair

On Wed, Mar 17, 2021 at 12:42 AM David Schinazi <[email-masked]>
wrote:

> Hi Christian,
>
> It seems to me that you're describing what's in the VN draft today.
> What am I missing?
>
> David
>
> On Mon, Mar 15, 2021 at 9:11 PM Christian Huitema <[email-masked]>
> wrote:
>
>> I have been considering pretty much the same design as Watson. In the
>> slide deck that you presented, this would be the "compatible" option.
>> The client would select  version X in the QUIC header of the Initial
>> packet, and format one or several TP stating:
>>
>> 1) Version in the QUIC header: X
>>
>> 2) Supported compatible versions: Y, Z, T, and maybe Grease. These must
>> be "compatible" versions.
>>
>> The server will:
>>
>> 1) verify that the version in the QUIC header is indeed X. If it is not,
>> close the connection with an error.
>>
>> 2) pick one of X, Y, Z or T as the selected version, say Y.
>> (Questionable whether the version in the QUIC header should be set to X
>> or Y.)
>>
>> 3) Set the TP stating something like "you proposed X and I selected Y"
>>
>> 4) Very optionally, mention in a TP that "this server also supports
>> versions V, W." These might be "incompatible" versions.
>>
>> If none of X, Y, Z, T are supported, the server replies with a VN.
>>
>> On receiving the server TP, the client verifies that the server saw the
>> intended version X, and chose one of the supported version. The client
>> might remember additional version V and W for next time, but that's
>> extra complexity.
>>
>> -- Christian Huitema
>>
>> On 3/15/2021 5:18 PM, David Schinazi wrote:
>> > Hi Watson,
>> >
>> > Could you elaborate on your proposal? In particular:
>> > How does the client transmit its supported versions?
>> > What does "compatible" mean?
>> > What does "the server selects" mean?
>> > What does "the server proceeds" mean?
>> >
>> > Thanks,
>> > David
>> >
>> > On Wed, Mar 10, 2021 at 1:55 PM Watson Ladd <[email-masked]>
>> wrote:
>> >
>> >> Dear WG,
>> >>
>> >> I'd like to proffer the world's simplest version negotiation scheme,
>> >> based on comments heard during the meeting today from a number of
>> >> people.
>> >>
>> >> The following weak assumptions are made: the client has a set of
>> >> versions. The server has a partial ordering on versions: this means
>> >> that versions are not necessarily preferred over each other (consider
>> >> experiments where we will do what the client offers first), but the
>> >> relation is transitive. Then the server selection is a function of the
>> >> client offered version and supported set.
>> >>
>> >> The client transmits its supported versions and a proffered hello
>> >> version in the first packet. The server selects. If that selection is
>> >> incompatible they try again with the new selected version transmitted
>> >> in VN. If it is compatible, the server selects and proceeds.
>> >>
>> >> The constraint on the handshake is that the supported versions and
>> >> offered version and server selection are incorporated on the handshake
>> >> in such a way that a mismatch triggers failure, and no two different
>> >> versions can derive the same keys. If we assume that e.g. SHA256 is
>> >> unbroken this is easy to get.
>> >>
>> >> This only permits a downgrade to a version the server was willing to
>> >> prefer.
>> >>
>> >> Sincerely,
>> >> Watson Ladd
>> >>
>> >>
>>
>>

---

From: Watson Ladd <[email-masked]>
Date: Mon, 12 Apr 2021 22:11:11 -0700

On Mon, Apr 12, 2021 at 12:44 PM Lucas Pardue
<[email-masked]> wrote:
>
> Hi Watson and Christian,
>
> Thanks for your input on the topic of QUIC Version Negotiation. The thread has fizzled out a bit. The QUIC Version Negotiation interim meeting is next week (Wednesday April 20, 21:00 UTC), it would be great if you could add some further concrete ideas to the discussion. In particular, if you're describing an alternative to what the VN draft has today, there is value in us hearing it out because it might help the QUIC WG make progress in this area.

I would be happy to attend.

>
> Kind regards
> Lucas
> QUIC WG Co-chair
>
> On Wed, Mar 17, 2021 at 12:42 AM David Schinazi <[email-masked]> wrote:
>>
>> Hi Christian,
>>
>> On Mon, Mar 15, 2021 at 9:11 PM Christian Huitema <[email-masked]> wrote:
>>>
>>> > On Wed, Mar 10, 2021 at 1:55 PM Watson Ladd <[email-masked]> wrote:
>>> >
>>> >> Dear WG,
>>> >>

-- 
Astra mortemque praestare gradatim

---

From: Christian Huitema <[email-masked]>
Date: Tue, 13 Apr 2021 00:06:14 -0700

> I would be happy to attend.

I will try to attend too. If I can find the invite and link...

---

From: David Schinazi <[email-masked]>
Date: Tue, 13 Apr 2021 10:51:27 -0700

Hi Watson and Christian,

Glad to hear you'll be there! Would you also be able to prepare a proposal?
It sounds like you've put some thought into this and it would be great to
have something concrete to discuss.

Thanks,
David

On Tue, Apr 13, 2021 at 12:06 AM Christian Huitema <[email-masked]>
wrote:

> >> Thanks for your input on the topic of QUIC Version Negotiation. The
> thread has fizzled out a bit. The QUIC Version Negotiation interim meeting
> is next week (Wednesday April 20, 21:00 UTC), it would be great if you
> could add some further concrete ideas to the discussion. In particular, if
> you're describing an alternative to what the VN draft has today, there is
> value in us hearing it out because it might help the QUIC WG make progress
> in this area.

---

From: Kazuho Oku <[email-masked]>
Date: Wed, 21 Apr 2021 15:39:50 +0900

Please correct me if I'm wrong, but it seems to me that people are using
"compatible version" as a term to describe packets carrying first-flight
initial data (e.g., ClientHello) using QUIC version X to which servers
might respond with something other than Version Negotiation packets _nor_
QUIC version X packets.

IIUC, the intention is to allow endpoints start the handshake using QUIC v1
but end up with using something other than QUIC v1, without incurring the
cost of one extra round-trip due to Version Negotiation packet being sent
by the server.

Based on this understanding, I have one question. Do we need such a feature?

QUIC v1 already has Transport Parameters that can be used for negotiating
how 0-RTT and short header packets would be used. By using Transport
Parameters, we can define extensions that add, modify, or remove any
feature wrt how application data would be exchanged.

The idea of having a mechanism for selecting a QUIC version between
"compatible versions" sounds to me like just creating another way of
negotiating features using TLS messages as the conveyor. Hence the question.

-- 
Kazuho Oku

---

From: David Schinazi <[email-masked]>
Date: Wed, 21 Apr 2021 07:48:36 -0700

Hi Kazuho,

First, to confirm: your characterization of compatible VN matches my
understanding.

Then, on the topic of what we need, let's start with basics. Your point
that QUICv1 has extension points is true,
but we've designed QUIC as a versioned protocol to allow innovation outside
of the confines of QUICv1. We
could in theory say that the QUIC version field is ossified and no other
versions are allowed for perpetuity,
but I think that this would be a loss for our ecosystem. If we assume that
there is value in having other versions
of QUIC, then there is a need for version negotiation. This doesn't apply
to HTTP/3 or other application protocols
that negotiate their QUIC version out of band (e.g. via Alt-Svc), but we
built QUIC in such a way to specifically
enable non-HTTP application protocols. Now, given that we want version
negotiation, we'll need at least incompatible
version negotiation, as that is the one that supports all potential
versions. If we decide to build incompatible version
negotiation, we need to prevent downgrade attacks - attackers should not be
able to modify the version field on
long headers, and should not be able to inject or modify version
negotiation packets. To solve this, we need to
authenticate these versions in the TLS transcript, which means adding a new
transport parameter. At a minimum,
this transport parameter needs to include the versions being sent in long
headers, and needs some form of what
was sent in a version negotiation packet.

To summarize that wall of text, if we don't want to ossify on QUICv1, we
need a new transport parameter with
some version information.

Now, to answer your question about compatible version negotiation: it does
mean adding one more field in the
client-to-server transport parameter so the client can list its compatible
version. In terms of wire encoding, that's
the only change. The only complexity in compatible version negotiation is
in defining the concepts.

My personal opinion is that we should tackle this minor complexity in order
to make QUIC more robust. Having a
version negotiation mechanism that doesn't cost a round trip will help
encourage innovators to use new versions
of QUIC as opposed to shoehorning everything into extensions to QUICv1. My
intuition is that this feature will
impact the long term success of QUIC, and is therefore worth the minor
complexity.

David

On Tue, Apr 20, 2021 at 11:40 PM Kazuho Oku <[email-masked]> wrote:

> IIUC, the intention is to allow endpoints start the handshake using QUIC
> v1 but end up with using something other than QUIC v1, without incurring
> the cost of one extra round-trip due to Version Negotiation packet being
> sent by the server.
>

---

From: Christian Huitema <[email-masked]>
Date: Wed, 21 Apr 2021 08:03:46 -0700

Maybe the first question is, do we need to support what you call 
"incompatible" version negotiation, i.e., the original design from 4 
years ago. It was taken off the spec for a number of reasons, of which I 
remember two:

1) VN packets are easy to spoof by ill-intended third parties. We can 
protect that with end-to-end verification, but that merely downgrades 
the third party action to a denial of service, which is not great.

2) Version negotiation does not feel good when rolling partial upgrades 
of server farms, because the server of the second connection is not 
necessarily the same as the server sending the VN, andmight support a 
different set of versions.

One reason for removing support is, if nobody expect VN to work, clients 
can just ignore incoming VN packets and get rid of the DOS surface.

The proposed "compatible" version negotiation makes third party 
interference significantly harder -- it requires MITM-ing the 
connection, instead of merely shooting a VN packet. It also solves the 
server farm issue, since it maintains a single connection.

-- Christian Huitema

---

From: David Schinazi <[email-masked]>
Date: Wed, 21 Apr 2021 08:11:30 -0700

I'll note that there are many ways for an attacker to close
a QUIC connection during the handshake:
- send ICMP port unreachable
- send a version negotiation packet with no real versions
- send an initial with a ServerHello of the attacker's choosing
- send a retry with a token of the attacker's choosing

We do not plan on preventing these attacks in Chrome,
because for example ICMP allows us to determine that QUIC
is blocked and fall back to TCP without having the user wait
for a timeout.

As far as I know, preventing denial of service before the
handshake is complete is not a feature provided by QUICv1.

David

---

From: Kazuho Oku <[email-masked]>
Date: Thu, 22 Apr 2021 05:19:23 +0900

Hi, David, Christian,

Thank you for your comments.

2021年4月21日(水) 23:48 David Schinazi <[email-masked]>:

> but we've designed QUIC as a versioned protocol to allow innovation
> outside of the confines of QUICv1. We
> negotiation, we need to prevent downgrade attacks - attackers should not
> be able to modify the version field on
> authenticate these versions in the TLS transcript, which means adding a
> new transport parameter. At a minimum,

I think I agree to what David has written here, regarding the importance of
incompatible version negotiation.

As David points out, having in QUIC v1 downgrade prevention for
incompatible versions is a MUST, for somebody deploying a QUIC version that
is incompatible with QUIC v1 (e.g., a variant that does not use TLS as the
handshake mechanism), considering that such version is more preferable to
be used than v1 when both can be used.

> My personal opinion is that we should tackle this minor complexity in
> order to make QUIC more robust. Having a

While I agree that compatible version negotiation is much easier to design
than incompatible version negotiation, I'm not sure if I'm convinced of the
necessity to have compatible version negotiation.

Innovators can use Transport Parameters to change how short header packets
would be used in the way they want. Depending on how much they change, it
could be an entirely different protocol. But that does not warrant the
necessity of designing a compatible version negotiation mechanism. One can
simply define QUIC_VERSION_123 Transport Parameter. Another person can
define QUIC_VERSION_234. If the server supports both, then the server can
choose from one, and send either of the two to indicate which one has been
chosen.

But even before that, I would point out that in most cases, innovators will
be incentivized to extend v1, because in most cases innovators are
interested in adding one feature at a time to QUIC, rather than designing
everything from scratch. I think that is a good thing for the entire
ecosystem, because we can reuse components, rather than redesigning and
reimplementing everything.

-- 
Kazuho Oku