This issue tracker has been migrated to GitHub, and is currently read-only.
For more information, see the GitHub FAQs in the Python's Developer Guide.

classification
Title: Support TLS Encrypted ClientHello (ECH)
Type: enhancement Stage:
Components: SSL Versions:
process
Status: open Resolution:
Dependencies: Superseder:
Assigned To: christian.heimes Nosy List: christian.heimes, eighthave
Priority: normal Keywords:

Created on 2021-10-22 08:59 by eighthave, last changed 2022-04-11 14:59 by admin.

Messages (3)
msg404732 - (view) Author: Hans-Christoph Steiner (eighthave) Date: 2021-10-22 08:59
The next version of the IETF-standardized TLS protocol is known as Encrypted ClientHello (ECH) [1] formerly known as Encrypted SNI (ESNI). This ticket collects information for ECH support, and tracks which APIs have to be added to Python in order to implement ECH in Python's ssl module.  ECH is built on top of TLSv1.3 and completes the unfinished work from the TLSv1.3 effort.  It is now in draft-13 and there are many implementations that are interoperating.  ECH is working for openssl[2], boringssl[3], nginx, Apache HTTPD, lighttpd, HAProxy, Conscrypt[4], curl, and more.  There is work underway in Firefox [5] and Chromium [6].  It has been sketched out for OkHTTP [7].  Early versions of the standard, known as ESNI, have been deployed in Firefox releases and some production web services.  ECH works in conjunction with the new DNS RR Types HTTPS and SVCB [8].  This means that DNS needs to be handled a bit differently.

As far as I understand it, the ssl module has to gain additional features:

1. HTTPS/SVCB DNS queries for setting up TLS connection with ECH.
2. A way to provide ECH Config Lists as bytes directly to ssl clients.
3. A callback that gets called whenever ECH negotiation fails and the server offers a "Retry Config".
4. A method to ensure encrypted DNS is used so all metadata is encrypted.

OpenSSL does not implement the necessary APIs yet. Stephen Farrell's development OpenSSL fork [9] implements ECH and has been used in Apache HTTPD, nginx, lighttpd, HAProxy, and curl implementations.

The TLS WG maintain a page with information about other implementations:
https://github.com/tlswg/draft-ietf-tls-esni/wiki/Implementations


[1] https://www.ietf.org/archive/id/draft-ietf-tls-esni-13.html
[2] https://github.com/openssl/openssl/issues/7482
[3] https://bugs.chromium.org/p/boringssl/issues/detail?id=275
[5] https://bugzilla.mozilla.org/show_bug.cgi?id=1725938
[6] https://bugs.chromium.org/p/chromium/issues/detail?id=1091403
[6] https://github.com/google/conscrypt/issues/730
[7] https://github.com/square/okhttp/issues/6539
[8] https://www.ietf.org/archive/id/draft-ietf-dnsop-svcb-https-07.html
[9] https://github.com/sftcd/openssl
msg404749 - (view) Author: Christian Heimes (christian.heimes) * (Python committer) Date: 2021-10-22 10:41
Thanks for filing this feature request!

The DNS lookup part is out of scope for the ssl module. I don't want to get into the DNS business. At $WORK I work on BIND, DNSSEC and DNS over TLS. Secure DNS (and DNS in general) is already complicated when you control the entire stack and only have to deal with one family of Linux distros. AFAIK there isn't even a platform-independent way to perform lookups with abitrary RRTYPEs. res_nquery() is only available on some platforms and doesn't work reliable with some libcs. I have had issues with EDNS0 on musl in the past. KRB5KDC SRV looks with large responses where unreliable. Let's offload the DNS part of consumers of the ssl module. They can use python-dns or c-ares.

The ECH part and callback look sensible, though. I'll include the APIs as soon as OpenSSL support them.
msg405513 - (view) Author: Hans-Christoph Steiner (eighthave) Date: 2021-11-02 15:51
I agree with all you say, but I think it is important to not rule out handling HTTPS/SVCB DNS here.  It can happen at a later stage though.  What you propose works great for the first step.

If handling the DNS is punted to some external library, that means that each client app will have to implement this itself, and its non-trivial.  In that scenario, very few clients will implement it.  This makes me believe that this should be implemented in the core.  Granted, its an open question whether the ssl module is the right place.  For example, it could makes more sense to handle HTTPS/SVCB DNS in the HTTP libs (urllib, requests, etc), but that means non-HTTP uses (XMPP, Matrix, etc) will be disadvantaged.
History
Date User Action Args
2022-04-11 14:59:51adminsetgithub: 89730
2021-11-02 15:51:37eighthavesetmessages: + msg405513
2021-10-22 10:41:35christian.heimessetmessages: + msg404749
2021-10-22 08:59:46eighthavecreate