github.com/Carcraftz/utls@v0.0.0-20220413235215-6b7c52fd78b6/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  	"fmt"
    11  )
    12  
    13  // Naming convention:
    14  // Unsupported things are prefixed with "Fake"
    15  // Things, supported by utls, but not crypto/tls' are prefixed with "utls"
    16  // Supported things, that have changed their ID are prefixed with "Old"
    17  // Supported but disabled things are prefixed with "Disabled". We will _enable_ them.
    18  const (
    19  	utlsExtensionPadding              uint16 = 21
    20  	utlsExtensionExtendedMasterSecret uint16 = 23 // https://tools.ietf.org/html/rfc7627
    21  
    22  	// extensions with 'fake' prefix break connection, if server echoes them back
    23  	fakeExtensionChannelID uint16 = 30032 // not IANA assigned
    24  
    25  	fakeRecordSizeLimit uint16 = 0x001c
    26  )
    27  
    28  const (
    29  	OLD_TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256   = uint16(0xcc13)
    30  	OLD_TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256 = uint16(0xcc14)
    31  
    32  	DISABLED_TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384 = uint16(0xc024)
    33  	DISABLED_TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384   = uint16(0xc028)
    34  	DISABLED_TLS_RSA_WITH_AES_256_CBC_SHA256         = uint16(0x003d)
    35  
    36  	FAKE_OLD_TLS_DHE_RSA_WITH_CHACHA20_POLY1305_SHA256 = uint16(0xcc15) // we can try to craft these ciphersuites
    37  	FAKE_TLS_DHE_RSA_WITH_AES_128_GCM_SHA256           = uint16(0x009e) // from existing pieces, if needed
    38  
    39  	FAKE_TLS_DHE_RSA_WITH_AES_128_CBC_SHA  = uint16(0x0033)
    40  	FAKE_TLS_DHE_RSA_WITH_AES_256_CBC_SHA  = uint16(0x0039)
    41  	FAKE_TLS_RSA_WITH_RC4_128_MD5          = uint16(0x0004)
    42  	FAKE_TLS_EMPTY_RENEGOTIATION_INFO_SCSV = uint16(0x00ff)
    43  )
    44  
    45  // newest signatures
    46  var (
    47  	FakePKCS1WithSHA224 SignatureScheme = 0x0301
    48  	FakeECDSAWithSHA224 SignatureScheme = 0x0303
    49  
    50  	// fakeEd25519 = SignatureAndHash{0x08, 0x07}
    51  	// fakeEd448 = SignatureAndHash{0x08, 0x08}
    52  )
    53  
    54  // fake curves(groups)
    55  var (
    56  	FakeFFDHE2048 = uint16(0x0100)
    57  	FakeFFDHE3072 = uint16(0x0101)
    58  )
    59  
    60  // https://tools.ietf.org/html/draft-ietf-tls-certificate-compression-04
    61  type CertCompressionAlgo uint16
    62  
    63  const (
    64  	CertCompressionZlib   CertCompressionAlgo = 0x0001
    65  	CertCompressionBrotli CertCompressionAlgo = 0x0002
    66  )
    67  
    68  const (
    69  	PskModePlain uint8 = pskModePlain
    70  	PskModeDHE   uint8 = pskModeDHE
    71  )
    72  
    73  type ClientHelloID struct {
    74  	Client string
    75  
    76  	// Version specifies version of a mimicked clients (e.g. browsers).
    77  	// Not used in randomized, custom handshake, and default Go.
    78  	Version string
    79  
    80  	// Seed is only used for randomized fingerprints to seed PRNG.
    81  	// Must not be modified once set.
    82  	Seed *PRNGSeed
    83  }
    84  
    85  func (p *ClientHelloID) Str() string {
    86  	return fmt.Sprintf("%s-%s", p.Client, p.Version)
    87  }
    88  
    89  func (p *ClientHelloID) IsSet() bool {
    90  	return (p.Client == "") && (p.Version == "")
    91  }
    92  
    93  const (
    94  	// clients
    95  	helloGolang           = "Golang"
    96  	helloRandomized       = "Randomized"
    97  	helloRandomizedALPN   = "Randomized-ALPN"
    98  	helloRandomizedNoALPN = "Randomized-NoALPN"
    99  	helloCustom           = "Custom"
   100  	helloFirefox          = "Firefox"
   101  	helloChrome           = "Chrome"
   102  	helloIOS              = "iOS"
   103  	helloAndroid          = "Android"
   104  
   105  	// versions
   106  	helloAutoVers = "0"
   107  )
   108  
   109  type ClientHelloSpec struct {
   110  	CipherSuites       []uint16       // nil => default
   111  	CompressionMethods []uint8        // nil => no compression
   112  	Extensions         []TLSExtension // nil => no extensions
   113  
   114  	TLSVersMin uint16 // [1.0-1.3] default: parse from .Extensions, if SupportedVersions ext is not present => 1.0
   115  	TLSVersMax uint16 // [1.2-1.3] default: parse from .Extensions, if SupportedVersions ext is not present => 1.2
   116  
   117  	// GreaseStyle: currently only random
   118  	// sessionID may or may not depend on ticket; nil => random
   119  	GetSessionID func(ticket []byte) [32]byte
   120  
   121  	// TLSFingerprintLink string // ?? link to tlsfingerprint.io for informational purposes
   122  }
   123  
   124  var (
   125  	// HelloGolang will use default "crypto/tls" handshake marshaling codepath, which WILL
   126  	// overwrite your changes to Hello(Config, Session are fine).
   127  	// You might want to call BuildHandshakeState() before applying any changes.
   128  	// UConn.Extensions will be completely ignored.
   129  	HelloGolang = ClientHelloID{helloGolang, helloAutoVers, nil}
   130  
   131  	// HelloCustom will prepare ClientHello with empty uconn.Extensions so you can fill it with
   132  	// TLSExtensions manually or use ApplyPreset function
   133  	HelloCustom = ClientHelloID{helloCustom, helloAutoVers, nil}
   134  
   135  	// HelloRandomized* randomly adds/reorders extensions, ciphersuites, etc.
   136  	HelloRandomized       = ClientHelloID{helloRandomized, helloAutoVers, nil}
   137  	HelloRandomizedALPN   = ClientHelloID{helloRandomizedALPN, helloAutoVers, nil}
   138  	HelloRandomizedNoALPN = ClientHelloID{helloRandomizedNoALPN, helloAutoVers, nil}
   139  
   140  	// The rest will will parrot given browser.
   141  	HelloFirefox_Auto = HelloFirefox_65
   142  	HelloFirefox_55   = ClientHelloID{helloFirefox, "55", nil}
   143  	HelloFirefox_56   = ClientHelloID{helloFirefox, "56", nil}
   144  	HelloFirefox_63   = ClientHelloID{helloFirefox, "63", nil}
   145  	HelloFirefox_65   = ClientHelloID{helloFirefox, "65", nil}
   146  
   147  	HelloChrome_Auto = HelloChrome_100
   148  	HelloChrome_58   = ClientHelloID{helloChrome, "58", nil}
   149  	HelloChrome_62   = ClientHelloID{helloChrome, "62", nil}
   150  	HelloChrome_70   = ClientHelloID{helloChrome, "70", nil}
   151  	HelloChrome_72   = ClientHelloID{helloChrome, "72", nil}
   152  	HelloChrome_83   = ClientHelloID{helloChrome, "83", nil}
   153  	HelloChrome_100  = ClientHelloID{helloChrome, "100", nil}
   154  
   155  	HelloIOS_Auto = HelloIOS_12_1
   156  	HelloIOS_11_1 = ClientHelloID{helloIOS, "111", nil} // legacy "111" means 11.1
   157  	HelloIOS_12_1 = ClientHelloID{helloIOS, "12.1", nil}
   158  )
   159  
   160  // based on spec's GreaseStyle, GREASE_PLACEHOLDER may be replaced by another GREASE value
   161  // https://tools.ietf.org/html/draft-ietf-tls-grease-01
   162  const GREASE_PLACEHOLDER = 0x0a0a
   163  
   164  // utlsMacSHA384 returns a SHA-384 based MAC. These are only supported in TLS 1.2
   165  // so the given version is ignored.
   166  func utlsMacSHA384(version uint16, key []byte) macFunction {
   167  	return tls10MAC{h: hmac.New(sha512.New384, key)}
   168  }
   169  
   170  var (
   171  	utlsSupportedCipherSuites []*cipherSuite
   172  	utlsSupportedGroups       map[CurveID]bool
   173  )
   174  
   175  func init() {
   176  	utlsSupportedCipherSuites = append(cipherSuites, []*cipherSuite{
   177  		{OLD_TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256, 32, 0, 12, ecdheRSAKA,
   178  			suiteECDHE | suiteTLS12 | suiteDefaultOff, nil, nil, aeadChaCha20Poly1305},
   179  		{OLD_TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256, 32, 0, 12, ecdheECDSAKA,
   180  			suiteECDHE | suiteECDSA | suiteTLS12 | suiteDefaultOff, nil, nil, aeadChaCha20Poly1305},
   181  	}...)
   182  
   183  	utlsSupportedGroups = map[CurveID]bool{
   184  		X25519:    true,
   185  		CurveP256: true,
   186  	}
   187  }
   188  
   189  // EnableWeakCiphers allows utls connections to continue in some cases, when weak cipher was chosen.
   190  // This provides better compatibility with servers on the web, but weakens security. Feel free
   191  // to use this option if you establish additional secure connection inside of utls connection.
   192  // This option does not change the shape of parrots (i.e. same ciphers will be offered either way).
   193  // Must be called before establishing any connections.
   194  func EnableWeakCiphers() {
   195  	utlsSupportedCipherSuites = append(cipherSuites, []*cipherSuite{
   196  		{DISABLED_TLS_RSA_WITH_AES_256_CBC_SHA256, 32, 32, 16, rsaKA,
   197  			suiteTLS12 | suiteDefaultOff, cipherAES, macSHA256, nil},
   198  
   199  		{DISABLED_TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384, 32, 48, 16, ecdheECDSAKA,
   200  			suiteECDHE | suiteECDSA | suiteTLS12 | suiteDefaultOff | suiteSHA384, cipherAES, utlsMacSHA384, nil},
   201  		{DISABLED_TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384, 32, 48, 16, ecdheRSAKA,
   202  			suiteECDHE | suiteTLS12 | suiteDefaultOff | suiteSHA384, cipherAES, utlsMacSHA384, nil},
   203  	}...)
   204  }
   205  
   206  // EnableVartimeGroups allows utls connections to continue in some cases, when
   207  // a curve with a variable time implementation was chosen.  This provides
   208  // better compatibility with servers on the web, but weakens security.  This
   209  // provides better compatibility with servers on the web, but weakens security.
   210  // Feel free to use this option if you establish additional secure connection
   211  // inside of utls connection.  This option does not change the shape of
   212  // parrots (i.e. same groups will be offered either way).  Must be called
   213  // before establishing any connections.
   214  func EnableVartimeGroups() {
   215  	for _, curveID := range []CurveID{
   216  		CurveP384,
   217  		CurveP521,
   218  	} {
   219  		utlsSupportedGroups[curveID] = true
   220  	}
   221  }