github.com/Carcraftz/utls@v0.0.0-20220413235215-6b7c52fd78b6/u_parrots.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/sha256" 9 "encoding/binary" 10 "errors" 11 "fmt" 12 "io" 13 "sort" 14 "strconv" 15 ) 16 17 func utlsIdToSpec(id ClientHelloID) (ClientHelloSpec, error) { 18 switch id { 19 case HelloChrome_58, HelloChrome_62: 20 return ClientHelloSpec{ 21 TLSVersMax: VersionTLS12, 22 TLSVersMin: VersionTLS10, 23 CipherSuites: []uint16{ 24 GREASE_PLACEHOLDER, 25 TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, 26 TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256, 27 TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384, 28 TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384, 29 TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305, 30 TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305, 31 TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA, 32 TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA, 33 TLS_RSA_WITH_AES_128_GCM_SHA256, 34 TLS_RSA_WITH_AES_256_GCM_SHA384, 35 TLS_RSA_WITH_AES_128_CBC_SHA, 36 TLS_RSA_WITH_AES_256_CBC_SHA, 37 TLS_RSA_WITH_3DES_EDE_CBC_SHA, 38 }, 39 CompressionMethods: []byte{compressionNone}, 40 Extensions: []TLSExtension{ 41 &UtlsGREASEExtension{}, 42 &RenegotiationInfoExtension{Renegotiation: RenegotiateOnceAsClient}, 43 &SNIExtension{}, 44 &UtlsExtendedMasterSecretExtension{}, 45 &SessionTicketExtension{}, 46 &SignatureAlgorithmsExtension{SupportedSignatureAlgorithms: []SignatureScheme{ 47 ECDSAWithP256AndSHA256, 48 PSSWithSHA256, 49 PKCS1WithSHA256, 50 ECDSAWithP384AndSHA384, 51 PSSWithSHA384, 52 PKCS1WithSHA384, 53 PSSWithSHA512, 54 PKCS1WithSHA512, 55 PKCS1WithSHA1}, 56 }, 57 &StatusRequestExtension{}, 58 &SCTExtension{}, 59 &ALPNExtension{AlpnProtocols: []string{"h2", "http/1.1"}}, 60 &FakeChannelIDExtension{}, 61 &SupportedPointsExtension{SupportedPoints: []byte{pointFormatUncompressed}}, 62 &SupportedCurvesExtension{[]CurveID{CurveID(GREASE_PLACEHOLDER), 63 X25519, CurveP256, CurveP384}}, 64 &UtlsGREASEExtension{}, 65 &UtlsPaddingExtension{GetPaddingLen: BoringPaddingStyle}, 66 }, 67 GetSessionID: sha256.Sum256, 68 }, nil 69 case HelloChrome_70: 70 return ClientHelloSpec{ 71 TLSVersMin: VersionTLS10, 72 TLSVersMax: VersionTLS13, 73 CipherSuites: []uint16{ 74 GREASE_PLACEHOLDER, 75 TLS_AES_128_GCM_SHA256, 76 TLS_AES_256_GCM_SHA384, 77 TLS_CHACHA20_POLY1305_SHA256, 78 TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, 79 TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256, 80 TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384, 81 TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384, 82 TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305, 83 TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305, 84 TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA, 85 TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA, 86 TLS_RSA_WITH_AES_128_GCM_SHA256, 87 TLS_RSA_WITH_AES_256_GCM_SHA384, 88 TLS_RSA_WITH_AES_128_CBC_SHA, 89 TLS_RSA_WITH_AES_256_CBC_SHA, 90 TLS_RSA_WITH_3DES_EDE_CBC_SHA, 91 }, 92 CompressionMethods: []byte{ 93 compressionNone, 94 }, 95 Extensions: []TLSExtension{ 96 &UtlsGREASEExtension{}, 97 &RenegotiationInfoExtension{Renegotiation: RenegotiateOnceAsClient}, 98 &SNIExtension{}, 99 &UtlsExtendedMasterSecretExtension{}, 100 &SessionTicketExtension{}, 101 &SignatureAlgorithmsExtension{SupportedSignatureAlgorithms: []SignatureScheme{ 102 ECDSAWithP256AndSHA256, 103 PSSWithSHA256, 104 PKCS1WithSHA256, 105 ECDSAWithP384AndSHA384, 106 PSSWithSHA384, 107 PKCS1WithSHA384, 108 PSSWithSHA512, 109 PKCS1WithSHA512, 110 PKCS1WithSHA1, 111 }}, 112 &StatusRequestExtension{}, 113 &SCTExtension{}, 114 &ALPNExtension{AlpnProtocols: []string{"h2", "http/1.1"}}, 115 &FakeChannelIDExtension{}, 116 &SupportedPointsExtension{SupportedPoints: []byte{ 117 pointFormatUncompressed, 118 }}, 119 &KeyShareExtension{[]KeyShare{ 120 {Group: CurveID(GREASE_PLACEHOLDER), Data: []byte{0}}, 121 {Group: X25519}, 122 }}, 123 &PSKKeyExchangeModesExtension{[]uint8{pskModeDHE}}, 124 &SupportedVersionsExtension{[]uint16{ 125 GREASE_PLACEHOLDER, 126 VersionTLS13, 127 VersionTLS12, 128 VersionTLS11, 129 VersionTLS10}}, 130 &SupportedCurvesExtension{[]CurveID{ 131 CurveID(GREASE_PLACEHOLDER), 132 X25519, 133 CurveP256, 134 CurveP384, 135 }}, 136 &CompressCertificateExtension{ 137 Algorithms: []CertCompressionAlgo{CertCompressionBrotli}, 138 }, 139 &UtlsGREASEExtension{}, 140 &UtlsPaddingExtension{GetPaddingLen: BoringPaddingStyle}, 141 }, 142 }, nil 143 case HelloChrome_72: 144 return ClientHelloSpec{ 145 CipherSuites: []uint16{ 146 GREASE_PLACEHOLDER, 147 TLS_AES_128_GCM_SHA256, 148 TLS_AES_256_GCM_SHA384, 149 TLS_CHACHA20_POLY1305_SHA256, 150 TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, 151 TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256, 152 TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384, 153 TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384, 154 TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305, 155 TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305, 156 TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA, 157 TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA, 158 TLS_RSA_WITH_AES_128_GCM_SHA256, 159 TLS_RSA_WITH_AES_256_GCM_SHA384, 160 TLS_RSA_WITH_AES_128_CBC_SHA, 161 TLS_RSA_WITH_AES_256_CBC_SHA, 162 TLS_RSA_WITH_3DES_EDE_CBC_SHA, 163 }, 164 CompressionMethods: []byte{ 165 0x00, // compressionNone 166 }, 167 Extensions: []TLSExtension{ 168 &UtlsGREASEExtension{}, 169 &SNIExtension{}, 170 &UtlsExtendedMasterSecretExtension{}, 171 &RenegotiationInfoExtension{Renegotiation: RenegotiateOnceAsClient}, 172 &SupportedCurvesExtension{[]CurveID{ 173 CurveID(GREASE_PLACEHOLDER), 174 X25519, 175 CurveP256, 176 CurveP384, 177 }}, 178 &SupportedPointsExtension{SupportedPoints: []byte{ 179 0x00, // pointFormatUncompressed 180 }}, 181 &SessionTicketExtension{}, 182 &ALPNExtension{AlpnProtocols: []string{"h2", "http/1.1"}}, 183 &StatusRequestExtension{}, 184 &SignatureAlgorithmsExtension{SupportedSignatureAlgorithms: []SignatureScheme{ 185 ECDSAWithP256AndSHA256, 186 PSSWithSHA256, 187 PKCS1WithSHA256, 188 ECDSAWithP384AndSHA384, 189 PSSWithSHA384, 190 PKCS1WithSHA384, 191 PSSWithSHA512, 192 PKCS1WithSHA512, 193 PKCS1WithSHA1, 194 }}, 195 &SCTExtension{}, 196 &KeyShareExtension{[]KeyShare{ 197 {Group: CurveID(GREASE_PLACEHOLDER), Data: []byte{0}}, 198 {Group: X25519}, 199 }}, 200 &PSKKeyExchangeModesExtension{[]uint8{ 201 PskModeDHE, 202 }}, 203 &SupportedVersionsExtension{[]uint16{ 204 GREASE_PLACEHOLDER, 205 VersionTLS13, 206 VersionTLS12, 207 VersionTLS11, 208 VersionTLS10, 209 }}, 210 &CompressCertificateExtension{ 211 Algorithms: []CertCompressionAlgo{CertCompressionBrotli}, 212 }, 213 &UtlsGREASEExtension{}, 214 &UtlsPaddingExtension{GetPaddingLen: BoringPaddingStyle}, 215 }, 216 }, nil 217 case HelloChrome_83: 218 return ClientHelloSpec{ 219 CipherSuites: []uint16{ 220 GREASE_PLACEHOLDER, 221 TLS_AES_128_GCM_SHA256, 222 TLS_AES_256_GCM_SHA384, 223 TLS_CHACHA20_POLY1305_SHA256, 224 TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, 225 TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256, 226 TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384, 227 TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384, 228 TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305, 229 TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305, 230 TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA, 231 TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA, 232 TLS_RSA_WITH_AES_128_GCM_SHA256, 233 TLS_RSA_WITH_AES_256_GCM_SHA384, 234 TLS_RSA_WITH_AES_128_CBC_SHA, 235 TLS_RSA_WITH_AES_256_CBC_SHA, 236 }, 237 CompressionMethods: []byte{ 238 0x00, // compressionNone 239 }, 240 Extensions: []TLSExtension{ 241 &UtlsGREASEExtension{}, 242 &SNIExtension{}, 243 &UtlsExtendedMasterSecretExtension{}, 244 &RenegotiationInfoExtension{Renegotiation: RenegotiateOnceAsClient}, 245 &SupportedCurvesExtension{[]CurveID{ 246 CurveID(GREASE_PLACEHOLDER), 247 X25519, 248 CurveP256, 249 CurveP384, 250 }}, 251 &SupportedPointsExtension{SupportedPoints: []byte{ 252 0x00, // pointFormatUncompressed 253 }}, 254 &SessionTicketExtension{}, 255 &ALPNExtension{AlpnProtocols: []string{"h2", "http/1.1"}}, 256 &StatusRequestExtension{}, 257 &SignatureAlgorithmsExtension{SupportedSignatureAlgorithms: []SignatureScheme{ 258 ECDSAWithP256AndSHA256, 259 PSSWithSHA256, 260 PKCS1WithSHA256, 261 ECDSAWithP384AndSHA384, 262 PSSWithSHA384, 263 PKCS1WithSHA384, 264 PSSWithSHA512, 265 PKCS1WithSHA512, 266 }}, 267 &SCTExtension{}, 268 &KeyShareExtension{[]KeyShare{ 269 {Group: CurveID(GREASE_PLACEHOLDER), Data: []byte{0}}, 270 {Group: X25519}, 271 }}, 272 &PSKKeyExchangeModesExtension{[]uint8{ 273 PskModeDHE, 274 }}, 275 &SupportedVersionsExtension{[]uint16{ 276 GREASE_PLACEHOLDER, 277 VersionTLS13, 278 VersionTLS12, 279 VersionTLS11, 280 VersionTLS10, 281 }}, 282 &CompressCertificateExtension{[]CertCompressionAlgo{ 283 CertCompressionBrotli, 284 }}, 285 &UtlsGREASEExtension{}, 286 &UtlsPaddingExtension{GetPaddingLen: BoringPaddingStyle}, 287 }, 288 }, nil 289 case HelloChrome_100: 290 return ClientHelloSpec{ 291 CipherSuites: []uint16{ 292 GREASE_PLACEHOLDER, 293 TLS_AES_128_GCM_SHA256, 294 TLS_AES_256_GCM_SHA384, 295 TLS_CHACHA20_POLY1305_SHA256, 296 TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, 297 TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256, 298 TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384, 299 TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384, 300 TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305, 301 TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305, 302 TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA, 303 TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA, 304 TLS_RSA_WITH_AES_128_GCM_SHA256, 305 TLS_RSA_WITH_AES_256_GCM_SHA384, 306 TLS_RSA_WITH_AES_128_CBC_SHA, 307 TLS_RSA_WITH_AES_256_CBC_SHA, 308 }, 309 CompressionMethods: []uint8{ 310 0x00, 311 }, 312 Extensions: []TLSExtension{ 313 &UtlsGREASEExtension{}, 314 &SNIExtension{}, 315 &UtlsExtendedMasterSecretExtension{}, 316 &RenegotiationInfoExtension{Renegotiation: RenegotiateOnceAsClient}, 317 &SupportedCurvesExtension{[]CurveID{ 318 CurveID(GREASE_PLACEHOLDER), 319 X25519, 320 CurveP256, 321 CurveP384, 322 }}, 323 &SupportedPointsExtension{SupportedPoints: []byte{ 324 0x00, // pointFormatUncompressed 325 }}, 326 &SessionTicketExtension{}, 327 &ALPNExtension{AlpnProtocols: []string{"h2", "http/1.1"}}, 328 &StatusRequestExtension{}, 329 &SignatureAlgorithmsExtension{SupportedSignatureAlgorithms: []SignatureScheme{ 330 ECDSAWithP256AndSHA256, 331 PSSWithSHA256, 332 PKCS1WithSHA256, 333 ECDSAWithP384AndSHA384, 334 PSSWithSHA384, 335 PKCS1WithSHA384, 336 PSSWithSHA512, 337 PKCS1WithSHA512, 338 }}, 339 &SCTExtension{}, 340 &KeyShareExtension{[]KeyShare{ 341 {Group: CurveID(GREASE_PLACEHOLDER), Data: []byte{0}}, 342 {Group: X25519}, 343 }}, 344 &PSKKeyExchangeModesExtension{[]uint8{ 345 PskModeDHE, 346 }}, 347 &SupportedVersionsExtension{[]uint16{ 348 GREASE_PLACEHOLDER, 349 VersionTLS13, 350 VersionTLS12, 351 }}, 352 &CompressCertificateExtension{[]CertCompressionAlgo{ 353 CertCompressionBrotli, 354 }}, 355 &GenericExtension{Id: 0x4469}, // WARNING: UNKNOWN EXTENSION, USE AT YOUR OWN RISK 356 &UtlsGREASEExtension{}, 357 &UtlsPaddingExtension{GetPaddingLen: BoringPaddingStyle}, 358 }, 359 }, nil 360 case HelloFirefox_55, HelloFirefox_56: 361 return ClientHelloSpec{ 362 TLSVersMax: VersionTLS12, 363 TLSVersMin: VersionTLS10, 364 CipherSuites: []uint16{ 365 TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, 366 TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256, 367 TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305, 368 TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305, 369 TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384, 370 TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384, 371 TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA, 372 TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA, 373 TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA, 374 TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA, 375 FAKE_TLS_DHE_RSA_WITH_AES_128_CBC_SHA, 376 FAKE_TLS_DHE_RSA_WITH_AES_256_CBC_SHA, 377 TLS_RSA_WITH_AES_128_CBC_SHA, 378 TLS_RSA_WITH_AES_256_CBC_SHA, 379 TLS_RSA_WITH_3DES_EDE_CBC_SHA, 380 }, 381 CompressionMethods: []byte{compressionNone}, 382 Extensions: []TLSExtension{ 383 &SNIExtension{}, 384 &UtlsExtendedMasterSecretExtension{}, 385 &RenegotiationInfoExtension{Renegotiation: RenegotiateOnceAsClient}, 386 &SupportedCurvesExtension{[]CurveID{X25519, CurveP256, CurveP384, CurveP521}}, 387 &SupportedPointsExtension{SupportedPoints: []byte{pointFormatUncompressed}}, 388 &SessionTicketExtension{}, 389 &ALPNExtension{AlpnProtocols: []string{"h2", "http/1.1"}}, 390 &StatusRequestExtension{}, 391 &SignatureAlgorithmsExtension{SupportedSignatureAlgorithms: []SignatureScheme{ 392 ECDSAWithP256AndSHA256, 393 ECDSAWithP384AndSHA384, 394 ECDSAWithP521AndSHA512, 395 PSSWithSHA256, 396 PSSWithSHA384, 397 PSSWithSHA512, 398 PKCS1WithSHA256, 399 PKCS1WithSHA384, 400 PKCS1WithSHA512, 401 ECDSAWithSHA1, 402 PKCS1WithSHA1}, 403 }, 404 &UtlsPaddingExtension{GetPaddingLen: BoringPaddingStyle}, 405 }, 406 GetSessionID: nil, 407 }, nil 408 case HelloFirefox_63, HelloFirefox_65: 409 return ClientHelloSpec{ 410 TLSVersMin: VersionTLS10, 411 TLSVersMax: VersionTLS13, 412 CipherSuites: []uint16{ 413 TLS_AES_128_GCM_SHA256, 414 TLS_CHACHA20_POLY1305_SHA256, 415 TLS_AES_256_GCM_SHA384, 416 TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, 417 TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256, 418 TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305, 419 TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305, 420 TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384, 421 TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384, 422 TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA, 423 TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA, 424 TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA, 425 TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA, 426 FAKE_TLS_DHE_RSA_WITH_AES_128_CBC_SHA, 427 FAKE_TLS_DHE_RSA_WITH_AES_256_CBC_SHA, 428 TLS_RSA_WITH_AES_128_CBC_SHA, 429 TLS_RSA_WITH_AES_256_CBC_SHA, 430 TLS_RSA_WITH_3DES_EDE_CBC_SHA, 431 }, 432 CompressionMethods: []byte{ 433 compressionNone, 434 }, 435 Extensions: []TLSExtension{ 436 &SNIExtension{}, 437 &UtlsExtendedMasterSecretExtension{}, 438 &RenegotiationInfoExtension{Renegotiation: RenegotiateOnceAsClient}, 439 &SupportedCurvesExtension{[]CurveID{ 440 X25519, 441 CurveP256, 442 CurveP384, 443 CurveP521, 444 CurveID(FakeFFDHE2048), 445 CurveID(FakeFFDHE3072), 446 }}, 447 &SupportedPointsExtension{SupportedPoints: []byte{ 448 pointFormatUncompressed, 449 }}, 450 &SessionTicketExtension{}, 451 &ALPNExtension{AlpnProtocols: []string{"h2", "http/1.1"}}, 452 &StatusRequestExtension{}, 453 &KeyShareExtension{[]KeyShare{ 454 {Group: X25519}, 455 {Group: CurveP256}, 456 }}, 457 &SupportedVersionsExtension{[]uint16{ 458 VersionTLS13, 459 VersionTLS12, 460 VersionTLS11, 461 VersionTLS10}}, 462 &SignatureAlgorithmsExtension{SupportedSignatureAlgorithms: []SignatureScheme{ 463 ECDSAWithP256AndSHA256, 464 ECDSAWithP384AndSHA384, 465 ECDSAWithP521AndSHA512, 466 PSSWithSHA256, 467 PSSWithSHA384, 468 PSSWithSHA512, 469 PKCS1WithSHA256, 470 PKCS1WithSHA384, 471 PKCS1WithSHA512, 472 ECDSAWithSHA1, 473 PKCS1WithSHA1, 474 }}, 475 &PSKKeyExchangeModesExtension{[]uint8{pskModeDHE}}, 476 &FakeRecordSizeLimitExtension{0x4001}, 477 &UtlsPaddingExtension{GetPaddingLen: BoringPaddingStyle}, 478 }}, nil 479 case HelloIOS_11_1: 480 return ClientHelloSpec{ 481 TLSVersMax: VersionTLS12, 482 TLSVersMin: VersionTLS10, 483 CipherSuites: []uint16{ 484 TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384, 485 TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, 486 DISABLED_TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384, 487 TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256, 488 TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA, 489 TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA, 490 TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305, 491 TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384, 492 TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256, 493 DISABLED_TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384, 494 TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256, 495 TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA, 496 TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA, 497 TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305, 498 TLS_RSA_WITH_AES_256_GCM_SHA384, 499 TLS_RSA_WITH_AES_128_GCM_SHA256, 500 DISABLED_TLS_RSA_WITH_AES_256_CBC_SHA256, 501 TLS_RSA_WITH_AES_128_CBC_SHA256, 502 TLS_RSA_WITH_AES_256_CBC_SHA, 503 TLS_RSA_WITH_AES_128_CBC_SHA, 504 }, 505 CompressionMethods: []byte{ 506 compressionNone, 507 }, 508 Extensions: []TLSExtension{ 509 &RenegotiationInfoExtension{Renegotiation: RenegotiateOnceAsClient}, 510 &SNIExtension{}, 511 &UtlsExtendedMasterSecretExtension{}, 512 &SignatureAlgorithmsExtension{SupportedSignatureAlgorithms: []SignatureScheme{ 513 ECDSAWithP256AndSHA256, 514 PSSWithSHA256, 515 PKCS1WithSHA256, 516 ECDSAWithP384AndSHA384, 517 PSSWithSHA384, 518 PKCS1WithSHA384, 519 PSSWithSHA512, 520 PKCS1WithSHA512, 521 PKCS1WithSHA1, 522 }}, 523 &StatusRequestExtension{}, 524 &NPNExtension{}, 525 &SCTExtension{}, 526 &ALPNExtension{AlpnProtocols: []string{"h2", "h2-16", "h2-15", "h2-14", "spdy/3.1", "spdy/3", "http/1.1"}}, 527 &SupportedPointsExtension{SupportedPoints: []byte{ 528 pointFormatUncompressed, 529 }}, 530 &SupportedCurvesExtension{Curves: []CurveID{ 531 X25519, 532 CurveP256, 533 CurveP384, 534 CurveP521, 535 }}, 536 }, 537 }, nil 538 case HelloIOS_12_1: 539 return ClientHelloSpec{ 540 CipherSuites: []uint16{ 541 TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384, 542 TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, 543 DISABLED_TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384, 544 TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256, 545 TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA, 546 TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA, 547 TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305, 548 TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384, 549 TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256, 550 DISABLED_TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384, 551 TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256, 552 TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA, 553 TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA, 554 TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305, 555 TLS_RSA_WITH_AES_256_GCM_SHA384, 556 TLS_RSA_WITH_AES_128_GCM_SHA256, 557 DISABLED_TLS_RSA_WITH_AES_256_CBC_SHA256, 558 TLS_RSA_WITH_AES_128_CBC_SHA256, 559 TLS_RSA_WITH_AES_256_CBC_SHA, 560 TLS_RSA_WITH_AES_128_CBC_SHA, 561 0xc008, 562 TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA, 563 TLS_RSA_WITH_3DES_EDE_CBC_SHA, 564 }, 565 CompressionMethods: []byte{ 566 compressionNone, 567 }, 568 Extensions: []TLSExtension{ 569 &RenegotiationInfoExtension{Renegotiation: RenegotiateOnceAsClient}, 570 &SNIExtension{}, 571 &UtlsExtendedMasterSecretExtension{}, 572 &SignatureAlgorithmsExtension{SupportedSignatureAlgorithms: []SignatureScheme{ 573 ECDSAWithP256AndSHA256, 574 PSSWithSHA256, 575 PKCS1WithSHA256, 576 ECDSAWithP384AndSHA384, 577 ECDSAWithSHA1, 578 PSSWithSHA384, 579 PSSWithSHA384, 580 PKCS1WithSHA384, 581 PSSWithSHA512, 582 PKCS1WithSHA512, 583 PKCS1WithSHA1, 584 }}, 585 &StatusRequestExtension{}, 586 &NPNExtension{}, 587 &SCTExtension{}, 588 &ALPNExtension{AlpnProtocols: []string{"h2", "h2-16", "h2-15", "h2-14", "spdy/3.1", "spdy/3", "http/1.1"}}, 589 &SupportedPointsExtension{SupportedPoints: []byte{ 590 pointFormatUncompressed, 591 }}, 592 &SupportedCurvesExtension{[]CurveID{ 593 X25519, 594 CurveP256, 595 CurveP384, 596 CurveP521, 597 }}, 598 }, 599 }, nil 600 default: 601 return ClientHelloSpec{}, errors.New("ClientHello ID " + id.Str() + " is unknown") 602 } 603 } 604 605 func (uconn *UConn) applyPresetByID(id ClientHelloID) (err error) { 606 var spec ClientHelloSpec 607 uconn.ClientHelloID = id 608 // choose/generate the spec 609 switch id.Client { 610 case helloRandomized, helloRandomizedNoALPN, helloRandomizedALPN: 611 spec, err = uconn.generateRandomizedSpec() 612 if err != nil { 613 return err 614 } 615 case helloCustom: 616 return nil 617 618 default: 619 spec, err = utlsIdToSpec(id) 620 if err != nil { 621 return err 622 } 623 } 624 625 return uconn.ApplyPreset(&spec) 626 } 627 628 // ApplyPreset should only be used in conjunction with HelloCustom to apply custom specs. 629 // Fields of TLSExtensions that are slices/pointers are shared across different connections with 630 // same ClientHelloSpec. It is advised to use different specs and avoid any shared state. 631 func (uconn *UConn) ApplyPreset(p *ClientHelloSpec) error { 632 var err error 633 634 err = uconn.SetTLSVers(p.TLSVersMin, p.TLSVersMax, p.Extensions) 635 if err != nil { 636 return err 637 } 638 639 privateHello, ecdheParams, err := uconn.makeClientHello() 640 if err != nil { 641 return err 642 } 643 uconn.HandshakeState.Hello = privateHello.getPublicPtr() 644 uconn.HandshakeState.State13.EcdheParams = ecdheParamMapToPublic(ecdheParams) 645 hello := uconn.HandshakeState.Hello 646 session := uconn.HandshakeState.Session 647 648 switch len(hello.Random) { 649 case 0: 650 hello.Random = make([]byte, 32) 651 _, err := io.ReadFull(uconn.config.rand(), hello.Random) 652 if err != nil { 653 return errors.New("tls: short read from Rand: " + err.Error()) 654 } 655 case 32: 656 // carry on 657 default: 658 return errors.New("ClientHello expected length: 32 bytes. Got: " + 659 strconv.Itoa(len(hello.Random)) + " bytes") 660 } 661 if len(hello.CipherSuites) == 0 { 662 hello.CipherSuites = defaultCipherSuites() 663 } 664 if len(hello.CompressionMethods) == 0 { 665 hello.CompressionMethods = []uint8{compressionNone} 666 } 667 668 // Currently, GREASE is assumed to come from BoringSSL 669 grease_bytes := make([]byte, 2*ssl_grease_last_index) 670 grease_extensions_seen := 0 671 _, err = io.ReadFull(uconn.config.rand(), grease_bytes) 672 if err != nil { 673 return errors.New("tls: short read from Rand: " + err.Error()) 674 } 675 for i := range uconn.greaseSeed { 676 uconn.greaseSeed[i] = binary.LittleEndian.Uint16(grease_bytes[2*i : 2*i+2]) 677 } 678 if uconn.greaseSeed[ssl_grease_extension1] == uconn.greaseSeed[ssl_grease_extension2] { 679 uconn.greaseSeed[ssl_grease_extension2] ^= 0x1010 680 } 681 682 hello.CipherSuites = make([]uint16, len(p.CipherSuites)) 683 copy(hello.CipherSuites, p.CipherSuites) 684 for i := range hello.CipherSuites { 685 if hello.CipherSuites[i] == GREASE_PLACEHOLDER { 686 hello.CipherSuites[i] = GetBoringGREASEValue(uconn.greaseSeed, ssl_grease_cipher) 687 } 688 } 689 uconn.GetSessionID = p.GetSessionID 690 uconn.Extensions = make([]TLSExtension, len(p.Extensions)) 691 copy(uconn.Extensions, p.Extensions) 692 693 // reGrease, and point things to each other 694 for _, e := range uconn.Extensions { 695 switch ext := e.(type) { 696 case *SNIExtension: 697 if ext.ServerName == "" { 698 ext.ServerName = uconn.config.ServerName 699 } 700 case *UtlsGREASEExtension: 701 switch grease_extensions_seen { 702 case 0: 703 ext.Value = GetBoringGREASEValue(uconn.greaseSeed, ssl_grease_extension1) 704 case 1: 705 ext.Value = GetBoringGREASEValue(uconn.greaseSeed, ssl_grease_extension2) 706 ext.Body = []byte{0} 707 default: 708 return errors.New("at most 2 grease extensions are supported") 709 } 710 grease_extensions_seen += 1 711 case *SessionTicketExtension: 712 if session == nil && uconn.config.ClientSessionCache != nil { 713 cacheKey := clientSessionCacheKey(uconn.RemoteAddr(), uconn.config) 714 session, _ = uconn.config.ClientSessionCache.Get(cacheKey) 715 // TODO: use uconn.loadSession(hello.getPrivateObj()) to support TLS 1.3 PSK-style resumption 716 } 717 err := uconn.SetSessionState(session) 718 if err != nil { 719 return err 720 } 721 case *SupportedCurvesExtension: 722 for i := range ext.Curves { 723 if ext.Curves[i] == GREASE_PLACEHOLDER { 724 ext.Curves[i] = CurveID(GetBoringGREASEValue(uconn.greaseSeed, ssl_grease_group)) 725 } 726 } 727 case *KeyShareExtension: 728 for i := range ext.KeyShares { 729 curveID := ext.KeyShares[i].Group 730 if curveID == GREASE_PLACEHOLDER { 731 ext.KeyShares[i].Group = CurveID(GetBoringGREASEValue(uconn.greaseSeed, ssl_grease_group)) 732 continue 733 } 734 if len(ext.KeyShares[i].Data) > 1 { 735 continue 736 } 737 738 var params ecdheParameters 739 switch utlsSupportedGroups[curveID] { 740 case true: 741 var ok bool 742 params, ok = uconn.HandshakeState.State13.EcdheParams[curveID] 743 if !ok { 744 // Should never happen. 745 return fmt.Errorf("BUG: unsupported Curve in KeyShareExtension: %v.", curveID) 746 } 747 case false: 748 var err error 749 params, err = generateECDHEParameters(uconn.config.rand(), curveID) 750 if err != nil { 751 return fmt.Errorf("unsupported Curve in KeyShareExtension: %v."+ 752 "To mimic it, fill the Data(key) field manually.", curveID) 753 } 754 } 755 756 ext.KeyShares[i].Data = params.PublicKey() 757 } 758 case *SupportedVersionsExtension: 759 for i := range ext.Versions { 760 if ext.Versions[i] == GREASE_PLACEHOLDER { 761 ext.Versions[i] = GetBoringGREASEValue(uconn.greaseSeed, ssl_grease_version) 762 } 763 } 764 case *CompressCertificateExtension: 765 uconn.HandshakeState.State13.CertCompAlgs = ext.Algorithms 766 } 767 } 768 return nil 769 } 770 771 func (uconn *UConn) generateRandomizedSpec() (ClientHelloSpec, error) { 772 p := ClientHelloSpec{} 773 774 if uconn.ClientHelloID.Seed == nil { 775 seed, err := NewPRNGSeed() 776 if err != nil { 777 return p, err 778 } 779 uconn.ClientHelloID.Seed = seed 780 } 781 782 r, err := newPRNGWithSeed(uconn.ClientHelloID.Seed) 783 if err != nil { 784 return p, err 785 } 786 787 id := uconn.ClientHelloID 788 789 var WithALPN bool 790 switch id.Client { 791 case helloRandomizedALPN: 792 WithALPN = true 793 case helloRandomizedNoALPN: 794 WithALPN = false 795 case helloRandomized: 796 if r.FlipWeightedCoin(0.7) { 797 WithALPN = true 798 } else { 799 WithALPN = false 800 } 801 default: 802 return p, fmt.Errorf("using non-randomized ClientHelloID %v to generate randomized spec", id.Client) 803 } 804 805 p.CipherSuites = make([]uint16, len(defaultCipherSuites())) 806 copy(p.CipherSuites, defaultCipherSuites()) 807 shuffledSuites, err := shuffledCiphers(r) 808 if err != nil { 809 return p, err 810 } 811 812 if r.FlipWeightedCoin(0.4) { 813 p.TLSVersMin = VersionTLS10 814 p.TLSVersMax = VersionTLS13 815 tls13ciphers := make([]uint16, len(defaultCipherSuitesTLS13())) 816 copy(tls13ciphers, defaultCipherSuitesTLS13()) 817 r.rand.Shuffle(len(tls13ciphers), func(i, j int) { 818 tls13ciphers[i], tls13ciphers[j] = tls13ciphers[j], tls13ciphers[i] 819 }) 820 // appending TLS 1.3 ciphers before TLS 1.2, since that's what popular implementations do 821 shuffledSuites = append(tls13ciphers, shuffledSuites...) 822 823 // TLS 1.3 forbids RC4 in any configurations 824 shuffledSuites = removeRC4Ciphers(shuffledSuites) 825 } else { 826 p.TLSVersMin = VersionTLS10 827 p.TLSVersMax = VersionTLS12 828 } 829 830 p.CipherSuites = removeRandomCiphers(r, shuffledSuites, 0.4) 831 832 sni := SNIExtension{uconn.config.ServerName} 833 sessionTicket := SessionTicketExtension{Session: uconn.HandshakeState.Session} 834 835 sigAndHashAlgos := []SignatureScheme{ 836 ECDSAWithP256AndSHA256, 837 PKCS1WithSHA256, 838 ECDSAWithP384AndSHA384, 839 PKCS1WithSHA384, 840 PKCS1WithSHA1, 841 PKCS1WithSHA512, 842 } 843 844 if r.FlipWeightedCoin(0.63) { 845 sigAndHashAlgos = append(sigAndHashAlgos, ECDSAWithSHA1) 846 } 847 if r.FlipWeightedCoin(0.59) { 848 sigAndHashAlgos = append(sigAndHashAlgos, ECDSAWithP521AndSHA512) 849 } 850 if r.FlipWeightedCoin(0.51) || p.TLSVersMax == VersionTLS13 { 851 // https://tools.ietf.org/html/rfc8446 says "...RSASSA-PSS (which is mandatory in TLS 1.3)..." 852 sigAndHashAlgos = append(sigAndHashAlgos, PSSWithSHA256) 853 if r.FlipWeightedCoin(0.9) { 854 // these usually go together 855 sigAndHashAlgos = append(sigAndHashAlgos, PSSWithSHA384) 856 sigAndHashAlgos = append(sigAndHashAlgos, PSSWithSHA512) 857 } 858 } 859 860 r.rand.Shuffle(len(sigAndHashAlgos), func(i, j int) { 861 sigAndHashAlgos[i], sigAndHashAlgos[j] = sigAndHashAlgos[j], sigAndHashAlgos[i] 862 }) 863 sigAndHash := SignatureAlgorithmsExtension{SupportedSignatureAlgorithms: sigAndHashAlgos} 864 865 status := StatusRequestExtension{} 866 sct := SCTExtension{} 867 ems := UtlsExtendedMasterSecretExtension{} 868 points := SupportedPointsExtension{SupportedPoints: []byte{pointFormatUncompressed}} 869 870 curveIDs := []CurveID{} 871 if r.FlipWeightedCoin(0.71) || p.TLSVersMax == VersionTLS13 { 872 curveIDs = append(curveIDs, X25519) 873 } 874 curveIDs = append(curveIDs, CurveP256, CurveP384) 875 if r.FlipWeightedCoin(0.46) { 876 curveIDs = append(curveIDs, CurveP521) 877 } 878 879 curves := SupportedCurvesExtension{curveIDs} 880 881 padding := UtlsPaddingExtension{GetPaddingLen: BoringPaddingStyle} 882 reneg := RenegotiationInfoExtension{Renegotiation: RenegotiateOnceAsClient} 883 884 p.Extensions = []TLSExtension{ 885 &sni, 886 &sessionTicket, 887 &sigAndHash, 888 &points, 889 &curves, 890 } 891 892 if WithALPN { 893 if len(uconn.config.NextProtos) == 0 { 894 // if user didn't specify alpn yet, choose something popular 895 uconn.config.NextProtos = []string{"h2", "http/1.1"} 896 } 897 alpn := ALPNExtension{AlpnProtocols: uconn.config.NextProtos} 898 p.Extensions = append(p.Extensions, &alpn) 899 } 900 901 if r.FlipWeightedCoin(0.62) || p.TLSVersMax == VersionTLS13 { 902 // always include for TLS 1.3, since TLS 1.3 ClientHellos are often over 256 bytes 903 // and that's when padding is required to work around buggy middleboxes 904 p.Extensions = append(p.Extensions, &padding) 905 } 906 if r.FlipWeightedCoin(0.74) { 907 p.Extensions = append(p.Extensions, &status) 908 } 909 if r.FlipWeightedCoin(0.46) { 910 p.Extensions = append(p.Extensions, &sct) 911 } 912 if r.FlipWeightedCoin(0.75) { 913 p.Extensions = append(p.Extensions, &reneg) 914 } 915 if r.FlipWeightedCoin(0.77) { 916 p.Extensions = append(p.Extensions, &ems) 917 } 918 if p.TLSVersMax == VersionTLS13 { 919 ks := KeyShareExtension{[]KeyShare{ 920 {Group: X25519}, // the key for the group will be generated later 921 }} 922 if r.FlipWeightedCoin(0.25) { 923 ks.KeyShares = append(ks.KeyShares, KeyShare{Group: CurveP256}) 924 } 925 pskExchangeModes := PSKKeyExchangeModesExtension{[]uint8{pskModeDHE}} 926 supportedVersionsExt := SupportedVersionsExtension{ 927 Versions: makeSupportedVersions(p.TLSVersMin, p.TLSVersMax), 928 } 929 p.Extensions = append(p.Extensions, &ks, &pskExchangeModes, &supportedVersionsExt) 930 } 931 r.rand.Shuffle(len(p.Extensions), func(i, j int) { 932 p.Extensions[i], p.Extensions[j] = p.Extensions[j], p.Extensions[i] 933 }) 934 935 return p, nil 936 } 937 938 func removeRandomCiphers(r *prng, s []uint16, maxRemovalProbability float64) []uint16 { 939 // removes elements in place 940 // probability to remove increases for further elements 941 // never remove first cipher 942 if len(s) <= 1 { 943 return s 944 } 945 946 // remove random elements 947 floatLen := float64(len(s)) 948 sliceLen := len(s) 949 for i := 1; i < sliceLen; i++ { 950 if r.FlipWeightedCoin(maxRemovalProbability * float64(i) / floatLen) { 951 s = append(s[:i], s[i+1:]...) 952 sliceLen-- 953 i-- 954 } 955 } 956 return s[:sliceLen] 957 } 958 959 func shuffledCiphers(r *prng) ([]uint16, error) { 960 ciphers := make(sortableCiphers, len(cipherSuites)) 961 perm := r.Perm(len(cipherSuites)) 962 for i, suite := range cipherSuites { 963 ciphers[i] = sortableCipher{suite: suite.id, 964 isObsolete: ((suite.flags & suiteTLS12) == 0), 965 randomTag: perm[i]} 966 } 967 sort.Sort(ciphers) 968 return ciphers.GetCiphers(), nil 969 } 970 971 type sortableCipher struct { 972 isObsolete bool 973 randomTag int 974 suite uint16 975 } 976 977 type sortableCiphers []sortableCipher 978 979 func (ciphers sortableCiphers) Len() int { 980 return len(ciphers) 981 } 982 983 func (ciphers sortableCiphers) Less(i, j int) bool { 984 if ciphers[i].isObsolete && !ciphers[j].isObsolete { 985 return false 986 } 987 if ciphers[j].isObsolete && !ciphers[i].isObsolete { 988 return true 989 } 990 return ciphers[i].randomTag < ciphers[j].randomTag 991 } 992 993 func (ciphers sortableCiphers) Swap(i, j int) { 994 ciphers[i], ciphers[j] = ciphers[j], ciphers[i] 995 } 996 997 func (ciphers sortableCiphers) GetCiphers() []uint16 { 998 cipherIDs := make([]uint16, len(ciphers)) 999 for i := range ciphers { 1000 cipherIDs[i] = ciphers[i].suite 1001 } 1002 return cipherIDs 1003 } 1004 1005 func removeRC4Ciphers(s []uint16) []uint16 { 1006 // removes elements in place 1007 sliceLen := len(s) 1008 for i := 0; i < sliceLen; i++ { 1009 cipher := s[i] 1010 if cipher == TLS_ECDHE_ECDSA_WITH_RC4_128_SHA || 1011 cipher == TLS_ECDHE_RSA_WITH_RC4_128_SHA || 1012 cipher == TLS_RSA_WITH_RC4_128_SHA { 1013 s = append(s[:i], s[i+1:]...) 1014 sliceLen-- 1015 i-- 1016 } 1017 } 1018 return s[:sliceLen] 1019 }