customTLSProfiles_test.go 6.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189
  1. /*
  2. * Copyright (c) 2019, Psiphon Inc.
  3. * All rights reserved.
  4. *
  5. * This program is free software: you can redistribute it and/or modify
  6. * it under the terms of the GNU General Public License as published by
  7. * the Free Software Foundation, either version 3 of the License, or
  8. * (at your option) any later version.
  9. *
  10. * This program is distributed in the hope that it will be useful,
  11. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13. * GNU General Public License for more details.
  14. *
  15. * You should have received a copy of the GNU General Public License
  16. * along with this program. If not, see <http://www.gnu.org/licenses/>.
  17. *
  18. */
  19. package protocol
  20. import (
  21. "bytes"
  22. "crypto/sha256"
  23. "encoding/json"
  24. "testing"
  25. utls "github.com/refraction-networking/utls"
  26. )
  27. func TestCustomTLSProfiles(t *testing.T) {
  28. // Based on utls.HelloChrome_62. Some attributes have been removed to
  29. // eliminate randomness; and additional extensions have been added for extra
  30. // test coverage.
  31. utlsClientHelloSpec := &utls.ClientHelloSpec{
  32. TLSVersMax: utls.VersionTLS12,
  33. TLSVersMin: utls.VersionTLS10,
  34. CipherSuites: []uint16{
  35. utls.TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,
  36. utls.TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,
  37. utls.TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,
  38. utls.TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384,
  39. utls.TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305,
  40. utls.TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305,
  41. utls.TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA,
  42. utls.TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA,
  43. utls.TLS_RSA_WITH_AES_128_GCM_SHA256,
  44. utls.TLS_RSA_WITH_AES_256_GCM_SHA384,
  45. utls.TLS_RSA_WITH_AES_128_CBC_SHA,
  46. utls.TLS_RSA_WITH_AES_256_CBC_SHA,
  47. utls.TLS_RSA_WITH_3DES_EDE_CBC_SHA,
  48. },
  49. CompressionMethods: []byte{0},
  50. Extensions: []utls.TLSExtension{
  51. &utls.RenegotiationInfoExtension{Renegotiation: utls.RenegotiateOnceAsClient},
  52. &utls.SNIExtension{},
  53. &utls.UtlsExtendedMasterSecretExtension{},
  54. &utls.SessionTicketExtension{},
  55. &utls.SignatureAlgorithmsExtension{SupportedSignatureAlgorithms: []utls.SignatureScheme{
  56. utls.ECDSAWithP256AndSHA256,
  57. utls.PSSWithSHA256,
  58. utls.PKCS1WithSHA256,
  59. utls.ECDSAWithP384AndSHA384,
  60. utls.PSSWithSHA384,
  61. utls.PKCS1WithSHA384,
  62. utls.PSSWithSHA512,
  63. utls.PKCS1WithSHA512,
  64. utls.PKCS1WithSHA1},
  65. },
  66. &utls.StatusRequestExtension{},
  67. &utls.SCTExtension{},
  68. &utls.ALPNExtension{AlpnProtocols: []string{"h2", "http/1.1"}},
  69. &utls.FakeChannelIDExtension{},
  70. &utls.SupportedPointsExtension{SupportedPoints: []byte{0}},
  71. &utls.SupportedCurvesExtension{Curves: []utls.CurveID{
  72. utls.X25519, utls.CurveP256, utls.CurveP384}},
  73. &utls.UtlsPaddingExtension{GetPaddingLen: utls.BoringPaddingStyle},
  74. // Additional extensions for test coverage
  75. &utls.NPNExtension{NextProtos: []string{"http/1.1"}},
  76. &utls.GenericExtension{Id: 9999, Data: []byte("generic extension")},
  77. &utls.KeyShareExtension{KeyShares: []utls.KeyShare{
  78. {Group: utls.X25519, Data: []byte{9, 9, 9, 9}},
  79. }},
  80. &utls.PSKKeyExchangeModesExtension{Modes: []uint8{
  81. utls.PskModeDHE,
  82. }},
  83. &utls.SupportedVersionsExtension{Versions: []uint16{
  84. utls.VersionTLS13,
  85. utls.VersionTLS12,
  86. utls.VersionTLS11,
  87. utls.VersionTLS10,
  88. }},
  89. &utls.UtlsCompressCertExtension{Algorithms: []utls.CertCompressionAlgo{
  90. utls.CertCompressionBrotli,
  91. }},
  92. &utls.FakeChannelIDExtension{},
  93. &utls.FakeRecordSizeLimitExtension{Limit: 9999},
  94. },
  95. GetSessionID: sha256.Sum256,
  96. }
  97. customTLSProfilesJSON := []byte(`
  98. [
  99. {
  100. "Name": "CustomProfile",
  101. "UTLSSpec": {
  102. "TLSVersMax": 771,
  103. "TLSVersMin": 769,
  104. "CipherSuites": [49195, 49199, 49196, 49200, 52393, 52392, 49171, 49172, 156, 157, 47, 53, 10],
  105. "CompressionMethods": [0],
  106. "Extensions" : [
  107. {"Name": "RenegotiationInfo", "Data": {"Renegotiation": 1}},
  108. {"Name": "SNI"},
  109. {"Name": "ExtendedMasterSecret"},
  110. {"Name": "SessionTicket"},
  111. {"Name": "SignatureAlgorithms", "Data": {"SupportedSignatureAlgorithms": [1027, 2052, 1025, 1283, 2053, 1281, 2054, 1537, 513]}},
  112. {"Name": "StatusRequest"},
  113. {"Name": "SCT"},
  114. {"Name": "ALPN", "Data": {"AlpnProtocols": ["h2", "http/1.1"]}},
  115. {"Name": "ChannelID"},
  116. {"Name": "SupportedPoints", "Data": {"SupportedPoints": [0]}},
  117. {"Name": "SupportedCurves", "Data": {"Curves": [29, 23, 24]}},
  118. {"Name": "BoringPadding"},
  119. {"Name": "NPN", "Data": {"NextProtos": ["h2", "http/1.1"]}},
  120. {"Name": "Generic", "Data": {"Id": 9999, "Data": [103, 101, 110, 101, 114, 105, 99, 32, 101, 120, 116, 101, 110, 115, 105, 111, 110]}},
  121. {"Name": "KeyShare", "Data": {"KeyShares": [{"Group": 29, "Data": [9, 9, 9, 9]}]}},
  122. {"Name": "PSKKeyExchangeModes", "Data": {"Modes": [1]}},
  123. {"Name": "SupportedVersions", "Data": {"Versions": [772, 771, 770, 769]}},
  124. {"Name": "CertCompressionAlgs", "Data": {"Algorithms": [2]}},
  125. {"Name": "ChannelID"},
  126. {"Name": "RecordSizeLimit", "Data": {"Limit": 9999}}],
  127. "GetSessionID": "SHA-256"
  128. }
  129. }
  130. ]`)
  131. var customTLSProfiles CustomTLSProfiles
  132. err := json.Unmarshal(customTLSProfilesJSON, &customTLSProfiles)
  133. if err != nil {
  134. t.Fatalf("Unmarshal failed: %s", err)
  135. }
  136. err = customTLSProfiles.Validate()
  137. if err != nil {
  138. t.Fatalf("Validate failed: %s", err)
  139. }
  140. profile := customTLSProfiles[0]
  141. profileClientHelloSpec, err := profile.GetClientHelloSpec()
  142. if err != nil {
  143. t.Fatalf("GetClientHelloSpec failed: %s", err)
  144. }
  145. zeroes := make([]byte, 32)
  146. conn1 := utls.UClient(nil, &utls.Config{InsecureSkipVerify: true}, utls.HelloCustom)
  147. conn1.ApplyPreset(utlsClientHelloSpec)
  148. conn1.SetClientRandom(zeroes)
  149. conn1.HandshakeState.Hello.SessionId = zeroes
  150. err = conn1.BuildHandshakeState()
  151. if err != nil {
  152. t.Fatalf("BuildHandshakeState failed: %s", err)
  153. }
  154. conn2 := utls.UClient(nil, &utls.Config{InsecureSkipVerify: true}, utls.HelloCustom)
  155. conn2.ApplyPreset(profileClientHelloSpec)
  156. conn2.SetClientRandom(zeroes)
  157. conn2.HandshakeState.Hello.SessionId = zeroes
  158. err = conn2.BuildHandshakeState()
  159. if err != nil {
  160. t.Fatalf("BuildHandshakeState failed: %s", err)
  161. }
  162. if len(conn1.HandshakeState.Hello.Raw) == 0 {
  163. t.Fatalf("Missing raw ClientHello")
  164. }
  165. if len(conn2.HandshakeState.Hello.Raw) == 0 {
  166. t.Fatalf("Missing raw ClientHello")
  167. }
  168. if !bytes.Equal(conn1.HandshakeState.Hello.Raw, conn2.HandshakeState.Hello.Raw) {
  169. t.Fatalf("Unidentical raw ClientHellos")
  170. }
  171. }