github.com/3andne/restls-client-go@v0.1.6/u_fingerprinter_test.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  	"bytes"
     9  	"encoding/hex"
    10  	"fmt"
    11  	"io/ioutil"
    12  	"net"
    13  	"reflect"
    14  	"testing"
    15  )
    16  
    17  func 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  
    45  func compareClientHelloFields(t *testing.T, fieldName string, expected, actual *PubClientHelloMsg) {
    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  
    80  func 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
   165  func 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
   175  func 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  
   188  func 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  
   236  func 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  
   250  func 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  
   293  func 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  
   375  func 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  	generatedSpec, err := f.FingerprintClientHello(helloBytes)
   505  	if err != nil {
   506  		t.Errorf("got error: %v; expected to succeed", err)
   507  		return
   508  	}
   509  
   510  	for _, ext := range generatedSpec.Extensions {
   511  		if _, ok := (ext).(*FakePreSharedKeyExtension); ok {
   512  			return
   513  		}
   514  	}
   515  	t.Errorf("generated ClientHelloSpec with KeepPSK does not include preshared key extension")
   516  }
   517  
   518  func TestUTLSHandshakeClientFingerprintedSpecFromChrome_58(t *testing.T) {
   519  	helloID := HelloChrome_58
   520  	serverName := "foobar"
   521  	originalConfig := getUTLSTestConfig()
   522  	originalConfig.ServerName = serverName
   523  	uconn := UClient(&net.TCPConn{}, originalConfig, helloID)
   524  	if err := uconn.BuildHandshakeState(); err != nil {
   525  		t.Errorf("got error: %v; expected to succeed", err)
   526  	}
   527  
   528  	f := &Fingerprinter{}
   529  	minTLSVers := createMinTLSVersion(uconn.vers)
   530  	generatedSpec, err := f.FingerprintClientHello(prependRecordHeader(uconn.HandshakeState.Hello.Raw, minTLSVers))
   531  	if err != nil {
   532  		t.Errorf("got error: %v; expected to succeed", err)
   533  	}
   534  
   535  	hello := &helloSpec{
   536  		name: fmt.Sprintf("%v-fingerprinted", helloID.Str()),
   537  		spec: generatedSpec,
   538  	}
   539  
   540  	newConfig := getUTLSTestConfig()
   541  	newConfig.ServerName = serverName
   542  
   543  	opensslCipherName := "ECDHE-RSA-AES128-GCM-SHA256"
   544  	test := &clientTest{
   545  		name:   "UTLS-" + opensslCipherName + "-" + hello.helloName(),
   546  		args:   []string{"-cipher", opensslCipherName},
   547  		config: newConfig,
   548  	}
   549  
   550  	runUTLSClientTestTLS12(t, test, hello)
   551  }
   552  
   553  func TestUTLSHandshakeClientFingerprintedSpecFromChrome_70(t *testing.T) {
   554  	helloID := HelloChrome_70
   555  	serverName := "foobar"
   556  	originalConfig := getUTLSTestConfig()
   557  	originalConfig.ServerName = serverName
   558  
   559  	uconn := UClient(&net.TCPConn{}, originalConfig, helloID)
   560  	if err := uconn.BuildHandshakeState(); err != nil {
   561  		t.Errorf("got error: %v; expected to succeed", err)
   562  	}
   563  
   564  	f := &Fingerprinter{}
   565  	minTLSVers := createMinTLSVersion(uconn.vers)
   566  	generatedSpec, err := f.FingerprintClientHello(prependRecordHeader(uconn.HandshakeState.Hello.Raw, minTLSVers))
   567  	if err != nil {
   568  		t.Errorf("got error: %v; expected to succeed", err)
   569  	}
   570  
   571  	hello := &helloSpec{
   572  		name: fmt.Sprintf("%v-fingerprinted", helloID.Str()),
   573  		spec: generatedSpec,
   574  	}
   575  
   576  	newConfig := getUTLSTestConfig()
   577  	newConfig.ServerName = serverName
   578  
   579  	opensslCipherName := "TLS_AES_128_GCM_SHA256"
   580  	test := &clientTest{
   581  		name:   "UTLS-" + opensslCipherName + "-" + hello.helloName(),
   582  		args:   []string{"-ciphersuites", opensslCipherName},
   583  		config: newConfig,
   584  	}
   585  
   586  	runUTLSClientTestTLS13(t, test, hello)
   587  }
   588  
   589  func TestUTLSHandshakeClientFingerprintedSpecFromRaw(t *testing.T) {
   590  	// TLSv1.3 Record Layer: Handshake Protocol: Client Hello
   591  	//     Content Type: Handshake (22)
   592  	//     Version: TLS 1.0 (0x0301)
   593  	//     Length: 512
   594  	// Handshake Protocol: Client Hello
   595  	//     Handshake Type: Client Hello (1)
   596  	//     Length: 508
   597  	//     Version: TLS 1.2 (0x0303)
   598  	//     Random: 7fd76fa530c24816ea9e4a6cf2e939f2350b9486a7bac58e…
   599  	//     Session ID Length: 32
   600  	//     Session ID: d9b01fc4f4b6fe14fe9ce652442d66588d982cb25913d866…
   601  	//     Cipher Suites Length: 36
   602  	//     Cipher Suites (18 suites)
   603  	//         Cipher Suite: TLS_AES_128_GCM_SHA256 (0x1301)
   604  	//         Cipher Suite: TLS_CHACHA20_POLY1305_SHA256 (0x1303)
   605  	//         Cipher Suite: TLS_AES_256_GCM_SHA384 (0x1302)
   606  	//         Cipher Suite: TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256 (0xc02b)
   607  	//         Cipher Suite: TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 (0xc02f)
   608  	//         Cipher Suite: TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256 (0xcca9)
   609  	//         Cipher Suite: TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256 (0xcca8)
   610  	//         Cipher Suite: TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384 (0xc02c)
   611  	//         Cipher Suite: TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (0xc030)
   612  	//         Cipher Suite: TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA (0xc00a)
   613  	//         Cipher Suite: TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA (0xc009)
   614  	//         Cipher Suite: TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA (0xc013)
   615  	//         Cipher Suite: TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA (0xc014)
   616  	//         Cipher Suite: TLS_RSA_WITH_AES_128_GCM_SHA256 (0x009c)
   617  	//         Cipher Suite: TLS_RSA_WITH_AES_256_GCM_SHA384 (0x009d)
   618  	//         Cipher Suite: TLS_RSA_WITH_AES_128_CBC_SHA (0x002f)
   619  	//         Cipher Suite: TLS_RSA_WITH_AES_256_CBC_SHA (0x0035)
   620  	//         Cipher Suite: TLS_RSA_WITH_3DES_EDE_CBC_SHA (0x000a)
   621  	//     Compression Methods Length: 1
   622  	//     Compression Methods (1 method)
   623  	//     Extensions Length: 399
   624  	//     Extension: server_name (len=34)
   625  	//         Type: server_name (0)
   626  	//         Length: 34
   627  	//         Server Name Indication extension
   628  	//     Extension: extended_master_secret (len=0)
   629  	//         Type: extended_master_secret (23)
   630  	//         Length: 0
   631  	//     Extension: renegotiation_info (len=1)
   632  	//         Type: renegotiation_info (65281)
   633  	//         Length: 1
   634  	//         Renegotiation Info extension
   635  	//     Extension: supported_groups (len=14)
   636  	//         Type: supported_groups (10)
   637  	//         Length: 14
   638  	//         Supported Groups List Length: 12
   639  	//         Supported Groups (6 groups)
   640  	//     Extension: ec_point_formats (len=2)
   641  	//         Type: ec_point_formats (11)
   642  	//         Length: 2
   643  	//         EC point formats Length: 1
   644  	//         Elliptic curves point formats (1)
   645  	//     Extension: application_layer_protocol_negotiation (len=14)
   646  	//         Type: application_layer_protocol_negotiation (16)
   647  	//         Length: 14
   648  	//         ALPN Extension Length: 12
   649  	//         ALPN Protocol
   650  	//     Extension: status_request (len=5)
   651  	//         Type: status_request (5)
   652  	//         Length: 5
   653  	//         Certificate Status Type: OCSP (1)
   654  	//         Responder ID list Length: 0
   655  	//         Request Extensions Length: 0
   656  	//     Extension: key_share (len=107)
   657  	//         Type: key_share (51)
   658  	//         Length: 107
   659  	//         Key Share extension
   660  	//     Extension: supported_versions (len=5)
   661  	//         Type: supported_versions (43)
   662  	//         Length: 5
   663  	//         Supported Versions length: 4
   664  	//         Supported Version: TLS 1.3 (0x0304)
   665  	//         Supported Version: TLS 1.2 (0x0303)
   666  	//     Extension: signature_algorithms (len=24)
   667  	//         Type: signature_algorithms (13)
   668  	//         Length: 24
   669  	//         Signature Hash Algorithms Length: 22
   670  	//         Signature Hash Algorithms (11 algorithms)
   671  	//     Extension: record_size_limit (len=2)
   672  	//         Type: record_size_limit (28)
   673  	//         Length: 2
   674  	//         Record Size Limit: 16385
   675  	//     Extension: padding (len=143)
   676  	//         Type: padding (21)
   677  	//         Length: 143
   678  	//         Padding Data: 000000000000000000000000000000000000000000000000…
   679  	byteString := []byte("1603010200010001fc03037fd76fa530c24816ea9e4a6cf2e939f2350b9486a7bac58ece5753767fb6112420d9b01fc4f4b6fe14fe9ce652442d66588d982cb25913d866348bde54d3899abe0024130113031302c02bc02fcca9cca8c02cc030c00ac009c013c014009c009d002f0035000a0100018f00000022002000001d70656f706c652d70612e636c69656e7473362e676f6f676c652e636f6d00170000ff01000100000a000e000c001d00170018001901000101000b000201000010000e000c02683208687474702f312e310005000501000000000033006b0069001d002065e566ff33dfbeb012e3b13b87d75612bd0fbc3963673df90afed533dccc9b5400170041047fcc2666d04c31272a2e39905c771a89edf5a71dae301ec2fa0e7bc4d0e06580a0d36324e3dc4f29e200a8905badd11c00daf11588977bf501597dac5fdc55bf002b00050403040303000d0018001604030503060308040805080604010501060102030201001c000240010015008f0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000")
   680  	helloBytes := make([]byte, hex.DecodedLen(len(byteString)))
   681  	_, err := hex.Decode(helloBytes, byteString)
   682  	if err != nil {
   683  		t.Errorf("got error: %v; expected to succeed", err)
   684  		return
   685  	}
   686  
   687  	f := &Fingerprinter{}
   688  	generatedSpec, err := f.FingerprintClientHello(helloBytes)
   689  	if err != nil {
   690  		t.Errorf("got error: %v; expected to succeed", err)
   691  	}
   692  
   693  	hello := &helloSpec{
   694  		name: "raw-capture-fingerprinted",
   695  		spec: generatedSpec,
   696  	}
   697  
   698  	config := getUTLSTestConfig()
   699  
   700  	opensslCipherName := "TLS_AES_128_GCM_SHA256"
   701  	test := &clientTest{
   702  		name:   "UTLS-" + opensslCipherName + "-" + hello.helloName(),
   703  		args:   []string{"-ciphersuites", opensslCipherName},
   704  		config: config,
   705  	}
   706  
   707  	runUTLSClientTestTLS13(t, test, hello)
   708  }
   709  
   710  // FingerprintClientHello should work when the dump contains the client's greeting and subsequent frames.
   711  // Lack of subsequent frames should not lead to inoperability of FingerprintClientHello.
   712  func TestFingerprintDumpLargerThanExtensions(t *testing.T) {
   713  	// Dump of curl/7.74.0 with some test request https://tlsfingerprint.io/id/37695dd988f0c8b8
   714  	dump := "1603010200010001fc03032e763fe74cd8472de77d17eef1cf4cb9b18d0163196a69337d0d7c6c844a1b71202aef889ccf5bdef725185b7c0cc51a100311c7c3992b1d206beaef121a111cc5003e130213031301c02cc030009fcca9cca8ccaac02bc02f009ec024c028006bc023c0270067c00ac0140039c009c0130033009d009c003d003c0035002f00ff010001750000000e000c0000096c6f63616c686f7374000b000403000102000a000c000a001d0017001e00190018337400000010000e000c02683208687474702f312e31001600000017000000310000000d002a0028040305030603080708080809080a080b080408050806040105010601030303010302040205020602002b00050403040303002d00020101003300260024001d00204f21193633f4a0c751143f0084941995cc6fb7cb87545f56f07877c99615f074001500be000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001403030001011703030045f621cd4a3c52c89e0d94c6f6a79d5863274af09696811cb73c433aa05ea5bb7a266cbc11cdbd18a553c9b4ba02c202ec709faabfdd9e9b76c1b2162dd8296cdbc9e6451742170303005ff37ae5fd6c2f240472c6248abb2a82dd2e634d4da4f67d0db94cf56eebe7e9e3766f6458f87c82bdd70a4d75e0f904c368a7c57beba6d76ea9d3f6d06e26cdf1dcb4c6fa2067f269268e91e94ade464efdb2e5f5cf2f7930faeb6f2a4a3bc2"
   715  	// shortDump := "1603010200010001fc03032e763fe74cd8472de77d17eef1cf4cb9b18d0163196a69337d0d7c6c844a1b71202aef889ccf5bdef725185b7c0cc51a100311c7c3992b1d206beaef121a111cc5003e130213031301c02cc030009fcca9cca8ccaac02bc02f009ec024c028006bc023c0270067c00ac0140039c009c0130033009d009c003d003c0035002f00ff010001750000000e000c0000096c6f63616c686f7374000b000403000102000a000c000a001d0017001e00190018337400000010000e000c02683208687474702f312e31001600000017000000310000000d002a0028040305030603080708080809080a080b080408050806040105010601030303010302040205020602002b00050403040303002d00020101003300260024001d00204f21193633f4a0c751143f0084941995cc6fb7cb87545f56f07877c99615f074001500be00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"
   716  	helloBytes, err := hex.DecodeString(dump)
   717  	if err != nil {
   718  		t.Error(err)
   719  		return
   720  	}
   721  	f := &Fingerprinter{
   722  		AllowBluntMimicry: true,
   723  	}
   724  	clientHelloSpec, err := f.FingerprintClientHello(helloBytes)
   725  	if err != nil {
   726  		t.Errorf("got error: %v; expected to succeed", err)
   727  	}
   728  	if clientHelloSpec == nil {
   729  		t.Error("clientHelloSpec cannot be nil")
   730  	}
   731  }