Re: [TLS] ESNI interoperability questions

Rob Sayre <> Mon, 25 November 2019 06:46 UTC

Return-Path: <>
Received: from localhost (localhost []) by (Postfix) with ESMTP id 0B1D412080A for <>; Sun, 24 Nov 2019 22:46:34 -0800 (PST)
X-Virus-Scanned: amavisd-new at
X-Spam-Flag: NO
X-Spam-Score: -1.998
X-Spam-Status: No, score=-1.998 tagged_above=-999 required=5 tests=[BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, FREEMAIL_FROM=0.001, HTML_MESSAGE=0.001, RCVD_IN_DNSWL_NONE=-0.0001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001] autolearn=ham autolearn_force=no
Authentication-Results: (amavisd-new); dkim=pass (2048-bit key)
Received: from ([]) by localhost ( []) (amavisd-new, port 10024) with ESMTP id AD0bwwF5Yo2M for <>; Sun, 24 Nov 2019 22:46:32 -0800 (PST)
Received: from ( [IPv6:2607:f8b0:4864:20::d33]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by (Postfix) with ESMTPS id F154C120806 for <>; Sun, 24 Nov 2019 22:46:31 -0800 (PST)
Received: by with SMTP id k13so14913070ioa.9 for <>; Sun, 24 Nov 2019 22:46:31 -0800 (PST)
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed;; s=20161025; h=mime-version:references:in-reply-to:from:date:message-id:subject:to; bh=zUXxXOFvuAGdI+6YtAMVbvy8iXJp8+xLvDg33tz2SrI=; b=IW9ugSj9KXPfdsEi/xRzJmz4HAx3mdvAGjYDJ83f8ncDE0jMHtkBxH9FKDOF1rG1C6 XsGbIDbAnIFrmb0IJHYUuRyfBbbpQr8vOHA0fYTmdeXmhpquhvQHpSNK93KamY2jZoxS aMJi1BEDMgAfI0y3wJCN5nM23eeQsFLSo4XBwAcIPcamCjM3vE9JdZQhizOb+lMwk+GJ 3h9KSAyaLKPYPUAtTteBQh4m/G5NqdtkHQBTTw93P3gXcKL0GNWGVOtAuW4lbv4mBCf1 o3dKeZIFuRPMpNfig3Mod0nEW4yldTkYPgo2+SY5pMXHuUefxK/R4oGobNz2fDLYu2nI KeXA==
X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed;; s=20161025; h=x-gm-message-state:mime-version:references:in-reply-to:from:date :message-id:subject:to; bh=zUXxXOFvuAGdI+6YtAMVbvy8iXJp8+xLvDg33tz2SrI=; b=D5luz2hvxHMGyzCoFN8F3ctLMt0Baj8QIcKmAKbm/mNX+/R9mvQtFX3TEr7YRLdiAE br6CgXI3w4yhD4tOswPW5q2+N8gBkUkXpMtJssIFZDR7eLaEUbSpkR06oF/LNqxasd9E aQErBVsJmeR8KYuxfFAv5AMGUHlIW6OPpswaFDymw2TtoW02nd4RwHiLS/MGmu0bQXV1 LjEOLxOp0wyyhVJTxR/Sl5tTW4Ac4hOTu7yqoMnk+kfkFQKLgqzcsPbChf38kvkGBUKW sAGsorEtUmymfu3zTXkYemza6WhO+4+pFsIzu+/SBrFXE0Xahxfws8UzmHVu89vSgG0i XGQw==
X-Gm-Message-State: APjAAAU7WYh2pBrO/nDXQXCwL6E2ODgi48FbiekyCKwm8oTmRM57/uTQ MNMqwOsPu3WWb2yAAULX1Tu2fSA31fHEcBEKMR3PY2UM
X-Google-Smtp-Source: APXvYqxwfPrFLPDP5lS/qgDt/dxeiMfkc5fv1HbSAPQUmvPganMeEmOTabo0ou1X86y2RtROHj2qwbQ9zs69+7rLJAE=
X-Received: by 2002:a05:6602:8c:: with SMTP id h12mr340726iob.254.1574664390773; Sun, 24 Nov 2019 22:46:30 -0800 (PST)
MIME-Version: 1.0
References: <>
In-Reply-To: <>
From: Rob Sayre <>
Date: Sun, 24 Nov 2019 22:46:18 -0800
Message-ID: <>
To: "" <>
Content-Type: multipart/alternative; boundary="000000000000a70f330598261f24"
Archived-At: <>
Subject: Re: [TLS] ESNI interoperability questions
X-Mailman-Version: 2.1.29
Precedence: list
List-Id: "This is the mailing list for the Transport Layer Security working group of the IETF." <>
List-Unsubscribe: <>, <>
List-Archive: <>
List-Post: <>
List-Help: <>
List-Subscribe: <>, <>
X-List-Received-Date: Mon, 25 Nov 2019 06:46:34 -0000


This client now interoperates with Cloudflare and the copy
of OpenSSL. It's tri-licensed under the Apache 2, MIT, and ISC licenses. It
won't be merged until draft-06 is out, at a minimum.

I found some things confusing in the draft:

1) The draft uses field names that carry a lot of weight, but they're not
always explained in prose.
2) I think the draft could benefit from a more procedural description of
the steps required, like one might read in a WHATWG draft. This preference
could just be what I'm used to, though.
3) It's not clear what to do if the server doesn't consult the (E)SNI at
all. For example, Cloudflare doesn't seem to check things for big clients
like, which presumably have a dedicated IP. In newer PRs and
proposals, should a bogus encrypted SNI from the client trigger a retry
request even if the server doesn't need the SNI?
4) The draft seems to require more precise explanation around the key
exchange, since it uses some functions from the TLS 1.3 key schedule in a
novel way. I saw weird names and patterns in both rustls and NSS. For
example, in rustls, the secret input "Z" ended up being named
"premaster_secret". It works, but there's a semantic mismatch.


[0] Example:,-p-)

On Sat, Oct 26, 2019 at 3:31 PM Rob Sayre <> wrote:

> Hi,
> I think I have a working ESNI client, but I'm encountering a strange error
> testing with Cloudflare.
> I initially tested with "", but found this was a bad idea,
> because that host doesn't seem to require an SNI or ESNI. So, a bogus ESNI
> triggered no errors.
> When my client sends an ESNI to a Cloudfront-fronted domain, I get a
> handshake_failure error (40). According to the -02 draft, this should only
> happen if the server fails to negotiate TLS 1.3. I've got my client
> configured for TLS 1.3 only, so this shouldn't be an issue. When I add an
> unencrypted SNI to an otherwise identical ClientHello, everything works
> over TLS 1.3. If there are problems with my ESNI encryption, I should see
> other errors. Things like "illegal_parameter" or "decrypt_error", right?
> In Wireshark, I can at least see that my encrypted_server_name extension
> matches Firefox's cipher and key share entries, and the lengths of
> record_digest and encrypted_sni are the same. Firefox does send some
> extensions I don't, like ALPN. Does the absence of unencrypted SNI imply
> the presence of other extensions?
> I also wondered about extension order. Since the ClientHello.key_share is
> part of the ESNI calculation, does it need to appear first in the
> extensions list?
> thanks,
> Rob