mirror of
https://github.com/golang/go.git
synced 2026-06-27 19:30:52 +00:00
crypto/tls: skip unsupported ECH config versions
When we encounter an ECHConfig structure with an unsupported version, the RFC 9849 section 4 text indicates we MUST ignore it. The parseECHConfig helper returns a skip boolean when this case is hit, but previously processECHClientHello treated this as equivalent to a non-nil error return, sending an alert and terminating the handshake. Instead we should handle the nil error true skip case by continuing to try the next available echKeys entry, ignoring the unsupported version entry. If we exhaust all available echKeys without finding a supported one, we will not accept ECH as expected. Change-Id: Id0a21c48b472756ad27a028be4d8422c1e9dd3ef Reviewed-on: https://go-review.googlesource.com/c/go/+/771461 LUCI-TryBot-Result: golang-scoped@luci-project-accounts.iam.gserviceaccount.com <golang-scoped@luci-project-accounts.iam.gserviceaccount.com> Auto-Submit: Daniel McCarney <daniel@binaryparadox.net> Reviewed-by: Carlos Amedee <carlos@golang.org> Reviewed-by: Roland Shoemaker <roland@golang.org>
This commit is contained in:
parent
be9da6ce60
commit
10b5baca54
2 changed files with 22 additions and 5 deletions
|
|
@ -572,7 +572,7 @@ func (c *Conn) processECHClientHello(outer *clientHelloMsg, echKeys []EncryptedC
|
|||
|
||||
for _, echKey := range echKeys {
|
||||
skip, config, err := parseECHConfig(echKey.Config)
|
||||
if err != nil || skip {
|
||||
if err != nil {
|
||||
c.sendAlert(alertInternalError)
|
||||
return nil, nil, fmt.Errorf("tls: invalid EncryptedClientHelloKey Config: %s", err)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2333,9 +2333,9 @@ func TestECH(t *testing.T) {
|
|||
t.Fatal(err)
|
||||
}
|
||||
|
||||
marshalECHConfig := func(id uint8, pubKey []byte, publicName string, maxNameLen uint8) []byte {
|
||||
marshalECHConfig := func(version uint16, id uint8, pubKey []byte, publicName string, maxNameLen uint8) []byte {
|
||||
builder := cryptobyte.NewBuilder(nil)
|
||||
builder.AddUint16(extensionEncryptedClientHello)
|
||||
builder.AddUint16(version)
|
||||
builder.AddUint16LengthPrefixed(func(builder *cryptobyte.Builder) {
|
||||
builder.AddUint8(id)
|
||||
builder.AddUint16(0x0020 /* DHKEM(X25519, HKDF-SHA256) */)
|
||||
|
|
@ -2361,7 +2361,7 @@ func TestECH(t *testing.T) {
|
|||
t.Fatal(err)
|
||||
}
|
||||
|
||||
echConfig := marshalECHConfig(123, echKey.PublicKey().Bytes(), "public.example", 32)
|
||||
echConfig := marshalECHConfig(extensionEncryptedClientHello, 123, echKey.PublicKey().Bytes(), "public.example", 32)
|
||||
|
||||
builder := cryptobyte.NewBuilder(nil)
|
||||
builder.AddUint16LengthPrefixed(func(builder *cryptobyte.Builder) {
|
||||
|
|
@ -2426,12 +2426,29 @@ func TestECH(t *testing.T) {
|
|||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
randConfig := marshalECHConfig(32, randKey.PublicKey().Bytes(), "random.example", 32)
|
||||
randConfig := marshalECHConfig(extensionEncryptedClientHello, 32, randKey.PublicKey().Bytes(), "random.example", 32)
|
||||
serverConfig.EncryptedClientHelloKeys = []EncryptedClientHelloKey{
|
||||
{Config: randConfig, PrivateKey: randKey.Bytes(), SendAsRetry: true},
|
||||
}
|
||||
|
||||
check()
|
||||
|
||||
// A server configured with an unsupported-version ECHConfig ahead of a
|
||||
// usable one must skip the unusable entry (per RFC 9849 §4) and
|
||||
// trial-decrypt against the next key, rather than aborting the handshake
|
||||
// on the first entry.
|
||||
unsupportedKey, err := ecdh.X25519().GenerateKey(rand.Reader)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
unsupportedConfig := marshalECHConfig(0xbadd, 99, unsupportedKey.PublicKey().Bytes(), "public.example", 32)
|
||||
serverConfig.GetEncryptedClientHelloKeys = nil
|
||||
serverConfig.EncryptedClientHelloKeys = []EncryptedClientHelloKey{
|
||||
{Config: unsupportedConfig, PrivateKey: unsupportedKey.Bytes(), SendAsRetry: true},
|
||||
{Config: echConfig, PrivateKey: echKey.Bytes(), SendAsRetry: true},
|
||||
}
|
||||
|
||||
check()
|
||||
}
|
||||
|
||||
func TestMessageSigner(t *testing.T) {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue