-
Notifications
You must be signed in to change notification settings - Fork 143
ECH and ESNI support in picotls
Encrypted Server Name Indication for TLS 1.3 (ESNI) is an extension to TLS 1.3 that sends the server name in an encrypted form. In later drafts, the ESNI specification evolved into Encrypted Client Hello.
Early versions of picotls supported working group draft-02, but the new versions support ECH. The documentation below is out of date.
Use openssl 1.1.0 or above to generate a ESNI private key using X25519 or secp256r1.
% openssl genpkey -algorithm x25519 > esni-x25519.key
% openssl ecparam -name secp256r1 -genkey -noout -out esni-secp256r1.key
OpenSSL 1.1.0 or above is required for generating X25519 keys.
Use the picotls-esni command to build a ESNI Resource Record. The command takes the private key(s) and the cipher-suites to be supported for encrypting the ESNI extension.
The example below creates a ESNI Resource Record that contains two private keys and declares support for two cipher-suites.
% picotls-esni -K esni-x25519.key -K esni-secp256r1.key -c aes128-gcm -c chacha20-poly1305 > esni-rr.bin
See picotls-esni -h
to find other options.
The generated ESNI Resource Record must be deployed to the authoritative DNS server using the TXT record type, with the _esni
prefix.
As a server, the "cli" command accepts two options that are used for Encrypted SNI.
-E
option specifies the filename of the ESNI Resource Record.
-K
option specifies the filename of the ESNI private key. The option can be used more than once to specify multiple keys.
The example below launches a TLS server running at 127.0.0.1:4433 using the keys and the Resource Record being generated in the examples above.
% ./cli -K esni-x25519.key -K esni-secp256r1.key -E esni-rr.bin -k server.key -c server.crt 127.0.0.1 4433
There is no change to how the command is being run in client mode.
The command automatically resolves the ESNI key associated to the server it connects to, by calling res_query
.
% ./cli 127.0.0.1 4433
ptls_context_t::esni
is a NULL-terminated list of ESNI contexts. Each ESNI context contains a list of key exnchanges, as well as the information to be found in the ESNI Resource Record (e.g., cipher-suites, padded-length).
For building the ESNI context, a helper function called ptls_esni_init_context
is provided. The function accepts a ptls_iovec_t
specifying the ESNI Resource Record and a NULL-terminated list of key exchanges.
Its use can be found in the setup_esni
function in t/util.h
.
An application that is willing to use ESNI should setup ptls_handshake_properties_t::client.esni_keys
to point to the ESNI Resource Record of the server the application is going to connect to. If set, picotls will parse the provided Resource Record and use the Encrypted SNI extension.