echspec
echspec is a conformance testing tool for ECH implementation.

Installation
The gem is available at rubygems.org. You can install it the following:
$ gem install echspec
Usage
$ echspec --help
Usage: echspec [OPTIONS] <HOSTNAME>
-f, --file FILE path to ECHConfigs PEM file (default resolve ECHConfigs via DNS)
-p, --port VALUE server port number (default 443)
-n, --not-force-compliant-hpke not force compliant ECHConfig HPKE cipher suite
-v, --verbose verbose mode; prints message stack if raised an error
-s, --sections SECTIONS sections to test; by the default, test all sections
You can run it the following:
$ echspec research.cloudflare.com
TLS Encrypted Client Hello Server
✔ MUST implement the following HPKE cipher suite: KEM: DHKEM(X25519, HKDF-SHA256), KDF: HKDF-SHA256 and AEAD: AES-128-GCM. [9]
✔ MUST abort with an "illegal_parameter" alert, if EncodedClientHelloInner is padded with non-zero values. [5.1-9]
✔ MUST abort with an "illegal_parameter" alert, if any referenced extension is missing in ClientHelloOuter. [5.1-10]
✔ MUST abort with an "illegal_parameter" alert, if any extension is referenced in OuterExtensions more than once. [5.1-10]
✔ MUST abort with an "illegal_parameter" alert, if "encrypted_client_hello" is referenced in OuterExtensions. [5.1-10]
✔ MUST abort with an "illegal_parameter" alert, if the extensions in ClientHelloOuter corresponding to those in OuterExtensions do not occur in the same order. [5.1-10]
✔ MUST abort with an "illegal_parameter" alert, if ECHClientHello.type is not a valid ECHClientHelloType in ClientHelloInner. [7-5]
x MUST abort with an "illegal_parameter" alert, if ECHClientHello.type is not a valid ECHClientHelloType in ClientHelloOuter. [7-5]
✔ MUST abort with an "illegal_parameter" alert, if ClientHelloInner offers TLS 1.2 or below. [7.1-11]
✔ MUST include the "encrypted_client_hello" extension in its EncryptedExtensions with the "retry_configs" field set to one or more ECHConfig. [7.1-14.2.1]
✔ MUST abort with a "missing_extension" alert, if 2nd ClientHelloOuter does not contains the "encrypted_client_hello" extension. [7.1.1-2]
✔ MUST abort with an "illegal_parameter" alert, if 2nd ClientHelloOuter "encrypted_client_hello" enc is empty. [7.1.1-2]
✔ MUST abort with a "decrypt_error" alert, if fails to decrypt 2nd ClientHelloOuter. [7.1.1-5]
Failures:
1) MUST abort with an "illegal_parameter" alert, if ECHClientHello.type is not a valid ECHClientHelloType in ClientHelloOuter. [7-5]
https://datatracker.ietf.org/doc/html/draft-ietf-tls-esni-22#section-7-5
did not send expected alert: illegal_parameter
1 failure
By default, echspec retrieves ECHConfigs via HTTPS records. By using the -f, --file FILE option, you can specify an ECHConfig pem file. If you need to test the server on localhost, you can run it the following:
$ echspec -f fixtures/echconfigs.pem -p 4433 localhost
By default, echspec uses the following HPKE cipher suite
- KEM
- DHKEM(X25519, HKDF-SHA256)
- KDF
- HKDF-SHA256
- AEAD
- AES-128-GCM
Using the -n or --not-force-compliant-hpke, you can not enforce the HPKE cipher suite.
$ echspec -f fixtures/echconfigs.pem -p 4433 -n localhost
If you specify the SECTIONS, you can run only SECTIONS the following:
$ echspec -f fixtures/echconfigs.pem -p 4433 -n -s 7.1.1-2,7.1.1-5 localhost
TLS Encrypted Client Hello Server
✔ MUST abort with a "missing_extension" alert, if 2nd ClientHelloOuter does not contains the "encrypted_client_hello" extension. [7.1.1-2]
✔ MUST abort with an "illegal_parameter" alert, if 2nd ClientHelloOuter "encrypted_client_hello" enc is empty. [7.1.1-2]
✔ MUST abort with a "decrypt_error" alert, if fails to decrypt 2nd ClientHelloOuter. [7.1.1-5]
Using the -v or --verbose option provides a message stack if an error occurs. The message stack is formatted as JSON.
$ echspec -s 7-5 -v research.cloudflare.com 2>&1 > /dev/null | jq .
Note
echspec is inspired by:
License
echspec is available as open source under the terms of the MIT License.