Subject: Re: Analysis of version negotiation

From: "Martin Thomson" <[email-masked]>
Date: Wed, 21 Apr 2021 17:37:35 +1000

Hey folks,

I spent a few minutes and updated this document.  Part of that involved removing another field (the most tricky one).

The resulting protocol can be very simple in the end:

A simple transport parameter is needed for each endpoint with a list of values:
  the client sends all compatible versions, with its chosen version listed first
  the server sends all versions (optionally excluding compatible versions, and always excluding versions that aren't fully deployed at the server)

Validation/negotiation is:
  the server verifies that the first version listed by the client is the version that was used by the client
  the server then chooses its most-preferred compatible version from the set provided by the client
  the client verifies that it wouldn't have chosen something different from the set provided by server

This is at least as simple as the design Christian describes.  I believe that the analysis supports the conclusion that this is secure (but it's amateur work so it's not worth much).

What I find encouraging is that this design is very flexible in terms of being able to support both compatible and incompatible negotiation while allowing progressive rollout (or rollback) of new versions.  That might mean we don't have to sacrifice flexibility or use cases at all.

On Wed, Mar 24, 2021, at 14:25, Martin Thomson wrote:
> Hey everyone,
> 
> https://docs.google.com/document/d/1HXu7LoMP8Z30JkHyMOuVOtG5W9AFOQtsL8vuSbFxXUw/edit?usp=sharing is my crude attempt at an analysis of the security of the version negotiation draft, including some suggestions that might make the protocol more efficient.
> 
> I will you reach your own conclusion, but I found some cuts that can be 
> made in the design.  Not as many as I expected originally though.  I 
> did just realize that an entire component can come out, but I haven't 
> edited it out yet; I'll leave that in case others disagree with my 
> assessment there.
> 
> It's long and complicated, sadly.  That's the one thing that I might 
> regret most about the decision to defer solving this problem properly 
> in the first place.  In any case, I hope that this is a useful 
> contribution to the discussion.
> 
> Cheers,
> Martin

---

From: Kazuho Oku <[email-masked]>
Date: Wed, 21 Apr 2021 19:12:19 +0900

2021年4月21日(水) 16:38 Martin Thomson <[email-masked]>:

> Hey folks,
>
> I spent a few minutes and updated this document.  Part of that involved
> removing another field (the most tricky one).
>
>   the server sends all versions (optionally excluding compatible versions,
> and always excluding versions that aren't fully deployed at the server)
>
> This is at least as simple as the design Christian describes.  I believe
> that the analysis supports the conclusion that this is secure (but it's
> amateur work so it's not worth much).
>
> What I find encouraging is that this design is very flexible in terms of
> being able to support both compatible and incompatible negotiation while
> allowing progressive rollout (or rollback) of new versions.  That might
> mean we don't have to sacrifice flexibility or use cases at all.
>

Hi Martin,

Thank you for your analysis.

While I’m not sure if I understand your design, I assume you are correct to
point out that there would be a simple, flexible model that supports both
compatible and non-compatible version negotiation. IMO, it’s about how much
we can reduce from a simple model, that requires each endpoint to
retransmit / verify all information that it has previously exchanged.

That said, I’m not sure if that means that we can support both compatible
and no-compatible version negotiation without extra cost.

That’s because in case of compatible version negotiation, all the message
sent by peer is implicitly validated by the TLS handshake transcript.
There’s no necessity to require QUIC stacks to detect MITM attacks. In
contrast, incompatible version negotiation involves VN packet that is not
covered by the TLS handshake transcript, therefore, at least the server is
required to explicitly validate what it has sent in VN.

The other point is the moment when the version changes.

In case of compatible version negotiation, depending on the design, it
could happen during the handshake then be retroactively verified when the
handshake concludes, or could happen when the endpoints start sending /
receiving 1-RTT packets. But regardless, it is going to happen
mid-connection.

Whereas in case of non-compatible version negotiation, switch between the
versions happen _before_ the transport machinery and the TLS handshake
starts.

To summarize, how and when things can be verified is different between
compatible and non-compatible version negotiation. And therefore I’m afraid
that supporting both would cost us more than just supporting one.

I prefer choosing just one. And regarding which, as I’ve stated in my other
mail, I’m not sure if there’s much value in supporting compatible version
negotiation [1]. I prefer doing minimal things. Therefore, I’m inclined to
say that we might just design non-compatible version negotiation and call
it done (assuming that we have to, IIRC that was the sense of the room when
we were designing V1), or not do anything at all if there’s no need for
non-compatible version negotiation.

[1] https://mailarchive.ietf.org/arch/msg/quic/iGMImeHtxAkUsAjcorQfJhoDrHE/

> https://docs.google.com/document/d/1HXu7LoMP8Z30JkHyMOuVOtG5W9AFOQtsL8vuSbFxXUw/edit?usp=sharing
> is my crude attempt at an analysis of the security of the version
> negotiation draft, including some suggestions that might make the protocol
> more efficient.
> >

-- 
Kazuho Oku