Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions common.go
Original file line number Diff line number Diff line change
Expand Up @@ -130,6 +130,7 @@ const (
extensionRenegotiationInfo uint16 = 0xff01
extensionECHOuterExtensions uint16 = 0xfd00
extensionEncryptedClientHello uint16 = 0xfe0d
extensionTrustAnchors uint16 = 0xca34
)

// TLS signaling cipher suite values
Expand All @@ -152,6 +153,8 @@ const (
CurveP521 CurveID = 25
X25519 CurveID = 29
X25519MLKEM768 CurveID = 4588
FFDHE2048 CurveID = 0x0100
FFDHE3072 CurveID = 0x0101
)

func isTLS13OnlyKeyExchange(curve CurveID) bool {
Expand Down Expand Up @@ -393,6 +396,7 @@ type ClientSessionCache interface {

// SignatureScheme identifies a signature algorithm supported by TLS. See
// RFC 8446, Section 4.2.3.
// RFC 9881 for PQ
type SignatureScheme uint16

const (
Expand All @@ -417,6 +421,11 @@ const (
// Legacy signature and hash algorithms for TLS 1.2.
PKCS1WithSHA1 SignatureScheme = 0x0201
ECDSAWithSHA1 SignatureScheme = 0x0203

// MLDSA algorithms for PQ cryptography
MLDSA44 SignatureScheme = 0x0904
MLDSA65 SignatureScheme = 0x0905
MLDSA87 SignatureScheme = 0x0906
)

// ClientHelloInfo contains information from a ClientHello message in order to
Expand Down
18 changes: 18 additions & 0 deletions handshake_messages.go
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,7 @@ type clientHelloMsg struct {
pskBinders [][]byte
quicTransportParameters []byte
encryptedClientHello []byte
trustAnchors bool
// extensions are only populated on the server-side of a handshake
extensions []uint16

Expand Down Expand Up @@ -318,6 +319,17 @@ func (m *clientHelloMsg) marshalMsgReorderOuterExts(echInner bool, outerExts []u
})
}
}
if m.trustAnchors {
// RFC 9881
if echInner {
echOuterExts = append(echOuterExts, extensionTrustAnchors)
} else {
exts.AddUint16(extensionTrustAnchors)
exts.AddUint16LengthPrefixed(func(exts *cryptobyte.Builder) {
exts.AddUint16(0) // 00 00
})
}
}
// [uTLS SECTION BEGIN]
// reorder OuterExtensions according to their order in the spec
if echInner && outerExts != nil {
Expand Down Expand Up @@ -694,6 +706,12 @@ func (m *clientHelloMsg) unmarshal(data []byte) bool {
}
m.pskBinders = append(m.pskBinders, binder)
}
case extensionTrustAnchors:
var data uint16
if !extData.ReadUint16(&data) {
return false
}
m.trustAnchors = data == 0
case extensionEncryptedClientHello:
if !extData.ReadBytes(&m.encryptedClientHello, len(extData)) {
return false
Expand Down
3 changes: 3 additions & 0 deletions handshake_messages_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -234,6 +234,9 @@ func (*clientHelloMsg) Generate(rand *rand.Rand, size int) reflect.Value {
if rand.Intn(10) > 5 {
m.earlyData = true
}
if rand.Intn(10) > 5 {
m.trustAnchors = true
}
if rand.Intn(10) > 5 {
m.encryptedClientHello = randomBytes(rand.Intn(50)+1, rand)
}
Expand Down
12 changes: 10 additions & 2 deletions u_common.go
Original file line number Diff line number Diff line change
Expand Up @@ -645,18 +645,26 @@ var (
HelloChrome_131 = ClientHelloID{helloChrome, "131", nil, nil}
// Chrome w/ New ALPS codepoint
HelloChrome_133 = ClientHelloID{helloChrome, "133", nil, nil}
// Chrome w/ Trust anchors (Draft)
HelloChrome_141_TA = ClientHelloID{helloChrome, "141", nil, nil}
// Chrome w/ TA and PQ MLDSA Signatures (Experimental feature)
HelloChrome_144_TA_PQS = ClientHelloID{helloChrome, "144", nil, nil}

HelloIOS_Auto = HelloIOS_14
HelloIOS_11_1 = ClientHelloID{helloIOS, "111", nil, nil} // legacy "111" means 11.1
HelloIOS_12_1 = ClientHelloID{helloIOS, "12.1", nil, nil}
HelloIOS_13 = ClientHelloID{helloIOS, "13", nil, nil}
HelloIOS_14 = ClientHelloID{helloIOS, "14", nil, nil}

HelloAndroid_11_OkHttp = ClientHelloID{helloAndroid, "11", nil, nil}
HelloAndroid_OkHttp_Auto = HelloAndroid_16_OkHttp
HelloAndroid_11_OkHttp = ClientHelloID{helloAndroid, "11", nil, nil}
HelloAndroid_16_OkHttp = ClientHelloID{helloAndroid, "16", nil, nil}

HelloEdge_Auto = HelloEdge_85 // HelloEdge_106 seems to be incompatible with this library
// Probably should be deleted completely
HelloEdge_Auto = HelloEdge_133 // HelloEdge_106 seems to be incompatible with this library
HelloEdge_85 = ClientHelloID{helloEdge, "85", nil, nil}
HelloEdge_106 = ClientHelloID{helloEdge, "106", nil, nil}
HelloEdge_133 = HelloChrome_133 // It's basically Chrome 1:1

HelloSafari_Auto = HelloSafari_26_3
HelloSafari_16_0 = ClientHelloID{helloSafari, "16.0", nil, nil}
Expand Down
225 changes: 220 additions & 5 deletions u_parrots.go
Original file line number Diff line number Diff line change
Expand Up @@ -964,6 +964,157 @@ func utlsIdToSpec(id ClientHelloID) (ClientHelloSpec, error) {
&UtlsGREASEExtension{},
}),
}, nil
case HelloChrome_141_TA:
return ClientHelloSpec{
CipherSuites: []uint16{
GREASE_PLACEHOLDER,
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,
TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305,
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{},
&SNIExtension{},
&ExtendedMasterSecretExtension{},
&RenegotiationInfoExtension{Renegotiation: RenegotiateOnceAsClient},
&SupportedCurvesExtension{[]CurveID{
GREASE_PLACEHOLDER,
X25519MLKEM768,
X25519,
CurveP256,
CurveP384,
}},
&SupportedPointsExtension{SupportedPoints: []byte{
0x00, // pointFormatUncompressed
}},
&SessionTicketExtension{},
&ALPNExtension{AlpnProtocols: []string{"h2", "http/1.1"}},
&StatusRequestExtension{},
&SignatureAlgorithmsExtension{SupportedSignatureAlgorithms: []SignatureScheme{
ECDSAWithP256AndSHA256,
PSSWithSHA256,
PKCS1WithSHA256,
ECDSAWithP384AndSHA384,
PSSWithSHA384,
PKCS1WithSHA384,
PSSWithSHA512,
PKCS1WithSHA512,
}},
&SCTExtension{},
&KeyShareExtension{[]KeyShare{
{Group: CurveID(GREASE_PLACEHOLDER), Data: []byte{0}},
{Group: X25519MLKEM768},
{Group: X25519},
}},
&PSKKeyExchangeModesExtension{[]uint8{
PskModeDHE,
}},
&SupportedVersionsExtension{[]uint16{
GREASE_PLACEHOLDER,
VersionTLS13,
VersionTLS12,
}},
&UtlsCompressCertExtension{[]CertCompressionAlgo{
CertCompressionBrotli,
}},
&ApplicationSettingsExtensionNew{SupportedProtocols: []string{"h2"}},
&TrustAnchorsExtension{},
BoringGREASEECH(),
&UtlsGREASEExtension{},
}),
}, nil
case HelloChrome_144_TA_PQS:
return ClientHelloSpec{
CipherSuites: []uint16{
GREASE_PLACEHOLDER,
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,
TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305,
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{},
&SNIExtension{},
&ExtendedMasterSecretExtension{},
&RenegotiationInfoExtension{Renegotiation: RenegotiateOnceAsClient},
&SupportedCurvesExtension{[]CurveID{
GREASE_PLACEHOLDER,
X25519MLKEM768,
X25519,
CurveP256,
CurveP384,
}},
&SupportedPointsExtension{SupportedPoints: []byte{
0x00, // pointFormatUncompressed
}},
&SessionTicketExtension{},
&ALPNExtension{AlpnProtocols: []string{"h2", "http/1.1"}},
&StatusRequestExtension{},
&SignatureAlgorithmsExtension{SupportedSignatureAlgorithms: []SignatureScheme{
MLDSA44,
MLDSA65,
MLDSA87,
ECDSAWithP256AndSHA256,
PSSWithSHA256,
PKCS1WithSHA256,
ECDSAWithP384AndSHA384,
PSSWithSHA384,
PKCS1WithSHA384,
PSSWithSHA512,
PKCS1WithSHA512,
}},
&SCTExtension{},
&KeyShareExtension{[]KeyShare{
{Group: CurveID(GREASE_PLACEHOLDER), Data: []byte{0}},
{Group: X25519MLKEM768},
{Group: X25519},
}},
&PSKKeyExchangeModesExtension{[]uint8{
PskModeDHE,
}},
&SupportedVersionsExtension{[]uint16{
GREASE_PLACEHOLDER,
VersionTLS13,
VersionTLS12,
}},
&UtlsCompressCertExtension{[]CertCompressionAlgo{
CertCompressionBrotli,
}},
&ApplicationSettingsExtensionNew{SupportedProtocols: []string{"h2"}},
&TrustAnchorsExtension{},
BoringGREASEECH(),
&UtlsGREASEExtension{},
}),
}, nil
case HelloFirefox_55, HelloFirefox_56:
return ClientHelloSpec{
TLSVersMax: VersionTLS12,
Expand Down Expand Up @@ -1481,7 +1632,6 @@ func utlsIdToSpec(id ClientHelloID) (ClientHelloSpec, error) {
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,
Expand All @@ -1505,15 +1655,16 @@ func utlsIdToSpec(id ClientHelloID) (ClientHelloSpec, error) {
CurveP256,
CurveP384,
CurveP521,
0x0100,
0x0101,
FFDHE2048,
FFDHE3072,
},
},
&SupportedPointsExtension{
SupportedPoints: []uint8{
0x0, // uncompressed
},
},
&SessionTicketExtension{}, // Actually it's supported from Firefox 3.0
&ALPNExtension{
AlpnProtocols: []string{
"h2",
Expand Down Expand Up @@ -1566,6 +1717,9 @@ func utlsIdToSpec(id ClientHelloID) (ClientHelloSpec, error) {
PKCS1WithSHA1,
},
},
&PSKKeyExchangeModesExtension{[]uint8{
PskModeDHE,
}}, // This is default since Firefox 60
&FakeRecordSizeLimitExtension{
Limit: 0x4001,
},
Expand Down Expand Up @@ -1877,10 +2031,10 @@ func utlsIdToSpec(id ClientHelloID) (ClientHelloSpec, error) {
CipherSuites: []uint16{
TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,
TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,
0xcca9, // Cipher Suite: TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256 (0xcca9)
TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256,
TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,
TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384,
0xcca8, // Cipher Suite: TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256 (0xcca8)
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,
Expand Down Expand Up @@ -1918,6 +2072,67 @@ func utlsIdToSpec(id ClientHelloID) (ClientHelloSpec, error) {
}},
},
}, nil
case HelloAndroid_16_OkHttp:
return ClientHelloSpec{
CipherSuites: []uint16{
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,
},
Extensions: []TLSExtension{
&SNIExtension{},
&ExtendedMasterSecretExtension{},
&RenegotiationInfoExtension{Renegotiation: RenegotiateOnceAsClient},
&SupportedCurvesExtension{Curves: []CurveID{
X25519,
CurveP256,
CurveP384,
}},
&SupportedPointsExtension{SupportedPoints: []byte{
0x00,
}},
&SessionTicketExtension{},
&ALPNExtension{AlpnProtocols: []string{"h2", "http/1.1"}},
&StatusRequestExtension{},
&SignatureAlgorithmsExtension{SupportedSignatureAlgorithms: []SignatureScheme{
ECDSAWithP256AndSHA256,
PSSWithSHA256,
PKCS1WithSHA256,
ECDSAWithP384AndSHA384,
PSSWithSHA384,
PKCS1WithSHA384,
PSSWithSHA512,
PKCS1WithSHA512,
PKCS1WithSHA1,
}},
&KeyShareExtension{KeyShares: []KeyShare{
{Group: X25519},
}},
&PSKKeyExchangeModesExtension{Modes: []uint8{
PskModeDHE,
}},
&SupportedVersionsExtension{Versions: []uint16{
VersionTLS13,
VersionTLS12,
}},
&UtlsPaddingExtension{GetPaddingLen: BoringPaddingStyle},
},
}, nil
case HelloEdge_85:
return ClientHelloSpec{
CipherSuites: []uint16{
Expand Down
Loading