tlsDialer.go 39 KB

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