u_conn.go 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649
  1. // Copyright 2017 Google Inc. All rights reserved.
  2. // Use of this source code is governed by a BSD-style
  3. // license that can be found in the LICENSE file.
  4. package tls
  5. import (
  6. "bufio"
  7. "bytes"
  8. "crypto/cipher"
  9. "encoding/binary"
  10. "errors"
  11. "fmt"
  12. "io"
  13. "net"
  14. "strconv"
  15. "sync/atomic"
  16. )
  17. type UConn struct {
  18. *Conn
  19. Extensions []TLSExtension
  20. ClientHelloID ClientHelloID
  21. ClientHelloBuilt bool
  22. HandshakeState ClientHandshakeState
  23. // sessionID may or may not depend on ticket; nil => random
  24. GetSessionID func(ticket []byte) [32]byte
  25. greaseSeed [ssl_grease_last_index]uint16
  26. omitSNIExtension bool
  27. // certCompressionAlgs represents the set of advertised certificate compression
  28. // algorithms, as specified in the ClientHello. This is only relevant client-side, for the
  29. // server certificate. All other forms of certificate compression are unsupported.
  30. certCompressionAlgs []CertCompressionAlgo
  31. }
  32. // UClient returns a new uTLS client, with behavior depending on clientHelloID.
  33. // Config CAN be nil, but make sure to eventually specify ServerName.
  34. func UClient(conn net.Conn, config *Config, clientHelloID ClientHelloID) *UConn {
  35. if config == nil {
  36. config = &Config{}
  37. }
  38. tlsConn := Conn{conn: conn, config: config, isClient: true}
  39. handshakeState := ClientHandshakeState{C: &tlsConn, Hello: &ClientHelloMsg{}}
  40. uconn := UConn{Conn: &tlsConn, ClientHelloID: clientHelloID, HandshakeState: handshakeState}
  41. uconn.HandshakeState.uconn = &uconn
  42. return &uconn
  43. }
  44. // BuildHandshakeState behavior varies based on ClientHelloID and
  45. // whether it was already called before.
  46. // If HelloGolang:
  47. // [only once] make default ClientHello and overwrite existing state
  48. // If any other mimicking ClientHelloID is used:
  49. // [only once] make ClientHello based on ID and overwrite existing state
  50. // [each call] apply uconn.Extensions config to internal crypto/tls structures
  51. // [each call] marshal ClientHello.
  52. //
  53. // BuildHandshakeState is automatically called before uTLS performs handshake,
  54. // amd should only be called explicitly to inspect/change fields of
  55. // default/mimicked ClientHello.
  56. func (uconn *UConn) BuildHandshakeState() error {
  57. if uconn.ClientHelloID == HelloGolang {
  58. if uconn.ClientHelloBuilt {
  59. return nil
  60. }
  61. // use default Golang ClientHello.
  62. hello, ecdheParams, err := uconn.makeClientHello()
  63. if err != nil {
  64. return err
  65. }
  66. uconn.HandshakeState.Hello = hello.getPublicPtr()
  67. uconn.HandshakeState.State13.EcdheParams = ecdheParams
  68. uconn.HandshakeState.C = uconn.Conn
  69. } else {
  70. if !uconn.ClientHelloBuilt {
  71. err := uconn.applyPresetByID(uconn.ClientHelloID)
  72. if err != nil {
  73. return err
  74. }
  75. if uconn.omitSNIExtension {
  76. uconn.removeSNIExtension()
  77. }
  78. }
  79. err := uconn.ApplyConfig()
  80. if err != nil {
  81. return err
  82. }
  83. err = uconn.MarshalClientHello()
  84. if err != nil {
  85. return err
  86. }
  87. }
  88. uconn.ClientHelloBuilt = true
  89. return nil
  90. }
  91. // SetSessionState sets the session ticket, which may be preshared or fake.
  92. // If session is nil, the body of session ticket extension will be unset,
  93. // but the extension itself still MAY be present for mimicking purposes.
  94. // Session tickets to be reused - use same cache on following connections.
  95. func (uconn *UConn) SetSessionState(session *ClientSessionState) error {
  96. uconn.HandshakeState.Session = session
  97. var sessionTicket []uint8
  98. if session != nil {
  99. sessionTicket = session.sessionTicket
  100. }
  101. uconn.HandshakeState.Hello.TicketSupported = true
  102. uconn.HandshakeState.Hello.SessionTicket = sessionTicket
  103. for _, ext := range uconn.Extensions {
  104. st, ok := ext.(*SessionTicketExtension)
  105. if !ok {
  106. continue
  107. }
  108. st.Session = session
  109. if session != nil {
  110. if len(session.SessionTicket()) > 0 {
  111. if uconn.GetSessionID != nil {
  112. sid := uconn.GetSessionID(session.SessionTicket())
  113. uconn.HandshakeState.Hello.SessionId = sid[:]
  114. return nil
  115. }
  116. }
  117. var sessionID [32]byte
  118. _, err := io.ReadFull(uconn.config.rand(), sessionID[:])
  119. if err != nil {
  120. return err
  121. }
  122. uconn.HandshakeState.Hello.SessionId = sessionID[:]
  123. }
  124. return nil
  125. }
  126. return nil
  127. }
  128. // If you want session tickets to be reused - use same cache on following connections
  129. func (uconn *UConn) SetSessionCache(cache ClientSessionCache) {
  130. uconn.config.ClientSessionCache = cache
  131. uconn.HandshakeState.Hello.TicketSupported = true
  132. }
  133. // SetClientRandom sets client random explicitly.
  134. // BuildHandshakeFirst() must be called before SetClientRandom.
  135. // r must to be 32 bytes long.
  136. func (uconn *UConn) SetClientRandom(r []byte) error {
  137. if len(r) != 32 {
  138. return errors.New("Incorrect client random length! Expected: 32, got: " + strconv.Itoa(len(r)))
  139. } else {
  140. uconn.HandshakeState.Hello.Random = make([]byte, 32)
  141. copy(uconn.HandshakeState.Hello.Random, r)
  142. return nil
  143. }
  144. }
  145. func (uconn *UConn) SetSNI(sni string) {
  146. hname := hostnameInSNI(sni)
  147. uconn.config.ServerName = hname
  148. for _, ext := range uconn.Extensions {
  149. sniExt, ok := ext.(*SNIExtension)
  150. if ok {
  151. sniExt.ServerName = hname
  152. }
  153. }
  154. }
  155. // RemoveSNIExtension removes SNI from the list of extensions sent in ClientHello
  156. // It returns an error when used with HelloGolang ClientHelloID
  157. func (uconn *UConn) RemoveSNIExtension() error {
  158. if uconn.ClientHelloID == HelloGolang {
  159. return fmt.Errorf("Cannot call RemoveSNIExtension on a UConn with a HelloGolang ClientHelloID")
  160. }
  161. uconn.omitSNIExtension = true
  162. return nil
  163. }
  164. func (uconn *UConn) removeSNIExtension() {
  165. filteredExts := make([]TLSExtension, 0, len(uconn.Extensions))
  166. for _, e := range uconn.Extensions {
  167. if _, ok := e.(*SNIExtension); !ok {
  168. filteredExts = append(filteredExts, e)
  169. }
  170. }
  171. uconn.Extensions = filteredExts
  172. }
  173. // Handshake runs the client handshake using given clientHandshakeState
  174. // Requires hs.hello, and, optionally, hs.session to be set.
  175. func (c *UConn) Handshake() error {
  176. c.handshakeMutex.Lock()
  177. defer c.handshakeMutex.Unlock()
  178. if err := c.handshakeErr; err != nil {
  179. return err
  180. }
  181. if c.handshakeComplete() {
  182. return nil
  183. }
  184. c.in.Lock()
  185. defer c.in.Unlock()
  186. if c.isClient {
  187. // [uTLS section begins]
  188. err := c.BuildHandshakeState()
  189. if err != nil {
  190. return err
  191. }
  192. // [uTLS section ends]
  193. c.handshakeErr = c.clientHandshake()
  194. } else {
  195. c.handshakeErr = c.serverHandshake()
  196. }
  197. if c.handshakeErr == nil {
  198. c.handshakes++
  199. } else {
  200. // If an error occurred during the hadshake try to flush the
  201. // alert that might be left in the buffer.
  202. c.flush()
  203. }
  204. if c.handshakeErr == nil && !c.handshakeComplete() {
  205. c.handshakeErr = errors.New("tls: internal error: handshake should have had a result")
  206. }
  207. return c.handshakeErr
  208. }
  209. // Copy-pasted from tls.Conn in its entirety. But c.Handshake() is now utls' one, not tls.
  210. // Write writes data to the connection.
  211. func (c *UConn) Write(b []byte) (int, error) {
  212. // interlock with Close below
  213. for {
  214. x := atomic.LoadInt32(&c.activeCall)
  215. if x&1 != 0 {
  216. return 0, errClosed
  217. }
  218. if atomic.CompareAndSwapInt32(&c.activeCall, x, x+2) {
  219. defer atomic.AddInt32(&c.activeCall, -2)
  220. break
  221. }
  222. }
  223. if err := c.Handshake(); err != nil {
  224. return 0, err
  225. }
  226. c.out.Lock()
  227. defer c.out.Unlock()
  228. if err := c.out.err; err != nil {
  229. return 0, err
  230. }
  231. if !c.handshakeComplete() {
  232. return 0, alertInternalError
  233. }
  234. if c.closeNotifySent {
  235. return 0, errShutdown
  236. }
  237. // SSL 3.0 and TLS 1.0 are susceptible to a chosen-plaintext
  238. // attack when using block mode ciphers due to predictable IVs.
  239. // This can be prevented by splitting each Application Data
  240. // record into two records, effectively randomizing the IV.
  241. //
  242. // https://www.openssl.org/~bodo/tls-cbc.txt
  243. // https://bugzilla.mozilla.org/show_bug.cgi?id=665814
  244. // https://www.imperialviolet.org/2012/01/15/beastfollowup.html
  245. var m int
  246. if len(b) > 1 && c.vers <= VersionTLS10 {
  247. if _, ok := c.out.cipher.(cipher.BlockMode); ok {
  248. n, err := c.writeRecordLocked(recordTypeApplicationData, b[:1])
  249. if err != nil {
  250. return n, c.out.setErrorLocked(err)
  251. }
  252. m, b = 1, b[1:]
  253. }
  254. }
  255. n, err := c.writeRecordLocked(recordTypeApplicationData, b)
  256. return n + m, c.out.setErrorLocked(err)
  257. }
  258. // clientHandshakeWithOneState checks that exactly one expected state is set (1.2 or 1.3)
  259. // and performs client TLS handshake with that state
  260. func (c *UConn) clientHandshake() (err error) {
  261. // [uTLS section begins]
  262. hello := c.HandshakeState.Hello.getPrivatePtr()
  263. defer func() { c.HandshakeState.Hello = hello.getPublicPtr() }()
  264. sessionIsAlreadySet := c.HandshakeState.Session != nil
  265. // after this point exactly 1 out of 2 HandshakeState pointers is non-nil,
  266. // useTLS13 variable tells which pointer
  267. // [uTLS section ends]
  268. if c.config == nil {
  269. c.config = defaultConfig()
  270. }
  271. // This may be a renegotiation handshake, in which case some fields
  272. // need to be reset.
  273. c.didResume = false
  274. // [uTLS section begins]
  275. // don't make new ClientHello, use hs.hello
  276. // preserve the checks from beginning and end of makeClientHello()
  277. if len(c.config.ServerName) == 0 && !c.config.InsecureSkipVerify {
  278. return errors.New("tls: either ServerName or InsecureSkipVerify must be specified in the tls.Config")
  279. }
  280. nextProtosLength := 0
  281. for _, proto := range c.config.NextProtos {
  282. if l := len(proto); l == 0 || l > 255 {
  283. return errors.New("tls: invalid NextProtos value")
  284. } else {
  285. nextProtosLength += 1 + l
  286. }
  287. }
  288. if nextProtosLength > 0xffff {
  289. return errors.New("tls: NextProtos values too large")
  290. }
  291. if c.handshakes > 0 {
  292. hello.secureRenegotiation = c.clientFinished[:]
  293. }
  294. // [uTLS section ends]
  295. cacheKey, session, earlySecret, binderKey := c.loadSession(hello)
  296. if cacheKey != "" && session != nil {
  297. defer func() {
  298. // If we got a handshake failure when resuming a session, throw away
  299. // the session ticket. See RFC 5077, Section 3.2.
  300. //
  301. // RFC 8446 makes no mention of dropping tickets on failure, but it
  302. // does require servers to abort on invalid binders, so we need to
  303. // delete tickets to recover from a corrupted PSK.
  304. if err != nil {
  305. c.config.ClientSessionCache.Put(cacheKey, nil)
  306. }
  307. }()
  308. }
  309. if !sessionIsAlreadySet { // uTLS: do not overwrite already set session
  310. err = c.SetSessionState(session)
  311. if err != nil {
  312. return
  313. }
  314. }
  315. if _, err := c.writeRecord(recordTypeHandshake, hello.marshal()); err != nil {
  316. return err
  317. }
  318. msg, err := c.readHandshake()
  319. if err != nil {
  320. return err
  321. }
  322. serverHello, ok := msg.(*serverHelloMsg)
  323. if !ok {
  324. c.sendAlert(alertUnexpectedMessage)
  325. return unexpectedMessageError(serverHello, msg)
  326. }
  327. if err := c.pickTLSVersion(serverHello); err != nil {
  328. return err
  329. }
  330. // uTLS: do not create new handshakeState, use existing one
  331. if c.vers == VersionTLS13 {
  332. hs13 := c.HandshakeState.toPrivate13()
  333. hs13.serverHello = serverHello
  334. hs13.hello = hello
  335. if !sessionIsAlreadySet {
  336. hs13.earlySecret = earlySecret
  337. hs13.binderKey = binderKey
  338. }
  339. // In TLS 1.3, session tickets are delivered after the handshake.
  340. err = hs13.handshake()
  341. if handshakeState := hs13.toPublic13(); handshakeState != nil {
  342. c.HandshakeState = *handshakeState
  343. }
  344. return err
  345. }
  346. hs12 := c.HandshakeState.toPrivate12()
  347. hs12.serverHello = serverHello
  348. hs12.hello = hello
  349. err = hs12.handshake()
  350. if handshakeState := hs12.toPublic12(); handshakeState != nil {
  351. c.HandshakeState = *handshakeState
  352. }
  353. if err != nil {
  354. return err
  355. }
  356. // If we had a successful handshake and hs.session is different from
  357. // the one already cached - cache a new one.
  358. if cacheKey != "" && hs12.session != nil && session != hs12.session {
  359. c.config.ClientSessionCache.Put(cacheKey, hs12.session)
  360. }
  361. return nil
  362. }
  363. func (uconn *UConn) ApplyConfig() error {
  364. for _, ext := range uconn.Extensions {
  365. err := ext.writeToUConn(uconn)
  366. if err != nil {
  367. return err
  368. }
  369. }
  370. return nil
  371. }
  372. func (uconn *UConn) MarshalClientHello() error {
  373. hello := uconn.HandshakeState.Hello
  374. headerLength := 2 + 32 + 1 + len(hello.SessionId) +
  375. 2 + len(hello.CipherSuites)*2 +
  376. 1 + len(hello.CompressionMethods)
  377. extensionsLen := 0
  378. var paddingExt *UtlsPaddingExtension
  379. for _, ext := range uconn.Extensions {
  380. if pe, ok := ext.(*UtlsPaddingExtension); !ok {
  381. // If not padding - just add length of extension to total length
  382. extensionsLen += ext.Len()
  383. } else {
  384. // If padding - process it later
  385. if paddingExt == nil {
  386. paddingExt = pe
  387. } else {
  388. return errors.New("Multiple padding extensions!")
  389. }
  390. }
  391. }
  392. if paddingExt != nil {
  393. // determine padding extension presence and length
  394. paddingExt.Update(headerLength + 4 + extensionsLen + 2)
  395. extensionsLen += paddingExt.Len()
  396. }
  397. helloLen := headerLength
  398. if len(uconn.Extensions) > 0 {
  399. helloLen += 2 + extensionsLen // 2 bytes for extensions' length
  400. }
  401. helloBuffer := bytes.Buffer{}
  402. bufferedWriter := bufio.NewWriterSize(&helloBuffer, helloLen+4) // 1 byte for tls record type, 3 for length
  403. // We use buffered Writer to avoid checking write errors after every Write(): whenever first error happens
  404. // Write() will become noop, and error will be accessible via Flush(), which is called once in the end
  405. binary.Write(bufferedWriter, binary.BigEndian, typeClientHello)
  406. helloLenBytes := []byte{byte(helloLen >> 16), byte(helloLen >> 8), byte(helloLen)} // poor man's uint24
  407. binary.Write(bufferedWriter, binary.BigEndian, helloLenBytes)
  408. binary.Write(bufferedWriter, binary.BigEndian, hello.Vers)
  409. binary.Write(bufferedWriter, binary.BigEndian, hello.Random)
  410. binary.Write(bufferedWriter, binary.BigEndian, uint8(len(hello.SessionId)))
  411. binary.Write(bufferedWriter, binary.BigEndian, hello.SessionId)
  412. binary.Write(bufferedWriter, binary.BigEndian, uint16(len(hello.CipherSuites)<<1))
  413. for _, suite := range hello.CipherSuites {
  414. binary.Write(bufferedWriter, binary.BigEndian, suite)
  415. }
  416. binary.Write(bufferedWriter, binary.BigEndian, uint8(len(hello.CompressionMethods)))
  417. binary.Write(bufferedWriter, binary.BigEndian, hello.CompressionMethods)
  418. if len(uconn.Extensions) > 0 {
  419. binary.Write(bufferedWriter, binary.BigEndian, uint16(extensionsLen))
  420. for _, ext := range uconn.Extensions {
  421. bufferedWriter.ReadFrom(ext)
  422. }
  423. }
  424. err := bufferedWriter.Flush()
  425. if err != nil {
  426. return err
  427. }
  428. if helloBuffer.Len() != 4+helloLen {
  429. return errors.New("utls: unexpected ClientHello length. Expected: " + strconv.Itoa(4+helloLen) +
  430. ". Got: " + strconv.Itoa(helloBuffer.Len()))
  431. }
  432. hello.Raw = helloBuffer.Bytes()
  433. return nil
  434. }
  435. // get current state of cipher and encrypt zeros to get keystream
  436. func (uconn *UConn) GetOutKeystream(length int) ([]byte, error) {
  437. zeros := make([]byte, length)
  438. if outCipher, ok := uconn.out.cipher.(cipher.AEAD); ok {
  439. // AEAD.Seal() does not mutate internal state, other ciphers might
  440. return outCipher.Seal(nil, uconn.out.seq[:], zeros, nil), nil
  441. }
  442. return nil, errors.New("Could not convert OutCipher to cipher.AEAD")
  443. }
  444. // SetTLSVers sets min and max TLS version in all appropriate places.
  445. // Function will use first non-zero version parsed in following order:
  446. // 1) Provided minTLSVers, maxTLSVers
  447. // 2) specExtensions may have SupportedVersionsExtension
  448. // 3) [default] min = TLS 1.0, max = TLS 1.2
  449. //
  450. // Error is only returned if things are in clearly undesirable state
  451. // to help user fix them.
  452. func (uconn *UConn) SetTLSVers(minTLSVers, maxTLSVers uint16, specExtensions []TLSExtension) error {
  453. if minTLSVers == 0 && maxTLSVers == 0 {
  454. // if version is not set explicitly in the ClientHelloSpec, check the SupportedVersions extension
  455. supportedVersionsExtensionsPresent := 0
  456. for _, e := range specExtensions {
  457. switch ext := e.(type) {
  458. case *SupportedVersionsExtension:
  459. findVersionsInSupportedVersionsExtensions := func(versions []uint16) (uint16, uint16) {
  460. // returns (minVers, maxVers)
  461. minVers := uint16(0)
  462. maxVers := uint16(0)
  463. for _, vers := range versions {
  464. if vers == GREASE_PLACEHOLDER {
  465. continue
  466. }
  467. if maxVers < vers || maxVers == 0 {
  468. maxVers = vers
  469. }
  470. if minVers > vers || minVers == 0 {
  471. minVers = vers
  472. }
  473. }
  474. return minVers, maxVers
  475. }
  476. supportedVersionsExtensionsPresent += 1
  477. minTLSVers, maxTLSVers = findVersionsInSupportedVersionsExtensions(ext.Versions)
  478. if minTLSVers == 0 && maxTLSVers == 0 {
  479. return fmt.Errorf("SupportedVersions extension has invalid Versions field")
  480. } // else: proceed
  481. }
  482. }
  483. switch supportedVersionsExtensionsPresent {
  484. case 0:
  485. // if mandatory for TLS 1.3 extension is not present, just default to 1.2
  486. minTLSVers = VersionTLS10
  487. maxTLSVers = VersionTLS12
  488. case 1:
  489. default:
  490. return fmt.Errorf("uconn.Extensions contains %v separate SupportedVersions extensions",
  491. supportedVersionsExtensionsPresent)
  492. }
  493. }
  494. if minTLSVers < VersionTLS10 || minTLSVers > VersionTLS12 {
  495. return fmt.Errorf("uTLS does not support 0x%X as min version", minTLSVers)
  496. }
  497. if maxTLSVers < VersionTLS10 || maxTLSVers > VersionTLS13 {
  498. return fmt.Errorf("uTLS does not support 0x%X as max version", maxTLSVers)
  499. }
  500. uconn.HandshakeState.Hello.SupportedVersions = makeSupportedVersions(minTLSVers, maxTLSVers)
  501. uconn.config.MinVersion = minTLSVers
  502. uconn.config.MaxVersion = maxTLSVers
  503. return nil
  504. }
  505. func (uconn *UConn) SetUnderlyingConn(c net.Conn) {
  506. uconn.Conn.conn = c
  507. }
  508. func (uconn *UConn) GetUnderlyingConn() net.Conn {
  509. return uconn.Conn.conn
  510. }
  511. // MakeConnWithCompleteHandshake allows to forge both server and client side TLS connections.
  512. // Major Hack Alert.
  513. func MakeConnWithCompleteHandshake(tcpConn net.Conn, version uint16, cipherSuite uint16, masterSecret []byte, clientRandom []byte, serverRandom []byte, isClient bool) *Conn {
  514. tlsConn := &Conn{conn: tcpConn, config: &Config{}, isClient: isClient}
  515. cs := cipherSuiteByID(cipherSuite)
  516. if cs == nil {
  517. return nil
  518. }
  519. // This is mostly borrowed from establishKeys()
  520. clientMAC, serverMAC, clientKey, serverKey, clientIV, serverIV :=
  521. keysFromMasterSecret(version, cs, masterSecret, clientRandom, serverRandom,
  522. cs.macLen, cs.keyLen, cs.ivLen)
  523. var clientCipher, serverCipher interface{}
  524. var clientHash, serverHash macFunction
  525. if cs.cipher != nil {
  526. clientCipher = cs.cipher(clientKey, clientIV, true /* for reading */)
  527. clientHash = cs.mac(version, clientMAC)
  528. serverCipher = cs.cipher(serverKey, serverIV, false /* not for reading */)
  529. serverHash = cs.mac(version, serverMAC)
  530. } else {
  531. clientCipher = cs.aead(clientKey, clientIV)
  532. serverCipher = cs.aead(serverKey, serverIV)
  533. }
  534. if isClient {
  535. tlsConn.in.prepareCipherSpec(version, serverCipher, serverHash)
  536. tlsConn.out.prepareCipherSpec(version, clientCipher, clientHash)
  537. } else {
  538. tlsConn.in.prepareCipherSpec(version, clientCipher, clientHash)
  539. tlsConn.out.prepareCipherSpec(version, serverCipher, serverHash)
  540. }
  541. // skip the handshake states
  542. tlsConn.handshakeStatus = 1
  543. tlsConn.cipherSuite = cipherSuite
  544. tlsConn.haveVers = true
  545. tlsConn.vers = version
  546. // Update to the new cipher specs
  547. // and consume the finished messages
  548. tlsConn.in.changeCipherSpec()
  549. tlsConn.out.changeCipherSpec()
  550. tlsConn.in.incSeq()
  551. tlsConn.out.incSeq()
  552. return tlsConn
  553. }
  554. func makeSupportedVersions(minVers, maxVers uint16) []uint16 {
  555. a := make([]uint16, maxVers-minVers+1)
  556. for i := range a {
  557. a[i] = maxVers - uint16(i)
  558. }
  559. return a
  560. }