git.prognetwork.ru/x0r/utls@v1.3.3/u_common.go (about)

     1  // Copyright 2017 Google Inc. All rights reserved.
     2  // Use of this source code is governed by a BSD-style
     3  // license that can be found in the LICENSE file.
     4  
     5  package tls
     6  
     7  import (
     8  	"crypto/hmac"
     9  	"crypto/sha512"
    10  	"encoding/json"
    11  	"errors"
    12  	"fmt"
    13  	"hash"
    14  	"log"
    15  
    16  	"git.prognetwork.ru/x0r/utls/internal/helper"
    17  	"golang.org/x/crypto/cryptobyte"
    18  )
    19  
    20  // Naming convention:
    21  // Unsupported things are prefixed with "Fake"
    22  // Things, supported by utls, but not crypto/tls' are prefixed with "utls"
    23  // Supported things, that have changed their ID are prefixed with "Old"
    24  // Supported but disabled things are prefixed with "Disabled". We will _enable_ them.
    25  
    26  // TLS handshake message types.
    27  const (
    28  	utlsTypeEncryptedExtensions uint8 = 8 // implemention incomplete by crypto/tls
    29  	// https://datatracker.ietf.org/doc/html/rfc8879#section-7.2
    30  	utlsTypeCompressedCertificate uint8 = 25
    31  )
    32  
    33  // TLS
    34  const (
    35  	extensionNextProtoNeg uint16 = 13172 // not IANA assigned. Removed by crypto/tls since Nov 2019
    36  
    37  	utlsExtensionPadding              uint16 = 21
    38  	utlsExtensionExtendedMasterSecret uint16 = 23    // https://tools.ietf.org/html/rfc7627
    39  	utlsExtensionCompressCertificate  uint16 = 27    // https://datatracker.ietf.org/doc/html/rfc8879#section-7.1
    40  	utlsExtensionApplicationSettings  uint16 = 17513 // not IANA assigned
    41  	utlsFakeExtensionCustom           uint16 = 1234  // not IANA assigned, for ALPS
    42  
    43  	// extensions with 'fake' prefix break connection, if server echoes them back
    44  	fakeExtensionEncryptThenMAC       uint16 = 22
    45  	fakeExtensionTokenBinding         uint16 = 24
    46  	fakeExtensionDelegatedCredentials uint16 = 34
    47  	fakeExtensionPreSharedKey         uint16 = 41
    48  	fakeOldExtensionChannelID         uint16 = 30031 // not IANA assigned
    49  	fakeExtensionChannelID            uint16 = 30032 // not IANA assigned
    50  )
    51  
    52  const (
    53  	OLD_TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256   = uint16(0xcc13)
    54  	OLD_TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256 = uint16(0xcc14)
    55  
    56  	DISABLED_TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384 = uint16(0xc024)
    57  	DISABLED_TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384   = uint16(0xc028)
    58  	DISABLED_TLS_RSA_WITH_AES_256_CBC_SHA256         = uint16(0x003d)
    59  
    60  	FAKE_OLD_TLS_DHE_RSA_WITH_CHACHA20_POLY1305_SHA256 = uint16(0xcc15) // we can try to craft these ciphersuites
    61  	FAKE_TLS_DHE_RSA_WITH_AES_128_GCM_SHA256           = uint16(0x009e) // from existing pieces, if needed
    62  
    63  	FAKE_TLS_DHE_RSA_WITH_AES_128_CBC_SHA    = uint16(0x0033)
    64  	FAKE_TLS_DHE_RSA_WITH_AES_256_CBC_SHA    = uint16(0x0039)
    65  	FAKE_TLS_RSA_WITH_RC4_128_MD5            = uint16(0x0004)
    66  	FAKE_TLS_DHE_RSA_WITH_AES_256_GCM_SHA384 = uint16(0x009f)
    67  	FAKE_TLS_DHE_DSS_WITH_AES_128_CBC_SHA    = uint16(0x0032)
    68  	FAKE_TLS_DHE_RSA_WITH_AES_256_CBC_SHA256 = uint16(0x006b)
    69  	FAKE_TLS_DHE_RSA_WITH_AES_128_CBC_SHA256 = uint16(0x0067)
    70  	FAKE_TLS_EMPTY_RENEGOTIATION_INFO_SCSV   = uint16(0x00ff)
    71  
    72  	// https://docs.microsoft.com/en-us/dotnet/api/system.net.security.tlsciphersuite?view=netcore-3.1
    73  	FAKE_TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA = uint16(0xc008)
    74  )
    75  
    76  // Other things
    77  const (
    78  	fakeRecordSizeLimit uint16 = 0x001c
    79  )
    80  
    81  // newest signatures
    82  var (
    83  	FakePKCS1WithSHA224 SignatureScheme = 0x0301
    84  	FakeECDSAWithSHA224 SignatureScheme = 0x0303
    85  
    86  	FakeSHA1WithDSA   SignatureScheme = 0x0202
    87  	FakeSHA256WithDSA SignatureScheme = 0x0402
    88  
    89  	// fakeEd25519 = SignatureAndHash{0x08, 0x07}
    90  	// fakeEd448 = SignatureAndHash{0x08, 0x08}
    91  )
    92  
    93  // fake curves(groups)
    94  var (
    95  	FakeFFDHE2048 = uint16(0x0100)
    96  	FakeFFDHE3072 = uint16(0x0101)
    97  )
    98  
    99  // https://tools.ietf.org/html/draft-ietf-tls-certificate-compression-04
   100  type CertCompressionAlgo uint16
   101  
   102  const (
   103  	CertCompressionZlib   CertCompressionAlgo = 0x0001
   104  	CertCompressionBrotli CertCompressionAlgo = 0x0002
   105  	CertCompressionZstd   CertCompressionAlgo = 0x0003
   106  )
   107  
   108  const (
   109  	PskModePlain uint8 = pskModePlain
   110  	PskModeDHE   uint8 = pskModeDHE
   111  )
   112  
   113  type ClientHelloID struct {
   114  	Client string
   115  
   116  	// Version specifies version of a mimicked clients (e.g. browsers).
   117  	// Not used in randomized, custom handshake, and default Go.
   118  	Version string
   119  
   120  	// Seed is only used for randomized fingerprints to seed PRNG.
   121  	// Must not be modified once set.
   122  	Seed *PRNGSeed
   123  
   124  	// Weights are only used for randomized fingerprints in func
   125  	// generateRandomizedSpec(). Must not be modified once set.
   126  	Weights *Weights
   127  }
   128  
   129  func (p *ClientHelloID) Str() string {
   130  	return fmt.Sprintf("%s-%s", p.Client, p.Version)
   131  }
   132  
   133  func (p *ClientHelloID) IsSet() bool {
   134  	return (p.Client == "") && (p.Version == "")
   135  }
   136  
   137  const (
   138  	// clients
   139  	helloGolang           = "Golang"
   140  	helloRandomized       = "Randomized"
   141  	helloRandomizedALPN   = "Randomized-ALPN"
   142  	helloRandomizedNoALPN = "Randomized-NoALPN"
   143  	helloCustom           = "Custom"
   144  	helloFirefox          = "Firefox"
   145  	helloChrome           = "Chrome"
   146  	helloIOS              = "iOS"
   147  	helloAndroid          = "Android"
   148  	helloEdge             = "Edge"
   149  	helloSafari           = "Safari"
   150  	hello360              = "360Browser"
   151  	helloQQ               = "QQBrowser"
   152  
   153  	// versions
   154  	helloAutoVers = "0"
   155  )
   156  
   157  type ClientHelloSpec struct {
   158  	CipherSuites       []uint16       // nil => default
   159  	CompressionMethods []uint8        // nil => no compression
   160  	Extensions         []TLSExtension // nil => no extensions
   161  
   162  	TLSVersMin uint16 // [1.0-1.3] default: parse from .Extensions, if SupportedVersions ext is not present => 1.0
   163  	TLSVersMax uint16 // [1.2-1.3] default: parse from .Extensions, if SupportedVersions ext is not present => 1.2
   164  
   165  	// GreaseStyle: currently only random
   166  	// sessionID may or may not depend on ticket; nil => random
   167  	GetSessionID func(ticket []byte) [32]byte
   168  
   169  	// TLSFingerprintLink string // ?? link to tlsfingerprint.io for informational purposes
   170  }
   171  
   172  // ReadCipherSuites is a helper function to construct a list of cipher suites from
   173  // a []byte into []uint16.
   174  //
   175  // example: []byte{0x13, 0x01, 0x13, 0x02, 0x13, 0x03} => []uint16{0x1301, 0x1302, 0x1303}
   176  func (chs *ClientHelloSpec) ReadCipherSuites(b []byte) error {
   177  	cipherSuites := []uint16{}
   178  	s := cryptobyte.String(b)
   179  	for !s.Empty() {
   180  		var suite uint16
   181  		if !s.ReadUint16(&suite) {
   182  			return errors.New("unable to read ciphersuite")
   183  		}
   184  		cipherSuites = append(cipherSuites, unGREASEUint16(suite))
   185  	}
   186  	chs.CipherSuites = cipherSuites
   187  	return nil
   188  }
   189  
   190  // ReadCompressionMethods is a helper function to construct a list of compression
   191  // methods from a []byte into []uint8.
   192  func (chs *ClientHelloSpec) ReadCompressionMethods(compressionMethods []byte) error {
   193  	chs.CompressionMethods = compressionMethods
   194  	return nil
   195  }
   196  
   197  // ReadTLSExtensions is a helper function to construct a list of TLS extensions from
   198  // a byte slice into []TLSExtension.
   199  //
   200  // If keepPSK is not set, the PSK extension will cause an error.
   201  func (chs *ClientHelloSpec) ReadTLSExtensions(b []byte, allowBluntMimicry bool) error {
   202  	extensions := cryptobyte.String(b)
   203  	for !extensions.Empty() {
   204  		var extension uint16
   205  		var extData cryptobyte.String
   206  		if !extensions.ReadUint16(&extension) {
   207  			return fmt.Errorf("unable to read extension ID")
   208  		}
   209  		if !extensions.ReadUint16LengthPrefixed(&extData) {
   210  			return fmt.Errorf("unable to read data for extension %x", extension)
   211  		}
   212  
   213  		ext := ExtensionFromID(extension)
   214  		extWriter, ok := ext.(TLSExtensionWriter)
   215  		if ext != nil && ok { // known extension and implements TLSExtensionWriter properly
   216  			if extension == extensionSupportedVersions {
   217  				chs.TLSVersMin = 0
   218  				chs.TLSVersMax = 0
   219  			}
   220  			if _, err := extWriter.Write(extData); err != nil {
   221  				return err
   222  			}
   223  
   224  			chs.Extensions = append(chs.Extensions, extWriter)
   225  		} else {
   226  			if allowBluntMimicry {
   227  				chs.Extensions = append(chs.Extensions, &GenericExtension{extension, extData})
   228  			} else {
   229  				return fmt.Errorf("unsupported extension %d", extension)
   230  			}
   231  		}
   232  	}
   233  	return nil
   234  }
   235  
   236  func (chs *ClientHelloSpec) AlwaysAddPadding() {
   237  	alreadyHasPadding := false
   238  	for _, ext := range chs.Extensions {
   239  		if _, ok := ext.(*UtlsPaddingExtension); ok {
   240  			alreadyHasPadding = true
   241  			break
   242  		}
   243  		if _, ok := ext.(*FakePreSharedKeyExtension); ok {
   244  			alreadyHasPadding = true // PSK must be last, so we don't need to add padding
   245  			break
   246  		}
   247  	}
   248  	if !alreadyHasPadding {
   249  		chs.Extensions = append(chs.Extensions, &UtlsPaddingExtension{GetPaddingLen: BoringPaddingStyle})
   250  	}
   251  }
   252  
   253  // Import TLS ClientHello data from client.tlsfingerprint.io:8443
   254  //
   255  // data is a map of []byte with following keys:
   256  // - cipher_suites: [10, 10, 19, 1, 19, 2, 19, 3, 192, 43, 192, 47, 192, 44, 192, 48, 204, 169, 204, 168, 192, 19, 192, 20, 0, 156, 0, 157, 0, 47, 0, 53]
   257  // - compression_methods: [0] => null
   258  // - extensions: [10, 10, 255, 1, 0, 45, 0, 35, 0, 16, 68, 105, 0, 11, 0, 43, 0, 18, 0, 13, 0, 0, 0, 10, 0, 27, 0, 5, 0, 51, 0, 23, 10, 10, 0, 21]
   259  // - pt_fmts (ec_point_formats): [1, 0] => len: 1, content: 0x00
   260  // - sig_algs (signature_algorithms): [0, 16, 4, 3, 8, 4, 4, 1, 5, 3, 8, 5, 5, 1, 8, 6, 6, 1] => len: 16, content: 0x0403, 0x0804, 0x0401, 0x0503, 0x0805, 0x0501, 0x0806, 0x0601
   261  // - supported_versions: [10, 10, 3, 4, 3, 3] => 0x0a0a, 0x0304, 0x0303 (GREASE, TLS 1.3, TLS 1.2)
   262  // - curves (named_groups, supported_groups): [0, 8, 10, 10, 0, 29, 0, 23, 0, 24] => len: 8, content: GREASE, 0x001d, 0x0017, 0x0018
   263  // - alpn: [0, 12, 2, 104, 50, 8, 104, 116, 116, 112, 47, 49, 46, 49] => len: 12, content: h2, http/1.1
   264  // - key_share: [10, 10, 0, 1, 0, 29, 0, 32] => {group: 0x0a0a, len:1}, {group: 0x001d, len:32}
   265  // - psk_key_exchange_modes: [1] => psk_dhe_ke(0x01)
   266  // - cert_compression_algs: [2, 0, 2] => brotli (0x0002)
   267  // - record_size_limit: [0, 255] => 255
   268  //
   269  // TLSVersMin/TLSVersMax are set to 0 if supported_versions is present.
   270  // To prevent conflict, they should be set manually if needed BEFORE calling this function.
   271  func (chs *ClientHelloSpec) ImportTLSClientHello(data map[string][]byte) error {
   272  	var tlsExtensionTypes []uint16
   273  	var err error
   274  
   275  	if data["cipher_suites"] == nil {
   276  		return errors.New("cipher_suites is required")
   277  	}
   278  	chs.CipherSuites, err = helper.Uint8to16(data["cipher_suites"])
   279  	if err != nil {
   280  		return err
   281  	}
   282  
   283  	if data["compression_methods"] == nil {
   284  		return errors.New("compression_methods is required")
   285  	}
   286  	chs.CompressionMethods = data["compression_methods"]
   287  
   288  	if data["extensions"] == nil {
   289  		return errors.New("extensions is required")
   290  	}
   291  	tlsExtensionTypes, err = helper.Uint8to16(data["extensions"])
   292  	if err != nil {
   293  		return err
   294  	}
   295  
   296  	for _, extType := range tlsExtensionTypes {
   297  		extension := ExtensionFromID(extType)
   298  		extWriter, ok := extension.(TLSExtensionWriter)
   299  		if !ok {
   300  			return fmt.Errorf("unsupported extension %d", extType)
   301  		}
   302  		if extension == nil || !ok {
   303  			log.Printf("[Warning] Unsupported extension %d added as a &GenericExtension without Data", extType)
   304  			chs.Extensions = append(chs.Extensions, &GenericExtension{extType, []byte{}})
   305  		} else {
   306  			switch extType {
   307  			case extensionSupportedPoints:
   308  				if data["pt_fmts"] == nil {
   309  					return errors.New("pt_fmts is required")
   310  				}
   311  				_, err = extWriter.Write(data["pt_fmts"])
   312  				if err != nil {
   313  					return err
   314  				}
   315  			case extensionSignatureAlgorithms:
   316  				if data["sig_algs"] == nil {
   317  					return errors.New("sig_algs is required")
   318  				}
   319  				_, err = extWriter.Write(data["sig_algs"])
   320  				if err != nil {
   321  					return err
   322  				}
   323  			case extensionSupportedVersions:
   324  				chs.TLSVersMin = 0
   325  				chs.TLSVersMax = 0
   326  
   327  				if data["supported_versions"] == nil {
   328  					return errors.New("supported_versions is required")
   329  				}
   330  
   331  				// need to add uint8 length prefix
   332  				fixedData := make([]byte, len(data["supported_versions"])+1)
   333  				fixedData[0] = uint8(len(data["supported_versions"]) & 0xff)
   334  				copy(fixedData[1:], data["supported_versions"])
   335  				_, err = extWriter.Write(fixedData)
   336  				if err != nil {
   337  					return err
   338  				}
   339  			case extensionSupportedCurves:
   340  				if data["curves"] == nil {
   341  					return errors.New("curves is required")
   342  				}
   343  
   344  				_, err = extWriter.Write(data["curves"])
   345  				if err != nil {
   346  					return err
   347  				}
   348  			case extensionALPN:
   349  				if data["alpn"] == nil {
   350  					return errors.New("alpn is required")
   351  				}
   352  
   353  				_, err = extWriter.Write(data["alpn"])
   354  				if err != nil {
   355  					return err
   356  				}
   357  			case extensionKeyShare:
   358  				if data["key_share"] == nil {
   359  					return errors.New("key_share is required")
   360  				}
   361  
   362  				// need to add (zero) data per each key share, [10, 10, 0, 1] => [10, 10, 0, 1, 0]
   363  				fixedData := make([]byte, 0)
   364  				for i := 0; i < len(data["key_share"]); i += 4 {
   365  					fixedData = append(fixedData, data["key_share"][i:i+4]...)
   366  					for j := 0; j < int(data["key_share"][i+3]); j++ {
   367  						fixedData = append(fixedData, 0)
   368  					}
   369  				}
   370  				// add uint16 length prefix
   371  				fixedData = append([]byte{uint8(len(fixedData) >> 8), uint8(len(fixedData) & 0xff)}, fixedData...)
   372  
   373  				_, err = extWriter.Write(fixedData)
   374  				if err != nil {
   375  					return err
   376  				}
   377  			case extensionPSKModes:
   378  				if data["psk_key_exchange_modes"] == nil {
   379  					return errors.New("psk_key_exchange_modes is required")
   380  				}
   381  
   382  				// need to add uint8 length prefix
   383  				fixedData := make([]byte, len(data["psk_key_exchange_modes"])+1)
   384  				fixedData[0] = uint8(len(data["psk_key_exchange_modes"]) & 0xff)
   385  				copy(fixedData[1:], data["psk_key_exchange_modes"])
   386  				_, err = extWriter.Write(fixedData)
   387  				if err != nil {
   388  					return err
   389  				}
   390  			case utlsExtensionCompressCertificate:
   391  				if data["cert_compression_algs"] == nil {
   392  					return errors.New("cert_compression_algs is required")
   393  				}
   394  
   395  				// need to add uint8 length prefix
   396  				fixedData := make([]byte, len(data["cert_compression_algs"])+1)
   397  				fixedData[0] = uint8(len(data["cert_compression_algs"]) & 0xff)
   398  				copy(fixedData[1:], data["cert_compression_algs"])
   399  				_, err = extWriter.Write(fixedData)
   400  				if err != nil {
   401  					return err
   402  				}
   403  			case fakeRecordSizeLimit:
   404  				if data["record_size_limit"] == nil {
   405  					return errors.New("record_size_limit is required")
   406  				}
   407  
   408  				_, err = extWriter.Write(data["record_size_limit"]) // uint16 as []byte
   409  				if err != nil {
   410  					return err
   411  				}
   412  			case utlsExtensionApplicationSettings:
   413  				// TODO: tlsfingerprint.io should record/provide application settings data
   414  				extWriter.(*ApplicationSettingsExtension).SupportedProtocols = []string{"h2"}
   415  			case fakeExtensionPreSharedKey:
   416  				log.Printf("[Warning] PSK extension added without data")
   417  			default:
   418  				if !isGREASEUint16(extType) {
   419  					log.Printf("[Warning] extension %d added without data", extType)
   420  				} /*else {
   421  					log.Printf("[Warning] GREASE extension added but ID/Data discarded. They will be automatically re-GREASEd on ApplyPreset() call.")
   422  				}*/
   423  			}
   424  			chs.Extensions = append(chs.Extensions, extWriter)
   425  		}
   426  	}
   427  	return nil
   428  }
   429  
   430  // ImportTLSClientHelloFromJSON imports ClientHelloSpec from JSON data from client.tlsfingerprint.io format
   431  //
   432  // It calls ImportTLSClientHello internally after unmarshaling JSON data into map[string][]byte
   433  func (chs *ClientHelloSpec) ImportTLSClientHelloFromJSON(jsonB []byte) error {
   434  	var data map[string][]byte
   435  	err := json.Unmarshal(jsonB, &data)
   436  	if err != nil {
   437  		return err
   438  	}
   439  	return chs.ImportTLSClientHello(data)
   440  }
   441  
   442  // FromRaw converts a ClientHello message in the form of raw bytes into a ClientHelloSpec.
   443  func (chs *ClientHelloSpec) FromRaw(raw []byte, allowBluntMimicry ...bool) error {
   444  	if chs == nil {
   445  		return errors.New("cannot unmarshal into nil ClientHelloSpec")
   446  	}
   447  
   448  	var bluntMimicry = false
   449  	if len(allowBluntMimicry) == 1 {
   450  		bluntMimicry = allowBluntMimicry[0]
   451  	}
   452  
   453  	*chs = ClientHelloSpec{} // reset
   454  	s := cryptobyte.String(raw)
   455  
   456  	var contentType uint8
   457  	var recordVersion uint16
   458  	if !s.ReadUint8(&contentType) || // record type
   459  		!s.ReadUint16(&recordVersion) || !s.Skip(2) { // record version and length
   460  		return errors.New("unable to read record type, version, and length")
   461  	}
   462  
   463  	if recordType(contentType) != recordTypeHandshake {
   464  		return errors.New("record is not a handshake")
   465  	}
   466  
   467  	var handshakeVersion uint16
   468  	var handshakeType uint8
   469  
   470  	if !s.ReadUint8(&handshakeType) || !s.Skip(3) || // message type and 3 byte length
   471  		!s.ReadUint16(&handshakeVersion) || !s.Skip(32) { // 32 byte random
   472  		return errors.New("unable to read handshake message type, length, and random")
   473  	}
   474  
   475  	if handshakeType != typeClientHello {
   476  		return errors.New("handshake message is not a ClientHello")
   477  	}
   478  
   479  	chs.TLSVersMin = recordVersion
   480  	chs.TLSVersMax = handshakeVersion
   481  
   482  	var ignoredSessionID cryptobyte.String
   483  	if !s.ReadUint8LengthPrefixed(&ignoredSessionID) {
   484  		return errors.New("unable to read session id")
   485  	}
   486  
   487  	// CipherSuites
   488  	var cipherSuitesBytes cryptobyte.String
   489  	if !s.ReadUint16LengthPrefixed(&cipherSuitesBytes) {
   490  		return errors.New("unable to read ciphersuites")
   491  	}
   492  
   493  	if err := chs.ReadCipherSuites(cipherSuitesBytes); err != nil {
   494  		return err
   495  	}
   496  
   497  	// CompressionMethods
   498  	var compressionMethods cryptobyte.String
   499  	if !s.ReadUint8LengthPrefixed(&compressionMethods) {
   500  		return errors.New("unable to read compression methods")
   501  	}
   502  
   503  	if err := chs.ReadCompressionMethods(compressionMethods); err != nil {
   504  		return err
   505  	}
   506  
   507  	if s.Empty() {
   508  		// Extensions are optional
   509  		return nil
   510  	}
   511  
   512  	var extensions cryptobyte.String
   513  	if !s.ReadUint16LengthPrefixed(&extensions) {
   514  		return errors.New("unable to read extensions data")
   515  	}
   516  
   517  	if err := chs.ReadTLSExtensions(extensions, bluntMimicry); err != nil {
   518  		return err
   519  	}
   520  
   521  	return nil
   522  }
   523  
   524  // UnmarshalJSON unmarshals a ClientHello message in the form of JSON into a ClientHelloSpec.
   525  func (chs *ClientHelloSpec) UnmarshalJSON(jsonB []byte) error {
   526  	var chsju ClientHelloSpecJSONUnmarshaler
   527  	if err := json.Unmarshal(jsonB, &chsju); err != nil {
   528  		return err
   529  	}
   530  
   531  	*chs = chsju.ClientHelloSpec()
   532  	return nil
   533  }
   534  
   535  var (
   536  	// HelloGolang will use default "crypto/tls" handshake marshaling codepath, which WILL
   537  	// overwrite your changes to Hello(Config, Session are fine).
   538  	// You might want to call BuildHandshakeState() before applying any changes.
   539  	// UConn.Extensions will be completely ignored.
   540  	HelloGolang = ClientHelloID{helloGolang, helloAutoVers, nil, nil}
   541  
   542  	// HelloCustom will prepare ClientHello with empty uconn.Extensions so you can fill it with
   543  	// TLSExtensions manually or use ApplyPreset function
   544  	HelloCustom = ClientHelloID{helloCustom, helloAutoVers, nil, nil}
   545  
   546  	// HelloRandomized* randomly adds/reorders extensions, ciphersuites, etc.
   547  	HelloRandomized       = ClientHelloID{helloRandomized, helloAutoVers, nil, nil}
   548  	HelloRandomizedALPN   = ClientHelloID{helloRandomizedALPN, helloAutoVers, nil, nil}
   549  	HelloRandomizedNoALPN = ClientHelloID{helloRandomizedNoALPN, helloAutoVers, nil, nil}
   550  
   551  	// The rest will will parrot given browser.
   552  	HelloFirefox_Auto = HelloFirefox_105
   553  	HelloFirefox_55   = ClientHelloID{helloFirefox, "55", nil, nil}
   554  	HelloFirefox_56   = ClientHelloID{helloFirefox, "56", nil, nil}
   555  	HelloFirefox_63   = ClientHelloID{helloFirefox, "63", nil, nil}
   556  	HelloFirefox_65   = ClientHelloID{helloFirefox, "65", nil, nil}
   557  	HelloFirefox_99   = ClientHelloID{helloFirefox, "99", nil, nil}
   558  	HelloFirefox_102  = ClientHelloID{helloFirefox, "102", nil, nil}
   559  	HelloFirefox_105  = ClientHelloID{helloFirefox, "105", nil, nil}
   560  
   561  	HelloChrome_Auto        = HelloChrome_106_Shuffle
   562  	HelloChrome_58          = ClientHelloID{helloChrome, "58", nil, nil}
   563  	HelloChrome_62          = ClientHelloID{helloChrome, "62", nil, nil}
   564  	HelloChrome_70          = ClientHelloID{helloChrome, "70", nil, nil}
   565  	HelloChrome_72          = ClientHelloID{helloChrome, "72", nil, nil}
   566  	HelloChrome_83          = ClientHelloID{helloChrome, "83", nil, nil}
   567  	HelloChrome_87          = ClientHelloID{helloChrome, "87", nil, nil}
   568  	HelloChrome_96          = ClientHelloID{helloChrome, "96", nil, nil}
   569  	HelloChrome_100         = ClientHelloID{helloChrome, "100", nil, nil}
   570  	HelloChrome_102         = ClientHelloID{helloChrome, "102", nil, nil}
   571  	HelloChrome_106_Shuffle = ClientHelloID{helloChrome, "106", nil, nil} // beta: shuffler enabled starting from 106
   572  
   573  	// Chrome with PSK: Chrome start sending this ClientHello after doing TLS 1.3 handshake with the same server.
   574  	HelloChrome_100_PSK      = ClientHelloID{helloChrome, "100_PSK", nil, nil} // beta: PSK extension added. uTLS doesn't fully support PSK. Use at your own risk.
   575  	HelloChrome_112_PSK_Shuf = ClientHelloID{helloChrome, "112_PSK", nil, nil} // beta: PSK extension added. uTLS doesn't fully support PSK. Use at your own risk.
   576  
   577  	HelloIOS_Auto = HelloIOS_14
   578  	HelloIOS_11_1 = ClientHelloID{helloIOS, "111", nil, nil} // legacy "111" means 11.1
   579  	HelloIOS_12_1 = ClientHelloID{helloIOS, "12.1", nil, nil}
   580  	HelloIOS_13   = ClientHelloID{helloIOS, "13", nil, nil}
   581  	HelloIOS_14   = ClientHelloID{helloIOS, "14", nil, nil}
   582  
   583  	HelloAndroid_11_OkHttp = ClientHelloID{helloAndroid, "11", nil, nil}
   584  
   585  	HelloEdge_Auto = HelloEdge_85 // HelloEdge_106 seems to be incompatible with this library
   586  	HelloEdge_85   = ClientHelloID{helloEdge, "85", nil, nil}
   587  	HelloEdge_106  = ClientHelloID{helloEdge, "106", nil, nil}
   588  
   589  	HelloSafari_Auto = HelloSafari_16_0
   590  	HelloSafari_16_0 = ClientHelloID{helloSafari, "16.0", nil, nil}
   591  
   592  	Hello360_Auto = Hello360_7_5 // Hello360_11_0 seems to be incompatible with this library
   593  	Hello360_7_5  = ClientHelloID{hello360, "7.5", nil, nil}
   594  	Hello360_11_0 = ClientHelloID{hello360, "11.0", nil, nil}
   595  
   596  	HelloQQ_Auto = HelloQQ_11_1
   597  	HelloQQ_11_1 = ClientHelloID{helloQQ, "11.1", nil, nil}
   598  )
   599  
   600  type Weights struct {
   601  	Extensions_Append_ALPN                             float64
   602  	TLSVersMax_Set_VersionTLS13                        float64
   603  	CipherSuites_Remove_RandomCiphers                  float64
   604  	SigAndHashAlgos_Append_ECDSAWithSHA1               float64
   605  	SigAndHashAlgos_Append_ECDSAWithP521AndSHA512      float64
   606  	SigAndHashAlgos_Append_PSSWithSHA256               float64
   607  	SigAndHashAlgos_Append_PSSWithSHA384_PSSWithSHA512 float64
   608  	CurveIDs_Append_X25519                             float64
   609  	CurveIDs_Append_CurveP521                          float64
   610  	Extensions_Append_Padding                          float64
   611  	Extensions_Append_Status                           float64
   612  	Extensions_Append_SCT                              float64
   613  	Extensions_Append_Reneg                            float64
   614  	Extensions_Append_EMS                              float64
   615  	FirstKeyShare_Set_CurveP256                        float64
   616  	Extensions_Append_ALPS                             float64
   617  }
   618  
   619  // Do not modify them directly as they may being used. If you
   620  // want to use your custom weights, please make a copy first.
   621  var DefaultWeights = Weights{
   622  	Extensions_Append_ALPN:                             0.7,
   623  	TLSVersMax_Set_VersionTLS13:                        0.4,
   624  	CipherSuites_Remove_RandomCiphers:                  0.4,
   625  	SigAndHashAlgos_Append_ECDSAWithSHA1:               0.63,
   626  	SigAndHashAlgos_Append_ECDSAWithP521AndSHA512:      0.59,
   627  	SigAndHashAlgos_Append_PSSWithSHA256:               0.51,
   628  	SigAndHashAlgos_Append_PSSWithSHA384_PSSWithSHA512: 0.9,
   629  	CurveIDs_Append_X25519:                             0.71,
   630  	CurveIDs_Append_CurveP521:                          0.46,
   631  	Extensions_Append_Padding:                          0.62,
   632  	Extensions_Append_Status:                           0.74,
   633  	Extensions_Append_SCT:                              0.46,
   634  	Extensions_Append_Reneg:                            0.75,
   635  	Extensions_Append_EMS:                              0.77,
   636  	FirstKeyShare_Set_CurveP256:                        0.25,
   637  	Extensions_Append_ALPS:                             0.33,
   638  }
   639  
   640  // based on spec's GreaseStyle, GREASE_PLACEHOLDER may be replaced by another GREASE value
   641  // https://tools.ietf.org/html/draft-ietf-tls-grease-01
   642  const GREASE_PLACEHOLDER = 0x0a0a
   643  
   644  func isGREASEUint16(v uint16) bool {
   645  	// First byte is same as second byte
   646  	// and lowest nibble is 0xa
   647  	return ((v >> 8) == v&0xff) && v&0xf == 0xa
   648  }
   649  
   650  func unGREASEUint16(v uint16) uint16 {
   651  	if isGREASEUint16(v) {
   652  		return GREASE_PLACEHOLDER
   653  	} else {
   654  		return v
   655  	}
   656  }
   657  
   658  // utlsMacSHA384 returns a SHA-384 based MAC. These are only supported in TLS 1.2
   659  // so the given version is ignored.
   660  func utlsMacSHA384(key []byte) hash.Hash {
   661  	return hmac.New(sha512.New384, key)
   662  }
   663  
   664  var utlsSupportedCipherSuites []*cipherSuite
   665  
   666  func init() {
   667  	utlsSupportedCipherSuites = append(cipherSuites, []*cipherSuite{
   668  		{OLD_TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256, 32, 0, 12, ecdheRSAKA,
   669  			suiteECDHE | suiteTLS12, nil, nil, aeadChaCha20Poly1305},
   670  		{OLD_TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256, 32, 0, 12, ecdheECDSAKA,
   671  			suiteECDHE | suiteECSign | suiteTLS12, nil, nil, aeadChaCha20Poly1305},
   672  	}...)
   673  }
   674  
   675  // EnableWeakCiphers allows utls connections to continue in some cases, when weak cipher was chosen.
   676  // This provides better compatibility with servers on the web, but weakens security. Feel free
   677  // to use this option if you establish additional secure connection inside of utls connection.
   678  // This option does not change the shape of parrots (i.e. same ciphers will be offered either way).
   679  // Must be called before establishing any connections.
   680  func EnableWeakCiphers() {
   681  	utlsSupportedCipherSuites = append(cipherSuites, []*cipherSuite{
   682  		{DISABLED_TLS_RSA_WITH_AES_256_CBC_SHA256, 32, 32, 16, rsaKA,
   683  			suiteTLS12, cipherAES, macSHA256, nil},
   684  
   685  		{DISABLED_TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384, 32, 48, 16, ecdheECDSAKA,
   686  			suiteECDHE | suiteECSign | suiteTLS12 | suiteSHA384, cipherAES, utlsMacSHA384, nil},
   687  		{DISABLED_TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384, 32, 48, 16, ecdheRSAKA,
   688  			suiteECDHE | suiteTLS12 | suiteSHA384, cipherAES, utlsMacSHA384, nil},
   689  	}...)
   690  }