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

Christian Huitema <notifications@github.com> Tue, 04 December 2018 20:27 UTC

Return-Path: <bounces+848413-a050-quic-issues=ietf.org@sgmail.github.com>
X-Original-To: quic-issues@ietfa.amsl.com
Delivered-To: quic-issues@ietfa.amsl.com
Received: from localhost (localhost [127.0.0.1]) by ietfa.amsl.com (Postfix) with ESMTP id 8A9DA130E92 for <quic-issues@ietfa.amsl.com>; Tue, 4 Dec 2018 12:27:36 -0800 (PST)
X-Virus-Scanned: amavisd-new at amsl.com
X-Spam-Flag: NO
X-Spam-Score: -4.46
X-Spam-Level:
X-Spam-Status: No, score=-4.46 tagged_above=-999 required=5 tests=[BAYES_00=-1.9, DKIMWL_WL_HIGH=-1.46, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, HTML_MESSAGE=0.001, MAILING_LIST_MULTI=-1, RCVD_IN_DNSWL_NONE=-0.0001, SPF_PASS=-0.001] autolearn=ham autolearn_force=no
Authentication-Results: ietfa.amsl.com (amavisd-new); dkim=pass (1024-bit key) header.d=github.com
Received: from mail.ietf.org ([4.31.198.44]) by localhost (ietfa.amsl.com [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id ztZTrYHfPTZP for <quic-issues@ietfa.amsl.com>; Tue, 4 Dec 2018 12:27:32 -0800 (PST)
Received: from o4.sgmail.github.com (o4.sgmail.github.com [192.254.112.99]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by ietfa.amsl.com (Postfix) with ESMTPS id 802D4130E8B for <quic-issues@ietf.org>; Tue, 4 Dec 2018 12:27:32 -0800 (PST)
DKIM-Signature: v=1; a=rsa-sha1; c=relaxed/relaxed; d=github.com; h=from:reply-to:to:cc:subject:mime-version:content-type:content-transfer-encoding:list-id:list-archive:list-post:list-unsubscribe; s=s20150108; bh=0/GnjBkEb2wDzw9vRGLAgdGWbWU=; b=XRPMI8rAnm5o23Jd iy6evMlArfeEwnZyWSXJ/vgxXvbYjxhf799GNitMd0ZxMzLh+5x5mKl54PqMsmeZ yEUre7xqRDQerEOanimQViGB9rRJqXq6p79/dQNLCOXovbvHQ6FWJMZH3Yks2hFk FP0bH71U7R5WIP8ZrJP/rumQys4=
Received: by filter0429p1iad2.sendgrid.net with SMTP id filter0429p1iad2-18107-5C06E333-6 2018-12-04 20:27:31.324729674 +0000 UTC m=+66576.521638382
Received: from github-lowworker-56a5eb2.cp1-iad.github.net (unknown [192.30.252.33]) by ismtpd0012p1iad1.sendgrid.net (SG) with ESMTP id ayP5ePZPSkafIjtqveAbDA for <quic-issues@ietf.org>; Tue, 04 Dec 2018 20:27:31.098 +0000 (UTC)
Received: from github.com (localhost [127.0.0.1]) by github-lowworker-56a5eb2.cp1-iad.github.net (Postfix) with ESMTP id 0C624C0F0E for <quic-issues@ietf.org>; Tue, 4 Dec 2018 12:27:31 -0800 (PST)
Date: Tue, 04 Dec 2018 20:27:31 +0000
From: Christian Huitema <notifications@github.com>
Reply-To: quicwg/base-drafts <reply+0166e4abbdd3a49e0c903192255d8ee6017ca06f5020494d92cf00000001181ea53392a169ce17184276@reply.github.com>
To: quicwg/base-drafts <base-drafts@noreply.github.com>
Cc: Subscribed <subscribed@noreply.github.com>
Message-ID: <quicwg/base-drafts/issues/2097@github.com>
Subject: [quicwg/base-drafts] Server Initial verification for Attacker On The Side defense (#2097)
Mime-Version: 1.0
Content-Type: multipart/alternative; boundary="--==_mimepart_5c06e333a3bf_7efb3fa9af0d45c4246584"; charset="UTF-8"
Content-Transfer-Encoding: 7bit
Precedence: list
X-GitHub-Sender: huitema
X-GitHub-Recipient: quic-issues
X-GitHub-Reason: subscribed
X-Auto-Response-Suppress: All
X-GitHub-Recipient-Address: quic-issues@ietf.org
X-SG-EID: l64QuQ2uJCcEyUykJbxN122A6QRmEpucztpreh3Pak08tDYF3vtGZy6WiOhY54RcVOkg6I34MfUgSZ UDjv6+X3inPduFdLQj0qA99wmEQZjcqG7cPkZLUA8SIPgh8DRlN0i17pDyEI2y0q3hHyDsq+ElVa1+ PdIMddqxXcXy917hzdxRXIT63j68dZfH2pDivNC0ApAA5ap8QmWlkLFVak3zM6tisihiPn5MaQhvG8 k=
Archived-At: <https://mailarchive.ietf.org/arch/msg/quic-issues/ZYbRKKxLwafefLEzZr-xpxJkGhs>
X-BeenThere: quic-issues@ietf.org
X-Mailman-Version: 2.1.29
List-Id: Notification list for GitHub issues related to the QUIC WG <quic-issues.ietf.org>
List-Unsubscribe: <https://www.ietf.org/mailman/options/quic-issues>, <mailto:quic-issues-request@ietf.org?subject=unsubscribe>
List-Archive: <https://mailarchive.ietf.org/arch/browse/quic-issues/>
List-Post: <mailto:quic-issues@ietf.org>
List-Help: <mailto:quic-issues-request@ietf.org?subject=help>
List-Subscribe: <https://www.ietf.org/mailman/listinfo/quic-issues>, <mailto:quic-issues-request@ietf.org?subject=subscribe>
X-List-Received-Date: Tue, 04 Dec 2018 20:27:37 -0000

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