crypto/tls: omit PSK in ECH outer client hello

When using ECH, do not include the PSK extension in the outer hello.
Including the PSK extension allows for a degradation in privacy, as an
on-path attacker can harvest outer client hellos, and then construct new
hellos using the PSK extension and arbitrary guessed SNI values,
replaying them to the target server. If the server rejects the PSK, the
handshake will continue, but if the PSK is accepted, the binder check
will fail.

Thanks to Coia Prant (github.com/rbqvq) for
reporting this issue.

Fixes CVE-2026-42505
Fixes #79282

Change-Id: Ib3a3c948106a57c1b07b9e61a58cbf757848be18
Reviewed-on: https://go-review.googlesource.com/c/go/+/775960
Auto-Submit: Roland Shoemaker <roland@golang.org>
TryBot-Bypass: Roland Shoemaker <roland@golang.org>
Reviewed-by: Daniel McCarney <daniel@binaryparadox.net>
Reviewed-by: Carlos Amedee <carlos@golang.org>
This commit is contained in:
yuhan6665
2026-09-10 23:12:18 -04:00
parent e235ff1892
commit 7dba75cce3
+3 -1
View File
@@ -5,6 +5,7 @@
package reality
import (
"bytes"
"errors"
"fmt"
"slices"
@@ -317,7 +318,8 @@ func (m *clientHelloMsg) marshalMsg(echInner bool) ([]byte, error) {
})
})
}
if len(m.pskIdentities) > 0 { // pre_shared_key must be the last extension
// pre_shared_key must be the last extension
if len(m.pskIdentities) > 0 && (echInner || len(m.encryptedClientHello) == 0 || bytes.Equal(m.encryptedClientHello, []byte{byte(innerECHExt)})) {
// RFC 8446, Section 4.2.11
exts.AddUint16(extensionPreSharedKey)
exts.AddUint16LengthPrefixed(func(exts *cryptobyte.Builder) {