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/sha256" 9 "encoding/binary" 10 "errors" 11 "fmt" 12 "io" 13 "sort" 14 "strconv" 15) 16 17func 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 HelloFirefox_55, HelloFirefox_56: 218 return ClientHelloSpec{ 219 TLSVersMax: VersionTLS12, 220 TLSVersMin: VersionTLS10, 221 CipherSuites: []uint16{ 222 TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, 223 TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256, 224 TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305, 225 TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305, 226 TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384, 227 TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384, 228 TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA, 229 TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA, 230 TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA, 231 TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA, 232 FAKE_TLS_DHE_RSA_WITH_AES_128_CBC_SHA, 233 FAKE_TLS_DHE_RSA_WITH_AES_256_CBC_SHA, 234 TLS_RSA_WITH_AES_128_CBC_SHA, 235 TLS_RSA_WITH_AES_256_CBC_SHA, 236 TLS_RSA_WITH_3DES_EDE_CBC_SHA, 237 }, 238 CompressionMethods: []byte{compressionNone}, 239 Extensions: []TLSExtension{ 240 &SNIExtension{}, 241 &UtlsExtendedMasterSecretExtension{}, 242 &RenegotiationInfoExtension{renegotiation: RenegotiateOnceAsClient}, 243 &SupportedCurvesExtension{[]CurveID{X25519, CurveP256, CurveP384, CurveP521}}, 244 &SupportedPointsExtension{SupportedPoints: []byte{pointFormatUncompressed}}, 245 &SessionTicketExtension{}, 246 &ALPNExtension{AlpnProtocols: []string{"h2", "http/1.1"}}, 247 &StatusRequestExtension{}, 248 &SignatureAlgorithmsExtension{SupportedSignatureAlgorithms: []SignatureScheme{ 249 ECDSAWithP256AndSHA256, 250 ECDSAWithP384AndSHA384, 251 ECDSAWithP521AndSHA512, 252 PSSWithSHA256, 253 PSSWithSHA384, 254 PSSWithSHA512, 255 PKCS1WithSHA256, 256 PKCS1WithSHA384, 257 PKCS1WithSHA512, 258 ECDSAWithSHA1, 259 PKCS1WithSHA1}, 260 }, 261 &UtlsPaddingExtension{GetPaddingLen: BoringPaddingStyle}, 262 }, 263 GetSessionID: nil, 264 }, nil 265 case HelloFirefox_63, HelloFirefox_65: 266 return ClientHelloSpec{ 267 TLSVersMin: VersionTLS10, 268 TLSVersMax: VersionTLS13, 269 CipherSuites: []uint16{ 270 TLS_AES_128_GCM_SHA256, 271 TLS_CHACHA20_POLY1305_SHA256, 272 TLS_AES_256_GCM_SHA384, 273 TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, 274 TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256, 275 TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305, 276 TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305, 277 TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384, 278 TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384, 279 TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA, 280 TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA, 281 TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA, 282 TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA, 283 FAKE_TLS_DHE_RSA_WITH_AES_128_CBC_SHA, 284 FAKE_TLS_DHE_RSA_WITH_AES_256_CBC_SHA, 285 TLS_RSA_WITH_AES_128_CBC_SHA, 286 TLS_RSA_WITH_AES_256_CBC_SHA, 287 TLS_RSA_WITH_3DES_EDE_CBC_SHA, 288 }, 289 CompressionMethods: []byte{ 290 compressionNone, 291 }, 292 Extensions: []TLSExtension{ 293 &SNIExtension{}, 294 &UtlsExtendedMasterSecretExtension{}, 295 &RenegotiationInfoExtension{renegotiation: RenegotiateOnceAsClient}, 296 &SupportedCurvesExtension{[]CurveID{ 297 X25519, 298 CurveP256, 299 CurveP384, 300 CurveP521, 301 CurveID(FakeFFDHE2048), 302 CurveID(FakeFFDHE3072), 303 }}, 304 &SupportedPointsExtension{SupportedPoints: []byte{ 305 pointFormatUncompressed, 306 }}, 307 &SessionTicketExtension{}, 308 &ALPNExtension{AlpnProtocols: []string{"h2", "http/1.1"}}, 309 &StatusRequestExtension{}, 310 &KeyShareExtension{[]KeyShare{ 311 {Group: X25519}, 312 {Group: CurveP256}, 313 }}, 314 &SupportedVersionsExtension{[]uint16{ 315 VersionTLS13, 316 VersionTLS12, 317 VersionTLS11, 318 VersionTLS10}}, 319 &SignatureAlgorithmsExtension{SupportedSignatureAlgorithms: []SignatureScheme{ 320 ECDSAWithP256AndSHA256, 321 ECDSAWithP384AndSHA384, 322 ECDSAWithP521AndSHA512, 323 PSSWithSHA256, 324 PSSWithSHA384, 325 PSSWithSHA512, 326 PKCS1WithSHA256, 327 PKCS1WithSHA384, 328 PKCS1WithSHA512, 329 ECDSAWithSHA1, 330 PKCS1WithSHA1, 331 }}, 332 &PSKKeyExchangeModesExtension{[]uint8{pskModeDHE}}, 333 &FakeRecordSizeLimitExtension{0x4001}, 334 &UtlsPaddingExtension{GetPaddingLen: BoringPaddingStyle}, 335 }}, nil 336 case HelloIOS_11_1: 337 return ClientHelloSpec{ 338 TLSVersMax: VersionTLS12, 339 TLSVersMin: VersionTLS10, 340 CipherSuites: []uint16{ 341 TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384, 342 TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, 343 DISABLED_TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384, 344 TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256, 345 TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA, 346 TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA, 347 TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305, 348 TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384, 349 TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256, 350 DISABLED_TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384, 351 TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256, 352 TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA, 353 TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA, 354 TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305, 355 TLS_RSA_WITH_AES_256_GCM_SHA384, 356 TLS_RSA_WITH_AES_128_GCM_SHA256, 357 DISABLED_TLS_RSA_WITH_AES_256_CBC_SHA256, 358 TLS_RSA_WITH_AES_128_CBC_SHA256, 359 TLS_RSA_WITH_AES_256_CBC_SHA, 360 TLS_RSA_WITH_AES_128_CBC_SHA, 361 }, 362 CompressionMethods: []byte{ 363 compressionNone, 364 }, 365 Extensions: []TLSExtension{ 366 &RenegotiationInfoExtension{renegotiation: RenegotiateOnceAsClient}, 367 &SNIExtension{}, 368 &UtlsExtendedMasterSecretExtension{}, 369 &SignatureAlgorithmsExtension{SupportedSignatureAlgorithms: []SignatureScheme{ 370 ECDSAWithP256AndSHA256, 371 PSSWithSHA256, 372 PKCS1WithSHA256, 373 ECDSAWithP384AndSHA384, 374 PSSWithSHA384, 375 PKCS1WithSHA384, 376 PSSWithSHA512, 377 PKCS1WithSHA512, 378 PKCS1WithSHA1, 379 }}, 380 &StatusRequestExtension{}, 381 &NPNExtension{}, 382 &SCTExtension{}, 383 &ALPNExtension{AlpnProtocols: []string{"h2", "h2-16", "h2-15", "h2-14", "spdy/3.1", "spdy/3", "http/1.1"}}, 384 &SupportedPointsExtension{SupportedPoints: []byte{ 385 pointFormatUncompressed, 386 }}, 387 &SupportedCurvesExtension{Curves: []CurveID{ 388 X25519, 389 CurveP256, 390 CurveP384, 391 CurveP521, 392 }}, 393 }, 394 }, nil 395 case HelloIOS_12_1: 396 return ClientHelloSpec{ 397 CipherSuites: []uint16{ 398 TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384, 399 TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, 400 DISABLED_TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384, 401 TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256, 402 TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA, 403 TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA, 404 TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305, 405 TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384, 406 TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256, 407 DISABLED_TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384, 408 TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256, 409 TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA, 410 TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA, 411 TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305, 412 TLS_RSA_WITH_AES_256_GCM_SHA384, 413 TLS_RSA_WITH_AES_128_GCM_SHA256, 414 DISABLED_TLS_RSA_WITH_AES_256_CBC_SHA256, 415 TLS_RSA_WITH_AES_128_CBC_SHA256, 416 TLS_RSA_WITH_AES_256_CBC_SHA, 417 TLS_RSA_WITH_AES_128_CBC_SHA, 418 0xc008, 419 TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA, 420 TLS_RSA_WITH_3DES_EDE_CBC_SHA, 421 }, 422 CompressionMethods: []byte{ 423 compressionNone, 424 }, 425 Extensions: []TLSExtension{ 426 &RenegotiationInfoExtension{renegotiation: RenegotiateOnceAsClient}, 427 &SNIExtension{}, 428 &UtlsExtendedMasterSecretExtension{}, 429 &SignatureAlgorithmsExtension{SupportedSignatureAlgorithms: []SignatureScheme{ 430 ECDSAWithP256AndSHA256, 431 PSSWithSHA256, 432 PKCS1WithSHA256, 433 ECDSAWithP384AndSHA384, 434 ECDSAWithSHA1, 435 PSSWithSHA384, 436 PSSWithSHA384, 437 PKCS1WithSHA384, 438 PSSWithSHA512, 439 PKCS1WithSHA512, 440 PKCS1WithSHA1, 441 }}, 442 &StatusRequestExtension{}, 443 &NPNExtension{}, 444 &SCTExtension{}, 445 &ALPNExtension{AlpnProtocols: []string{"h2", "h2-16", "h2-15", "h2-14", "spdy/3.1", "spdy/3", "http/1.1"}}, 446 &SupportedPointsExtension{SupportedPoints: []byte{ 447 pointFormatUncompressed, 448 }}, 449 &SupportedCurvesExtension{[]CurveID{ 450 X25519, 451 CurveP256, 452 CurveP384, 453 CurveP521, 454 }}, 455 }, 456 }, nil 457 default: 458 return ClientHelloSpec{}, errors.New("ClientHello ID " + id.Str() + " is unknown") 459 } 460} 461 462func (uconn *UConn) applyPresetByID(id ClientHelloID) (err error) { 463 var spec ClientHelloSpec 464 uconn.ClientHelloID = id 465 // choose/generate the spec 466 switch id.Client { 467 case helloRandomized, helloRandomizedNoALPN, helloRandomizedALPN: 468 spec, err = uconn.generateRandomizedSpec() 469 if err != nil { 470 return err 471 } 472 case helloCustom: 473 return nil 474 475 default: 476 spec, err = utlsIdToSpec(id) 477 if err != nil { 478 return err 479 } 480 } 481 482 return uconn.ApplyPreset(&spec) 483} 484 485// ApplyPreset should only be used in conjunction with HelloCustom to apply custom specs. 486// Fields of TLSExtensions that are slices/pointers are shared across different connections with 487// same ClientHelloSpec. It is advised to use different specs and avoid any shared state. 488func (uconn *UConn) ApplyPreset(p *ClientHelloSpec) error { 489 var err error 490 491 err = uconn.SetTLSVers(p.TLSVersMin, p.TLSVersMax, p.Extensions) 492 if err != nil { 493 return err 494 } 495 496 privateHello, ecdheParams, err := uconn.makeClientHello() 497 if err != nil { 498 return err 499 } 500 uconn.HandshakeState.Hello = privateHello.getPublicPtr() 501 uconn.HandshakeState.State13.EcdheParams = ecdheParamMapToPublic(ecdheParams) 502 hello := uconn.HandshakeState.Hello 503 session := uconn.HandshakeState.Session 504 505 switch len(hello.Random) { 506 case 0: 507 hello.Random = make([]byte, 32) 508 _, err := io.ReadFull(uconn.config.rand(), hello.Random) 509 if err != nil { 510 return errors.New("tls: short read from Rand: " + err.Error()) 511 } 512 case 32: 513 // carry on 514 default: 515 return errors.New("ClientHello expected length: 32 bytes. Got: " + 516 strconv.Itoa(len(hello.Random)) + " bytes") 517 } 518 if len(hello.CipherSuites) == 0 { 519 hello.CipherSuites = defaultCipherSuites() 520 } 521 if len(hello.CompressionMethods) == 0 { 522 hello.CompressionMethods = []uint8{compressionNone} 523 } 524 525 // Currently, GREASE is assumed to come from BoringSSL 526 grease_bytes := make([]byte, 2*ssl_grease_last_index) 527 grease_extensions_seen := 0 528 _, err = io.ReadFull(uconn.config.rand(), grease_bytes) 529 if err != nil { 530 return errors.New("tls: short read from Rand: " + err.Error()) 531 } 532 for i := range uconn.greaseSeed { 533 uconn.greaseSeed[i] = binary.LittleEndian.Uint16(grease_bytes[2*i : 2*i+2]) 534 } 535 if uconn.greaseSeed[ssl_grease_extension1] == uconn.greaseSeed[ssl_grease_extension2] { 536 uconn.greaseSeed[ssl_grease_extension2] ^= 0x1010 537 } 538 539 hello.CipherSuites = make([]uint16, len(p.CipherSuites)) 540 copy(hello.CipherSuites, p.CipherSuites) 541 for i := range hello.CipherSuites { 542 if hello.CipherSuites[i] == GREASE_PLACEHOLDER { 543 hello.CipherSuites[i] = GetBoringGREASEValue(uconn.greaseSeed, ssl_grease_cipher) 544 } 545 } 546 uconn.GetSessionID = p.GetSessionID 547 uconn.Extensions = make([]TLSExtension, len(p.Extensions)) 548 copy(uconn.Extensions, p.Extensions) 549 550 // reGrease, and point things to each other 551 for _, e := range uconn.Extensions { 552 switch ext := e.(type) { 553 case *SNIExtension: 554 if ext.ServerName == "" { 555 ext.ServerName = uconn.config.ServerName 556 } 557 case *UtlsGREASEExtension: 558 switch grease_extensions_seen { 559 case 0: 560 ext.Value = GetBoringGREASEValue(uconn.greaseSeed, ssl_grease_extension1) 561 case 1: 562 ext.Value = GetBoringGREASEValue(uconn.greaseSeed, ssl_grease_extension2) 563 ext.Body = []byte{0} 564 default: 565 return errors.New("at most 2 grease extensions are supported") 566 } 567 grease_extensions_seen += 1 568 case *SessionTicketExtension: 569 if session == nil && uconn.config.ClientSessionCache != nil { 570 cacheKey := clientSessionCacheKey(uconn.RemoteAddr(), uconn.config) 571 session, _ = uconn.config.ClientSessionCache.Get(cacheKey) 572 // TODO: use uconn.loadSession(hello.getPrivateObj()) to support TLS 1.3 PSK-style resumption 573 } 574 err := uconn.SetSessionState(session) 575 if err != nil { 576 return err 577 } 578 case *SupportedCurvesExtension: 579 for i := range ext.Curves { 580 if ext.Curves[i] == GREASE_PLACEHOLDER { 581 ext.Curves[i] = CurveID(GetBoringGREASEValue(uconn.greaseSeed, ssl_grease_group)) 582 } 583 } 584 case *KeyShareExtension: 585 for i := range ext.KeyShares { 586 curveID := ext.KeyShares[i].Group 587 if curveID == GREASE_PLACEHOLDER { 588 ext.KeyShares[i].Group = CurveID(GetBoringGREASEValue(uconn.greaseSeed, ssl_grease_group)) 589 continue 590 } 591 if len(ext.KeyShares[i].Data) > 1 { 592 continue 593 } 594 595 var params ecdheParameters 596 switch utlsSupportedGroups[curveID] { 597 case true: 598 var ok bool 599 params, ok = uconn.HandshakeState.State13.EcdheParams[curveID] 600 if !ok { 601 // Should never happen. 602 return fmt.Errorf("BUG: unsupported Curve in KeyShareExtension: %v.", curveID) 603 } 604 case false: 605 var err error 606 params, err = generateECDHEParameters(uconn.config.rand(), curveID) 607 if err != nil { 608 return fmt.Errorf("unsupported Curve in KeyShareExtension: %v."+ 609 "To mimic it, fill the Data(key) field manually.", curveID) 610 } 611 } 612 613 ext.KeyShares[i].Data = params.PublicKey() 614 } 615 case *SupportedVersionsExtension: 616 for i := range ext.Versions { 617 if ext.Versions[i] == GREASE_PLACEHOLDER { 618 ext.Versions[i] = GetBoringGREASEValue(uconn.greaseSeed, ssl_grease_version) 619 } 620 } 621 case *CompressCertificateExtension: 622 uconn.HandshakeState.State13.CertCompAlgs = ext.Algorithms 623 } 624 } 625 return nil 626} 627 628func (uconn *UConn) generateRandomizedSpec() (ClientHelloSpec, error) { 629 p := ClientHelloSpec{} 630 631 if uconn.ClientHelloID.Seed == nil { 632 seed, err := NewPRNGSeed() 633 if err != nil { 634 return p, err 635 } 636 uconn.ClientHelloID.Seed = seed 637 } 638 639 r := newPRNGWithSeed(uconn.ClientHelloID.Seed) 640 641 id := uconn.ClientHelloID 642 643 var WithALPN bool 644 switch id.Client { 645 case helloRandomizedALPN: 646 WithALPN = true 647 case helloRandomizedNoALPN: 648 WithALPN = false 649 case helloRandomized: 650 if r.FlipWeightedCoin(0.7) { 651 WithALPN = true 652 } else { 653 WithALPN = false 654 } 655 default: 656 return p, fmt.Errorf("using non-randomized ClientHelloID %v to generate randomized spec", id.Client) 657 } 658 659 p.CipherSuites = make([]uint16, len(defaultCipherSuites())) 660 copy(p.CipherSuites, defaultCipherSuites()) 661 shuffledSuites, err := shuffledCiphers(r) 662 if err != nil { 663 return p, err 664 } 665 666 if r.FlipWeightedCoin(0.4) { 667 p.TLSVersMin = VersionTLS10 668 p.TLSVersMax = VersionTLS13 669 tls13ciphers := make([]uint16, len(defaultCipherSuitesTLS13())) 670 copy(tls13ciphers, defaultCipherSuitesTLS13()) 671 r.rand.Shuffle(len(tls13ciphers), func(i, j int) { 672 tls13ciphers[i], tls13ciphers[j] = tls13ciphers[j], tls13ciphers[i] 673 }) 674 // appending TLS 1.3 ciphers before TLS 1.2, since that's what popular implementations do 675 shuffledSuites = append(tls13ciphers, shuffledSuites...) 676 677 // TLS 1.3 forbids RC4 in any configurations 678 shuffledSuites = removeRC4Ciphers(shuffledSuites) 679 } else { 680 p.TLSVersMin = VersionTLS10 681 p.TLSVersMax = VersionTLS12 682 } 683 684 p.CipherSuites = removeRandomCiphers(r, shuffledSuites, 0.4) 685 686 sni := SNIExtension{uconn.config.ServerName} 687 sessionTicket := SessionTicketExtension{Session: uconn.HandshakeState.Session} 688 689 sigAndHashAlgos := []SignatureScheme{ 690 ECDSAWithP256AndSHA256, 691 PKCS1WithSHA256, 692 ECDSAWithP384AndSHA384, 693 PKCS1WithSHA384, 694 PKCS1WithSHA1, 695 PKCS1WithSHA512, 696 } 697 698 if r.FlipWeightedCoin(0.63) { 699 sigAndHashAlgos = append(sigAndHashAlgos, ECDSAWithSHA1) 700 } 701 if r.FlipWeightedCoin(0.59) { 702 sigAndHashAlgos = append(sigAndHashAlgos, ECDSAWithP521AndSHA512) 703 } 704 if r.FlipWeightedCoin(0.51) || p.TLSVersMax == VersionTLS13 { 705 // https://tools.ietf.org/html/rfc8446 says "...RSASSA-PSS (which is mandatory in TLS 1.3)..." 706 sigAndHashAlgos = append(sigAndHashAlgos, PSSWithSHA256) 707 if r.FlipWeightedCoin(0.9) { 708 // these usually go together 709 sigAndHashAlgos = append(sigAndHashAlgos, PSSWithSHA384) 710 sigAndHashAlgos = append(sigAndHashAlgos, PSSWithSHA512) 711 } 712 } 713 714 r.rand.Shuffle(len(sigAndHashAlgos), func(i, j int) { 715 sigAndHashAlgos[i], sigAndHashAlgos[j] = sigAndHashAlgos[j], sigAndHashAlgos[i] 716 }) 717 sigAndHash := SignatureAlgorithmsExtension{SupportedSignatureAlgorithms: sigAndHashAlgos} 718 719 status := StatusRequestExtension{} 720 sct := SCTExtension{} 721 ems := UtlsExtendedMasterSecretExtension{} 722 points := SupportedPointsExtension{SupportedPoints: []byte{pointFormatUncompressed}} 723 724 curveIDs := []CurveID{} 725 if r.FlipWeightedCoin(0.71) || p.TLSVersMax == VersionTLS13 { 726 curveIDs = append(curveIDs, X25519) 727 } 728 curveIDs = append(curveIDs, CurveP256, CurveP384) 729 if r.FlipWeightedCoin(0.46) { 730 curveIDs = append(curveIDs, CurveP521) 731 } 732 733 curves := SupportedCurvesExtension{curveIDs} 734 735 padding := UtlsPaddingExtension{GetPaddingLen: BoringPaddingStyle} 736 reneg := RenegotiationInfoExtension{renegotiation: RenegotiateOnceAsClient} 737 738 p.Extensions = []TLSExtension{ 739 &sni, 740 &sessionTicket, 741 &sigAndHash, 742 &points, 743 &curves, 744 } 745 746 if WithALPN { 747 if len(uconn.config.NextProtos) == 0 { 748 // if user didn't specify alpn yet, choose something popular 749 uconn.config.NextProtos = []string{"h2", "http/1.1"} 750 } 751 alpn := ALPNExtension{AlpnProtocols: uconn.config.NextProtos} 752 p.Extensions = append(p.Extensions, &alpn) 753 } 754 755 if r.FlipWeightedCoin(0.62) || p.TLSVersMax == VersionTLS13 { 756 // always include for TLS 1.3, since TLS 1.3 ClientHellos are often over 256 bytes 757 // and that's when padding is required to work around buggy middleboxes 758 p.Extensions = append(p.Extensions, &padding) 759 } 760 if r.FlipWeightedCoin(0.74) { 761 p.Extensions = append(p.Extensions, &status) 762 } 763 if r.FlipWeightedCoin(0.46) { 764 p.Extensions = append(p.Extensions, &sct) 765 } 766 if r.FlipWeightedCoin(0.75) { 767 p.Extensions = append(p.Extensions, &reneg) 768 } 769 if r.FlipWeightedCoin(0.77) { 770 p.Extensions = append(p.Extensions, &ems) 771 } 772 if p.TLSVersMax == VersionTLS13 { 773 ks := KeyShareExtension{[]KeyShare{ 774 {Group: X25519}, // the key for the group will be generated later 775 }} 776 if r.FlipWeightedCoin(0.25) { 777 ks.KeyShares = append(ks.KeyShares, KeyShare{Group: CurveP256}) 778 } 779 pskExchangeModes := PSKKeyExchangeModesExtension{[]uint8{pskModeDHE}} 780 supportedVersionsExt := SupportedVersionsExtension{ 781 Versions: makeSupportedVersions(p.TLSVersMin, p.TLSVersMax), 782 } 783 p.Extensions = append(p.Extensions, &ks, &pskExchangeModes, &supportedVersionsExt) 784 } 785 r.rand.Shuffle(len(p.Extensions), func(i, j int) { 786 p.Extensions[i], p.Extensions[j] = p.Extensions[j], p.Extensions[i] 787 }) 788 789 return p, nil 790} 791 792func removeRandomCiphers(r *prng, s []uint16, maxRemovalProbability float64) []uint16 { 793 // removes elements in place 794 // probability to remove increases for further elements 795 // never remove first cipher 796 if len(s) <= 1 { 797 return s 798 } 799 800 // remove random elements 801 floatLen := float64(len(s)) 802 sliceLen := len(s) 803 for i := 1; i < sliceLen; i++ { 804 if r.FlipWeightedCoin(maxRemovalProbability * float64(i) / floatLen) { 805 s = append(s[:i], s[i+1:]...) 806 sliceLen-- 807 i-- 808 } 809 } 810 return s[:sliceLen] 811} 812 813func shuffledCiphers(r *prng) ([]uint16, error) { 814 ciphers := make(sortableCiphers, len(cipherSuites)) 815 perm := r.Perm(len(cipherSuites)) 816 for i, suite := range cipherSuites { 817 ciphers[i] = sortableCipher{suite: suite.id, 818 isObsolete: ((suite.flags & suiteTLS12) == 0), 819 randomTag: perm[i]} 820 } 821 sort.Sort(ciphers) 822 return ciphers.GetCiphers(), nil 823} 824 825type sortableCipher struct { 826 isObsolete bool 827 randomTag int 828 suite uint16 829} 830 831type sortableCiphers []sortableCipher 832 833func (ciphers sortableCiphers) Len() int { 834 return len(ciphers) 835} 836 837func (ciphers sortableCiphers) Less(i, j int) bool { 838 if ciphers[i].isObsolete && !ciphers[j].isObsolete { 839 return false 840 } 841 if ciphers[j].isObsolete && !ciphers[i].isObsolete { 842 return true 843 } 844 return ciphers[i].randomTag < ciphers[j].randomTag 845} 846 847func (ciphers sortableCiphers) Swap(i, j int) { 848 ciphers[i], ciphers[j] = ciphers[j], ciphers[i] 849} 850 851func (ciphers sortableCiphers) GetCiphers() []uint16 { 852 cipherIDs := make([]uint16, len(ciphers)) 853 for i := range ciphers { 854 cipherIDs[i] = ciphers[i].suite 855 } 856 return cipherIDs 857} 858 859func removeRC4Ciphers(s []uint16) []uint16 { 860 // removes elements in place 861 sliceLen := len(s) 862 for i := 0; i < sliceLen; i++ { 863 cipher := s[i] 864 if cipher == TLS_ECDHE_ECDSA_WITH_RC4_128_SHA || 865 cipher == TLS_ECDHE_RSA_WITH_RC4_128_SHA || 866 cipher == TLS_RSA_WITH_RC4_128_SHA { 867 s = append(s[:i], s[i+1:]...) 868 sliceLen-- 869 i-- 870 } 871 } 872 return s[:sliceLen] 873} 874