crypto/tls: add ech client support

This CL adds a (very opinionated) client-side ECH implementation.

In particular, if a user configures a ECHConfigList, by setting the
Config.EncryptedClientHelloConfigList, but we determine that none of
the configs are appropriate, we will not fallback to plaintext SNI, and
will instead return an error. It is then up to the user to decide if
they wish to fallback to plaintext themselves (by removing the config
list).

Additionally if Config.EncryptedClientHelloConfigList is provided, we
will not offer TLS support lower than 1.3, since negotiating any other
version, while offering ECH, is a hard error anyway. Similarly, if a
user wishes to fallback to plaintext SNI by using 1.2, they may do so
by removing the config list.

With regard to PSK GREASE, we match the boringssl  behavior, which does
not include PSK identities/binders in the outer hello when doing ECH.

If the server rejects ECH, we will return a ECHRejectionError error,
which, if provided by the server, will contain a ECHConfigList in the
RetryConfigList field containing configs that should be used if the user
wishes to retry. It is up to the user to replace their existing
Config.EncryptedClientHelloConfigList with the retry config list.

Fixes #63369

Cq-Include-Trybots: luci.golang.try:gotip-linux-amd64-longtest
Change-Id: I9bc373c044064221a647a388ac61624efd6bbdbf
Reviewed-on: https://go-review.googlesource.com/c/go/+/578575
Reviewed-by: Ian Lance Taylor <iant@google.com>
Reviewed-by: Filippo Valsorda <filippo@golang.org>
Reviewed-by: Than McIntosh <thanm@google.com>
Reviewed-by: Dmitri Shuralyov <dmitshur@golang.org>
Auto-Submit: Roland Shoemaker <roland@golang.org>
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
This commit is contained in:
Roland Shoemaker 2024-04-11 08:50:36 -07:00
parent a2d887fa30
commit ce1cbd081a
14 changed files with 1214 additions and 251 deletions

View file

@ -58,6 +58,7 @@ const (
alertUnknownPSKIdentity alert = 115
alertCertificateRequired alert = 116
alertNoApplicationProtocol alert = 120
alertECHRequired alert = 121
)
var alertText = map[alert]string{
@ -94,6 +95,7 @@ var alertText = map[alert]string{
alertUnknownPSKIdentity: "unknown PSK identity",
alertCertificateRequired: "certificate required",
alertNoApplicationProtocol: "no application protocol",
alertECHRequired: "encrypted client hello required",
}
func (e alert) String() string {