Subject: [quicwg/base-drafts] Server Initial verification for Attacker On The Side defense (#2097)

From: Christian Huitema <[email-masked]>
Date: Tue, 04 Dec 2018 20:27:31 +0000 (UTC)

The more I am watching the long discussion of Pr #2076 and related email thread, the more I believe that the we cannot solve the problem by just requiring parallel evaluation of multiple contexts by the client. Let's start by stating the requirement: we want connection establishment to succeed, even in presence of "attackers on the side" that can forge and send arbitrary packets to client and servers.

@kazuho designed a server side defense, which is the first step in the "attacker on the side" defense. The client attempts to start a connection by sending a "Client Hello" packet to the server. Different client hellos create different contexts on the server, regardless of the contents of headers or of the addresses. To each context corresponds an handshake encryption key. Messages sent with that encryption key can only originate from the sender of the Client Hello. For one of the contexts, that origin will be the actual client. For the other contexts, it might be an attacker.

Protecting the server is not enough, because the attackers can spoof server responses. The client may receive several different "Server Hello" packets in response to a single "Client Hello". By default, the client cannot verify that the Server Hello originated from the intended server -- the server credentials will only arrive much later in the exchange. In the absence of server authentication, the client needs to open a connection context for each different Server Hello. Each context will be associated with an encryption key.  Just like in the server case, each context is associated with the actual sender of the Server Hello. One of these contexts will be associated with the intended servers. The client will only find out which one after it processes the server credentials, which will be received in the handshake messages. Until that, the client will have to process all messages in parallel.

This algorithm is hard to implement in QUIC V1, because the identifies its "connection context" with a single Connection Identifier (CID), which it commits to in the Initial packet -- and it has to do that, unless we want to spend an extra RTT in the connection setup. The parallel execution supposes managing several client contexts, each associated with a handshake key. We would get the following flow:

1) Client sends Client Hello with Dest=ICID, Srce= CCID.
2) Server receives Client Hello, creates context based on Server Hello content, picks SCID
3) Server sends Server Hello with Dest= CCID, Source=SCID
4) Client receives Server Hello, associates context with  the tuple (CCID, SCID)
5) Server sends Handshake messages with Dest= CCID, Source=SCID
6) Client verifies the messages with Handshake key associated with CCID, SCID. Messages that fail authentication are ignored.
7) Client sends ACK, etc with Dest=SCID, Srce=CCID
8) Client validate server credentials. Connection is established.

This works as long as the attacker forges its responses without knowledge of the server's SCID. If the attacker sees the first Server Hello (step 3), it can race a competing Server Hello with the same CCID, SCID. If the attacker wins the race, it will effectively "own" the context (CCID, SCID). To make that work, we need an extra parameter, for example a "Server Token" that would be carried in the Server Initial packets and also in the handshake packets, and that could be verified by the client. For example, the token could be the hash of the "Server Hello", computed with the hash algorithm negotiated for the handshake. The modified algorithm would be:

1) Client sends Client Hello with Dest=ICID, Srce= CCID.
2) Server receives Client Hello, creates context based on Server Hello content, picks SCID
3) Server sends Server Hello with Dest= CCID, Source=SCID, token = hash(Server Hello)
4) Client receives Server Hello, verifies the token. If the token does not match, the message is ignored. If it matches, client associates context with  the tuple (CCID, SCID, Token)
5) Server sends Handshake messages with Dest= CCID, Source=SCID, Token = hash(Server Hello)
6) Client verifies the messages with Handshake key associated with (CCID, SCID, Token). Messages that fail authentication are ignored.
7) Client sends ACK, etc with Dest=SCID, Srce=CCID  (No need for the server token there).
8) Client validate server credentials. Connection is established.

Adding the server token to the server's Initial and Handshake messages would be a significant change in the protocol, and adding speculative evaluation of multiple contexts would be a significant burden to the clients. There are other issues, such as how to handle HRR and stateless Retry, or how to signal that the server is busy without allowing attackers to spoof the busy signal. The Stateless Retry can probably be handled by creating yet another parallel evaluation context on the client. We would need to transport HRR responses in something like a Stateless Retry. And the client that really wants to be immune to DOS attacks should probably just ignore the busy signals, which is of course a tradeoff between robustness and responsiveness.

This creates a big set of changes, somewhat similar to the "stream zero reset" that the WG went through in June. Such a change would likely delay the WG by another 3 or 4 months, and result in a fairly heavy weight connection protocol. So maybe we should explore the other potential defense, "verify that the Server Hello originated from the intended server". The flow would then be:

