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