mirror of
https://github.com/refraction-networking/uquic.git
synced 2025-03-31 10:47:35 +03:00
686 lines
19 KiB
Go
686 lines
19 KiB
Go
package quic
|
|
|
|
import (
|
|
"crypto/rand"
|
|
"fmt"
|
|
"math/big"
|
|
mrand "math/rand"
|
|
|
|
tls "github.com/refraction-networking/utls"
|
|
)
|
|
|
|
type QUICID struct {
|
|
Client string
|
|
|
|
// Version specifies version of a mimicked clients (e.g. browsers).
|
|
Version string
|
|
|
|
// Fingerprint is a unique identifier for each different QUIC client/spec.
|
|
Fingerprint string
|
|
}
|
|
|
|
const (
|
|
// clients
|
|
quicFirefox = "Firefox"
|
|
quicChrome = "Chrome"
|
|
quicIOS = "iOS"
|
|
quicAndroid = "Android"
|
|
quicEdge = "Edge"
|
|
quicSafari = "Safari"
|
|
)
|
|
|
|
var (
|
|
QUICFirefox_116 = QUICFirefox_116A // point to most-popular 8-byte DCID
|
|
QUICFirefox_116A = QUICID{quicFirefox, "116", "31ea0e4ffd75b477"} // DCID.len = 8
|
|
QUICFirefox_116B = QUICID{quicFirefox, "116", "d07d3c9152fbc5e0"} // DCID.len = 9
|
|
QUICFirefox_116C = QUICID{quicFirefox, "116", "c74f87b2a9ccc006"} // DCID.len = 15
|
|
// TODO: add Firefox fingerprints with Token and PSK extension
|
|
|
|
QUICChrome_115 = QUICChrome_115_IPv4 // IPv4 is still more popular
|
|
QUICChrome_115_IPv4 = QUICID{quicChrome, "115", "beeb454235791d5c"} // IPv4: UDP payload 20-byte longer than IPv6 due to padding
|
|
QUICChrome_115_IPv6 = QUICID{quicChrome, "115_ip6", "beeb454235791d5c"} // IPv6
|
|
// TODO: add Chrome fingerprints with Token and PSK extension
|
|
|
|
// TODO: add more QUIC clients and versions
|
|
)
|
|
|
|
func QUICID2Spec(id QUICID) (QUICSpec, error) {
|
|
switch id {
|
|
case QUICChrome_115_IPv4:
|
|
return QUICSpec{
|
|
InitialPacketSpec: InitialPacketSpec{
|
|
SrcConnIDLength: 0,
|
|
DestConnIDLength: 8,
|
|
InitPacketNumberLength: 1,
|
|
InitPacketNumber: 1, // Chrome is special that it starts with 1 not 0
|
|
ClientTokenLength: 0,
|
|
FrameBuilder: &QUICRandomFrames{ // Chrome randomly inserts padding frames
|
|
MinPING: 0,
|
|
MaxPING: 10,
|
|
MinCRYPTO: 1,
|
|
MaxCRYPTO: 10,
|
|
MinPADDING: 3,
|
|
MaxPADDING: 6,
|
|
Length: 1231 - 16, // 16-byte for Auth Tag
|
|
},
|
|
},
|
|
ClientHelloSpec: &tls.ClientHelloSpec{
|
|
TLSVersMin: tls.VersionTLS13,
|
|
TLSVersMax: tls.VersionTLS13,
|
|
CipherSuites: []uint16{
|
|
tls.TLS_AES_128_GCM_SHA256,
|
|
tls.TLS_AES_256_GCM_SHA384,
|
|
tls.TLS_CHACHA20_POLY1305_SHA256,
|
|
},
|
|
CompressionMethods: []uint8{
|
|
0x0, // no compression
|
|
},
|
|
Extensions: tls.ShuffleChromeTLSExtensions([]tls.TLSExtension{
|
|
ShuffleQUICTransportParameters(&tls.QUICTransportParametersExtension{ // Order of QTPs are always shuffled
|
|
TransportParameters: tls.TransportParameters{
|
|
tls.InitialMaxStreamsUni(103),
|
|
tls.MaxIdleTimeout(30000),
|
|
tls.InitialMaxData(15728640),
|
|
tls.InitialMaxStreamDataUni(6291456),
|
|
&tls.VersionInformation{
|
|
ChoosenVersion: tls.VERSION_1,
|
|
AvailableVersions: []uint32{
|
|
tls.VERSION_GREASE,
|
|
tls.VERSION_1,
|
|
},
|
|
LegacyID: true,
|
|
},
|
|
&tls.FakeQUICTransportParameter{ // google_quic_version
|
|
Id: 0x4752,
|
|
Val: []byte{00, 00, 00, 01}, // Google QUIC version 1
|
|
},
|
|
&tls.FakeQUICTransportParameter{ // google_connection_options
|
|
Id: 0x3128,
|
|
Val: []byte{0x52, 0x56, 0x43, 0x4d},
|
|
},
|
|
tls.MaxDatagramFrameSize(65536),
|
|
tls.InitialMaxStreamsBidi(100),
|
|
tls.InitialMaxStreamDataBidiLocal(6291456),
|
|
VariableLengthGREASEQTP(0x10), // Random length for GREASE QTP
|
|
tls.InitialSourceConnectionID([]byte{}),
|
|
tls.MaxUDPPayloadSize(1472),
|
|
tls.InitialMaxStreamDataBidiRemote(6291456),
|
|
},
|
|
}),
|
|
&tls.ApplicationSettingsExtension{
|
|
SupportedProtocols: []string{
|
|
"h3",
|
|
},
|
|
},
|
|
&tls.UtlsCompressCertExtension{
|
|
Algorithms: []tls.CertCompressionAlgo{
|
|
tls.CertCompressionBrotli,
|
|
},
|
|
},
|
|
&tls.KeyShareExtension{
|
|
KeyShares: []tls.KeyShare{
|
|
{
|
|
Group: tls.X25519,
|
|
},
|
|
},
|
|
},
|
|
&tls.SignatureAlgorithmsExtension{
|
|
SupportedSignatureAlgorithms: []tls.SignatureScheme{
|
|
tls.ECDSAWithP256AndSHA256,
|
|
tls.PSSWithSHA256,
|
|
tls.PKCS1WithSHA256,
|
|
tls.ECDSAWithP384AndSHA384,
|
|
tls.PSSWithSHA384,
|
|
tls.PKCS1WithSHA384,
|
|
tls.PSSWithSHA512,
|
|
tls.PKCS1WithSHA512,
|
|
tls.PKCS1WithSHA1,
|
|
},
|
|
},
|
|
&tls.SNIExtension{},
|
|
&tls.SupportedCurvesExtension{
|
|
Curves: []tls.CurveID{
|
|
tls.CurveX25519,
|
|
tls.CurveSECP256R1,
|
|
tls.CurveSECP384R1,
|
|
},
|
|
},
|
|
&tls.PSKKeyExchangeModesExtension{
|
|
Modes: []uint8{
|
|
tls.PskModeDHE,
|
|
},
|
|
},
|
|
&tls.ALPNExtension{
|
|
AlpnProtocols: []string{
|
|
"h3",
|
|
},
|
|
},
|
|
&tls.SupportedVersionsExtension{
|
|
Versions: []uint16{
|
|
tls.VersionTLS13,
|
|
},
|
|
},
|
|
}),
|
|
},
|
|
}, nil
|
|
case QUICChrome_115_IPv6:
|
|
return QUICSpec{
|
|
InitialPacketSpec: InitialPacketSpec{
|
|
SrcConnIDLength: 0,
|
|
DestConnIDLength: 8,
|
|
InitPacketNumberLength: 1,
|
|
InitPacketNumber: 1, // Chrome is special that it starts with 1 not 0
|
|
ClientTokenLength: 0,
|
|
FrameBuilder: &QUICRandomFrames{ // Chrome randomly inserts padding frames
|
|
MinPING: 0,
|
|
MaxPING: 10,
|
|
MinCRYPTO: 1,
|
|
MaxCRYPTO: 10,
|
|
MinPADDING: 3,
|
|
MaxPADDING: 6,
|
|
Length: 1211 - 16, // IPv6 pads to a length that is 20-byte shorter than IPv4's version
|
|
},
|
|
},
|
|
ClientHelloSpec: &tls.ClientHelloSpec{
|
|
TLSVersMin: tls.VersionTLS13,
|
|
TLSVersMax: tls.VersionTLS13,
|
|
CipherSuites: []uint16{
|
|
tls.TLS_AES_128_GCM_SHA256,
|
|
tls.TLS_AES_256_GCM_SHA384,
|
|
tls.TLS_CHACHA20_POLY1305_SHA256,
|
|
},
|
|
CompressionMethods: []uint8{
|
|
0x0,
|
|
},
|
|
Extensions: tls.ShuffleChromeTLSExtensions([]tls.TLSExtension{
|
|
ShuffleQUICTransportParameters(&tls.QUICTransportParametersExtension{ // Order of QTPs are always shuffled
|
|
TransportParameters: tls.TransportParameters{
|
|
tls.InitialMaxStreamsUni(103),
|
|
tls.MaxIdleTimeout(30000),
|
|
tls.InitialMaxData(15728640),
|
|
tls.InitialMaxStreamDataUni(6291456),
|
|
&tls.VersionInformation{
|
|
ChoosenVersion: tls.VERSION_1,
|
|
AvailableVersions: []uint32{
|
|
tls.VERSION_GREASE,
|
|
tls.VERSION_1,
|
|
},
|
|
LegacyID: true,
|
|
},
|
|
&tls.FakeQUICTransportParameter{ // google_quic_version
|
|
Id: 0x4752,
|
|
Val: []byte{00, 00, 00, 01}, // Google QUIC version 1
|
|
},
|
|
&tls.FakeQUICTransportParameter{ // google_connection_options
|
|
Id: 0x3128,
|
|
Val: []byte{0x52, 0x56, 0x43, 0x4d},
|
|
},
|
|
tls.MaxDatagramFrameSize(65536),
|
|
tls.InitialMaxStreamsBidi(100),
|
|
tls.InitialMaxStreamDataBidiLocal(6291456),
|
|
VariableLengthGREASEQTP(0x10), // Random length for GREASE QTP
|
|
tls.InitialSourceConnectionID([]byte{}),
|
|
tls.MaxUDPPayloadSize(1472),
|
|
tls.InitialMaxStreamDataBidiRemote(6291456),
|
|
},
|
|
}),
|
|
&tls.ApplicationSettingsExtension{
|
|
SupportedProtocols: []string{
|
|
"h3",
|
|
},
|
|
},
|
|
&tls.UtlsCompressCertExtension{
|
|
Algorithms: []tls.CertCompressionAlgo{
|
|
tls.CertCompressionBrotli,
|
|
},
|
|
},
|
|
&tls.KeyShareExtension{
|
|
KeyShares: []tls.KeyShare{
|
|
{
|
|
Group: tls.X25519,
|
|
},
|
|
},
|
|
},
|
|
&tls.SignatureAlgorithmsExtension{
|
|
SupportedSignatureAlgorithms: []tls.SignatureScheme{
|
|
tls.ECDSAWithP256AndSHA256,
|
|
tls.PSSWithSHA256,
|
|
tls.PKCS1WithSHA256,
|
|
tls.ECDSAWithP384AndSHA384,
|
|
tls.PSSWithSHA384,
|
|
tls.PKCS1WithSHA384,
|
|
tls.PSSWithSHA512,
|
|
tls.PKCS1WithSHA512,
|
|
tls.PKCS1WithSHA1,
|
|
},
|
|
},
|
|
&tls.SNIExtension{},
|
|
&tls.SupportedCurvesExtension{
|
|
Curves: []tls.CurveID{
|
|
tls.CurveX25519,
|
|
tls.CurveSECP256R1,
|
|
tls.CurveSECP384R1,
|
|
},
|
|
},
|
|
&tls.PSKKeyExchangeModesExtension{
|
|
Modes: []uint8{
|
|
tls.PskModeDHE,
|
|
},
|
|
},
|
|
&tls.ALPNExtension{
|
|
AlpnProtocols: []string{
|
|
"h3",
|
|
},
|
|
},
|
|
&tls.SupportedVersionsExtension{
|
|
Versions: []uint16{
|
|
tls.VersionTLS13,
|
|
},
|
|
},
|
|
}),
|
|
},
|
|
}, nil
|
|
case QUICFirefox_116A:
|
|
return QUICSpec{
|
|
InitialPacketSpec: InitialPacketSpec{
|
|
SrcConnIDLength: 3,
|
|
DestConnIDLength: 8,
|
|
InitPacketNumberLength: 1,
|
|
InitPacketNumber: 0,
|
|
ClientTokenLength: 0,
|
|
FrameBuilder: QUICFrames{}, // empty = single crypto
|
|
},
|
|
ClientHelloSpec: &tls.ClientHelloSpec{
|
|
TLSVersMin: tls.VersionTLS13,
|
|
TLSVersMax: tls.VersionTLS13,
|
|
CipherSuites: []uint16{
|
|
tls.TLS_AES_128_GCM_SHA256,
|
|
tls.TLS_CHACHA20_POLY1305_SHA256,
|
|
tls.TLS_AES_256_GCM_SHA384,
|
|
},
|
|
CompressionMethods: []uint8{
|
|
0x0,
|
|
},
|
|
Extensions: []tls.TLSExtension{
|
|
&tls.SNIExtension{},
|
|
&tls.ExtendedMasterSecretExtension{},
|
|
&tls.RenegotiationInfoExtension{
|
|
Renegotiation: tls.RenegotiateOnceAsClient,
|
|
},
|
|
&tls.SupportedCurvesExtension{
|
|
Curves: []tls.CurveID{
|
|
tls.CurveX25519,
|
|
tls.CurveSECP256R1,
|
|
tls.CurveSECP384R1,
|
|
tls.CurveSECP521R1,
|
|
tls.FakeCurveFFDHE2048,
|
|
tls.FakeCurveFFDHE3072,
|
|
tls.FakeCurveFFDHE4096,
|
|
tls.FakeCurveFFDHE6144,
|
|
tls.FakeCurveFFDHE8192,
|
|
},
|
|
},
|
|
&tls.ALPNExtension{
|
|
AlpnProtocols: []string{
|
|
"h3",
|
|
},
|
|
},
|
|
&tls.StatusRequestExtension{},
|
|
&tls.FakeDelegatedCredentialsExtension{
|
|
SupportedSignatureAlgorithms: []tls.SignatureScheme{
|
|
tls.ECDSAWithP256AndSHA256,
|
|
tls.ECDSAWithP384AndSHA384,
|
|
tls.ECDSAWithP521AndSHA512,
|
|
tls.ECDSAWithSHA1,
|
|
},
|
|
},
|
|
&tls.KeyShareExtension{
|
|
KeyShares: []tls.KeyShare{
|
|
{
|
|
Group: tls.X25519,
|
|
},
|
|
},
|
|
},
|
|
&tls.SupportedVersionsExtension{
|
|
Versions: []uint16{
|
|
tls.VersionTLS13,
|
|
},
|
|
},
|
|
&tls.SignatureAlgorithmsExtension{
|
|
SupportedSignatureAlgorithms: []tls.SignatureScheme{
|
|
tls.ECDSAWithP256AndSHA256,
|
|
tls.ECDSAWithP384AndSHA384,
|
|
tls.ECDSAWithP521AndSHA512,
|
|
tls.ECDSAWithSHA1,
|
|
tls.PSSWithSHA256,
|
|
tls.PSSWithSHA384,
|
|
tls.PSSWithSHA512,
|
|
tls.PKCS1WithSHA256,
|
|
tls.PKCS1WithSHA384,
|
|
tls.PKCS1WithSHA512,
|
|
tls.PKCS1WithSHA1,
|
|
},
|
|
},
|
|
&tls.PSKKeyExchangeModesExtension{
|
|
Modes: []uint8{
|
|
tls.PskModeDHE,
|
|
},
|
|
},
|
|
&tls.FakeRecordSizeLimitExtension{
|
|
Limit: 0x4001,
|
|
},
|
|
ShuffleQUICTransportParameters(&tls.QUICTransportParametersExtension{
|
|
TransportParameters: tls.TransportParameters{
|
|
tls.InitialMaxStreamDataBidiRemote(0x100000),
|
|
tls.InitialMaxStreamsBidi(16),
|
|
tls.MaxDatagramFrameSize(1200),
|
|
tls.MaxIdleTimeout(30000),
|
|
tls.ActiveConnectionIDLimit(8),
|
|
&tls.GREASEQUICBit{},
|
|
&tls.VersionInformation{
|
|
ChoosenVersion: tls.VERSION_1,
|
|
AvailableVersions: []uint32{
|
|
tls.VERSION_GREASE,
|
|
tls.VERSION_1,
|
|
},
|
|
LegacyID: true,
|
|
},
|
|
tls.InitialMaxStreamsUni(16),
|
|
&tls.GREASETransportParameter{
|
|
Length: 2, // Firefox uses 2-byte GREASE values
|
|
},
|
|
tls.InitialMaxStreamDataBidiLocal(0xc00000),
|
|
tls.InitialMaxStreamDataUni(0x100000),
|
|
tls.InitialSourceConnectionID([]byte{}),
|
|
tls.MaxAckDelay(20),
|
|
tls.InitialMaxData(0x1800000),
|
|
&tls.DisableActiveMigration{},
|
|
},
|
|
}),
|
|
&tls.UtlsPaddingExtension{
|
|
GetPaddingLen: tls.BoringPaddingStyle,
|
|
},
|
|
},
|
|
},
|
|
UDPDatagramMinSize: 1357, // Firefox pads with zeroes at the end of UDP datagrams
|
|
}, nil
|
|
case QUICFirefox_116B:
|
|
return QUICSpec{
|
|
InitialPacketSpec: InitialPacketSpec{
|
|
SrcConnIDLength: 3,
|
|
DestConnIDLength: 9,
|
|
InitPacketNumberLength: 1,
|
|
InitPacketNumber: 0,
|
|
ClientTokenLength: 0,
|
|
FrameBuilder: QUICFrames{},
|
|
},
|
|
ClientHelloSpec: &tls.ClientHelloSpec{
|
|
TLSVersMin: tls.VersionTLS13,
|
|
TLSVersMax: tls.VersionTLS13,
|
|
CipherSuites: []uint16{
|
|
tls.TLS_AES_128_GCM_SHA256,
|
|
tls.TLS_CHACHA20_POLY1305_SHA256,
|
|
tls.TLS_AES_256_GCM_SHA384,
|
|
},
|
|
CompressionMethods: []uint8{
|
|
0x0,
|
|
},
|
|
Extensions: []tls.TLSExtension{
|
|
&tls.SNIExtension{},
|
|
&tls.ExtendedMasterSecretExtension{},
|
|
&tls.RenegotiationInfoExtension{
|
|
Renegotiation: tls.RenegotiateOnceAsClient,
|
|
},
|
|
&tls.SupportedCurvesExtension{
|
|
Curves: []tls.CurveID{
|
|
tls.CurveX25519,
|
|
tls.CurveSECP256R1,
|
|
tls.CurveSECP384R1,
|
|
tls.CurveSECP521R1,
|
|
tls.FakeCurveFFDHE2048,
|
|
tls.FakeCurveFFDHE3072,
|
|
tls.FakeCurveFFDHE4096,
|
|
tls.FakeCurveFFDHE6144,
|
|
tls.FakeCurveFFDHE8192,
|
|
},
|
|
},
|
|
&tls.ALPNExtension{
|
|
AlpnProtocols: []string{
|
|
"h3",
|
|
},
|
|
},
|
|
&tls.StatusRequestExtension{},
|
|
&tls.FakeDelegatedCredentialsExtension{
|
|
SupportedSignatureAlgorithms: []tls.SignatureScheme{
|
|
tls.ECDSAWithP256AndSHA256,
|
|
tls.ECDSAWithP384AndSHA384,
|
|
tls.ECDSAWithP521AndSHA512,
|
|
tls.ECDSAWithSHA1,
|
|
},
|
|
},
|
|
&tls.KeyShareExtension{
|
|
KeyShares: []tls.KeyShare{
|
|
{
|
|
Group: tls.X25519,
|
|
},
|
|
},
|
|
},
|
|
&tls.SupportedVersionsExtension{
|
|
Versions: []uint16{
|
|
tls.VersionTLS13,
|
|
},
|
|
},
|
|
&tls.SignatureAlgorithmsExtension{
|
|
SupportedSignatureAlgorithms: []tls.SignatureScheme{
|
|
tls.ECDSAWithP256AndSHA256,
|
|
tls.ECDSAWithP384AndSHA384,
|
|
tls.ECDSAWithP521AndSHA512,
|
|
tls.ECDSAWithSHA1,
|
|
tls.PSSWithSHA256,
|
|
tls.PSSWithSHA384,
|
|
tls.PSSWithSHA512,
|
|
tls.PKCS1WithSHA256,
|
|
tls.PKCS1WithSHA384,
|
|
tls.PKCS1WithSHA512,
|
|
tls.PKCS1WithSHA1,
|
|
},
|
|
},
|
|
&tls.PSKKeyExchangeModesExtension{
|
|
Modes: []uint8{
|
|
tls.PskModeDHE,
|
|
},
|
|
},
|
|
&tls.FakeRecordSizeLimitExtension{
|
|
Limit: 0x4001,
|
|
},
|
|
ShuffleQUICTransportParameters(&tls.QUICTransportParametersExtension{
|
|
TransportParameters: tls.TransportParameters{
|
|
tls.InitialMaxStreamDataBidiRemote(0x100000),
|
|
tls.InitialMaxStreamsBidi(16),
|
|
tls.MaxDatagramFrameSize(1200),
|
|
tls.MaxIdleTimeout(30000),
|
|
tls.ActiveConnectionIDLimit(8),
|
|
&tls.GREASEQUICBit{},
|
|
&tls.VersionInformation{
|
|
ChoosenVersion: tls.VERSION_1,
|
|
AvailableVersions: []uint32{
|
|
tls.VERSION_GREASE,
|
|
tls.VERSION_1,
|
|
},
|
|
LegacyID: true,
|
|
},
|
|
tls.InitialMaxStreamsUni(16),
|
|
&tls.GREASETransportParameter{
|
|
Length: 2, // Firefox uses 2-byte GREASE values
|
|
},
|
|
tls.InitialMaxStreamDataBidiLocal(0xc00000),
|
|
tls.InitialMaxStreamDataUni(0x100000),
|
|
tls.InitialSourceConnectionID([]byte{}),
|
|
tls.MaxAckDelay(20),
|
|
tls.InitialMaxData(0x1800000),
|
|
&tls.DisableActiveMigration{},
|
|
},
|
|
}),
|
|
&tls.UtlsPaddingExtension{
|
|
GetPaddingLen: tls.BoringPaddingStyle,
|
|
},
|
|
},
|
|
},
|
|
UDPDatagramMinSize: 1357,
|
|
}, nil
|
|
case QUICFirefox_116C:
|
|
return QUICSpec{
|
|
InitialPacketSpec: InitialPacketSpec{
|
|
SrcConnIDLength: 3,
|
|
DestConnIDLength: 15,
|
|
InitPacketNumberLength: 1,
|
|
InitPacketNumber: 0,
|
|
ClientTokenLength: 0,
|
|
FrameBuilder: QUICFrames{},
|
|
},
|
|
ClientHelloSpec: &tls.ClientHelloSpec{
|
|
TLSVersMin: tls.VersionTLS13,
|
|
TLSVersMax: tls.VersionTLS13,
|
|
CipherSuites: []uint16{
|
|
tls.TLS_AES_128_GCM_SHA256,
|
|
tls.TLS_CHACHA20_POLY1305_SHA256,
|
|
tls.TLS_AES_256_GCM_SHA384,
|
|
},
|
|
CompressionMethods: []uint8{
|
|
0x0,
|
|
},
|
|
Extensions: []tls.TLSExtension{
|
|
&tls.SNIExtension{},
|
|
&tls.ExtendedMasterSecretExtension{},
|
|
&tls.RenegotiationInfoExtension{
|
|
Renegotiation: tls.RenegotiateOnceAsClient,
|
|
},
|
|
&tls.SupportedCurvesExtension{
|
|
Curves: []tls.CurveID{
|
|
tls.CurveX25519,
|
|
tls.CurveSECP256R1,
|
|
tls.CurveSECP384R1,
|
|
tls.CurveSECP521R1,
|
|
tls.FakeCurveFFDHE2048,
|
|
tls.FakeCurveFFDHE3072,
|
|
tls.FakeCurveFFDHE4096,
|
|
tls.FakeCurveFFDHE6144,
|
|
tls.FakeCurveFFDHE8192,
|
|
},
|
|
},
|
|
&tls.ALPNExtension{
|
|
AlpnProtocols: []string{
|
|
"h3",
|
|
},
|
|
},
|
|
&tls.StatusRequestExtension{},
|
|
&tls.FakeDelegatedCredentialsExtension{
|
|
SupportedSignatureAlgorithms: []tls.SignatureScheme{
|
|
tls.ECDSAWithP256AndSHA256,
|
|
tls.ECDSAWithP384AndSHA384,
|
|
tls.ECDSAWithP521AndSHA512,
|
|
tls.ECDSAWithSHA1,
|
|
},
|
|
},
|
|
&tls.KeyShareExtension{
|
|
KeyShares: []tls.KeyShare{
|
|
{
|
|
Group: tls.X25519,
|
|
},
|
|
},
|
|
},
|
|
&tls.SupportedVersionsExtension{
|
|
Versions: []uint16{
|
|
tls.VersionTLS13,
|
|
},
|
|
},
|
|
&tls.SignatureAlgorithmsExtension{
|
|
SupportedSignatureAlgorithms: []tls.SignatureScheme{
|
|
tls.ECDSAWithP256AndSHA256,
|
|
tls.ECDSAWithP384AndSHA384,
|
|
tls.ECDSAWithP521AndSHA512,
|
|
tls.ECDSAWithSHA1,
|
|
tls.PSSWithSHA256,
|
|
tls.PSSWithSHA384,
|
|
tls.PSSWithSHA512,
|
|
tls.PKCS1WithSHA256,
|
|
tls.PKCS1WithSHA384,
|
|
tls.PKCS1WithSHA512,
|
|
tls.PKCS1WithSHA1,
|
|
},
|
|
},
|
|
&tls.PSKKeyExchangeModesExtension{
|
|
Modes: []uint8{
|
|
tls.PskModeDHE,
|
|
},
|
|
},
|
|
&tls.FakeRecordSizeLimitExtension{
|
|
Limit: 0x4001,
|
|
},
|
|
ShuffleQUICTransportParameters(&tls.QUICTransportParametersExtension{
|
|
TransportParameters: tls.TransportParameters{
|
|
tls.InitialMaxStreamDataBidiRemote(0x100000),
|
|
tls.InitialMaxStreamsBidi(16),
|
|
tls.MaxDatagramFrameSize(1200),
|
|
tls.MaxIdleTimeout(30000),
|
|
tls.ActiveConnectionIDLimit(8),
|
|
&tls.GREASEQUICBit{},
|
|
&tls.VersionInformation{
|
|
ChoosenVersion: tls.VERSION_1,
|
|
AvailableVersions: []uint32{
|
|
tls.VERSION_GREASE,
|
|
tls.VERSION_1,
|
|
},
|
|
LegacyID: true,
|
|
},
|
|
tls.InitialMaxStreamsUni(16),
|
|
&tls.GREASETransportParameter{
|
|
Length: 2,
|
|
},
|
|
tls.InitialMaxStreamDataBidiLocal(0xc00000),
|
|
tls.InitialMaxStreamDataUni(0x100000),
|
|
tls.InitialSourceConnectionID([]byte{}),
|
|
tls.MaxAckDelay(20),
|
|
tls.InitialMaxData(0x1800000),
|
|
&tls.DisableActiveMigration{},
|
|
},
|
|
}),
|
|
&tls.UtlsPaddingExtension{
|
|
GetPaddingLen: tls.BoringPaddingStyle,
|
|
},
|
|
},
|
|
},
|
|
UDPDatagramMinSize: 1357,
|
|
}, nil
|
|
default:
|
|
return QUICSpec{}, fmt.Errorf("unknown QUIC ID: %v", id)
|
|
}
|
|
}
|
|
|
|
func ShuffleTLSExtensions(exts []tls.TLSExtension) []tls.TLSExtension {
|
|
mrand.Shuffle(len(exts), func(i, j int) {
|
|
exts[i], exts[j] = exts[j], exts[i]
|
|
})
|
|
return exts
|
|
}
|
|
|
|
func ShuffleQUICTransportParameters(qtp *tls.QUICTransportParametersExtension) *tls.QUICTransportParametersExtension {
|
|
// shuffle the order of parameters
|
|
mrand.Shuffle(len(qtp.TransportParameters), func(i, j int) {
|
|
qtp.TransportParameters[i], qtp.TransportParameters[j] = qtp.TransportParameters[j], qtp.TransportParameters[i]
|
|
})
|
|
return qtp
|
|
}
|
|
|
|
func VariableLengthGREASEQTP(maxLen int) *tls.GREASETransportParameter {
|
|
// get random length for GREASE
|
|
greaseMaxLen := big.NewInt(0x10)
|
|
greaseLen, err := rand.Int(rand.Reader, greaseMaxLen)
|
|
if err != nil {
|
|
panic(err)
|
|
}
|
|
|
|
return &tls.GREASETransportParameter{
|
|
Length: uint16(greaseLen.Uint64()),
|
|
}
|
|
}
|