1) Client sends Client Hello with Dest=ICID, Srce= CCID.
2) Server receives Client Hello, creates context based on Server Hello content, picks SCID
3) Server sends Server Hello with Dest= CCID, Source=SCID
4) Client receives Server Hello, performs server origin verification, associates context with  the tuple (CCID, SCID)
5) Server sends Handshake messages with Dest= CCID, Source=SCID
6) Client verifies the messages with Handshake key associated with CCID, SCID. Messages that fail authentication are ignored.
7) Client sends ACK, etc with Dest=SCID, Srce=CCID
8) Client validate server credentials. Connection is established.

This is pretty much the same flow as Quic V1, with just an extra authentication added. We can debate what the server authentication should be. I think that we have a potential solution with something like ESNI, which uses a public key published by the "fronting server". The Server Hello could be verified by somehow demonstrating knowledge of that public key. Since ESNI and resistance to censorship go very much hand in hand, reusing the same credential would not be too much of a stretch.

-- 
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/issues/2097

---

From: MikkelFJ <[email-masked]>
Date: Tue, 04 Dec 2018 14:02:52 -0800

The first scenario can be attacked all the way up to point 8. certificate validation because an attacker seeing only client messages can create its own handshake key that competes with the server. The client will have to process all alternative handshake keys and alternative SCID values until one handshake passes certificate validation.

The second scenario with server token is not an improvement since the attacker can just provide it own fully valid ServerHello with a token. It will also eventually fail certificate, but only after consuming resources.

A fix to the above would be if the client already knows the server public key and the server signs a challenge in the first packet it responds. That challenge could be the ICID. This corresponds to step 4 in the third flow in the above.

If the server knows the clients public key (not usually the case, but can be used server to server), the client can can send a signed nonce.

NOTE: if the ICID is a hash of the ClientHello this prevents an attack where the attacker races a client initial. If the attacker attempts to copy the ICID with its own ClientHello, the handshake key will fail. If the attacker attempts to copy the ICID and the ClientHello, it will just be a retransmission, and the attacker will not have achieved anything. This assumes the initial packet only contains what is hashed in ICID.

-- 
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/issues/2097#issuecomment-444276041

---

From: Christian Huitema <[email-masked]>
Date: Tue, 04 Dec 2018 14:31:45 -0800

The first and second scenarios assume parallel processing of multiple contexts at clients and servers. Yes, that creates extra load. The goal of the defense is to sustain thst load until one of the contexts results in a valid connection. 

-- 
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/issues/2097#issuecomment-444284601

---

From: Kazuho Oku <[email-masked]>
Date: Wed, 05 Dec 2018 00:32:45 -0800

@huitema 
> This works as long as the attacker forges its responses without knowledge of the server's SCID. If the attacker sees the first Server Hello (step 3), it can race a competing Server Hello with the same CCID, SCID. If the attacker wins the race, it will effectively "own" the context (CCID, SCID).

I disagree with this observation (and the therefore the discussion that follows).

A client does not need to distinguish each "flow of handshake transcripts" based on SCID. What it should do is distinguish each flow by ServerHello that's being contained (for Initial packets) or the handshake key (for Handshake packets) that decrypts successfully.

Therefore, there is no need for a "server token."

-- 
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/issues/2097#issuecomment-444401558

---

From: Christian Huitema <[email-masked]>
Date: Wed, 05 Dec 2018 09:10:15 -0800

@kazuho: you are saying that the client does not need an extra ID because it can use trial decryption. That's true, but that's not a very desirable solution, because then attackers can DOS the client.

-- 
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/issues/2097#issuecomment-444564829

---

From: Martin Thomson <[email-masked]>
Date: Thu, 20 Dec 2018 20:55:42 -0800

@huitema, do you think taht this turns into any specific actions for the current drafts, or is that what turned into [draft-kazuho-quic-authenticated-handshake](https://datatracker.ietf.org/doc/draft-kazuho-quic-authenticated-handshake/)?

-- 
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/issues/2097#issuecomment-449249889

---

From: Christian Huitema <[email-masked]>
Date: Thu, 20 Dec 2018 22:58:49 -0800

@martinthomson there are two threads. We have been exploring a series of heuristics to make the exchange more robust without changing the protocol. The high level summary is that this works OK on the server side if one creates a context for each set of <hash(Client Initial), address tuple>, but that the complexity on the client is rather stiff. On the other hand, if we assume that there is a way to establish some kind of secret between client and server before the handshake, as with ESNI, then we arrive to a very robust solution as in the authenticated handshake draft.

Which is a long way to say Yes.

-- 
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/issues/2097#issuecomment-449281067

---

From: Martin Thomson <[email-masked]>
Date: Thu, 20 Dec 2018 23:58:53 -0800

Thanks, based on that I'm marking this v2.  As in, we might want to consider authentication in a new version.  (That might be all we consider, as in the draft :)

-- 
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/issues/2097#issuecomment-449298258