tlsDialer.go 39 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281
  1. /*
  2. * Copyright (c) 2015, 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. /*
  20. Copyright (c) 2012 The Go Authors. All rights reserved.
  21. Redistribution and use in source and binary forms, with or without
  22. modification, are permitted provided that the following conditions are
  23. met:
  24. * Redistributions of source code must retain the above copyright
  25. notice, this list of conditions and the following disclaimer.
  26. * Redistributions in binary form must reproduce the above
  27. copyright notice, this list of conditions and the following disclaimer
  28. in the documentation and/or other materials provided with the
  29. distribution.
  30. * Neither the name of Google Inc. nor the names of its
  31. contributors may be used to endorse or promote products derived from
  32. this software without specific prior written permission.
  33. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  34. "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  35. LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
  36. A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
  37. OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  38. SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
  39. LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  40. DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
  41. THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  42. (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
  43. OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  44. */
  45. // Originally based on https://gopkg.in/getlantern/tlsdialer.v1.
  46. package psiphon
  47. import (
  48. "bytes"
  49. "context"
  50. "crypto/x509"
  51. "encoding/binary"
  52. "encoding/hex"
  53. std_errors "errors"
  54. "io"
  55. "io/ioutil"
  56. "net"
  57. "sync/atomic"
  58. tls "github.com/Psiphon-Labs/psiphon-tls"
  59. "github.com/Psiphon-Labs/psiphon-tunnel-core/psiphon/common"
  60. "github.com/Psiphon-Labs/psiphon-tunnel-core/psiphon/common/errors"
  61. "github.com/Psiphon-Labs/psiphon-tunnel-core/psiphon/common/parameters"
  62. "github.com/Psiphon-Labs/psiphon-tunnel-core/psiphon/common/prng"
  63. "github.com/Psiphon-Labs/psiphon-tunnel-core/psiphon/common/protocol"
  64. utls "github.com/Psiphon-Labs/utls"
  65. )
  66. // CustomTLSConfig specifies the parameters for a CustomTLSDial, supporting
  67. // many TLS-related network obfuscation mechanisms.
  68. type CustomTLSConfig struct {
  69. // Parameters is the active set of parameters.Parameters to use for the TLS
  70. // dial. Must not be nil.
  71. Parameters *parameters.Parameters
  72. // Dial is the network connection dialer. TLS is layered on top of a new
  73. // network connection created with dialer. Must not be nil.
  74. Dial common.Dialer
  75. // DialAddr overrides the "addr" input to Dial when specified
  76. DialAddr string
  77. // UseDialAddrSNI specifies whether to always use the dial "addr"
  78. // host name in the SNI server_name field. When DialAddr is set,
  79. // its host name is used.
  80. UseDialAddrSNI bool
  81. // SNIServerName specifies the value to set in the SNI
  82. // server_name field. When blank, SNI is omitted. Note that
  83. // underlying TLS code also automatically omits SNI when
  84. // the server_name is an IP address.
  85. // SNIServerName is ignored when UseDialAddrSNI is true.
  86. SNIServerName string
  87. // DisableSystemRootCAs, when true, disables loading system root CAs when
  88. // verifying the server certificate chain. Set DisableSystemRootCAs only in
  89. // cases where system root CAs cannot be loaded and there is additional
  90. // security at the payload level; for example, if unsupported (iOS < 12) or
  91. // insufficient memory (VPN extension on iOS < 15).
  92. //
  93. // When DisableSystemRootCAs is set, VerifyServerName, VerifyPins, and
  94. // VerifyLegacyCertificate must not be set.
  95. DisableSystemRootCAs bool
  96. // VerifyServerName specifies a domain name that must appear in the server
  97. // certificate. When specified, certificate verification checks for
  98. // VerifyServerName in the server certificate, in place of the dial or SNI
  99. // hostname.
  100. VerifyServerName string
  101. // VerifyPins specifies one or more certificate pin values, one of which must
  102. // appear in the verified server certificate chain. A pin value is the
  103. // base64-encoded SHA2 digest of a certificate's public key. When specified,
  104. // at least one pin must match at least one certificate in the chain, at any
  105. // position; e.g., the root CA may be pinned, or the server certificate,
  106. // etc.
  107. VerifyPins []string
  108. // VerifyLegacyCertificate is a special case self-signed server
  109. // certificate case. Ignores IP SANs and basic constraints. No
  110. // certificate chain. Just checks that the server presented the
  111. // specified certificate.
  112. //
  113. // When VerifyLegacyCertificate is set, none of VerifyServerName, VerifyPins,
  114. // SkipVerify may be set.
  115. VerifyLegacyCertificate *x509.Certificate
  116. // SkipVerify completely disables server certificate verification.
  117. //
  118. // When SkipVerify is set, none of VerifyServerName, VerifyPins,
  119. // VerifyLegacyCertificate may be set.
  120. SkipVerify bool
  121. // TLSProfile specifies a particular indistinguishable TLS profile to use for
  122. // the TLS dial. Setting TLSProfile allows the caller to pin the selection so
  123. // all TLS connections in a certain context (e.g. a single meek connection)
  124. // use a consistent value. The value should be selected by calling
  125. // SelectTLSProfile, which will pick a value at random, subject to
  126. // compatibility constraints.
  127. //
  128. // When TLSProfile is "", a profile is selected at random and
  129. // DisableFrontingProviderTLSProfiles is ignored.
  130. TLSProfile string
  131. // NoDefaultTLSSessionID specifies whether to set a TLS session ID by
  132. // default, for a new TLS connection that is not resuming a session.
  133. // When nil, the parameter is set randomly.
  134. NoDefaultTLSSessionID *bool
  135. // RandomizedTLSProfileSeed specifies the PRNG seed to use when generating
  136. // a randomized TLS ClientHello, which applies to TLS profiles where
  137. // protocol.TLSProfileIsRandomized is true. The PRNG seed allows for
  138. // optional replay of a particular randomized Client Hello.
  139. RandomizedTLSProfileSeed *prng.Seed
  140. // TLSPadding indicates whether to move or add a TLS padding extension to the
  141. // front of the exension list and apply the specified padding length. Ignored
  142. // when 0.
  143. TLSPadding int
  144. // TrustedCACertificatesFilename specifies a file containing trusted
  145. // CA certs. See Config.TrustedCACertificatesFilename.
  146. TrustedCACertificatesFilename string
  147. // ObfuscatedSessionTicketKey enables obfuscated session tickets
  148. // using the specified key.
  149. ObfuscatedSessionTicketKey string
  150. // PassthroughMessage, when specified, is a 32 byte value that is sent in the
  151. // ClientHello random value field. The value should be generated using
  152. // obfuscator.MakeTLSPassthroughMessage.
  153. PassthroughMessage []byte
  154. // FragmentClientHello specifies whether to fragment the ClientHello.
  155. FragmentClientHello bool
  156. // ClientSessionCache specifies the cache to use to persist session tickets.
  157. ClientSessionCache utls.ClientSessionCache
  158. }
  159. // NewCustomTLSDialer creates a new dialer based on CustomTLSDial.
  160. func NewCustomTLSDialer(config *CustomTLSConfig) common.Dialer {
  161. return func(ctx context.Context, network, addr string) (net.Conn, error) {
  162. return CustomTLSDial(ctx, network, addr, config)
  163. }
  164. }
  165. // CustomTLSDial dials a new TLS connection using the parameters set in
  166. // CustomTLSConfig.
  167. //
  168. // The dial aborts if ctx becomes Done before the dial completes.
  169. func CustomTLSDial(
  170. ctx context.Context,
  171. network, addr string,
  172. config *CustomTLSConfig) (net.Conn, error) {
  173. // Note that servers may return a chain which excludes the root CA
  174. // cert https://datatracker.ietf.org/doc/html/rfc8446#section-4.4.2.
  175. // It will not be possible to verify the certificate chain when
  176. // system root CAs cannot be loaded and the server omits the root CA
  177. // certificate from the chain.
  178. //
  179. // TODO: attempt to do some amount of certificate verification when
  180. // config.DisableSystemRootCAs is set. It would be possible to
  181. // verify the certificate chain, server name, and pins, when
  182. // config.TrustedCACertificatesFilename is set and contains the root
  183. // CA certificate of the certificate chain returned by the server. Also,
  184. // verifying legacy certificates does not require system root CAs, but
  185. // there is no code path which uses config.DisableSystemRootCAs in
  186. // conjuction with config.VerifyLegacyCertificate. As it stands
  187. // config.DisableSystemRootCAs is only used on iOS < 15 and
  188. // config.VerifyLegacyCertificate is only used for Windows VPN mode.
  189. skipVerify := config.SkipVerify || config.DisableSystemRootCAs
  190. if (skipVerify &&
  191. (config.VerifyLegacyCertificate != nil ||
  192. len(config.VerifyServerName) > 0 ||
  193. len(config.VerifyPins) > 0)) ||
  194. (config.VerifyLegacyCertificate != nil &&
  195. (skipVerify ||
  196. len(config.VerifyServerName) > 0 ||
  197. len(config.VerifyPins) > 0)) {
  198. return nil, errors.TraceNew("incompatible certification verification parameters")
  199. }
  200. p := config.Parameters.Get()
  201. dialAddr := addr
  202. if config.DialAddr != "" {
  203. dialAddr = config.DialAddr
  204. }
  205. underlyingConn, err := config.Dial(ctx, network, dialAddr)
  206. if err != nil {
  207. return nil, errors.Trace(err)
  208. }
  209. // If the hard-coded session key is not set (e.g. FRONTED-MEEK-OSSH), SetSessionKey must be called.
  210. // The session key is set to the resolved IP address.
  211. if wrappedCache, ok := config.ClientSessionCache.(*common.UtlsClientSessionCacheWrapper); ok {
  212. wrappedCache.SetSessionKey(underlyingConn.RemoteAddr().String())
  213. }
  214. if config.FragmentClientHello {
  215. underlyingConn = NewTLSFragmentorConn(underlyingConn)
  216. }
  217. hostname, _, err := net.SplitHostPort(dialAddr)
  218. if err != nil {
  219. underlyingConn.Close()
  220. return nil, errors.Trace(err)
  221. }
  222. var tlsConfigRootCAs *x509.CertPool
  223. if !skipVerify &&
  224. config.VerifyLegacyCertificate == nil &&
  225. config.TrustedCACertificatesFilename != "" {
  226. tlsConfigRootCAs = x509.NewCertPool()
  227. certData, err := ioutil.ReadFile(config.TrustedCACertificatesFilename)
  228. if err != nil {
  229. return nil, errors.Trace(err)
  230. }
  231. tlsConfigRootCAs.AppendCertsFromPEM(certData)
  232. }
  233. // In some cases, skipVerify is false, but
  234. // utls.Config.InsecureSkipVerify will be set to true to disable verification
  235. // in utls that will otherwise fail: when SNI is omitted, and when
  236. // VerifyServerName differs from SNI. In these cases, the certificate chain
  237. // is verified in VerifyPeerCertificate.
  238. tlsConfigInsecureSkipVerify := false
  239. tlsConfigServerName := ""
  240. verifyServerName := hostname
  241. if skipVerify {
  242. tlsConfigInsecureSkipVerify = true
  243. }
  244. if config.UseDialAddrSNI {
  245. // Set SNI to match the dial hostname. This is the standard case.
  246. tlsConfigServerName = hostname
  247. } else if config.SNIServerName != "" {
  248. // Set a custom SNI value. If this value doesn't match the server
  249. // certificate, SkipVerify and/or VerifyServerName may need to be
  250. // configured; but by itself this case doesn't necessarily require
  251. // custom certificate verification.
  252. tlsConfigServerName = config.SNIServerName
  253. } else {
  254. // Omit SNI. If SkipVerify is not set, this case requires custom certificate
  255. // verification, which will check that the server certificate matches either
  256. // the dial hostname or VerifyServerName, as if the SNI were set to one of
  257. // those values.
  258. tlsConfigInsecureSkipVerify = true
  259. }
  260. // When VerifyServerName does not match the SNI, custom certificate
  261. // verification is necessary.
  262. if config.VerifyServerName != "" && config.VerifyServerName != tlsConfigServerName {
  263. verifyServerName = config.VerifyServerName
  264. tlsConfigInsecureSkipVerify = true
  265. }
  266. // With the VerifyPeerCertificate callback, we perform any custom certificate
  267. // verification at the same point in the TLS handshake as standard utls
  268. // verification; and abort the handshake at the same point, if custom
  269. // verification fails.
  270. var tlsConfigVerifyPeerCertificate func([][]byte, [][]*x509.Certificate) error
  271. if !skipVerify {
  272. tlsConfigVerifyPeerCertificate = func(rawCerts [][]byte, verifiedChains [][]*x509.Certificate) error {
  273. if config.VerifyLegacyCertificate != nil {
  274. return verifyLegacyCertificate(
  275. rawCerts, config.VerifyLegacyCertificate)
  276. }
  277. if tlsConfigInsecureSkipVerify {
  278. // Limitation: this verification path does not set the utls.Conn's
  279. // ConnectionState certificate information.
  280. if len(verifiedChains) > 0 {
  281. return errors.TraceNew("unexpected verified chains")
  282. }
  283. var err error
  284. verifiedChains, err = common.VerifyServerCertificate(
  285. tlsConfigRootCAs, rawCerts, verifyServerName)
  286. if err != nil {
  287. return errors.Trace(err)
  288. }
  289. }
  290. if len(config.VerifyPins) > 0 {
  291. err := common.VerifyCertificatePins(
  292. config.VerifyPins, verifiedChains)
  293. if err != nil {
  294. return errors.Trace(err)
  295. }
  296. }
  297. return nil
  298. }
  299. }
  300. tlsConfig := &utls.Config{
  301. RootCAs: tlsConfigRootCAs,
  302. InsecureSkipVerify: tlsConfigInsecureSkipVerify,
  303. InsecureSkipTimeVerify: tlsConfigInsecureSkipVerify,
  304. ServerName: tlsConfigServerName,
  305. VerifyPeerCertificate: tlsConfigVerifyPeerCertificate,
  306. OmitEmptyPsk: true,
  307. AlwaysIncludePSK: true,
  308. }
  309. var randomizedTLSProfileSeed *prng.Seed
  310. selectedTLSProfile := config.TLSProfile
  311. if selectedTLSProfile == "" {
  312. selectedTLSProfile, _, randomizedTLSProfileSeed, err = SelectTLSProfile(false, false, false, "", p)
  313. if err != nil {
  314. return nil, errors.Trace(err)
  315. }
  316. }
  317. utlsClientHelloID, utlsClientHelloSpec, err := getUTLSClientHelloID(
  318. p, selectedTLSProfile)
  319. if err != nil {
  320. return nil, errors.Trace(err)
  321. }
  322. isRandomized := protocol.TLSProfileIsRandomized(selectedTLSProfile)
  323. if isRandomized {
  324. // Give config.RandomizedTLSProfileSeed precedence over the seed
  325. // generated by SelectTLSProfile if selectedTLSProfile == "".
  326. if config.RandomizedTLSProfileSeed != nil {
  327. randomizedTLSProfileSeed = config.RandomizedTLSProfileSeed
  328. }
  329. if randomizedTLSProfileSeed == nil {
  330. randomizedTLSProfileSeed, err = prng.NewSeed()
  331. if err != nil {
  332. return nil, errors.Trace(err)
  333. }
  334. }
  335. utlsClientHelloID.Seed = new(utls.PRNGSeed)
  336. *utlsClientHelloID.Seed = [32]byte(*randomizedTLSProfileSeed)
  337. weights := utls.DefaultWeights
  338. weights.TLSVersMax_Set_VersionTLS13 = 0.5
  339. utlsClientHelloID.Weights = &weights
  340. }
  341. // As noted here,
  342. // https://gitlab.com/yawning/obfs4/commit/ca6765e3e3995144df2b1ca9f0e9d823a7f8a47c,
  343. // the dynamic record sizing optimization in crypto/tls is not commonly
  344. // implemented in browsers. Disable it for all utls parrots and select it
  345. // randomly when using the randomized client hello.
  346. if isRandomized {
  347. PRNG, err := prng.NewPRNGWithSaltedSeed(randomizedTLSProfileSeed, "tls-dynamic-record-sizing")
  348. if err != nil {
  349. return nil, errors.Trace(err)
  350. }
  351. tlsConfig.DynamicRecordSizingDisabled = PRNG.FlipCoin()
  352. } else {
  353. tlsConfig.DynamicRecordSizingDisabled = true
  354. }
  355. conn := utls.UClient(underlyingConn, tlsConfig, utlsClientHelloID)
  356. if utlsClientHelloSpec != nil {
  357. err := conn.ApplyPreset(utlsClientHelloSpec)
  358. if err != nil {
  359. return nil, errors.Trace(err)
  360. }
  361. }
  362. clientSessionCache := config.ClientSessionCache
  363. if clientSessionCache == nil {
  364. clientSessionCache = utls.NewLRUClientSessionCache(0)
  365. }
  366. conn.SetSessionCache(clientSessionCache)
  367. // TODO: can conn.SetClientRandom be made to take effect if called here? In
  368. // testing, the random value appears to be overwritten. As is, the overhead
  369. // of needRemarshal is now always required to handle
  370. // config.PassthroughMessage.
  371. // Build handshake state in advance to obtain the TLS version, which is used
  372. // to determine whether the following customizations may be applied. Don't use
  373. // getClientHelloVersion, since that may incur additional overhead.
  374. err = conn.BuildHandshakeStateWithoutSession()
  375. if err != nil {
  376. return nil, errors.Trace(err)
  377. }
  378. isTLS13 := false
  379. for _, vers := range conn.HandshakeState.Hello.SupportedVersions {
  380. if vers == utls.VersionTLS13 {
  381. isTLS13 = true
  382. break
  383. }
  384. }
  385. useEms := conn.HandshakeState.Hello.Ems
  386. if config.ObfuscatedSessionTicketKey == "" {
  387. err = conn.BuildHandshakeState()
  388. if err != nil {
  389. return nil, errors.Trace(err)
  390. }
  391. } else {
  392. // Add the obfuscated session ticket or obfuscated PSK.
  393. var obfuscatedSessionTicketKey [32]byte
  394. key, err := hex.DecodeString(config.ObfuscatedSessionTicketKey)
  395. if err == nil && len(key) != 32 {
  396. err = std_errors.New("invalid obfuscated session key length")
  397. }
  398. if err != nil {
  399. return nil, errors.Trace(err)
  400. }
  401. copy(obfuscatedSessionTicketKey[:], key) // shared secret
  402. obfuscatedSessionState, err := tls.NewObfuscatedClientSessionState(
  403. obfuscatedSessionTicketKey, isTLS13, useEms)
  404. if err != nil {
  405. return nil, errors.Trace(err)
  406. }
  407. sessionState := utls.MakeClientSessionState(
  408. obfuscatedSessionState.SessionTicket,
  409. obfuscatedSessionState.Vers,
  410. obfuscatedSessionState.CipherSuite,
  411. obfuscatedSessionState.MasterSecret,
  412. nil, nil)
  413. sessionState.SetCreatedAt(obfuscatedSessionState.CreatedAt)
  414. sessionState.SetEMS(obfuscatedSessionState.ExtMasterSecret)
  415. // TLS 1.3-only fields
  416. sessionState.SetAgeAdd(obfuscatedSessionState.AgeAdd)
  417. sessionState.SetUseBy(obfuscatedSessionState.UseBy)
  418. if isTLS13 {
  419. // Sets OOB PSK if required.
  420. if containsPSKExt(utlsClientHelloID, utlsClientHelloSpec) {
  421. if wrappedCache, ok := clientSessionCache.(*common.UtlsClientSessionCacheWrapper); ok {
  422. wrappedCache.Put("", sessionState)
  423. } else {
  424. return nil, errors.TraceNew("unexpected clientSessionCache type")
  425. }
  426. }
  427. } else {
  428. err := conn.SetSessionState(sessionState)
  429. if err != nil {
  430. return nil, errors.Trace(err)
  431. }
  432. }
  433. // Apply changes to utls
  434. err = conn.BuildHandshakeState()
  435. if err != nil {
  436. return nil, errors.Trace(err)
  437. }
  438. // Ensure that TLS ClientHello has required session ticket or PSK extension and
  439. // obfuscated session ticket or PSK cipher suite; the latter is required by
  440. // utls/tls.Conn.loadSession. If these requirements are not met the
  441. // obfuscation session ticket would be ignored, so fail.
  442. if isTLS13 {
  443. if containsPSKExt(utlsClientHelloID, utlsClientHelloSpec) {
  444. if !tls.ContainsObfuscatedPSKCipherSuite(
  445. conn.HandshakeState.Hello.CipherSuites) {
  446. return nil, errors.TraceNew("missing obfuscated PSK cipher suite")
  447. }
  448. if len(conn.HandshakeState.Hello.PskIdentities) == 0 {
  449. return nil, errors.TraceNew("missing PSK extension")
  450. }
  451. }
  452. } else {
  453. if !tls.ContainsObfuscatedSessionTicketCipherSuite(
  454. conn.HandshakeState.Hello.CipherSuites) {
  455. return nil, errors.TraceNew(
  456. "missing obfuscated session ticket cipher suite")
  457. }
  458. if len(conn.HandshakeState.Hello.SessionTicket) == 0 {
  459. return nil, errors.TraceNew("missing session ticket extension")
  460. }
  461. }
  462. }
  463. // Perform at most one remarshal for the following ClientHello
  464. // modifications.
  465. needRemarshal := false
  466. // Either pre-TLS 1.3 ClientHellos or any randomized ClientHello is a
  467. // candidate for NoDefaultSessionID logic.
  468. if len(conn.HandshakeState.Hello.SessionTicket) == 0 &&
  469. (!isTLS13 || utlsClientHelloID.Client == "Randomized") {
  470. var noDefaultSessionID bool
  471. if config.NoDefaultTLSSessionID != nil {
  472. noDefaultSessionID = *config.NoDefaultTLSSessionID
  473. } else {
  474. noDefaultSessionID = config.Parameters.Get().WeightedCoinFlip(
  475. parameters.NoDefaultTLSSessionIDProbability)
  476. }
  477. if noDefaultSessionID {
  478. conn.HandshakeState.Hello.SessionId = nil
  479. needRemarshal = true
  480. }
  481. }
  482. // utls doesn't omit the server_name extension when the ServerName value is
  483. // empty or an IP address. To avoid a fingerprintable invalid/unusual
  484. // server_name extension, remove it in these cases.
  485. if tlsConfigServerName == "" || net.ParseIP(tlsConfigServerName) != nil {
  486. // Assumes only one SNIExtension.
  487. // TODO: use new UConn.RemoveSNIExtension function?
  488. deleteIndex := -1
  489. for index, extension := range conn.Extensions {
  490. if _, ok := extension.(*utls.SNIExtension); ok {
  491. deleteIndex = index
  492. break
  493. }
  494. }
  495. if deleteIndex != -1 {
  496. conn.Extensions = append(
  497. conn.Extensions[:deleteIndex], conn.Extensions[deleteIndex+1:]...)
  498. }
  499. needRemarshal = true
  500. }
  501. if config.TLSPadding > 0 {
  502. tlsPadding := config.TLSPadding
  503. // Maximum padding size per RFC 7685
  504. if tlsPadding > 65535 {
  505. tlsPadding = 65535
  506. }
  507. // Assumes only one PaddingExtension.
  508. deleteIndex := -1
  509. for index, extension := range conn.Extensions {
  510. if _, ok := extension.(*utls.UtlsPaddingExtension); ok {
  511. deleteIndex = index
  512. break
  513. }
  514. }
  515. if deleteIndex != -1 {
  516. conn.Extensions = append(
  517. conn.Extensions[:deleteIndex], conn.Extensions[deleteIndex+1:]...)
  518. }
  519. paddingExtension := &utls.UtlsPaddingExtension{
  520. PaddingLen: tlsPadding,
  521. WillPad: true,
  522. }
  523. conn.Extensions = append([]utls.TLSExtension{paddingExtension}, conn.Extensions...)
  524. needRemarshal = true
  525. }
  526. if config.PassthroughMessage != nil {
  527. err := conn.SetClientRandom(config.PassthroughMessage)
  528. if err != nil {
  529. return nil, errors.Trace(err)
  530. }
  531. needRemarshal = true
  532. }
  533. if needRemarshal {
  534. // Apply changes to utls
  535. err = conn.MarshalClientHello()
  536. if err != nil {
  537. return nil, errors.Trace(err)
  538. }
  539. }
  540. // Perform the TLS Handshake.
  541. resultChannel := make(chan error)
  542. go func() {
  543. resultChannel <- conn.Handshake()
  544. }()
  545. select {
  546. case err = <-resultChannel:
  547. case <-ctx.Done():
  548. err = ctx.Err()
  549. // Interrupt the goroutine
  550. underlyingConn.Close()
  551. <-resultChannel
  552. }
  553. if err != nil {
  554. underlyingConn.Close()
  555. return nil, errors.Trace(err)
  556. }
  557. clientSentTicket := conn.ConnectionMetrics().ClientSentTicket
  558. didResume := conn.ConnectionState().DidResume
  559. return &tlsConn{
  560. Conn: conn,
  561. underlyingConn: underlyingConn,
  562. sentTicket: clientSentTicket,
  563. didResume: didResume,
  564. }, nil
  565. }
  566. type tlsConn struct {
  567. net.Conn
  568. underlyingConn net.Conn
  569. // TLS handshake states
  570. sentTicket bool
  571. didResume bool
  572. }
  573. func (conn *tlsConn) GetMetrics() common.LogFields {
  574. logFields := make(common.LogFields)
  575. // Include metrics, such as inproxy and fragmentor metrics, from the
  576. // underlying dial conn.
  577. underlyingMetrics, ok := conn.underlyingConn.(common.MetricsSource)
  578. if ok {
  579. logFields.Add(underlyingMetrics.GetMetrics())
  580. }
  581. sentTicket := "0"
  582. if conn.sentTicket {
  583. sentTicket = "1"
  584. }
  585. logFields["tls_sent_ticket"] = sentTicket
  586. didResume := "0"
  587. if conn.didResume {
  588. didResume = "1"
  589. }
  590. logFields["tls_did_resume"] = didResume
  591. return logFields
  592. }
  593. func verifyLegacyCertificate(rawCerts [][]byte, expectedCertificate *x509.Certificate) error {
  594. if len(rawCerts) < 1 {
  595. return errors.TraceNew("missing certificate")
  596. }
  597. if !bytes.Equal(rawCerts[0], expectedCertificate.Raw) {
  598. return errors.TraceNew("unexpected certificate")
  599. }
  600. return nil
  601. }
  602. func IsTLSConnUsingHTTP2(conn net.Conn) bool {
  603. if t, ok := conn.(*tlsConn); ok {
  604. if u, ok := t.Conn.(*utls.UConn); ok {
  605. state := u.ConnectionState()
  606. return state.NegotiatedProtocolIsMutual &&
  607. state.NegotiatedProtocol == "h2"
  608. }
  609. }
  610. return false
  611. }
  612. // SelectTLSProfile picks and returns a TLS profile at random from the
  613. // available candidates along with its version and a newly generated PRNG seed
  614. // if the profile is randomized, i.e. protocol.TLSProfileIsRandomized is true,
  615. // which should be used when generating a randomized TLS ClientHello.
  616. func SelectTLSProfile(
  617. requireTLS12SessionTickets bool,
  618. requireTLS13Support bool,
  619. isFronted bool,
  620. frontingProviderID string,
  621. p parameters.ParametersAccessor) (tlsProfile, tlsVersion string, randomizedTLSProfileSeed *prng.Seed, err error) {
  622. for i := 0; i < 1000; i++ {
  623. tlsProfile, tlsVersion, randomizedTLSProfileSeed, err = selectTLSProfile(requireTLS12SessionTickets, isFronted, frontingProviderID, p)
  624. if err != nil {
  625. return "", "", nil, errors.Trace(err)
  626. }
  627. if requireTLS13Support && tlsVersion != protocol.TLS_VERSION_13 {
  628. // Continue picking profiles at random until an eligible one is
  629. // chosen. It is okay to loop in this way because the probability of
  630. // selecting a TLS 1.3 profile is high enough that it should not
  631. // take too many iterations until one is chosen.
  632. continue
  633. }
  634. return
  635. }
  636. return "", "", nil, errors.TraceNew("Failed to select a TLS profile")
  637. }
  638. // selectTLSProfile is a helper that picks and returns a TLS profile at random
  639. // from the available candidates along with its version and a newly generated
  640. // PRNG seed if the profile is randomized, i.e. protocol.TLSProfileIsRandomized
  641. // is true.
  642. func selectTLSProfile(
  643. requireTLS12SessionTickets bool,
  644. isFronted bool,
  645. frontingProviderID string,
  646. p parameters.ParametersAccessor) (tlsProfile string, tlsVersion string, randomizedTLSProfileSeed *prng.Seed, err error) {
  647. // Two TLS profile lists are constructed, subject to limit constraints:
  648. // stock, fixed parrots (non-randomized SupportedTLSProfiles) and custom
  649. // parrots (CustomTLSProfileNames); and randomized. If one list is empty, the
  650. // non-empty list is used. Otherwise SelectRandomizedTLSProfileProbability
  651. // determines which list is used.
  652. //
  653. // Note that LimitTLSProfiles is not applied to CustomTLSProfiles; the
  654. // presence of a candidate in CustomTLSProfiles is treated as explicit
  655. // enabling.
  656. //
  657. // UseOnlyCustomTLSProfiles may be used to disable all stock TLS profiles and
  658. // use only CustomTLSProfiles; UseOnlyCustomTLSProfiles is ignored if
  659. // CustomTLSProfiles is empty.
  660. //
  661. // For fronted servers, DisableFrontingProviderTLSProfiles may be used
  662. // to disable TLS profiles which are incompatible with the TLS stack used
  663. // by the front. For example, if a utls parrot doesn't fully support all
  664. // of the capabilities in the ClientHello. Unlike the LimitTLSProfiles case,
  665. // DisableFrontingProviderTLSProfiles may disable CustomTLSProfiles.
  666. limitTLSProfiles := p.TLSProfiles(parameters.LimitTLSProfiles)
  667. var disableTLSProfiles protocol.TLSProfiles
  668. if isFronted && frontingProviderID != "" {
  669. disableTLSProfiles = p.LabeledTLSProfiles(
  670. parameters.DisableFrontingProviderTLSProfiles, frontingProviderID)
  671. }
  672. randomizedTLSProfiles := make([]string, 0)
  673. parrotTLSProfiles := make([]string, 0)
  674. for _, tlsProfile := range p.CustomTLSProfileNames() {
  675. if !common.Contains(disableTLSProfiles, tlsProfile) {
  676. parrotTLSProfiles = append(parrotTLSProfiles, tlsProfile)
  677. }
  678. }
  679. useOnlyCustomTLSProfiles := p.Bool(parameters.UseOnlyCustomTLSProfiles)
  680. if useOnlyCustomTLSProfiles && len(parrotTLSProfiles) == 0 {
  681. useOnlyCustomTLSProfiles = false
  682. }
  683. if !useOnlyCustomTLSProfiles {
  684. for _, tlsProfile := range protocol.SupportedTLSProfiles {
  685. if len(limitTLSProfiles) > 0 &&
  686. !common.Contains(limitTLSProfiles, tlsProfile) {
  687. continue
  688. }
  689. if common.Contains(disableTLSProfiles, tlsProfile) {
  690. continue
  691. }
  692. // requireTLS12SessionTickets is specified for
  693. // UNFRONTED-MEEK-SESSION-TICKET-OSSH, a protocol which depends on using
  694. // obfuscated session tickets to ensure that the server doesn't send its
  695. // certificate in the TLS handshake. TLS 1.2 profiles which omit session
  696. // tickets should not be selected. As TLS 1.3 encrypts the server
  697. // certificate message, there's no exclusion for TLS 1.3.
  698. if requireTLS12SessionTickets &&
  699. protocol.TLS12ProfileOmitsSessionTickets(tlsProfile) {
  700. continue
  701. }
  702. if protocol.TLSProfileIsRandomized(tlsProfile) {
  703. randomizedTLSProfiles = append(randomizedTLSProfiles, tlsProfile)
  704. } else {
  705. parrotTLSProfiles = append(parrotTLSProfiles, tlsProfile)
  706. }
  707. }
  708. }
  709. if len(randomizedTLSProfiles) > 0 &&
  710. (len(parrotTLSProfiles) == 0 ||
  711. p.WeightedCoinFlip(parameters.SelectRandomizedTLSProfileProbability)) {
  712. tlsProfile = randomizedTLSProfiles[prng.Intn(len(randomizedTLSProfiles))]
  713. }
  714. if tlsProfile == "" {
  715. if len(parrotTLSProfiles) == 0 {
  716. return "", "", nil, nil
  717. } else {
  718. tlsProfile = parrotTLSProfiles[prng.Intn(len(parrotTLSProfiles))]
  719. }
  720. }
  721. utlsClientHelloID, utlsClientHelloSpec, err := getUTLSClientHelloID(
  722. p, tlsProfile)
  723. if err != nil {
  724. return "", "", nil, errors.Trace(err)
  725. }
  726. if protocol.TLSProfileIsRandomized(tlsProfile) {
  727. randomizedTLSProfileSeed, err = prng.NewSeed()
  728. if err != nil {
  729. return "", "", nil, errors.Trace(err)
  730. }
  731. utlsClientHelloID.Seed = new(utls.PRNGSeed)
  732. *utlsClientHelloID.Seed = [32]byte(*randomizedTLSProfileSeed)
  733. }
  734. tlsVersion, err = getClientHelloVersion(
  735. utlsClientHelloID, utlsClientHelloSpec)
  736. if err != nil {
  737. return "", "", nil, errors.Trace(err)
  738. }
  739. return tlsProfile, tlsVersion, randomizedTLSProfileSeed, nil
  740. }
  741. func getUTLSClientHelloID(
  742. p parameters.ParametersAccessor,
  743. tlsProfile string) (utls.ClientHelloID, *utls.ClientHelloSpec, error) {
  744. switch tlsProfile {
  745. // IMPORTANT: when adding new cases here, also add to
  746. // getClientHelloVersion below.
  747. case protocol.TLS_PROFILE_IOS_111:
  748. return utls.HelloIOS_11_1, nil, nil
  749. case protocol.TLS_PROFILE_IOS_121:
  750. return utls.HelloIOS_12_1, nil, nil
  751. case protocol.TLS_PROFILE_IOS_13:
  752. return utls.HelloIOS_13, nil, nil
  753. case protocol.TLS_PROFILE_IOS_14:
  754. return utls.HelloIOS_14, nil, nil
  755. case protocol.TLS_PROFILE_SAFARI_16:
  756. return utls.HelloSafari_16_0, nil, nil
  757. case protocol.TLS_PROFILE_CHROME_58:
  758. return utls.HelloChrome_58, nil, nil
  759. case protocol.TLS_PROFILE_CHROME_62:
  760. return utls.HelloChrome_62, nil, nil
  761. case protocol.TLS_PROFILE_CHROME_70:
  762. return utls.HelloChrome_70, nil, nil
  763. case protocol.TLS_PROFILE_CHROME_72:
  764. return utls.HelloChrome_72, nil, nil
  765. case protocol.TLS_PROFILE_CHROME_83:
  766. return utls.HelloChrome_83, nil, nil
  767. case protocol.TLS_PROFILE_CHROME_96:
  768. return utls.HelloChrome_96, nil, nil
  769. case protocol.TLS_PROFILE_CHROME_102:
  770. return utls.HelloChrome_102, nil, nil
  771. case protocol.TLS_PROFILE_CHROME_106:
  772. return utls.HelloChrome_106_Shuffle, nil, nil
  773. case protocol.TLS_PROFILE_CHROME_112_PSK:
  774. return utls.HelloChrome_112_PSK_Shuf, nil, nil
  775. case protocol.TLS_PROFILE_CHROME_120:
  776. return utls.HelloChrome_120, nil, nil
  777. case protocol.TLS_PROFILE_CHROME_120_PQ:
  778. return utls.HelloChrome_120_PQ, nil, nil
  779. case protocol.TLS_PROFILE_FIREFOX_55:
  780. return utls.HelloFirefox_55, nil, nil
  781. case protocol.TLS_PROFILE_FIREFOX_56:
  782. return utls.HelloFirefox_56, nil, nil
  783. case protocol.TLS_PROFILE_FIREFOX_65:
  784. return utls.HelloFirefox_65, nil, nil
  785. case protocol.TLS_PROFILE_FIREFOX_99:
  786. return utls.HelloFirefox_99, nil, nil
  787. case protocol.TLS_PROFILE_FIREFOX_105:
  788. return utls.HelloFirefox_105, nil, nil
  789. case protocol.TLS_PROFILE_RANDOMIZED:
  790. return utls.HelloRandomized, nil, nil
  791. }
  792. // utls.HelloCustom with a utls.ClientHelloSpec is used for
  793. // CustomTLSProfiles.
  794. customTLSProfile := p.CustomTLSProfile(tlsProfile)
  795. if customTLSProfile == nil {
  796. return utls.ClientHelloID{},
  797. nil,
  798. errors.Tracef("unknown TLS profile: %s", tlsProfile)
  799. }
  800. utlsClientHelloSpec, err := customTLSProfile.GetClientHelloSpec()
  801. if err != nil {
  802. return utls.ClientHelloID{}, nil, errors.Trace(err)
  803. }
  804. return utls.HelloCustom, utlsClientHelloSpec, nil
  805. }
  806. func getClientHelloVersion(
  807. utlsClientHelloID utls.ClientHelloID,
  808. utlsClientHelloSpec *utls.ClientHelloSpec) (string, error) {
  809. switch utlsClientHelloID {
  810. case utls.HelloIOS_11_1, utls.HelloIOS_12_1,
  811. utls.HelloChrome_58, utls.HelloChrome_62,
  812. utls.HelloFirefox_55, utls.HelloFirefox_56:
  813. return protocol.TLS_VERSION_12, nil
  814. case utls.HelloIOS_13, utls.HelloIOS_14,
  815. utls.HelloChrome_70, utls.HelloChrome_72,
  816. utls.HelloChrome_83, utls.HelloChrome_96,
  817. utls.HelloChrome_102, utls.HelloChrome_120,
  818. utls.HelloChrome_120_PQ, utls.HelloChrome_106_Shuffle,
  819. utls.HelloChrome_112_PSK_Shuf, utls.HelloFirefox_65,
  820. utls.HelloFirefox_99, utls.HelloFirefox_105,
  821. utls.HelloSafari_16_0, utls.HelloGolang:
  822. return protocol.TLS_VERSION_13, nil
  823. }
  824. // As utls.HelloRandomized/Custom may be either TLS 1.2 or TLS 1.3, we cannot
  825. // perform a simple ClientHello ID check. BuildHandshakeState is run, which
  826. // constructs the entire ClientHello.
  827. //
  828. // Assumes utlsClientHelloID.Seed has been set; otherwise the result is
  829. // ephemeral.
  830. //
  831. // BenchmarkRandomizedGetClientHelloVersion indicates that this operation
  832. // takes on the order of 0.05ms and allocates ~8KB for randomized client
  833. // hellos.
  834. conn := utls.UClient(
  835. nil,
  836. &utls.Config{InsecureSkipVerify: true},
  837. utlsClientHelloID)
  838. if utlsClientHelloSpec != nil {
  839. err := conn.ApplyPreset(utlsClientHelloSpec)
  840. if err != nil {
  841. return "", errors.Trace(err)
  842. }
  843. }
  844. err := conn.BuildHandshakeState()
  845. if err != nil {
  846. return "", errors.Trace(err)
  847. }
  848. for _, v := range conn.HandshakeState.Hello.SupportedVersions {
  849. if v == utls.VersionTLS13 {
  850. return protocol.TLS_VERSION_13, nil
  851. }
  852. }
  853. return protocol.TLS_VERSION_12, nil
  854. }
  855. func init() {
  856. // Favor compatibility over security. CustomTLSDial is used as an obfuscation
  857. // layer; users of CustomTLSDial, including meek and remote server list
  858. // downloads, don't depend on this TLS for its security properties.
  859. utls.EnableWeakCiphers()
  860. }
  861. type TLSFragmentorConn struct {
  862. net.Conn
  863. clientHelloSent int32
  864. }
  865. func NewTLSFragmentorConn(
  866. conn net.Conn,
  867. ) net.Conn {
  868. return &TLSFragmentorConn{
  869. Conn: conn,
  870. }
  871. }
  872. func (c *TLSFragmentorConn) Close() error {
  873. return c.Conn.Close()
  874. }
  875. func (c *TLSFragmentorConn) Read(b []byte) (n int, err error) {
  876. return c.Conn.Read(b)
  877. }
  878. func (c *TLSFragmentorConn) GetMetrics() common.LogFields {
  879. logFields := make(common.LogFields)
  880. // Include metrics, such as inproxy and fragmentor metrics, from the
  881. // underlying dial conn.
  882. underlyingMetrics, ok := c.Conn.(common.MetricsSource)
  883. if ok {
  884. logFields.Add(underlyingMetrics.GetMetrics())
  885. }
  886. return logFields
  887. }
  888. // Write transparently splits the first TLS record containing ClientHello into
  889. // two fragments and writes them separately to the underlying conn.
  890. // The second fragment contains the data portion of the SNI extension (i.e. the server name).
  891. // Write assumes a non-fragmented and complete ClientHello on the first call.
  892. func (c *TLSFragmentorConn) Write(b []byte) (n int, err error) {
  893. if atomic.LoadInt32(&c.clientHelloSent) == 0 {
  894. buf := bytes.NewReader(b)
  895. var contentType uint8
  896. err := binary.Read(buf, binary.BigEndian, &contentType)
  897. if err != nil {
  898. return 0, errors.Trace(err)
  899. }
  900. if contentType != 0x16 {
  901. return 0, errors.TraceNew("expected Handshake content type")
  902. }
  903. var version uint16
  904. err = binary.Read(buf, binary.BigEndian, &version)
  905. if err != nil {
  906. return 0, errors.Trace(err)
  907. }
  908. if version != 0x0303 && version != 0x0302 && version != 0x0301 {
  909. return 0, errors.TraceNew("expected TLS version 0x0303 or 0x0302 or 0x0301")
  910. }
  911. var msgLen uint16
  912. err = binary.Read(buf, binary.BigEndian, &msgLen)
  913. if err != nil {
  914. return 0, errors.Trace(err)
  915. }
  916. if len(b) != int(msgLen)+5 {
  917. return 0, errors.TraceNew("unexpected TLS message length")
  918. }
  919. var handshakeType uint8
  920. err = binary.Read(buf, binary.BigEndian, &handshakeType)
  921. if err != nil {
  922. return 0, errors.Trace(err)
  923. }
  924. if handshakeType != 0x01 {
  925. return 0, errors.TraceNew("expected ClientHello(1) handshake type")
  926. }
  927. var handshakeLen uint32
  928. err = binary.Read(buf, binary.BigEndian, &handshakeLen)
  929. if err != nil {
  930. return 0, errors.Trace(err)
  931. }
  932. handshakeLen >>= 8 // 24-bit value
  933. buf.UnreadByte() // Unread the last byte
  934. var legacyVersion uint16
  935. err = binary.Read(buf, binary.BigEndian, &legacyVersion)
  936. if err != nil {
  937. return 0, errors.Trace(err)
  938. }
  939. if legacyVersion != 0x0303 {
  940. return 0, errors.TraceNew("expected TLS version 0x0303")
  941. }
  942. // Skip random
  943. _, err = buf.Seek(32, io.SeekCurrent)
  944. if err != nil {
  945. return 0, errors.Trace(err)
  946. }
  947. var sessionIdLen uint8
  948. err = binary.Read(buf, binary.BigEndian, &sessionIdLen)
  949. if err != nil {
  950. return 0, errors.Trace(err)
  951. }
  952. if sessionIdLen > 32 {
  953. return 0, errors.TraceNew("unexpected session ID length")
  954. }
  955. // Skip session ID
  956. _, err = buf.Seek(int64(sessionIdLen), io.SeekCurrent)
  957. if err != nil {
  958. return 0, errors.Trace(err)
  959. }
  960. var cipherSuitesLen uint16
  961. err = binary.Read(buf, binary.BigEndian, &cipherSuitesLen)
  962. if err != nil {
  963. return 0, errors.Trace(err)
  964. }
  965. if cipherSuitesLen < 2 || cipherSuitesLen > 65535 {
  966. return 0, errors.TraceNew("unexpected cipher suites length")
  967. }
  968. // Skip cipher suites
  969. _, err = buf.Seek(int64(cipherSuitesLen), io.SeekCurrent)
  970. if err != nil {
  971. return 0, errors.Trace(err)
  972. }
  973. var compressionMethodsLen int8
  974. err = binary.Read(buf, binary.BigEndian, &compressionMethodsLen)
  975. if err != nil {
  976. return 0, errors.Trace(err)
  977. }
  978. if compressionMethodsLen < 1 || compressionMethodsLen > 32 {
  979. return 0, errors.TraceNew("unexpected compression methods length")
  980. }
  981. // Skip compression methods
  982. _, err = buf.Seek(int64(compressionMethodsLen), io.SeekCurrent)
  983. if err != nil {
  984. return 0, errors.Trace(err)
  985. }
  986. var extensionsLen uint16
  987. err = binary.Read(buf, binary.BigEndian, &extensionsLen)
  988. if err != nil {
  989. return 0, errors.Trace(err)
  990. }
  991. if extensionsLen < 2 || extensionsLen > 65535 {
  992. return 0, errors.TraceNew("unexpected extensions length")
  993. }
  994. // Finds SNI extension.
  995. for {
  996. if buf.Len() == 0 {
  997. return 0, errors.TraceNew("missing SNI extension")
  998. }
  999. var extensionType uint16
  1000. err = binary.Read(buf, binary.BigEndian, &extensionType)
  1001. if err != nil {
  1002. return 0, errors.Trace(err)
  1003. }
  1004. var extensionLen uint16
  1005. err = binary.Read(buf, binary.BigEndian, &extensionLen)
  1006. if err != nil {
  1007. return 0, errors.Trace(err)
  1008. }
  1009. // server_name(0) extension type
  1010. if extensionType == 0x0000 {
  1011. break
  1012. }
  1013. // Skip extension data
  1014. _, err = buf.Seek(int64(extensionLen), io.SeekCurrent)
  1015. if err != nil {
  1016. return 0, errors.Trace(err)
  1017. }
  1018. }
  1019. sniStartIndex := len(b) - buf.Len()
  1020. // Splits the ClientHello message into two fragments at sniStartIndex,
  1021. // and writes them separately to the underlying conn.
  1022. tlsMessage := b[5:]
  1023. frag1, frag2, err := splitTLSMessage(contentType, version, tlsMessage, sniStartIndex)
  1024. if err != nil {
  1025. return 0, errors.Trace(err)
  1026. }
  1027. n, err = c.Conn.Write(frag1)
  1028. if err != nil {
  1029. return n, errors.Trace(err)
  1030. }
  1031. n2, err := c.Conn.Write(frag2)
  1032. if err != nil {
  1033. return n + n2, errors.Trace(err)
  1034. }
  1035. atomic.CompareAndSwapInt32(&c.clientHelloSent, 0, 1)
  1036. return len(b), nil
  1037. }
  1038. return c.Conn.Write(b)
  1039. }
  1040. // splitTLSMessage splits a TLS message into two fragments.
  1041. // The two fragments are wrapped in TLS records.
  1042. func splitTLSMessage(contentType uint8, version uint16, msg []byte, splitIndex int) ([]byte, []byte, error) {
  1043. if splitIndex > len(msg)-1 {
  1044. return nil, nil, errors.TraceNew("split index out of range")
  1045. }
  1046. frag1 := make([]byte, splitIndex+5)
  1047. frag2 := make([]byte, len(msg)-splitIndex+5)
  1048. frag1[0] = byte(contentType)
  1049. binary.BigEndian.PutUint16(frag1[1:3], version)
  1050. binary.BigEndian.PutUint16(frag1[3:5], uint16(splitIndex))
  1051. copy(frag1[5:], msg[:splitIndex])
  1052. frag2[0] = byte(contentType)
  1053. binary.BigEndian.PutUint16(frag2[1:3], version)
  1054. binary.BigEndian.PutUint16(frag2[3:5], uint16(len(msg)-splitIndex))
  1055. copy(frag2[5:], msg[splitIndex:])
  1056. return frag1, frag2, nil
  1057. }
  1058. // containsPSKExt returns true if the ClientHelloSpec has a PreSharedKeyExtension.
  1059. // If spec is nil, the ClientHelloSpec is obtained from the ClientHelloID.
  1060. func containsPSKExt(id utls.ClientHelloID, spec *utls.ClientHelloSpec) bool {
  1061. if spec == nil {
  1062. myspec, err := utls.UTLSIdToSpec(id)
  1063. if err != nil {
  1064. return false
  1065. }
  1066. spec = &myspec
  1067. }
  1068. for _, ext := range spec.Extensions {
  1069. if _, ok := ext.(utls.PreSharedKeyExtension); ok {
  1070. return true
  1071. }
  1072. }
  1073. return false
  1074. }