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 "bytes" 9 "encoding/hex" 10 "fmt" 11 "io/ioutil" 12 "net" 13 "reflect" 14 "testing" 15) 16 17func assertEquality(t *testing.T, fieldName string, expected, actual interface{}) { 18 if kActual, ok := actual.(KeyShare); ok { 19 kExpected := expected.(KeyShare) 20 assertEquality(t, fieldName, kExpected.Group, kActual.Group) 21 return 22 } 23 24 if fieldName == "SupportedCurves" || fieldName == "KeyShares" { 25 cExpected := expected.(CurveID) 26 cActual := actual.(CurveID) 27 if isGREASEUint16(uint16(cExpected)) && isGREASEUint16(uint16(cActual)) { 28 return 29 } 30 } 31 32 if fieldName == "SupportedVersions" || fieldName == "CipherSuites" { 33 cExpected := expected.(uint16) 34 cActual := actual.(uint16) 35 if isGREASEUint16(cExpected) && isGREASEUint16(cActual) { 36 return 37 } 38 } 39 40 if expected != actual { 41 t.Errorf("%v fields not equal, expected: %v, got: %v", fieldName, expected, actual) 42 } 43} 44 45func compareClientHelloFields(t *testing.T, fieldName string, expected, actual *ClientHelloMsg) { 46 rExpected := reflect.ValueOf(expected) 47 if rExpected.Kind() != reflect.Ptr || rExpected.Elem().Kind() != reflect.Struct { 48 t.Errorf("Error using reflect to compare Hello fields") 49 } 50 rActual := reflect.ValueOf(actual) 51 if rActual.Kind() != reflect.Ptr || rActual.Elem().Kind() != reflect.Struct { 52 t.Errorf("Error using reflect to compare Hello fields") 53 } 54 55 rExpected = rExpected.Elem() 56 rActual = rActual.Elem() 57 58 fExpected := rExpected.FieldByName(fieldName) 59 fActual := rActual.FieldByName(fieldName) 60 if !(fExpected.IsValid() && fActual.IsValid()) { 61 t.Errorf("Error using reflect to lookup Hello field name: %v", fieldName) 62 } 63 64 if fExpected.Kind() == reflect.Slice { 65 sExpected := fExpected.Slice(0, fExpected.Len()) 66 sActual := fActual.Slice(0, fActual.Len()) 67 68 if sExpected.Len() != sActual.Len() { 69 t.Errorf("%v fields slice length not equal, expected: %v, got: %v", fieldName, fExpected, fActual) 70 } 71 72 for i := 0; i < sExpected.Len(); i++ { 73 assertEquality(t, fieldName, sExpected.Index(i).Interface(), sActual.Index(i).Interface()) 74 } 75 } else { 76 assertEquality(t, fieldName, fExpected.Interface(), fActual.Interface()) 77 } 78} 79 80func checkUTLSExtensionsEquality(t *testing.T, expected, actual TLSExtension) { 81 if expectedGrease, ok := expected.(*UtlsGREASEExtension); ok { 82 if actualGrease, ok := actual.(*UtlsGREASEExtension); ok { 83 if bytes.Equal(expectedGrease.Body, actualGrease.Body) { 84 return 85 } 86 } 87 } 88 89 if expected.Len() != actual.Len() { 90 t.Errorf("extension types length not equal\nexpected: %#v\ngot: %#v", expected, actual) 91 } 92 93 actualBytes, err := ioutil.ReadAll(actual) 94 if err != nil { 95 t.Errorf("got error: %v; expected to succeed", err) 96 } 97 expectedBytes, err := ioutil.ReadAll(expected) 98 if err != nil { 99 t.Errorf("got error: %v; expected to succeed", err) 100 } 101 102 logInequality := func() { 103 t.Errorf("extensions not equal\nexpected: %#v\nbytes:%#x\ngot: %#v\nbytes: %#x", expected, expectedBytes, actual, actualBytes) 104 } 105 106 if !bytes.Equal(expectedBytes, actualBytes) { 107 // handle all the cases where GREASE or other factors can cause byte unalignment 108 109 // at this point concrete types must match 110 expectedType := reflect.TypeOf(expected) 111 actualType := reflect.TypeOf(actual) 112 if expectedType != actualType { 113 t.Errorf("extensions not equal\nexpected: %#v\nbytes:%#x\ngot: %#v\nbytes: %#x", expected, expectedBytes, actual, actualBytes) 114 return 115 } 116 117 switch expectedExtension := expected.(type) { 118 case *SupportedCurvesExtension: 119 actualExtension := expected.(*SupportedCurvesExtension) 120 for i, expectedCurve := range expectedExtension.Curves { 121 actualCurve := actualExtension.Curves[i] 122 if expectedCurve == actualCurve { 123 continue 124 } 125 if isGREASEUint16(uint16(expectedCurve)) && isGREASEUint16(uint16(actualCurve)) { 126 continue 127 } 128 logInequality() 129 return 130 } 131 case *KeyShareExtension: 132 actualExtension := expected.(*KeyShareExtension) 133 for i, expectedKeyShare := range expectedExtension.KeyShares { 134 actualKeyShare := actualExtension.KeyShares[i] 135 // KeyShare data is unique per connection 136 if actualKeyShare.Group == expectedKeyShare.Group { 137 continue 138 } 139 if isGREASEUint16(uint16(expectedKeyShare.Group)) && isGREASEUint16(uint16(actualKeyShare.Group)) { 140 continue 141 } 142 logInequality() 143 return 144 } 145 case *SupportedVersionsExtension: 146 actualExtension := expected.(*SupportedVersionsExtension) 147 for i, expectedVersion := range expectedExtension.Versions { 148 actualVersion := actualExtension.Versions[i] 149 if isGREASEUint16(expectedVersion) && isGREASEUint16(actualVersion) || actualVersion == expectedVersion { 150 continue 151 } 152 logInequality() 153 return 154 } 155 default: 156 logInequality() 157 return 158 } 159 } 160} 161 162// Conn.vers is sometimes left to zero which is unacceptable to uTLS' SetTLSVers 163// https://github.com/refraction-networking/utls/blob/f7e7360167ed2903ef12898634512b66f8c3aad0/u_conn.go#L564-L566 164// https://github.com/refraction-networking/utls/blob/f7e7360167ed2903ef12898634512b66f8c3aad0/conn.go#L945-L948 165func createMinTLSVersion(vers uint16) uint16 { 166 if vers == 0 { 167 return VersionTLS10 168 } 169 return vers 170} 171 172// prependRecordHeader prepends a record header to a handshake messsage 173// if attempting to mimic an existing connection the minTLSVersion can be found 174// in the Conn.vers field 175func prependRecordHeader(hello []byte, minTLSVersion uint16) []byte { 176 l := len(hello) 177 if minTLSVersion == 0 { 178 minTLSVersion = VersionTLS10 179 } 180 header := []byte{ 181 uint8(recordTypeHandshake), // type 182 uint8(minTLSVersion >> 8 & 0xff), uint8(minTLSVersion & 0xff), // record version is the minimum supported 183 uint8(l >> 8 & 0xff), uint8(l & 0xff), // length 184 } 185 return append(header, hello...) 186} 187 188func checkUTLSFingerPrintClientHello(t *testing.T, clientHelloID ClientHelloID, serverName string) { 189 uconn := UClient(&net.TCPConn{}, &Config{ServerName: serverName}, clientHelloID) 190 if err := uconn.BuildHandshakeState(); err != nil { 191 t.Errorf("got error: %v; expected to succeed", err) 192 } 193 194 generatedUConn := UClient(&net.TCPConn{}, &Config{ServerName: "foobar"}, HelloCustom) 195 fingerprinter := &Fingerprinter{} 196 minTLSVers := createMinTLSVersion(uconn.vers) 197 generatedSpec, err := fingerprinter.FingerprintClientHello(prependRecordHeader(uconn.HandshakeState.Hello.Raw, minTLSVers)) 198 if err != nil { 199 t.Errorf("got error: %v; expected to succeed", err) 200 } 201 if err := generatedUConn.ApplyPreset(generatedSpec); err != nil { 202 t.Errorf("got error: %v; expected to succeed", err) 203 } 204 if err := generatedUConn.BuildHandshakeState(); err != nil { 205 t.Errorf("got error: %v; expected to succeed", err) 206 } 207 208 if len(uconn.HandshakeState.Hello.Raw) != len(generatedUConn.HandshakeState.Hello.Raw) { 209 t.Errorf("UConn from fingerprint has %d length, should have %d", len(generatedUConn.HandshakeState.Hello.Raw), len(uconn.HandshakeState.Hello.Raw)) 210 } 211 212 // We can't effectively check the extensions on randomized client hello ids 213 if !(clientHelloID == HelloRandomized || clientHelloID == HelloRandomizedALPN || clientHelloID == HelloRandomizedNoALPN) { 214 for i, originalExtension := range uconn.Extensions { 215 if _, ok := originalExtension.(*UtlsPaddingExtension); ok { 216 // We can't really compare padding extensions in this way 217 continue 218 } 219 220 generatedExtension := generatedUConn.Extensions[i] 221 checkUTLSExtensionsEquality(t, originalExtension, generatedExtension) 222 } 223 } 224 225 fieldsToTest := []string{ 226 "Vers", "CipherSuites", "CompressionMethods", "NextProtoNeg", "ServerName", "OcspStapling", "Scts", "SupportedCurves", 227 "SupportedPoints", "TicketSupported", "SupportedSignatureAlgorithms", "SecureRenegotiation", "SecureRenegotiationSupported", "AlpnProtocols", 228 "SupportedSignatureAlgorithmsCert", "SupportedVersions", "KeyShares", "EarlyData", "PskModes", "PskIdentities", "PskBinders", 229 } 230 231 for _, field := range fieldsToTest { 232 compareClientHelloFields(t, field, uconn.HandshakeState.Hello, generatedUConn.HandshakeState.Hello) 233 } 234} 235 236func TestUTLSFingerprintClientHello(t *testing.T) { 237 clientHellosToTest := []ClientHelloID{ 238 HelloChrome_58, HelloChrome_70, HelloChrome_83, HelloFirefox_55, HelloFirefox_63, HelloIOS_11_1, HelloIOS_12_1, HelloRandomized, HelloRandomizedALPN, HelloRandomizedNoALPN} 239 240 serverNames := []string{"foobar"} 241 242 for _, clientHello := range clientHellosToTest { 243 for _, serverName := range serverNames { 244 t.Logf("checking fingerprint generated client hello spec against %v and server name: %v", clientHello, serverName) 245 checkUTLSFingerPrintClientHello(t, clientHello, "foobar") 246 } 247 } 248} 249 250func TestUTLSFingerprintClientHelloBluntMimicry(t *testing.T) { 251 serverName := "foobar" 252 var extensionId uint16 = 0xfeed 253 extensionData := []byte("random data") 254 255 specWithGeneric, err := utlsIdToSpec(HelloChrome_Auto) 256 if err != nil { 257 t.Errorf("got error: %v; expected to succeed", err) 258 } 259 specWithGeneric.Extensions = append(specWithGeneric.Extensions, &GenericExtension{extensionId, extensionData}) 260 261 uconn := UClient(&net.TCPConn{}, &Config{ServerName: serverName}, HelloCustom) 262 263 if err := uconn.ApplyPreset(&specWithGeneric); err != nil { 264 t.Errorf("got error: %v; expected to succeed", err) 265 } 266 if err := uconn.BuildHandshakeState(); err != nil { 267 t.Errorf("got error: %v; expected to succeed", err) 268 } 269 270 f := &Fingerprinter{} 271 minTLSVers := createMinTLSVersion(uconn.vers) 272 _, err = f.FingerprintClientHello(prependRecordHeader(uconn.HandshakeState.Hello.Raw, minTLSVers)) 273 if err == nil { 274 t.Errorf("expected error generating spec from client hello with GenericExtension") 275 } 276 277 f = &Fingerprinter{AllowBluntMimicry: true} 278 generatedSpec, err := f.FingerprintClientHello(prependRecordHeader(uconn.HandshakeState.Hello.Raw, minTLSVers)) 279 if err != nil { 280 t.Errorf("got error: %v; expected to succeed", err) 281 } 282 283 for _, ext := range generatedSpec.Extensions { 284 if genericExtension, ok := (ext).(*GenericExtension); ok { 285 if genericExtension.Id == extensionId && bytes.Equal(genericExtension.Data, extensionData) { 286 return 287 } 288 } 289 } 290 t.Errorf("generated ClientHelloSpec with BluntMimicry did not correctly carry over generic extension") 291} 292 293func TestUTLSFingerprintClientHelloAlwaysAddPadding(t *testing.T) { 294 serverName := "foobar" 295 296 specWithoutPadding, err := utlsIdToSpec(HelloIOS_12_1) 297 if err != nil { 298 t.Errorf("got error: %v; expected to succeed", err) 299 } 300 specWithPadding, err := utlsIdToSpec(HelloChrome_83) 301 if err != nil { 302 t.Errorf("got error: %v; expected to succeed", err) 303 } 304 305 uconnWithoutPadding := UClient(&net.TCPConn{}, &Config{ServerName: serverName}, HelloCustom) 306 uconnWithPadding := UClient(&net.TCPConn{}, &Config{ServerName: serverName}, HelloCustom) 307 308 if err := uconnWithoutPadding.ApplyPreset(&specWithoutPadding); err != nil { 309 t.Errorf("got error: %v; expected to succeed", err) 310 } 311 if err := uconnWithoutPadding.BuildHandshakeState(); err != nil { 312 t.Errorf("got error: %v; expected to succeed", err) 313 } 314 315 if err := uconnWithPadding.ApplyPreset(&specWithPadding); err != nil { 316 t.Errorf("got error: %v; expected to succeed", err) 317 } 318 if err := uconnWithPadding.BuildHandshakeState(); err != nil { 319 t.Errorf("got error: %v; expected to succeed", err) 320 } 321 322 f := &Fingerprinter{} 323 minTLSVersWithoutPadding := createMinTLSVersion(uconnWithoutPadding.vers) 324 fingerprintedWithoutPadding, err := f.FingerprintClientHello(prependRecordHeader(uconnWithoutPadding.HandshakeState.Hello.Raw, minTLSVersWithoutPadding)) 325 if err != nil { 326 t.Errorf("got error: %v; expected to succeed", err) 327 } 328 329 for _, ext := range fingerprintedWithoutPadding.Extensions { 330 if _, ok := ext.(*UtlsPaddingExtension); ok { 331 t.Errorf("padding extension should not be present on fingerprinted ClientHelloSpec without AlwaysAddPadding set") 332 break 333 } 334 } 335 336 f = &Fingerprinter{AlwaysAddPadding: true} 337 generatedSpec, err := f.FingerprintClientHello(prependRecordHeader(uconnWithoutPadding.HandshakeState.Hello.Raw, minTLSVersWithoutPadding)) 338 if err != nil { 339 t.Errorf("got error: %v; expected to succeed", err) 340 } 341 342 hasPadding := false 343 for _, ext := range generatedSpec.Extensions { 344 if _, ok := ext.(*UtlsPaddingExtension); ok { 345 hasPadding = true 346 break 347 } 348 } 349 if !hasPadding { 350 t.Errorf("expected padding extension on fingerprinted ClientHelloSpec with AlwaysAddPadding set") 351 } 352 353 f = &Fingerprinter{AlwaysAddPadding: true} 354 minTLSVersWithPadding := createMinTLSVersion(uconnWithPadding.vers) 355 generatedSpec, err = f.FingerprintClientHello(prependRecordHeader(uconnWithPadding.HandshakeState.Hello.Raw, minTLSVersWithPadding)) 356 if err != nil { 357 t.Errorf("got error: %v; expected to succeed", err) 358 } 359 360 hasPadding = false 361 for _, ext := range generatedSpec.Extensions { 362 if _, ok := ext.(*UtlsPaddingExtension); ok { 363 if hasPadding { 364 t.Errorf("found double padding extension on fingerprinted ClientHelloSpec with AlwaysAddPadding set") 365 } 366 367 hasPadding = true 368 } 369 } 370 if !hasPadding { 371 t.Errorf("expected padding extension on fingerprinted ClientHelloSpec with AlwaysAddPadding set") 372 } 373} 374 375func TestUTLSFingerprintClientHelloKeepPSK(t *testing.T) { 376 // TLSv1.3 Record Layer: Handshake Protocol: Client Hello 377 // Content Type: Handshake (22) 378 // Version: TLS 1.0 (0x0301) 379 // Length: 576 380 // Handshake Protocol: Client Hello 381 // Handshake Type: Client Hello (1) 382 // Length: 572 383 // Version: TLS 1.2 (0x0303) 384 // Random: 5cef5aa9122008e37f0f74d717cd4ae0f745daba4292e6fb… 385 // Session ID Length: 32 386 // Session ID: 8c4aa23444084eeb70097efe0b8f6e3a56c717abd67505c9… 387 // Cipher Suites Length: 32 388 // Cipher Suites (16 suites) 389 // Compression Methods Length: 1 390 // Compression Methods (1 method) 391 // Extensions Length: 467 392 // Extension: Reserved (GREASE) (len=0) 393 // Type: Reserved (GREASE) (14906) 394 // Length: 0 395 // Data: <MISSING> 396 // Extension: server_name (len=22) 397 // Type: server_name (0) 398 // Length: 22 399 // Server Name Indication extension 400 // Server Name list length: 20 401 // Server Name Type: host_name (0) 402 // Server Name length: 17 403 // Server Name: edgeapi.slack.com 404 // Extension: extended_master_secret (len=0) 405 // Type: extended_master_secret (23) 406 // Length: 0 407 // Extension: renegotiation_info (len=1) 408 // Type: renegotiation_info (65281) 409 // Length: 1 410 // Renegotiation Info extension 411 // Renegotiation info extension length: 0 412 // Extension: supported_groups (len=10) 413 // Type: supported_groups (10) 414 // Length: 10 415 // Supported Groups List Length: 8 416 // Supported Groups (4 groups) 417 // Supported Group: Reserved (GREASE) (0xdada) 418 // Supported Group: x25519 (0x001d) 419 // Supported Group: secp256r1 (0x0017) 420 // Supported Group: secp384r1 (0x0018) 421 // Extension: ec_point_formats (len=2) 422 // Type: ec_point_formats (11) 423 // Length: 2 424 // EC point formats Length: 1 425 // Elliptic curves point formats (1) 426 // Extension: session_ticket (len=0) 427 // Type: session_ticket (35) 428 // Length: 0 429 // Data (0 bytes) 430 // Extension: application_layer_protocol_negotiation (len=14) 431 // Type: application_layer_protocol_negotiation (16) 432 // Length: 14 433 // ALPN Extension Length: 12 434 // ALPN Protocol 435 // ALPN string length: 2 436 // ALPN Next Protocol: h2 437 // ALPN string length: 8 438 // ALPN Next Protocol: http/1.1 439 // Extension: status_request (len=5) 440 // Type: status_request (5) 441 // Length: 5 442 // Certificate Status Type: OCSP (1) 443 // Responder ID list Length: 0 444 // Request Extensions Length: 0 445 // Extension: signature_algorithms (len=18) 446 // Type: signature_algorithms (13) 447 // Length: 18 448 // Signature Hash Algorithms Length: 16 449 // Signature Hash Algorithms (8 algorithms) 450 // Extension: signed_certificate_timestamp (len=0) 451 // Type: signed_certificate_timestamp (18) 452 // Length: 0 453 // Extension: key_share (len=43) 454 // Type: key_share (51) 455 // Length: 43 456 // Key Share extension 457 // Client Key Share Length: 41 458 // Key Share Entry: Group: Reserved (GREASE), Key Exchange length: 1 459 // Group: Reserved (GREASE) (56026) 460 // Key Exchange Length: 1 461 // Key Exchange: 00 462 // Key Share Entry: Group: x25519, Key Exchange length: 32 463 // Group: x25519 (29) 464 // Key Exchange Length: 32 465 // Key Exchange: e35e636d4e2dcd5f39309170285dab92dbe81fefe4926826… 466 // Extension: psk_key_exchange_modes (len=2) 467 // Type: psk_key_exchange_modes (45) 468 // Length: 2 469 // PSK Key Exchange Modes Length: 1 470 // PSK Key Exchange Mode: PSK with (EC)DHE key establishment (psk_dhe_ke) (1) 471 // Extension: supported_versions (len=11) 472 // Type: supported_versions (43) 473 // Length: 11 474 // Supported Versions length: 10 475 // Supported Version: Unknown (0x2a2a) 476 // Supported Version: TLS 1.3 (0x0304) 477 // Supported Version: TLS 1.2 (0x0303) 478 // Supported Version: TLS 1.1 (0x0302) 479 // Supported Version: TLS 1.0 (0x0301) 480 // Extension: compress_certificate (len=3) 481 // Type: compress_certificate (27) 482 // Length: 3 483 // Algorithms Length: 2 484 // Algorithm: brotli (2) 485 // Extension: Reserved (GREASE) (len=1) 486 // Type: Reserved (GREASE) (19018) 487 // Length: 1 488 // Data: 00 489 // Extension: pre_shared_key (len=267) 490 // Type: pre_shared_key (41) 491 // Length: 267 492 // Pre-Shared Key extension 493 494 byteString := []byte("16030102400100023c03035cef5aa9122008e37f0f74d717cd4ae0f745daba4292e6fbca3cd5bf9123498f208c4aa23444084eeb70097efe0b8f6e3a56c717abd67505c950aab314de59bd8f00204a4a130113021303c02bc02fc02cc030cca9cca8c013c014009c009d002f0035010001d33a3a0000000000160014000011656467656170692e736c61636b2e636f6d00170000ff01000100000a000a0008dada001d00170018000b00020100002300000010000e000c02683208687474702f312e31000500050100000000000d0012001004030804040105030805050108060601001200000033002b0029dada000100001d0020e35e636d4e2dcd5f39309170285dab92dbe81fefe4926826cec1ef881321687e002d00020101002b000b0a2a2a0304030303020301001b00030200024a4a0001000029010b00e600e017fab59672c1966ae78fc4dacd7efb42e735de956e3f96d342bb8e63a5233ce21c92d6d75036601d74ccbc3ca0085f3ac2ebbd83da13501ac3c6d612bcb453fb206a39a8112d768bea1976d7c14e6de9aa0ee70ea732554d3c57d1a993f1044a46c1fb371811039ef30582cacf41bd497121d67793b8ee4df7a60d525f7df052fd66cda7f141bb553d9253816752d923ac7c71426179db4f26a7d42f0d65a2dd2dbaafb86fa17b2da23fd57c5064c76551cfda86304051231e4da9e697fedbcb5ae8cb2f6cb92f71164acf2edff5bccc1266cd648a53cc46262eabf40727bcb6958a3d1300212083e99d791672d39919dcb387f2fa7aeee938ec32ecf4b861306f7df4f9a8a746") 495 496 helloBytes := make([]byte, hex.DecodedLen(len(byteString))) 497 _, err := hex.Decode(helloBytes, byteString) 498 if err != nil { 499 t.Errorf("got error: %v; expected to succeed", err) 500 return 501 } 502 503 f := &Fingerprinter{} 504 _, err = f.FingerprintClientHello(helloBytes) 505 if err == nil { 506 t.Errorf("expected error generating spec from client hello with PSK") 507 } 508 509 f = &Fingerprinter{KeepPSK: true} 510 generatedSpec, err := f.FingerprintClientHello(helloBytes) 511 if err != nil { 512 t.Errorf("got error: %v; expected to succeed", err) 513 return 514 } 515 516 for _, ext := range generatedSpec.Extensions { 517 if genericExtension, ok := (ext).(*GenericExtension); ok { 518 if genericExtension.Id == extensionPreSharedKey { 519 return 520 } 521 } 522 } 523 t.Errorf("generated ClientHelloSpec with KeepPSK does not include preshared key extension") 524} 525 526func TestUTLSHandshakeClientFingerprintedSpecFromChrome_58(t *testing.T) { 527 helloID := HelloChrome_58 528 serverName := "foobar" 529 originalConfig := getUTLSTestConfig() 530 originalConfig.ServerName = serverName 531 uconn := UClient(&net.TCPConn{}, originalConfig, helloID) 532 if err := uconn.BuildHandshakeState(); err != nil { 533 t.Errorf("got error: %v; expected to succeed", err) 534 } 535 536 f := &Fingerprinter{} 537 minTLSVers := createMinTLSVersion(uconn.vers) 538 generatedSpec, err := f.FingerprintClientHello(prependRecordHeader(uconn.HandshakeState.Hello.Raw, minTLSVers)) 539 if err != nil { 540 t.Errorf("got error: %v; expected to succeed", err) 541 } 542 543 hello := &helloSpec{ 544 name: fmt.Sprintf("%v-fingerprinted", helloID.Str()), 545 spec: generatedSpec, 546 } 547 548 newConfig := getUTLSTestConfig() 549 newConfig.ServerName = serverName 550 551 opensslCipherName := "ECDHE-RSA-AES128-GCM-SHA256" 552 test := &clientTest{ 553 name: "UTLS-" + opensslCipherName + "-" + hello.helloName(), 554 args: []string{"-cipher", opensslCipherName}, 555 config: newConfig, 556 } 557 558 runUTLSClientTestTLS12(t, test, hello) 559} 560 561func TestUTLSHandshakeClientFingerprintedSpecFromChrome_70(t *testing.T) { 562 helloID := HelloChrome_70 563 serverName := "foobar" 564 originalConfig := getUTLSTestConfig() 565 originalConfig.ServerName = serverName 566 567 uconn := UClient(&net.TCPConn{}, originalConfig, helloID) 568 if err := uconn.BuildHandshakeState(); err != nil { 569 t.Errorf("got error: %v; expected to succeed", err) 570 } 571 572 f := &Fingerprinter{} 573 minTLSVers := createMinTLSVersion(uconn.vers) 574 generatedSpec, err := f.FingerprintClientHello(prependRecordHeader(uconn.HandshakeState.Hello.Raw, minTLSVers)) 575 if err != nil { 576 t.Errorf("got error: %v; expected to succeed", err) 577 } 578 579 hello := &helloSpec{ 580 name: fmt.Sprintf("%v-fingerprinted", helloID.Str()), 581 spec: generatedSpec, 582 } 583 584 newConfig := getUTLSTestConfig() 585 newConfig.ServerName = serverName 586 587 opensslCipherName := "TLS_AES_128_GCM_SHA256" 588 test := &clientTest{ 589 name: "UTLS-" + opensslCipherName + "-" + hello.helloName(), 590 args: []string{"-ciphersuites", opensslCipherName}, 591 config: newConfig, 592 } 593 594 runUTLSClientTestTLS13(t, test, hello) 595} 596 597func TestUTLSHandshakeClientFingerprintedSpecFromRaw(t *testing.T) { 598 // TLSv1.3 Record Layer: Handshake Protocol: Client Hello 599 // Content Type: Handshake (22) 600 // Version: TLS 1.0 (0x0301) 601 // Length: 512 602 // Handshake Protocol: Client Hello 603 // Handshake Type: Client Hello (1) 604 // Length: 508 605 // Version: TLS 1.2 (0x0303) 606 // Random: 7fd76fa530c24816ea9e4a6cf2e939f2350b9486a7bac58e… 607 // Session ID Length: 32 608 // Session ID: d9b01fc4f4b6fe14fe9ce652442d66588d982cb25913d866… 609 // Cipher Suites Length: 36 610 // Cipher Suites (18 suites) 611 // Cipher Suite: TLS_AES_128_GCM_SHA256 (0x1301) 612 // Cipher Suite: TLS_CHACHA20_POLY1305_SHA256 (0x1303) 613 // Cipher Suite: TLS_AES_256_GCM_SHA384 (0x1302) 614 // Cipher Suite: TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256 (0xc02b) 615 // Cipher Suite: TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 (0xc02f) 616 // Cipher Suite: TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256 (0xcca9) 617 // Cipher Suite: TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256 (0xcca8) 618 // Cipher Suite: TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384 (0xc02c) 619 // Cipher Suite: TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (0xc030) 620 // Cipher Suite: TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA (0xc00a) 621 // Cipher Suite: TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA (0xc009) 622 // Cipher Suite: TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA (0xc013) 623 // Cipher Suite: TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA (0xc014) 624 // Cipher Suite: TLS_RSA_WITH_AES_128_GCM_SHA256 (0x009c) 625 // Cipher Suite: TLS_RSA_WITH_AES_256_GCM_SHA384 (0x009d) 626 // Cipher Suite: TLS_RSA_WITH_AES_128_CBC_SHA (0x002f) 627 // Cipher Suite: TLS_RSA_WITH_AES_256_CBC_SHA (0x0035) 628 // Cipher Suite: TLS_RSA_WITH_3DES_EDE_CBC_SHA (0x000a) 629 // Compression Methods Length: 1 630 // Compression Methods (1 method) 631 // Extensions Length: 399 632 // Extension: server_name (len=34) 633 // Type: server_name (0) 634 // Length: 34 635 // Server Name Indication extension 636 // Extension: extended_master_secret (len=0) 637 // Type: extended_master_secret (23) 638 // Length: 0 639 // Extension: renegotiation_info (len=1) 640 // Type: renegotiation_info (65281) 641 // Length: 1 642 // Renegotiation Info extension 643 // Extension: supported_groups (len=14) 644 // Type: supported_groups (10) 645 // Length: 14 646 // Supported Groups List Length: 12 647 // Supported Groups (6 groups) 648 // Extension: ec_point_formats (len=2) 649 // Type: ec_point_formats (11) 650 // Length: 2 651 // EC point formats Length: 1 652 // Elliptic curves point formats (1) 653 // Extension: application_layer_protocol_negotiation (len=14) 654 // Type: application_layer_protocol_negotiation (16) 655 // Length: 14 656 // ALPN Extension Length: 12 657 // ALPN Protocol 658 // Extension: status_request (len=5) 659 // Type: status_request (5) 660 // Length: 5 661 // Certificate Status Type: OCSP (1) 662 // Responder ID list Length: 0 663 // Request Extensions Length: 0 664 // Extension: key_share (len=107) 665 // Type: key_share (51) 666 // Length: 107 667 // Key Share extension 668 // Extension: supported_versions (len=5) 669 // Type: supported_versions (43) 670 // Length: 5 671 // Supported Versions length: 4 672 // Supported Version: TLS 1.3 (0x0304) 673 // Supported Version: TLS 1.2 (0x0303) 674 // Extension: signature_algorithms (len=24) 675 // Type: signature_algorithms (13) 676 // Length: 24 677 // Signature Hash Algorithms Length: 22 678 // Signature Hash Algorithms (11 algorithms) 679 // Extension: record_size_limit (len=2) 680 // Type: record_size_limit (28) 681 // Length: 2 682 // Record Size Limit: 16385 683 // Extension: padding (len=143) 684 // Type: padding (21) 685 // Length: 143 686 // Padding Data: 000000000000000000000000000000000000000000000000… 687 byteString := []byte("1603010200010001fc03037fd76fa530c24816ea9e4a6cf2e939f2350b9486a7bac58ece5753767fb6112420d9b01fc4f4b6fe14fe9ce652442d66588d982cb25913d866348bde54d3899abe0024130113031302c02bc02fcca9cca8c02cc030c00ac009c013c014009c009d002f0035000a0100018f00000022002000001d70656f706c652d70612e636c69656e7473362e676f6f676c652e636f6d00170000ff01000100000a000e000c001d00170018001901000101000b000201000010000e000c02683208687474702f312e310005000501000000000033006b0069001d002065e566ff33dfbeb012e3b13b87d75612bd0fbc3963673df90afed533dccc9b5400170041047fcc2666d04c31272a2e39905c771a89edf5a71dae301ec2fa0e7bc4d0e06580a0d36324e3dc4f29e200a8905badd11c00daf11588977bf501597dac5fdc55bf002b00050403040303000d0018001604030503060308040805080604010501060102030201001c000240010015008f0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000") 688 helloBytes := make([]byte, hex.DecodedLen(len(byteString))) 689 _, err := hex.Decode(helloBytes, byteString) 690 if err != nil { 691 t.Errorf("got error: %v; expected to succeed", err) 692 return 693 } 694 695 f := &Fingerprinter{} 696 generatedSpec, err := f.FingerprintClientHello(helloBytes) 697 if err != nil { 698 t.Errorf("got error: %v; expected to succeed", err) 699 } 700 701 hello := &helloSpec{ 702 name: "raw-capture-fingerprinted", 703 spec: generatedSpec, 704 } 705 706 config := getUTLSTestConfig() 707 708 opensslCipherName := "TLS_AES_128_GCM_SHA256" 709 test := &clientTest{ 710 name: "UTLS-" + opensslCipherName + "-" + hello.helloName(), 711 args: []string{"-ciphersuites", opensslCipherName}, 712 config: config, 713 } 714 715 runUTLSClientTestTLS13(t, test, hello) 716} 717