Description
The TLS 1.3 server HelloRetryRequest path validates many fields that must remain stable between the first and second ClientHello, but it does not reject a second ClientHello whose PSK identity list has changed. Binders and obfuscated ticket
ages may need to be recomputed after HRR, and incompatible PSKs may be dropped, but the accepted PSK identity set should not be replaced with a different set.
This is a protocol-conformance issue rather than a demonstrated credential bypass: the client still needs a valid PSK and binder for the PSK selected by the server.
Specification
RFC 8446 Section 4.1.2 restricts the changes permitted between ClientHello1 and ClientHello2 after HelloRetryRequest. RFC 8446 Sections 4.2.11 and 4.2.11.2 define PSK identities and binders, including the binder recomputation over the
HRR transcript.
Code references
go/src/crypto/tls/handshake_server_tls13.go:645 calls illegalClientHelloChange after reading ClientHello2.
go/src/crypto/tls/handshake_server_tls13.go:655 documents that illegalClientHelloChange implements the RFC 8446 HRR change check.
go/src/crypto/tls/handshake_server_tls13.go:389 through go/src/crypto/tls/handshake_server_tls13.go:431 validates the binder and selects the PSK from the current hs.clientHello, which is replaced by the second ClientHello at go/src/crypto/tls/handshake_server_tls13.go:651.
Test case
This can be a crypto/tls unit test for illegalClientHelloChange with two ClientHello messages that differ only in pskIdentities or pskBinders.
It should also be possible to turn this into a BoringSSL bogo-style TLS 1.3 test: send ClientHello1 with one valid PSK offer, trigger HRR, then send ClientHello2 with a different PSK identity and valid binder for that identity. The Go server should reject the second ClientHello as an illegal HRR change.
Description
The TLS 1.3 server HelloRetryRequest path validates many fields that must remain stable between the first and second ClientHello, but it does not reject a second ClientHello whose PSK identity list has changed. Binders and obfuscated ticket
ages may need to be recomputed after HRR, and incompatible PSKs may be dropped, but the accepted PSK identity set should not be replaced with a different set.
This is a protocol-conformance issue rather than a demonstrated credential bypass: the client still needs a valid PSK and binder for the PSK selected by the server.
Specification
RFC 8446 Section 4.1.2 restricts the changes permitted between ClientHello1 and ClientHello2 after HelloRetryRequest. RFC 8446 Sections 4.2.11 and 4.2.11.2 define PSK identities and binders, including the binder recomputation over the
HRR transcript.
Code references
go/src/crypto/tls/handshake_server_tls13.go:645callsillegalClientHelloChangeafter reading ClientHello2.go/src/crypto/tls/handshake_server_tls13.go:655documents thatillegalClientHelloChangeimplements the RFC 8446 HRR change check.go/src/crypto/tls/handshake_server_tls13.go:389throughgo/src/crypto/tls/handshake_server_tls13.go:431validates the binder and selects the PSK from the currenths.clientHello, which is replaced by the second ClientHello atgo/src/crypto/tls/handshake_server_tls13.go:651.Test case
This can be a
crypto/tlsunit test forillegalClientHelloChangewith two ClientHello messages that differ only inpskIdentitiesorpskBinders.It should also be possible to turn this into a BoringSSL bogo-style TLS 1.3 test: send ClientHello1 with one valid PSK offer, trigger HRR, then send ClientHello2 with a different PSK identity and valid binder for that identity. The Go server should reject the second ClientHello as an illegal HRR change.