mirror of
https://github.com/refraction-networking/utls.git
synced 2025-04-03 20:17:36 +03:00
updated to have more browser configs and psk support
This commit is contained in:
parent
23de245734
commit
f83e29e839
9 changed files with 324 additions and 23 deletions
2
.gitignore
vendored
Normal file
2
.gitignore
vendored
Normal file
|
@ -0,0 +1,2 @@
|
|||
.idea/
|
||||
.idea
|
4
cfkem.go
4
cfkem.go
|
@ -41,6 +41,7 @@ var (
|
|||
X25519Kyber768Draft00 = CurveID(0x6399)
|
||||
X25519Kyber768Draft00Old = CurveID(0xfe31)
|
||||
P256Kyber768Draft00 = CurveID(0xfe32)
|
||||
X25519MLKEM768 = CurveID(0x11ec)
|
||||
invalidCurveID = CurveID(0)
|
||||
)
|
||||
|
||||
|
@ -69,7 +70,10 @@ func curveIdToCirclScheme(id CurveID) kem.Scheme {
|
|||
return hybrid.Kyber768X25519()
|
||||
case P256Kyber768Draft00:
|
||||
return hybrid.P256Kyber768Draft00()
|
||||
case X25519MLKEM768:
|
||||
return hybrid.X25519MLKEM768()
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
|
|
|
@ -171,8 +171,9 @@ func runResumptionCheck(helloID tls.ClientHelloID, getCustomSpec func() *tls.Cli
|
|||
|
||||
func main() {
|
||||
tls13Url := "www.microsoft.com:443"
|
||||
tls12Url1 := "spocs.getpocket.com:443"
|
||||
tls12Url2 := "marketplace.visualstudio.com:443"
|
||||
tls13HRRUrl := "marketplace.visualstudio.com:443" // will send HRR for P384/P521
|
||||
tls12Url := "tls-v1-2.badssl.com:1012"
|
||||
|
||||
runResumptionCheck(tls.HelloChrome_100, nil, noResumption, tls13Url, 3, false) // no-resumption + utls
|
||||
func() {
|
||||
defer func() {
|
||||
|
@ -189,9 +190,9 @@ func main() {
|
|||
runResumptionCheck(tls.HelloChrome_100_PSK, nil, pskResumption, tls13Url, 1, false) // psk + utls
|
||||
runResumptionCheck(tls.HelloGolang, nil, pskResumption, tls13Url, 1, false) // psk + crypto/tls
|
||||
|
||||
runResumptionCheck(tls.HelloChrome_100_PSK, nil, ticketResumption, tls12Url1, 10, false) // session ticket + utls
|
||||
runResumptionCheck(tls.HelloGolang, nil, ticketResumption, tls12Url1, 10, false) // session ticket + crypto/tls
|
||||
runResumptionCheck(tls.HelloChrome_100_PSK, nil, ticketResumption, tls12Url2, 10, false) // session ticket + utls
|
||||
runResumptionCheck(tls.HelloGolang, nil, ticketResumption, tls12Url2, 10, false) // session ticket + crypto/tls
|
||||
runResumptionCheck(tls.HelloChrome_100_PSK, nil, pskResumption, tls13HRRUrl, 20, false) // psk (HRR) + utls
|
||||
runResumptionCheck(tls.HelloGolang, nil, pskResumption, tls13HRRUrl, 20, false) // psk (HRR) + crypto/tls // session ticket + crypto/tls
|
||||
|
||||
runResumptionCheck(tls.HelloChrome_100_PSK, nil, ticketResumption, tls12Url, 10, false) // session ticket + utls
|
||||
runResumptionCheck(tls.HelloGolang, nil, ticketResumption, tls12Url, 10, false)
|
||||
}
|
||||
|
|
4
go.mod
4
go.mod
|
@ -1,6 +1,6 @@
|
|||
module github.com/refraction-networking/utls
|
||||
|
||||
go 1.21
|
||||
go 1.22.5
|
||||
|
||||
retract (
|
||||
v1.4.1 // #218
|
||||
|
@ -9,7 +9,7 @@ retract (
|
|||
|
||||
require (
|
||||
github.com/andybalholm/brotli v1.0.6
|
||||
github.com/cloudflare/circl v1.3.7
|
||||
github.com/cloudflare/circl v1.5.0
|
||||
github.com/klauspost/compress v1.17.4
|
||||
golang.org/x/crypto v0.21.0
|
||||
golang.org/x/net v0.23.0
|
||||
|
|
4
go.sum
4
go.sum
|
@ -1,7 +1,7 @@
|
|||
github.com/andybalholm/brotli v1.0.6 h1:Yf9fFpf49Zrxb9NlQaluyE92/+X7UVHlhMNJN2sxfOI=
|
||||
github.com/andybalholm/brotli v1.0.6/go.mod h1:fO7iG3H7G2nSZ7m0zPUDn85XEX2GTukHGRSepvi9Eig=
|
||||
github.com/cloudflare/circl v1.3.7 h1:qlCDlTPz2n9fu58M0Nh1J/JzcFpfgkFHHX3O35r5vcU=
|
||||
github.com/cloudflare/circl v1.3.7/go.mod h1:sRTcRWXGLrKw6yIGJ+l7amYJFfAXbZG0kBSc8r4zxgA=
|
||||
github.com/cloudflare/circl v1.5.0 h1:hxIWksrX6XN5a1L2TI/h53AGPhNHoUBo+TD1ms9+pys=
|
||||
github.com/cloudflare/circl v1.5.0/go.mod h1:uddAzsPgqdMAYatqJ0lsjX1oECcQLIlRpzZh3pJrofs=
|
||||
github.com/klauspost/compress v1.17.4 h1:Ej5ixsIri7BrIjBkRZLTo6ghwrEtHFk7ijlczPW4fZ4=
|
||||
github.com/klauspost/compress v1.17.4/go.mod h1:/dCuZOvVtNoHsyb+cuJD3itjs3NbnF6KH9zAO4BDxPM=
|
||||
golang.org/x/crypto v0.21.0 h1:X31++rzVUdKhX5sWmSOFZxx8UW/ldWx55cbf08iNAMA=
|
||||
|
|
14
u_common.go
14
u_common.go
|
@ -75,10 +75,11 @@ const (
|
|||
)
|
||||
|
||||
const (
|
||||
CurveSECP256R1 CurveID = 0x0017
|
||||
CurveSECP384R1 CurveID = 0x0018
|
||||
CurveSECP521R1 CurveID = 0x0019
|
||||
CurveX25519 CurveID = 0x001d
|
||||
CurveSECP256R1 CurveID = 0x0017
|
||||
CurveSECP384R1 CurveID = 0x0018
|
||||
CurveSECP521R1 CurveID = 0x0019
|
||||
CurveX25519 CurveID = 0x001d
|
||||
CurveX25519MLKEM768 CurveID = 0x11ec
|
||||
|
||||
FakeCurveFFDHE2048 CurveID = 0x0100
|
||||
FakeCurveFFDHE3072 CurveID = 0x0101
|
||||
|
@ -596,6 +597,7 @@ var (
|
|||
HelloFirefox_102 = ClientHelloID{helloFirefox, "102", nil, nil}
|
||||
HelloFirefox_105 = ClientHelloID{helloFirefox, "105", nil, nil}
|
||||
HelloFirefox_120 = ClientHelloID{helloFirefox, "120", nil, nil}
|
||||
HelloFirefox_133 = ClientHelloID{helloFirefox, "133", nil, nil}
|
||||
|
||||
HelloChrome_Auto = HelloChrome_120
|
||||
HelloChrome_58 = ClientHelloID{helloChrome, "58", nil, nil}
|
||||
|
@ -612,6 +614,7 @@ var (
|
|||
// Chrome w/ PSK: Chrome start sending this ClientHello after doing TLS 1.3 handshake with the same server.
|
||||
// Beta: PSK extension added. However, uTLS doesn't ship with full PSK support.
|
||||
// Use at your own discretion.
|
||||
HelloChrome_PSK_Auto = HelloChrome_114_Padding_PSK_Shuf
|
||||
HelloChrome_100_PSK = ClientHelloID{helloChrome, "100_PSK", nil, nil}
|
||||
HelloChrome_112_PSK_Shuf = ClientHelloID{helloChrome, "112_PSK", nil, nil}
|
||||
HelloChrome_114_Padding_PSK_Shuf = ClientHelloID{helloChrome, "114_PSK", nil, nil}
|
||||
|
@ -624,7 +627,8 @@ var (
|
|||
// Chrome ECH
|
||||
HelloChrome_120 = ClientHelloID{helloChrome, "120", nil, nil}
|
||||
// Chrome w/ Post-Quantum Key Agreement and Encrypted ClientHello
|
||||
HelloChrome_120_PQ = ClientHelloID{helloChrome, "120_PQ", nil, nil}
|
||||
HelloChrome_120_PQ = ClientHelloID{helloChrome, "120_PQ", nil, nil}
|
||||
HelloChrome_131_PSK = ClientHelloID{helloChrome, "131_PSK", nil, nil}
|
||||
|
||||
HelloIOS_Auto = HelloIOS_14
|
||||
HelloIOS_11_1 = ClientHelloID{helloIOS, "111", nil, nil} // legacy "111" means 11.1
|
||||
|
|
218
u_parrots.go
218
u_parrots.go
|
@ -1309,6 +1309,130 @@ func utlsIdToSpec(id ClientHelloID) (ClientHelloSpec, error) {
|
|||
},
|
||||
},
|
||||
}, nil
|
||||
case HelloFirefox_133:
|
||||
return ClientHelloSpec{
|
||||
TLSVersMin: VersionTLS12,
|
||||
TLSVersMax: VersionTLS13,
|
||||
CipherSuites: []uint16{
|
||||
TLS_AES_128_GCM_SHA256,
|
||||
TLS_CHACHA20_POLY1305_SHA256,
|
||||
TLS_AES_256_GCM_SHA384,
|
||||
TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,
|
||||
TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,
|
||||
TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256,
|
||||
TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256,
|
||||
TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,
|
||||
TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384,
|
||||
TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA,
|
||||
TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA,
|
||||
TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA,
|
||||
TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA,
|
||||
TLS_RSA_WITH_AES_128_GCM_SHA256,
|
||||
TLS_RSA_WITH_AES_256_GCM_SHA384,
|
||||
TLS_RSA_WITH_AES_128_CBC_SHA,
|
||||
TLS_RSA_WITH_AES_256_CBC_SHA,
|
||||
},
|
||||
CompressionMethods: []uint8{
|
||||
0x0, // no compression
|
||||
},
|
||||
Extensions: []TLSExtension{
|
||||
&SNIExtension{},
|
||||
&ExtendedMasterSecretExtension{},
|
||||
&RenegotiationInfoExtension{
|
||||
Renegotiation: RenegotiateOnceAsClient,
|
||||
},
|
||||
&SupportedCurvesExtension{
|
||||
Curves: []CurveID{
|
||||
CurveX25519MLKEM768,
|
||||
CurveX25519,
|
||||
CurveSECP256R1,
|
||||
CurveSECP384R1,
|
||||
CurveSECP521R1,
|
||||
FakeCurveFFDHE2048,
|
||||
FakeCurveFFDHE3072,
|
||||
},
|
||||
},
|
||||
&SupportedPointsExtension{
|
||||
SupportedPoints: []uint8{
|
||||
0x0, // uncompressed
|
||||
},
|
||||
},
|
||||
&SessionTicketExtension{},
|
||||
&ALPNExtension{
|
||||
AlpnProtocols: []string{
|
||||
"h2",
|
||||
"http/1.1",
|
||||
},
|
||||
},
|
||||
&StatusRequestExtension{},
|
||||
&FakeDelegatedCredentialsExtension{
|
||||
SupportedSignatureAlgorithms: []SignatureScheme{
|
||||
0x0403,
|
||||
0x0503,
|
||||
0x0603,
|
||||
ECDSAWithSHA1,
|
||||
},
|
||||
},
|
||||
&KeyShareExtension{
|
||||
KeyShares: []KeyShare{
|
||||
{
|
||||
Group: CurveX25519MLKEM768,
|
||||
},
|
||||
{
|
||||
Group: CurveX25519,
|
||||
},
|
||||
{
|
||||
Group: CurveSECP256R1,
|
||||
},
|
||||
},
|
||||
},
|
||||
&SupportedVersionsExtension{
|
||||
Versions: []uint16{
|
||||
VersionTLS13,
|
||||
VersionTLS12,
|
||||
},
|
||||
},
|
||||
&SignatureAlgorithmsExtension{
|
||||
SupportedSignatureAlgorithms: []SignatureScheme{
|
||||
0x0403,
|
||||
0x0503,
|
||||
0x0603,
|
||||
0x0804,
|
||||
0x0805,
|
||||
0x0806,
|
||||
0x0401,
|
||||
0x0501,
|
||||
0x0601,
|
||||
0x0203,
|
||||
0x0201,
|
||||
},
|
||||
},
|
||||
&PSKKeyExchangeModesExtension{[]uint8{
|
||||
pskModeDHE,
|
||||
}},
|
||||
&FakeRecordSizeLimitExtension{
|
||||
Limit: 0x4001,
|
||||
},
|
||||
&UtlsCompressCertExtension{[]CertCompressionAlgo{
|
||||
CertCompressionZlib,
|
||||
CertCompressionBrotli,
|
||||
CertCompressionZstd,
|
||||
}},
|
||||
&GREASEEncryptedClientHelloExtension{
|
||||
CandidateCipherSuites: []HPKESymmetricCipherSuite{
|
||||
{
|
||||
KdfId: dicttls.HKDF_SHA256,
|
||||
AeadId: dicttls.AEAD_AES_128_GCM,
|
||||
},
|
||||
{
|
||||
KdfId: dicttls.HKDF_SHA256,
|
||||
AeadId: dicttls.AEAD_CHACHA20_POLY1305,
|
||||
},
|
||||
},
|
||||
CandidatePayloadLens: []uint16{447, 223}, // +16: 239
|
||||
},
|
||||
},
|
||||
}, nil
|
||||
case HelloIOS_11_1:
|
||||
return ClientHelloSpec{
|
||||
TLSVersMax: VersionTLS12,
|
||||
|
@ -2538,6 +2662,100 @@ func utlsIdToSpec(id ClientHelloID) (ClientHelloSpec, error) {
|
|||
&UtlsPreSharedKeyExtension{},
|
||||
}),
|
||||
}, nil
|
||||
|
||||
case HelloChrome_131_PSK:
|
||||
return ClientHelloSpec{
|
||||
CipherSuites: []uint16{
|
||||
GREASE_PLACEHOLDER, // Grease Placeholder for this version of chrome
|
||||
TLS_AES_128_GCM_SHA256,
|
||||
TLS_AES_256_GCM_SHA384,
|
||||
TLS_CHACHA20_POLY1305_SHA256,
|
||||
TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,
|
||||
TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,
|
||||
TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,
|
||||
TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384,
|
||||
TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256,
|
||||
TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256,
|
||||
TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA,
|
||||
TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA,
|
||||
TLS_RSA_WITH_AES_128_GCM_SHA256,
|
||||
TLS_RSA_WITH_AES_256_GCM_SHA384,
|
||||
TLS_RSA_WITH_AES_128_CBC_SHA,
|
||||
TLS_RSA_WITH_AES_256_CBC_SHA,
|
||||
},
|
||||
CompressionMethods: []byte{
|
||||
0x00, // compressionNone
|
||||
},
|
||||
Extensions: ShuffleChromeTLSExtensions([]TLSExtension{
|
||||
&UtlsGREASEExtension{},
|
||||
|
||||
&PSKKeyExchangeModesExtension{[]uint8{
|
||||
PskModeDHE,
|
||||
}},
|
||||
&SessionTicketExtension{},
|
||||
|
||||
&SCTExtension{},
|
||||
|
||||
&SupportedVersionsExtension{[]uint16{
|
||||
GREASE_PLACEHOLDER,
|
||||
VersionTLS13,
|
||||
VersionTLS12,
|
||||
}},
|
||||
|
||||
&SupportedPointsExtension{SupportedPoints: []byte{
|
||||
0x00, // pointFormatUncompressed
|
||||
}},
|
||||
|
||||
&UtlsCompressCertExtension{[]CertCompressionAlgo{
|
||||
CertCompressionBrotli,
|
||||
}},
|
||||
|
||||
&SignatureAlgorithmsExtension{SupportedSignatureAlgorithms: []SignatureScheme{
|
||||
ECDSAWithP256AndSHA256,
|
||||
PSSWithSHA256,
|
||||
PKCS1WithSHA256,
|
||||
ECDSAWithP384AndSHA384,
|
||||
PSSWithSHA384,
|
||||
PKCS1WithSHA384,
|
||||
PSSWithSHA512,
|
||||
PKCS1WithSHA512,
|
||||
}},
|
||||
|
||||
&RenegotiationInfoExtension{Renegotiation: RenegotiateOnceAsClient},
|
||||
&ApplicationSettingsExtension{SupportedProtocols: []string{"h2"}},
|
||||
&ExtendedMasterSecretExtension{},
|
||||
&StatusRequestExtension{},
|
||||
&SupportedCurvesExtension{[]CurveID{ //supported_groups
|
||||
GREASE_PLACEHOLDER, // Greese
|
||||
CurveX25519MLKEM768,
|
||||
CurveX25519,
|
||||
CurveSECP256R1,
|
||||
CurveSECP384R1,
|
||||
}},
|
||||
&ALPNExtension{
|
||||
AlpnProtocols: []string{
|
||||
"h2",
|
||||
"http/1.1",
|
||||
},
|
||||
},
|
||||
&SNIExtension{},
|
||||
&KeyShareExtension{
|
||||
KeyShares: []KeyShare{
|
||||
{
|
||||
Group: CurveID(GREASE_PLACEHOLDER), Data: []byte{0},
|
||||
},
|
||||
{
|
||||
Group: CurveX25519MLKEM768,
|
||||
},
|
||||
{
|
||||
Group: CurveX25519,
|
||||
},
|
||||
},
|
||||
},
|
||||
BoringGREASEECH(),
|
||||
&UtlsGREASEExtension{},
|
||||
}),
|
||||
}, nil
|
||||
default:
|
||||
if id.Client == helloRandomized || id.Client == helloRandomizedALPN || id.Client == helloRandomizedNoALPN {
|
||||
// Use empty values as they can be filled later by UConn.ApplyPreset or manually.
|
||||
|
|
|
@ -4,6 +4,7 @@ import (
|
|||
"encoding/json"
|
||||
"errors"
|
||||
"io"
|
||||
"time"
|
||||
|
||||
"golang.org/x/crypto/cryptobyte"
|
||||
)
|
||||
|
@ -68,6 +69,28 @@ type PreSharedKeyCommon struct {
|
|||
// > - Implementations should gather and provide the final pre-shared key (PSK) related data.
|
||||
//
|
||||
// > - This data will be incorporated into both the clientHello and HandshakeState, ensuring that the PSK-related information is properly set and ready for the handshake process.
|
||||
|
||||
//
|
||||
// HelloRetryRequest Phase (server selects a different curve supported but not selected by the client):
|
||||
//
|
||||
// - [UpdateOnHRR() called]:
|
||||
//
|
||||
// > - Implementations should update the extension's state accordingly and save the first Client Hello's hash.
|
||||
//
|
||||
// > - The binders should be recalculated based on the updated state LATER when PatchBuiltHello() and/or GetPreSharedKeyCommon() is called.
|
||||
//
|
||||
// - [PatchBuiltHello() called]:
|
||||
//
|
||||
// > - The client hello is already marshaled in the "hello.Raw" format.
|
||||
//
|
||||
// > - Implementations are expected to update the binders within the marshaled client hello.
|
||||
//
|
||||
// - [GetPreSharedKeyCommon() called]:
|
||||
//
|
||||
// > - Implementations should gather and provide the final pre-shared key (PSK) related data.
|
||||
//
|
||||
// > - This data will be incorporated into both the clientHello and HandshakeState, ensuring that the PSK-related information is properly set and ready for the handshake process.
|
||||
|
||||
type PreSharedKeyExtension interface {
|
||||
// TLSExtension must be implemented by all PreSharedKeyExtension implementations.
|
||||
TLSExtension
|
||||
|
@ -88,6 +111,8 @@ type PreSharedKeyExtension interface {
|
|||
// Its purpose is to update the binders of PSK (Pre-Shared Key) identities.
|
||||
PatchBuiltHello(hello *PubClientHelloMsg) error
|
||||
|
||||
UpdateOnHRR(prevClientHelloHash []byte, hs *clientHandshakeStateTLS13, timeNow time.Time) error
|
||||
|
||||
mustEmbedUnimplementedPreSharedKeyExtension() // this works like a type guard
|
||||
}
|
||||
|
||||
|
@ -99,7 +124,7 @@ func (*UnimplementedPreSharedKeyExtension) IsInitialized() bool {
|
|||
panic("tls: IsInitialized is not implemented for the PreSharedKeyExtension")
|
||||
}
|
||||
|
||||
func (*UnimplementedPreSharedKeyExtension) InitializeByUtls(session *SessionState, earlySecret []byte, binderKey []byte, identities []PskIdentity) {
|
||||
func (*UnimplementedPreSharedKeyExtension) InitializeByUtls(*SessionState, []byte, []byte, []PskIdentity) {
|
||||
panic("tls: Initialize is not implemented for the PreSharedKeyExtension")
|
||||
}
|
||||
|
||||
|
@ -119,14 +144,18 @@ func (*UnimplementedPreSharedKeyExtension) GetPreSharedKeyCommon() PreSharedKeyC
|
|||
panic("tls: GetPreSharedKeyCommon is not implemented for the PreSharedKeyExtension")
|
||||
}
|
||||
|
||||
func (*UnimplementedPreSharedKeyExtension) PatchBuiltHello(hello *PubClientHelloMsg) error {
|
||||
func (*UnimplementedPreSharedKeyExtension) PatchBuiltHello(*PubClientHelloMsg) error {
|
||||
panic("tls: ReadWithRawHello is not implemented for the PreSharedKeyExtension")
|
||||
}
|
||||
|
||||
func (*UnimplementedPreSharedKeyExtension) SetOmitEmptyPsk(val bool) {
|
||||
func (*UnimplementedPreSharedKeyExtension) SetOmitEmptyPsk(bool) {
|
||||
panic("tls: SetOmitEmptyPsk is not implemented for the PreSharedKeyExtension")
|
||||
}
|
||||
|
||||
func (*UnimplementedPreSharedKeyExtension) UpdateOnHRR([]byte, *clientHandshakeStateTLS13, time.Time) error {
|
||||
panic("tls: UpdateOnHRR is not implemented for the PreSharedKeyExtension")
|
||||
}
|
||||
|
||||
// UtlsPreSharedKeyExtension is an extension used to set the PSK extension in the
|
||||
// ClientHello.
|
||||
type UtlsPreSharedKeyExtension struct {
|
||||
|
@ -136,6 +165,10 @@ type UtlsPreSharedKeyExtension struct {
|
|||
cachedLength *int
|
||||
// Deprecated: Set OmitEmptyPsk in Config instead.
|
||||
OmitEmptyPsk bool
|
||||
|
||||
// used only for HRR-based recalculation of binders purpose
|
||||
prevClientHelloHash []byte // used for HRR-based recalculation of binders
|
||||
serverHello *serverHelloMsg
|
||||
}
|
||||
|
||||
func (e *UtlsPreSharedKeyExtension) IsInitialized() bool {
|
||||
|
@ -272,8 +305,17 @@ func (e *UtlsPreSharedKeyExtension) PatchBuiltHello(hello *PubClientHelloMsg) er
|
|||
private.raw = hello.Raw
|
||||
private.pskBinders = e.Binders // set the placeholder to the private Hello
|
||||
|
||||
//--- mirror loadSession() begin ---//
|
||||
// derived from loadSession() and processHelloRetryRequest() begin //
|
||||
transcript := e.cipherSuite.hash.New()
|
||||
|
||||
if len(e.prevClientHelloHash) > 0 { // HRR will set this field
|
||||
transcript.Write([]byte{typeMessageHash, 0, 0, uint8(len(e.prevClientHelloHash))})
|
||||
transcript.Write(e.prevClientHelloHash)
|
||||
if err := transcriptMsg(e.serverHello, transcript); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
helloBytes, err := private.marshalWithoutBinders() // no marshal() will be actually called, as we have set the field `raw`
|
||||
if err != nil {
|
||||
return err
|
||||
|
@ -284,7 +326,7 @@ func (e *UtlsPreSharedKeyExtension) PatchBuiltHello(hello *PubClientHelloMsg) er
|
|||
if err := private.updateBinders(pskBinders); err != nil {
|
||||
return err
|
||||
}
|
||||
//--- mirror loadSession() end ---//
|
||||
// derived end //
|
||||
e.Binders = pskBinders
|
||||
|
||||
// no need to care about other PSK related fields, they will be handled separately
|
||||
|
@ -292,11 +334,35 @@ func (e *UtlsPreSharedKeyExtension) PatchBuiltHello(hello *PubClientHelloMsg) er
|
|||
return io.EOF
|
||||
}
|
||||
|
||||
func (e *UtlsPreSharedKeyExtension) UpdateOnHRR(prevClientHelloHash []byte, hs *clientHandshakeStateTLS13, timeNow time.Time) error {
|
||||
if len(e.Identities) > 0 {
|
||||
e.Session = hs.session
|
||||
e.cipherSuite = cipherSuiteTLS13ByID(e.Session.cipherSuite)
|
||||
if e.cipherSuite.hash != hs.suite.hash {
|
||||
// disable PatchBuiltHello
|
||||
e.Session = nil
|
||||
e.cachedLength = new(int)
|
||||
return errors.New("tls: cipher suite hash mismatch, PSK will not be used")
|
||||
}
|
||||
|
||||
// update the obfuscated ticket age
|
||||
ticketAge := timeNow.Sub(time.Unix(int64(hs.session.createdAt), 0))
|
||||
e.Identities[0].ObfuscatedTicketAge = uint32(ticketAge/time.Millisecond) + hs.session.ageAdd
|
||||
|
||||
// e.Binders = nil
|
||||
e.cachedLength = nil // clear the cached length
|
||||
|
||||
e.prevClientHelloHash = prevClientHelloHash
|
||||
e.serverHello = hs.serverHello
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (e *UtlsPreSharedKeyExtension) Write(b []byte) (int, error) {
|
||||
return len(b), nil // ignore the data
|
||||
}
|
||||
|
||||
func (e *UtlsPreSharedKeyExtension) UnmarshalJSON(_ []byte) error {
|
||||
func (e *UtlsPreSharedKeyExtension) UnmarshalJSON([]byte) error {
|
||||
return nil // ignore the data
|
||||
}
|
||||
|
||||
|
@ -319,7 +385,7 @@ func (e *FakePreSharedKeyExtension) IsInitialized() bool {
|
|||
return e.Identities != nil && e.Binders != nil
|
||||
}
|
||||
|
||||
func (e *FakePreSharedKeyExtension) InitializeByUtls(session *SessionState, earlySecret []byte, binderKey []byte, identities []PskIdentity) {
|
||||
func (e *FakePreSharedKeyExtension) InitializeByUtls(*SessionState, []byte, []byte, []PskIdentity) {
|
||||
panic("InitializeByUtls failed: don't let utls initialize FakePreSharedKeyExtension; provide your own identities and binders or use UtlsPreSharedKeyExtension")
|
||||
}
|
||||
|
||||
|
@ -459,13 +525,19 @@ func (e *FakePreSharedKeyExtension) UnmarshalJSON(data []byte) error {
|
|||
return nil
|
||||
}
|
||||
|
||||
func (e *FakePreSharedKeyExtension) UpdateOnHRR([]byte, *clientHandshakeStateTLS13, time.Time) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// type guard
|
||||
var (
|
||||
_ PreSharedKeyExtension = (*UtlsPreSharedKeyExtension)(nil)
|
||||
_ TLSExtensionJSON = (*UtlsPreSharedKeyExtension)(nil)
|
||||
_ TLSExtensionWriter = (*UtlsPreSharedKeyExtension)(nil)
|
||||
_ PreSharedKeyExtension = (*FakePreSharedKeyExtension)(nil)
|
||||
_ TLSExtensionJSON = (*FakePreSharedKeyExtension)(nil)
|
||||
_ TLSExtensionWriter = (*FakePreSharedKeyExtension)(nil)
|
||||
_ PreSharedKeyExtension = (*UnimplementedPreSharedKeyExtension)(nil)
|
||||
)
|
||||
|
||||
// type ExternalPreSharedKeyExtension struct{} // TODO: wait for whoever cares about external PSK to implement it
|
||||
|
|
|
@ -223,7 +223,7 @@ func (s *sessionController) shouldUpdateBinders() bool {
|
|||
|
||||
func (s *sessionController) updateBinders() {
|
||||
uAssert(s.shouldUpdateBinders(), "tls: updateBinders failed: shouldn't update binders")
|
||||
s.pskExtension.PatchBuiltHello(s.uconnRef.HandshakeState.Hello)
|
||||
s.pskExtension.PatchBuiltHello(s.uconnRef.HandshakeState.Hello) // bugrisk: retured error is ignored
|
||||
}
|
||||
|
||||
func (s *sessionController) overrideExtension(extension Initializable, override func(), initializedState sessionControllerState) error {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue