Subject: [quicwg/base-drafts] Change connection ID with Transport Parameters (#1041)

From: ianswett <[email-masked]>
Date: Tue, 09 Jan 2018 03:22:18 +0000 (UTC)

Change the connection ID by specifying a new server chosen connection ID in transport parameters.  Allows a new connection ID to be supplied in Retry packets(Fixing issue #713) and allows multiple handshakes to occur on the same 4-tuple, fixing #714.

You can view, comment on, or merge this pull request online at:

  https://github.com/quicwg/base-drafts/pull/1041

-- Commit Summary --

  * Change connection ID with Transport Parameters

-- File Changes --

    M draft-ietf-quic-transport.md (19)

-- Patch Links --

https://github.com/quicwg/base-drafts/pull/1041.patch
https://github.com/quicwg/base-drafts/pull/1041.diff

-- 
You are receiving this because you are subscribed to this thread.
Reply to this email directly or view it on GitHub:
https://github.com/quicwg/base-drafts/pull/1041

---

From: ianswett <[email-masked]>
Date: Tue, 09 Jan 2018 03:23:59 +0000 (UTC)

@ianswett pushed 1 commit.

44e4741  Fix trailing whitespace

-- 
You are receiving this because you are subscribed to this thread.
View it on GitHub:
https://github.com/quicwg/base-drafts/pull/1041/files/cec74a672a6cabfa95c4ec583326b2621e7ca91b..44e474126a4cd5fc92649bbc41dc6edf13615a29

---

From: Martin Thomson <[email-masked]>
Date: Mon, 08 Jan 2018 20:13:54 -0800

martinthomson requested changes on this pull request.

I have a few reservations about using transport parameters for this.  I know we had some concerns about using NEW_CONNECTION_ID for this, but it might be a better approach.  I can already think of at least one gotcha with that, but it's potentially a cleaner model.

> @@ -690,14 +690,16 @@ The client MUST choose a random connection ID and use it in Initial packets
 ({{packet-initial}}) and 0-RTT packets ({{packet-protected}}).
 
 When the server receives a Initial packet and decides to proceed with the
-handshake, it chooses a new value for the connection ID and sends that in a
-Handshake packet ({{packet-handshake}}).  The server MAY choose to use the value
-that the client initially selects.
+handshake, it may chooses a new value for the connection ID and sends that in

MAY choose I think

> @@ -690,14 +690,16 @@ The client MUST choose a random connection ID and use it in Initial packets
 ({{packet-initial}}) and 0-RTT packets ({{packet-protected}}).
 
 When the server receives a Initial packet and decides to proceed with the
-handshake, it chooses a new value for the connection ID and sends that in a
-Handshake packet ({{packet-handshake}}).  The server MAY choose to use the value
-that the client initially selects.
+handshake, it may chooses a new value for the connection ID and sends that in
+the server_connection_id transport parameter ({{transport-parameter-definitions}})
+of the Handshake packet ({{packet-handshake}}).

A transport parameter can't be "of the Handshake packet".  You can drop from "of" onward.

-Once the client receives the connection ID that the server has chosen, it MUST
+If the client receives a new connection ID that the server has chosen, it MUST

Transport parameters are only really available once the handshake completes.  For one, they are in TLS EncryptedExtensions, which isn't necessarily right up front.  More importantly, though we could release them before the handshake completes, it makes it harder to reason about their authenticity.  Given that transport parameters are used for client address validation, that's problematic.

>  use it for all subsequent Handshake ({{packet-handshake}}) and 1-RTT
 ({{packet-protected}}) packets but not for 0-RTT packets ({{packet-protected}}).
 
+The server MUST NOT switch to the new connection ID until has received a
+packet containing the connection ID from the client.  In particular, the

I think that it is easier to make the switch with the change to 1-RTT protected packets.  Creating another mini-protocol here complicates things considerably.  Outside of cases with packet loss (where you can't rely on the client being able to recover the transport parameters), the only real difference is that you are changing the connection ID sent with the client's second flight (it's set of Handshake packets).

Now, I agree that there is potentially some value in having the right markings on the client Handshake packets, but maybe the right answer here is to use NEW_CONNECTION_ID.

-- 
You are receiving this because you are subscribed to this thread.
Reply to this email directly or view it on GitHub:
https://github.com/quicwg/base-drafts/pull/1041#pullrequestreview-87409147

---

From: ianswett <[email-masked]>
Date: Tue, 09 Jan 2018 06:39:20 -0800

ianswett commented on this pull request.

NEW_CONNECTION_ID wouldn't change the encryption level issues.  And we'd have to allow it during the handshake, which we don't today.

-- 
You are receiving this because you are subscribed to this thread.
Reply to this email directly or view it on GitHub:
https://github.com/quicwg/base-drafts/pull/1041#discussion_r160422887

---

From: ianswett <[email-masked]>
Date: Tue, 09 Jan 2018 06:40:59 -0800

7ba0b53  Martin's comments.

-- 
You are receiving this because you are subscribed to this thread.
View it on GitHub:
https://github.com/quicwg/base-drafts/pull/1041/files/44e474126a4cd5fc92649bbc41dc6edf13615a29..7ba0b5393f8a99d67be34c42188495450e6233dd

---

From: ianswett <[email-masked]>
Date: Tue, 09 Jan 2018 06:42:22 -0800

Aren't they available at the server side when a CHLO is received?  And shouldn't they be available in the stateless retry?

-- 
You are receiving this because you are subscribed to this thread.
Reply to this email directly or view it on GitHub:
https://github.com/quicwg/base-drafts/pull/1041#discussion_r160423722

---

From: ianswett <[email-masked]>
Date: Tue, 09 Jan 2018 14:43:30 +0000 (UTC)

Possibly I'm confused on the use of transport parameters.  It needs to be possible to negotiate in transport params, so they would have to be available to QUIC prior to the TLS handshake completing.

-- 
You are receiving this because you are subscribed to this thread.
Reply to this email directly or view it on GitHub:
https://github.com/quicwg/base-drafts/pull/1041#issuecomment-356303224

---

From: Nick Banks <[email-masked]>
Date: Tue, 09 Jan 2018 14:50:02 +0000 (UTC)

nibanks commented on this pull request.

I agree with @ianswett, that the client should be the one that starts using the new connection ID first. Otherwise, you are back to one of the original problems of multiple clients on the same 4-tuple and it is impossible to determine which of them to deliver the newly received packet to.

-- 
You are receiving this because you are subscribed to this thread.
Reply to this email directly or view it on GitHub:
https://github.com/quicwg/base-drafts/pull/1041#discussion_r160426015

---

From: ianswett <[email-masked]>
Date: Tue, 09 Jan 2018 15:01:40 +0000 (UTC)

One other concern about NEW_CONNECTION_ID is that the stateless retry is part of the TLS transcript, and so if the server chosen connection ID is in transport params, the handshake will fail at the end if the connection ID is changed.  I'm not sure why an attacker would want to insert a NEW_CONNECTION_ID frame in this context, but I think it would be impossible for the client to detect that it had occurred?

But if that's not an issue or we don't care, then NEW_CONNECTION_ID is workable.

My core goals are to solve the specified issues.  I do think it's better to have the client be the first to use the new connection ID.  The approach of the server suddenly changing the connection ID is very odd and as discussed, causes problems with multiple simultaneous handshakes.

-- 
You are receiving this because you are subscribed to this thread.
Reply to this email directly or view it on GitHub:
https://github.com/quicwg/base-drafts/pull/1041#issuecomment-356308755

---

From: Mike Bishop <[email-masked]>
Date: Tue, 09 Jan 2018 21:06:56 +0000 (UTC)

"Negotiate" is perhaps overstating things in the transport parameters.

> During connection establishment, both endpoints make authenticated declarations of their transport parameters. These declarations are made unilaterally by each endpoint. Endpoints are required to comply with the restrictions implied by these parameters; the description of each parameter includes rules for its handling.

In what scenario do you think the transport parameters have to be available before the handshake completes?

-- 
You are receiving this because you are subscribed to this thread.
Reply to this email directly or view it on GitHub:
https://github.com/quicwg/base-drafts/pull/1041#issuecomment-356414163

---

From: ianswett <[email-masked]>
Date: Tue, 09 Jan 2018 21:17:36 +0000 (UTC)

The main one I had in mind was feature negotiation.  A client wants to negotiate non-standard feature A and the server replies that A is ok.  I guess a server could enumerate all non-standard features it supported and both could agree after the handshake?

There are probably other use cases I'm not thinking of, but maybe all of them can be worked around.

-- 
You are receiving this because you are subscribed to this thread.
Reply to this email directly or view it on GitHub:
https://github.com/quicwg/base-drafts/pull/1041#issuecomment-356416953

---

From: Martin Thomson <[email-masked]>
Date: Tue, 09 Jan 2018 19:25:56 -0800

It's possible to use the declarations in transport parameters to effect negotiation, sure.  If I declare feature A and you do too, then it's safe to assume that using feature A won't cause problems.  I'd say that we probably need that for - for example - changing the ACK frame format to support new information.  And calling that negotiation isn't a stretch.  Right now, we don't have anything that negotiates and the text reflects that.

As for NEW_CONNECTION_ID, sure, an attacker can insert a connection ID.  The likely effect is to cause packets to be routed incorrectly, likely disrupting the handshake.  We've agreed that if an attacker is able to disrupt the handshake to this degree, then we're not going to try to stop them.  An attacker with that capability could also choose to block the handshake or tamper with it in other ways that would cause failure.  If the concern is misrouting, they could easily rewrite the connection ID.

If the server is able to (maybe because it didn't use the connection ID) and decides to accept the incorrectly-marked packets, then it just became complicit and I'm not sure that we need to worry about that.

One thing that I was wrong about here was that transport parameters are available to a client because the TLS handshake is complete.  There's a nasty race condition there though.  The handshake is really only complete once the client has sent its last flight, and that means using handshake packet protection keys, but using transport parameters from the completed handshake.  It's rather awkward.

We would also need to be clear about what connection ID is used for Handshake packets that the client sends when there is packet loss and it has to acknowledge server Handshake packets.

-- 
You are receiving this because you are subscribed to this thread.
Reply to this email directly or view it on GitHub:
https://github.com/quicwg/base-drafts/pull/1041#issuecomment-356489098

---

From: ianswett <[email-masked]>
Date: Wed, 10 Jan 2018 06:08:24 -0800

Thanks Martin, did you want me to re-write this using the NEW_CONNECTION_ID frame or do you think the transport parameters approach is also workable?

-- 
You are receiving this because you are subscribed to this thread.
Reply to this email directly or view it on GitHub:
https://github.com/quicwg/base-drafts/pull/1041#issuecomment-356612196

---

From: Martin Thomson <[email-masked]>
Date: Wed, 10 Jan 2018 12:35:24 -0800

I don't know.  Maybe we can talk about this in Melbourne.

-- 
You are receiving this because you are subscribed to this thread.
Reply to this email directly or view it on GitHub:
https://github.com/quicwg/base-drafts/pull/1041#issuecomment-356728258