tlsDialer.go 27 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882
  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/hex"
  54. std_errors "errors"
  55. "io/ioutil"
  56. "net"
  57. "github.com/Psiphon-Labs/psiphon-tunnel-core/psiphon/common"
  58. "github.com/Psiphon-Labs/psiphon-tunnel-core/psiphon/common/errors"
  59. "github.com/Psiphon-Labs/psiphon-tunnel-core/psiphon/common/parameters"
  60. "github.com/Psiphon-Labs/psiphon-tunnel-core/psiphon/common/prng"
  61. "github.com/Psiphon-Labs/psiphon-tunnel-core/psiphon/common/protocol"
  62. tris "github.com/Psiphon-Labs/tls-tris"
  63. utls "github.com/refraction-networking/utls"
  64. )
  65. // CustomTLSConfig specifies the parameters for a CustomTLSDial, supporting
  66. // many TLS-related network obfuscation mechanisms.
  67. type CustomTLSConfig struct {
  68. // Parameters is the active set of parameters.Parameters to use for the TLS
  69. // dial. Must not be nil.
  70. Parameters *parameters.Parameters
  71. // Dial is the network connection dialer. TLS is layered on top of a new
  72. // network connection created with dialer. Must not be nil.
  73. Dial common.Dialer
  74. // DialAddr overrides the "addr" input to Dial when specified
  75. DialAddr string
  76. // UseDialAddrSNI specifies whether to always use the dial "addr"
  77. // host name in the SNI server_name field. When DialAddr is set,
  78. // its host name is used.
  79. UseDialAddrSNI bool
  80. // SNIServerName specifies the value to set in the SNI
  81. // server_name field. When blank, SNI is omitted. Note that
  82. // underlying TLS code also automatically omits SNI when
  83. // the server_name is an IP address.
  84. // SNIServerName is ignored when UseDialAddrSNI is true.
  85. SNIServerName string
  86. // VerifyServerName specifies a domain name that must appear in the server
  87. // certificate. When specified, certificate verification checks for
  88. // VerifyServerName in the server certificate, in place of the dial or SNI
  89. // hostname.
  90. VerifyServerName string
  91. // VerifyPins specifies one or more certificate pin values, one of which must
  92. // appear in the verified server certificate chain. A pin value is the
  93. // base64-encoded SHA2 digest of a certificate's public key. When specified,
  94. // at least one pin must match at least one certificate in the chain, at any
  95. // position; e.g., the root CA may be pinned, or the server certificate,
  96. // etc.
  97. VerifyPins []string
  98. // VerifyLegacyCertificate is a special case self-signed server
  99. // certificate case. Ignores IP SANs and basic constraints. No
  100. // certificate chain. Just checks that the server presented the
  101. // specified certificate.
  102. //
  103. // When VerifyLegacyCertificate is set, none of VerifyServerName, VerifyPins,
  104. // SkipVerify may be set.
  105. VerifyLegacyCertificate *x509.Certificate
  106. // SkipVerify completely disables server certificate verification.
  107. //
  108. // When SkipVerify is set, none of VerifyServerName, VerifyPins,
  109. // VerifyLegacyCertificate may be set.
  110. SkipVerify bool
  111. // TLSProfile specifies a particular indistinguishable TLS profile to use for
  112. // the TLS dial. Setting TLSProfile allows the caller to pin the selection so
  113. // all TLS connections in a certain context (e.g. a single meek connection)
  114. // use a consistent value. The value should be selected by calling
  115. // SelectTLSProfile, which will pick a value at random, subject to
  116. // compatibility constraints.
  117. //
  118. // When TLSProfile is "", a profile is selected at random and
  119. // DisableFrontingProviderTLSProfiles is ignored.
  120. TLSProfile string
  121. // NoDefaultTLSSessionID specifies whether to set a TLS session ID by
  122. // default, for a new TLS connection that is not resuming a session.
  123. // When nil, the parameter is set randomly.
  124. NoDefaultTLSSessionID *bool
  125. // RandomizedTLSProfileSeed specifies the PRNG seed to use when generating
  126. // a randomized TLS ClientHello, which applies to TLS profiles where
  127. // protocol.TLSProfileIsRandomized is true. The PRNG seed allows for
  128. // optional replay of a particular randomized Client Hello.
  129. RandomizedTLSProfileSeed *prng.Seed
  130. // TLSPadding indicates whether to move or add a TLS padding extension to the
  131. // front of the exension list and apply the specified padding length. Ignored
  132. // when 0.
  133. TLSPadding int
  134. // TrustedCACertificatesFilename specifies a file containing trusted
  135. // CA certs. See Config.TrustedCACertificatesFilename.
  136. TrustedCACertificatesFilename string
  137. // ObfuscatedSessionTicketKey enables obfuscated session tickets
  138. // using the specified key.
  139. ObfuscatedSessionTicketKey string
  140. // PassthroughMessage, when specified, is a 32 byte value that is sent in the
  141. // ClientHello random value field. The value should be generated using
  142. // obfuscator.MakeTLSPassthroughMessage.
  143. PassthroughMessage []byte
  144. clientSessionCache utls.ClientSessionCache
  145. }
  146. // EnableClientSessionCache initializes a cache to use to persist session
  147. // tickets, enabling TLS session resumability across multiple
  148. // CustomTLSDial calls or dialers using the same CustomTLSConfig.
  149. func (config *CustomTLSConfig) EnableClientSessionCache() {
  150. if config.clientSessionCache == nil {
  151. config.clientSessionCache = utls.NewLRUClientSessionCache(0)
  152. }
  153. }
  154. // NewCustomTLSDialer creates a new dialer based on CustomTLSDial.
  155. func NewCustomTLSDialer(config *CustomTLSConfig) common.Dialer {
  156. return func(ctx context.Context, network, addr string) (net.Conn, error) {
  157. return CustomTLSDial(ctx, network, addr, config)
  158. }
  159. }
  160. // CustomTLSDial dials a new TLS connection using the parameters set in
  161. // CustomTLSConfig.
  162. //
  163. // The dial aborts if ctx becomes Done before the dial completes.
  164. func CustomTLSDial(
  165. ctx context.Context,
  166. network, addr string,
  167. config *CustomTLSConfig) (net.Conn, error) {
  168. if (config.SkipVerify &&
  169. (config.VerifyLegacyCertificate != nil ||
  170. len(config.VerifyServerName) > 0 ||
  171. len(config.VerifyPins) > 0)) ||
  172. (config.VerifyLegacyCertificate != nil &&
  173. (config.SkipVerify ||
  174. len(config.VerifyServerName) > 0 ||
  175. len(config.VerifyPins) > 0)) {
  176. return nil, errors.TraceNew("incompatible certification verification parameters")
  177. }
  178. p := config.Parameters.Get()
  179. dialAddr := addr
  180. if config.DialAddr != "" {
  181. dialAddr = config.DialAddr
  182. }
  183. rawConn, err := config.Dial(ctx, network, dialAddr)
  184. if err != nil {
  185. return nil, errors.Trace(err)
  186. }
  187. hostname, _, err := net.SplitHostPort(dialAddr)
  188. if err != nil {
  189. rawConn.Close()
  190. return nil, errors.Trace(err)
  191. }
  192. var tlsConfigRootCAs *x509.CertPool
  193. if !config.SkipVerify &&
  194. config.VerifyLegacyCertificate == nil &&
  195. config.TrustedCACertificatesFilename != "" {
  196. tlsConfigRootCAs = x509.NewCertPool()
  197. certData, err := ioutil.ReadFile(config.TrustedCACertificatesFilename)
  198. if err != nil {
  199. return nil, errors.Trace(err)
  200. }
  201. tlsConfigRootCAs.AppendCertsFromPEM(certData)
  202. }
  203. // In some cases, config.SkipVerify is false, but
  204. // utls.Config.InsecureSkipVerify will be set to true to disable verification
  205. // in utls that will otherwise fail: when SNI is omitted, and when
  206. // VerifyServerName differs from SNI. In these cases, the certificate chain
  207. // is verified in VerifyPeerCertificate.
  208. tlsConfigInsecureSkipVerify := false
  209. tlsConfigServerName := ""
  210. verifyServerName := hostname
  211. if config.SkipVerify {
  212. tlsConfigInsecureSkipVerify = true
  213. }
  214. if config.UseDialAddrSNI {
  215. // Set SNI to match the dial hostname. This is the standard case.
  216. tlsConfigServerName = hostname
  217. } else if config.SNIServerName != "" {
  218. // Set a custom SNI value. If this value doesn't match the server
  219. // certificate, SkipVerify and/or VerifyServerName may need to be
  220. // configured; but by itself this case doesn't necessarily require
  221. // custom certificate verification.
  222. tlsConfigServerName = config.SNIServerName
  223. } else {
  224. // Omit SNI. If SkipVerify is not set, this case requires custom certificate
  225. // verification, which will check that the server certificate matches either
  226. // the dial hostname or VerifyServerName, as if the SNI were set to one of
  227. // those values.
  228. tlsConfigInsecureSkipVerify = true
  229. }
  230. // When VerifyServerName does not match the SNI, custom certificate
  231. // verification is necessary.
  232. if config.VerifyServerName != "" && config.VerifyServerName != tlsConfigServerName {
  233. verifyServerName = config.VerifyServerName
  234. tlsConfigInsecureSkipVerify = true
  235. }
  236. // With the VerifyPeerCertificate callback, we perform any custom certificate
  237. // verification at the same point in the TLS handshake as standard utls
  238. // verification; and abort the handshake at the same point, if custom
  239. // verification fails.
  240. var tlsConfigVerifyPeerCertificate func([][]byte, [][]*x509.Certificate) error
  241. if !config.SkipVerify {
  242. tlsConfigVerifyPeerCertificate = func(rawCerts [][]byte, verifiedChains [][]*x509.Certificate) error {
  243. if config.VerifyLegacyCertificate != nil {
  244. return verifyLegacyCertificate(
  245. rawCerts, config.VerifyLegacyCertificate)
  246. }
  247. if tlsConfigInsecureSkipVerify {
  248. // Limitation: this verification path does not set the utls.Conn's
  249. // ConnectionState certificate information.
  250. if len(verifiedChains) > 0 {
  251. return errors.TraceNew("unexpected verified chains")
  252. }
  253. var err error
  254. verifiedChains, err = verifyServerCertificate(
  255. tlsConfigRootCAs, rawCerts, verifyServerName)
  256. if err != nil {
  257. return errors.Trace(err)
  258. }
  259. }
  260. if len(config.VerifyPins) > 0 {
  261. err := verifyCertificatePins(
  262. config.VerifyPins, verifiedChains)
  263. if err != nil {
  264. return errors.Trace(err)
  265. }
  266. }
  267. return nil
  268. }
  269. }
  270. tlsConfig := &utls.Config{
  271. RootCAs: tlsConfigRootCAs,
  272. InsecureSkipVerify: tlsConfigInsecureSkipVerify,
  273. ServerName: tlsConfigServerName,
  274. VerifyPeerCertificate: tlsConfigVerifyPeerCertificate,
  275. }
  276. selectedTLSProfile := config.TLSProfile
  277. if selectedTLSProfile == "" {
  278. selectedTLSProfile = SelectTLSProfile(false, false, "", p)
  279. }
  280. utlsClientHelloID, utlsClientHelloSpec, err := getUTLSClientHelloID(
  281. p, selectedTLSProfile)
  282. if err != nil {
  283. return nil, errors.Trace(err)
  284. }
  285. var randomizedTLSProfileSeed *prng.Seed
  286. isRandomized := protocol.TLSProfileIsRandomized(selectedTLSProfile)
  287. if isRandomized {
  288. randomizedTLSProfileSeed = config.RandomizedTLSProfileSeed
  289. if randomizedTLSProfileSeed == nil {
  290. randomizedTLSProfileSeed, err = prng.NewSeed()
  291. if err != nil {
  292. return nil, errors.Trace(err)
  293. }
  294. }
  295. utlsClientHelloID.Seed = new(utls.PRNGSeed)
  296. *utlsClientHelloID.Seed = [32]byte(*randomizedTLSProfileSeed)
  297. }
  298. // As noted here,
  299. // https://gitlab.com/yawning/obfs4/commit/ca6765e3e3995144df2b1ca9f0e9d823a7f8a47c,
  300. // the dynamic record sizing optimization in crypto/tls is not commonly
  301. // implemented in browsers. Disable it for all utls parrots and select it
  302. // randomly when using the randomized client hello.
  303. if isRandomized {
  304. PRNG, err := prng.NewPRNGWithSaltedSeed(randomizedTLSProfileSeed, "tls-dynamic-record-sizing")
  305. if err != nil {
  306. return nil, errors.Trace(err)
  307. }
  308. tlsConfig.DynamicRecordSizingDisabled = PRNG.FlipCoin()
  309. } else {
  310. tlsConfig.DynamicRecordSizingDisabled = true
  311. }
  312. conn := utls.UClient(rawConn, tlsConfig, utlsClientHelloID)
  313. if utlsClientHelloSpec != nil {
  314. err := conn.ApplyPreset(utlsClientHelloSpec)
  315. if err != nil {
  316. return nil, errors.Trace(err)
  317. }
  318. }
  319. clientSessionCache := config.clientSessionCache
  320. if clientSessionCache == nil {
  321. clientSessionCache = utls.NewLRUClientSessionCache(0)
  322. }
  323. conn.SetSessionCache(clientSessionCache)
  324. // TODO: can conn.SetClientRandom be made to take effect if called here? In
  325. // testing, the random value appears to be overwritten. As is, the overhead
  326. // of needRemarshal is now always required to handle
  327. // config.PassthroughMessage.
  328. // Build handshake state in advance to obtain the TLS version, which is used
  329. // to determine whether the following customizations may be applied. Don't use
  330. // getClientHelloVersion, since that may incur additional overhead.
  331. err = conn.BuildHandshakeState()
  332. if err != nil {
  333. return nil, errors.Trace(err)
  334. }
  335. isTLS13 := false
  336. for _, vers := range conn.HandshakeState.Hello.SupportedVersions {
  337. if vers == utls.VersionTLS13 {
  338. isTLS13 = true
  339. break
  340. }
  341. }
  342. // Add the obfuscated session ticket only when using TLS 1.2.
  343. //
  344. // Obfuscated session tickets are not currently supported in TLS 1.3, but we
  345. // allow UNFRONTED-MEEK-SESSION-TICKET-OSSH to use TLS 1.3 profiles for
  346. // additional diversity/capacity; TLS 1.3 encrypts the server certificate,
  347. // so the desired obfuscated session tickets property of obfuscating server
  348. // certificates is satisfied. We know that when the ClientHello offers TLS
  349. // 1.3, the Psiphon server, in these direct protocol cases, will negotiate
  350. // it.
  351. if config.ObfuscatedSessionTicketKey != "" && !isTLS13 {
  352. var obfuscatedSessionTicketKey [32]byte
  353. key, err := hex.DecodeString(config.ObfuscatedSessionTicketKey)
  354. if err == nil && len(key) != 32 {
  355. err = std_errors.New("invalid obfuscated session key length")
  356. }
  357. if err != nil {
  358. return nil, errors.Trace(err)
  359. }
  360. copy(obfuscatedSessionTicketKey[:], key)
  361. obfuscatedSessionState, err := tris.NewObfuscatedClientSessionState(
  362. obfuscatedSessionTicketKey)
  363. if err != nil {
  364. return nil, errors.Trace(err)
  365. }
  366. conn.SetSessionState(
  367. utls.MakeClientSessionState(
  368. obfuscatedSessionState.SessionTicket,
  369. obfuscatedSessionState.Vers,
  370. obfuscatedSessionState.CipherSuite,
  371. obfuscatedSessionState.MasterSecret,
  372. nil,
  373. nil))
  374. // Apply changes to utls
  375. err = conn.BuildHandshakeState()
  376. if err != nil {
  377. return nil, errors.Trace(err)
  378. }
  379. // Ensure that TLS ClientHello has required session ticket extension and
  380. // obfuscated session ticket cipher suite; the latter is required by
  381. // utls/tls.Conn.loadSession. If these requirements are not met the
  382. // obfuscation session ticket would be ignored, so fail.
  383. if !tris.ContainsObfuscatedSessionTicketCipherSuite(
  384. conn.HandshakeState.Hello.CipherSuites) {
  385. return nil, errors.TraceNew(
  386. "missing obfuscated session ticket cipher suite")
  387. }
  388. if len(conn.HandshakeState.Hello.SessionTicket) == 0 {
  389. return nil, errors.TraceNew("missing session ticket extension")
  390. }
  391. }
  392. // Perform at most one remarshal for the following ClientHello
  393. // modifications.
  394. needRemarshal := false
  395. // Either pre-TLS 1.3 ClientHellos or any randomized ClientHello is a
  396. // candidate for NoDefaultSessionID logic.
  397. if len(conn.HandshakeState.Hello.SessionTicket) == 0 &&
  398. (!isTLS13 || utlsClientHelloID.Client == "Randomized") {
  399. var noDefaultSessionID bool
  400. if config.NoDefaultTLSSessionID != nil {
  401. noDefaultSessionID = *config.NoDefaultTLSSessionID
  402. } else {
  403. noDefaultSessionID = config.Parameters.Get().WeightedCoinFlip(
  404. parameters.NoDefaultTLSSessionIDProbability)
  405. }
  406. if noDefaultSessionID {
  407. conn.HandshakeState.Hello.SessionId = nil
  408. needRemarshal = true
  409. }
  410. }
  411. // utls doesn't omit the server_name extension when the ServerName value is
  412. // empty or an IP address. To avoid a fingerprintable invalid/unusual
  413. // server_name extension, remove it in these cases.
  414. if tlsConfigServerName == "" || net.ParseIP(tlsConfigServerName) != nil {
  415. // Assumes only one SNIExtension.
  416. // TODO: use new UConn.RemoveSNIExtension function?
  417. deleteIndex := -1
  418. for index, extension := range conn.Extensions {
  419. if _, ok := extension.(*utls.SNIExtension); ok {
  420. deleteIndex = index
  421. break
  422. }
  423. }
  424. if deleteIndex != -1 {
  425. conn.Extensions = append(
  426. conn.Extensions[:deleteIndex], conn.Extensions[deleteIndex+1:]...)
  427. }
  428. needRemarshal = true
  429. }
  430. if config.TLSPadding > 0 {
  431. tlsPadding := config.TLSPadding
  432. // Maximum padding size per RFC 7685
  433. if tlsPadding > 65535 {
  434. tlsPadding = 65535
  435. }
  436. // Assumes only one PaddingExtension.
  437. deleteIndex := -1
  438. for index, extension := range conn.Extensions {
  439. if _, ok := extension.(*utls.UtlsPaddingExtension); ok {
  440. deleteIndex = index
  441. break
  442. }
  443. }
  444. if deleteIndex != -1 {
  445. conn.Extensions = append(
  446. conn.Extensions[:deleteIndex], conn.Extensions[deleteIndex+1:]...)
  447. }
  448. paddingExtension := &utls.UtlsPaddingExtension{
  449. PaddingLen: tlsPadding,
  450. WillPad: true,
  451. }
  452. conn.Extensions = append([]utls.TLSExtension{paddingExtension}, conn.Extensions...)
  453. needRemarshal = true
  454. }
  455. if config.PassthroughMessage != nil {
  456. err := conn.SetClientRandom(config.PassthroughMessage)
  457. if err != nil {
  458. return nil, errors.Trace(err)
  459. }
  460. needRemarshal = true
  461. }
  462. if needRemarshal {
  463. // Apply changes to utls
  464. err = conn.MarshalClientHello()
  465. if err != nil {
  466. return nil, errors.Trace(err)
  467. }
  468. }
  469. // Perform the TLS Handshake.
  470. resultChannel := make(chan error)
  471. go func() {
  472. resultChannel <- conn.Handshake()
  473. }()
  474. select {
  475. case err = <-resultChannel:
  476. case <-ctx.Done():
  477. err = ctx.Err()
  478. // Interrupt the goroutine
  479. rawConn.Close()
  480. <-resultChannel
  481. }
  482. if err != nil {
  483. rawConn.Close()
  484. return nil, errors.Trace(err)
  485. }
  486. return conn, nil
  487. }
  488. func verifyLegacyCertificate(rawCerts [][]byte, expectedCertificate *x509.Certificate) error {
  489. if len(rawCerts) < 1 {
  490. return errors.TraceNew("missing certificate")
  491. }
  492. if !bytes.Equal(rawCerts[0], expectedCertificate.Raw) {
  493. return errors.TraceNew("unexpected certificate")
  494. }
  495. return nil
  496. }
  497. func verifyServerCertificate(
  498. rootCAs *x509.CertPool, rawCerts [][]byte, verifyServerName string) ([][]*x509.Certificate, error) {
  499. // This duplicates the verification logic in utls (and standard crypto/tls).
  500. certs := make([]*x509.Certificate, len(rawCerts))
  501. for i, rawCert := range rawCerts {
  502. cert, err := x509.ParseCertificate(rawCert)
  503. if err != nil {
  504. return nil, errors.Trace(err)
  505. }
  506. certs[i] = cert
  507. }
  508. opts := x509.VerifyOptions{
  509. Roots: rootCAs,
  510. DNSName: verifyServerName,
  511. Intermediates: x509.NewCertPool(),
  512. }
  513. for i, cert := range certs {
  514. if i == 0 {
  515. continue
  516. }
  517. opts.Intermediates.AddCert(cert)
  518. }
  519. verifiedChains, err := certs[0].Verify(opts)
  520. if err != nil {
  521. return nil, errors.Trace(err)
  522. }
  523. return verifiedChains, nil
  524. }
  525. func verifyCertificatePins(pins []string, verifiedChains [][]*x509.Certificate) error {
  526. for _, chain := range verifiedChains {
  527. for _, cert := range chain {
  528. publicKeyDigest := sha256.Sum256(cert.RawSubjectPublicKeyInfo)
  529. expectedPin := base64.StdEncoding.EncodeToString(publicKeyDigest[:])
  530. if common.Contains(pins, expectedPin) {
  531. // Return success on the first match of any certificate public key to any
  532. // pin.
  533. return nil
  534. }
  535. }
  536. }
  537. return errors.TraceNew("no pin found")
  538. }
  539. func IsTLSConnUsingHTTP2(conn net.Conn) bool {
  540. if c, ok := conn.(*utls.UConn); ok {
  541. state := c.ConnectionState()
  542. return state.NegotiatedProtocolIsMutual &&
  543. state.NegotiatedProtocol == "h2"
  544. }
  545. return false
  546. }
  547. // SelectTLSProfile picks a TLS profile at random from the available candidates.
  548. func SelectTLSProfile(
  549. requireTLS12SessionTickets bool,
  550. isFronted bool,
  551. frontingProviderID string,
  552. p parameters.ParametersAccessor) string {
  553. // Two TLS profile lists are constructed, subject to limit constraints:
  554. // stock, fixed parrots (non-randomized SupportedTLSProfiles) and custom
  555. // parrots (CustomTLSProfileNames); and randomized. If one list is empty, the
  556. // non-empty list is used. Otherwise SelectRandomizedTLSProfileProbability
  557. // determines which list is used.
  558. //
  559. // Note that LimitTLSProfiles is not applied to CustomTLSProfiles; the
  560. // presence of a candidate in CustomTLSProfiles is treated as explicit
  561. // enabling.
  562. //
  563. // UseOnlyCustomTLSProfiles may be used to disable all stock TLS profiles and
  564. // use only CustomTLSProfiles; UseOnlyCustomTLSProfiles is ignored if
  565. // CustomTLSProfiles is empty.
  566. //
  567. // For fronted servers, DisableFrontingProviderTLSProfiles may be used
  568. // to disable TLS profiles which are incompatible with the TLS stack used
  569. // by the front. For example, if a utls parrot doesn't fully support all
  570. // of the capabilities in the ClientHello. Unlike the LimitTLSProfiles case,
  571. // DisableFrontingProviderTLSProfiles may disable CustomTLSProfiles.
  572. limitTLSProfiles := p.TLSProfiles(parameters.LimitTLSProfiles)
  573. var disableTLSProfiles protocol.TLSProfiles
  574. if isFronted && frontingProviderID != "" {
  575. disableTLSProfiles = p.LabeledTLSProfiles(
  576. parameters.DisableFrontingProviderTLSProfiles, frontingProviderID)
  577. }
  578. randomizedTLSProfiles := make([]string, 0)
  579. parrotTLSProfiles := make([]string, 0)
  580. for _, tlsProfile := range p.CustomTLSProfileNames() {
  581. if !common.Contains(disableTLSProfiles, tlsProfile) {
  582. parrotTLSProfiles = append(parrotTLSProfiles, tlsProfile)
  583. }
  584. }
  585. useOnlyCustomTLSProfiles := p.Bool(parameters.UseOnlyCustomTLSProfiles)
  586. if useOnlyCustomTLSProfiles && len(parrotTLSProfiles) == 0 {
  587. useOnlyCustomTLSProfiles = false
  588. }
  589. if !useOnlyCustomTLSProfiles {
  590. for _, tlsProfile := range protocol.SupportedTLSProfiles {
  591. if len(limitTLSProfiles) > 0 &&
  592. !common.Contains(limitTLSProfiles, tlsProfile) {
  593. continue
  594. }
  595. if common.Contains(disableTLSProfiles, tlsProfile) {
  596. continue
  597. }
  598. // requireTLS12SessionTickets is specified for
  599. // UNFRONTED-MEEK-SESSION-TICKET-OSSH, a protocol which depends on using
  600. // obfuscated session tickets to ensure that the server doesn't send its
  601. // certificate in the TLS handshake. TLS 1.2 profiles which omit session
  602. // tickets should not be selected. As TLS 1.3 encrypts the server
  603. // certificate message, there's no exclusion for TLS 1.3.
  604. if requireTLS12SessionTickets &&
  605. protocol.TLS12ProfileOmitsSessionTickets(tlsProfile) {
  606. continue
  607. }
  608. if protocol.TLSProfileIsRandomized(tlsProfile) {
  609. randomizedTLSProfiles = append(randomizedTLSProfiles, tlsProfile)
  610. } else {
  611. parrotTLSProfiles = append(parrotTLSProfiles, tlsProfile)
  612. }
  613. }
  614. }
  615. if len(randomizedTLSProfiles) > 0 &&
  616. (len(parrotTLSProfiles) == 0 ||
  617. p.WeightedCoinFlip(parameters.SelectRandomizedTLSProfileProbability)) {
  618. return randomizedTLSProfiles[prng.Intn(len(randomizedTLSProfiles))]
  619. }
  620. if len(parrotTLSProfiles) == 0 {
  621. return ""
  622. }
  623. return parrotTLSProfiles[prng.Intn(len(parrotTLSProfiles))]
  624. }
  625. func getUTLSClientHelloID(
  626. p parameters.ParametersAccessor,
  627. tlsProfile string) (utls.ClientHelloID, *utls.ClientHelloSpec, error) {
  628. switch tlsProfile {
  629. // IMPORTANT: when adding new cases here, also add to
  630. // getClientHelloVersion below.
  631. case protocol.TLS_PROFILE_IOS_111:
  632. return utls.HelloIOS_11_1, nil, nil
  633. case protocol.TLS_PROFILE_IOS_121:
  634. return utls.HelloIOS_12_1, nil, nil
  635. case protocol.TLS_PROFILE_IOS_13:
  636. return utls.HelloIOS_13, nil, nil
  637. case protocol.TLS_PROFILE_IOS_14:
  638. return utls.HelloIOS_14, nil, nil
  639. case protocol.TLS_PROFILE_CHROME_58:
  640. return utls.HelloChrome_58, nil, nil
  641. case protocol.TLS_PROFILE_CHROME_62:
  642. return utls.HelloChrome_62, nil, nil
  643. case protocol.TLS_PROFILE_CHROME_70:
  644. return utls.HelloChrome_70, nil, nil
  645. case protocol.TLS_PROFILE_CHROME_72:
  646. return utls.HelloChrome_72, nil, nil
  647. case protocol.TLS_PROFILE_CHROME_83:
  648. return utls.HelloChrome_83, nil, nil
  649. case protocol.TLS_PROFILE_CHROME_96:
  650. return utls.HelloChrome_96, nil, nil
  651. case protocol.TLS_PROFILE_CHROME_102:
  652. return utls.HelloChrome_102, nil, nil
  653. case protocol.TLS_PROFILE_FIREFOX_55:
  654. return utls.HelloFirefox_55, nil, nil
  655. case protocol.TLS_PROFILE_FIREFOX_56:
  656. return utls.HelloFirefox_56, nil, nil
  657. case protocol.TLS_PROFILE_FIREFOX_65:
  658. return utls.HelloFirefox_65, nil, nil
  659. case protocol.TLS_PROFILE_FIREFOX_99:
  660. return utls.HelloFirefox_99, nil, nil
  661. case protocol.TLS_PROFILE_FIREFOX_105:
  662. return utls.HelloFirefox_105, nil, nil
  663. case protocol.TLS_PROFILE_RANDOMIZED:
  664. return utls.HelloRandomized, nil, nil
  665. }
  666. // utls.HelloCustom with a utls.ClientHelloSpec is used for
  667. // CustomTLSProfiles.
  668. customTLSProfile := p.CustomTLSProfile(tlsProfile)
  669. if customTLSProfile == nil {
  670. return utls.HelloCustom,
  671. nil,
  672. errors.Tracef("unknown TLS profile: %s", tlsProfile)
  673. }
  674. utlsClientHelloSpec, err := customTLSProfile.GetClientHelloSpec()
  675. if err != nil {
  676. return utls.ClientHelloID{}, nil, errors.Trace(err)
  677. }
  678. return utls.HelloCustom, utlsClientHelloSpec, nil
  679. }
  680. func getClientHelloVersion(
  681. utlsClientHelloID utls.ClientHelloID,
  682. utlsClientHelloSpec *utls.ClientHelloSpec) (string, error) {
  683. switch utlsClientHelloID {
  684. case utls.HelloIOS_11_1, utls.HelloIOS_12_1,
  685. utls.HelloChrome_58, utls.HelloChrome_62,
  686. utls.HelloFirefox_55, utls.HelloFirefox_56:
  687. return protocol.TLS_VERSION_12, nil
  688. case utls.HelloChrome_70, utls.HelloChrome_72,
  689. utls.HelloChrome_83, utls.HelloChrome_96,
  690. utls.HelloChrome_102, utls.HelloFirefox_65,
  691. utls.HelloFirefox_99, utls.HelloFirefox_105,
  692. utls.HelloGolang:
  693. return protocol.TLS_VERSION_13, nil
  694. }
  695. // As utls.HelloRandomized/Custom may be either TLS 1.2 or TLS 1.3, we cannot
  696. // perform a simple ClientHello ID check. BuildHandshakeState is run, which
  697. // constructs the entire ClientHello.
  698. //
  699. // Assumes utlsClientHelloID.Seed has been set; otherwise the result is
  700. // ephemeral.
  701. //
  702. // BenchmarkRandomizedGetClientHelloVersion indicates that this operation
  703. // takes on the order of 0.05ms and allocates ~8KB for randomized client
  704. // hellos.
  705. conn := utls.UClient(
  706. nil,
  707. &utls.Config{InsecureSkipVerify: true},
  708. utlsClientHelloID)
  709. if utlsClientHelloSpec != nil {
  710. err := conn.ApplyPreset(utlsClientHelloSpec)
  711. if err != nil {
  712. return "", errors.Trace(err)
  713. }
  714. }
  715. err := conn.BuildHandshakeState()
  716. if err != nil {
  717. return "", errors.Trace(err)
  718. }
  719. for _, v := range conn.HandshakeState.Hello.SupportedVersions {
  720. if v == utls.VersionTLS13 {
  721. return protocol.TLS_VERSION_13, nil
  722. }
  723. }
  724. return protocol.TLS_VERSION_12, nil
  725. }
  726. func init() {
  727. // Favor compatibility over security. CustomTLSDial is used as an obfuscation
  728. // layer; users of CustomTLSDial, including meek and remote server list
  729. // downloads, don't depend on this TLS for its security properties.
  730. utls.EnableWeakCiphers()
  731. }