handshake.go 37 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286
  1. // Copyright 2013 The Go Authors. 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 ssh
  5. import (
  6. "crypto/rand"
  7. "errors"
  8. "fmt"
  9. "io"
  10. "log"
  11. "net"
  12. "strings"
  13. "sync"
  14. // [Psiphon]
  15. "github.com/Psiphon-Labs/psiphon-tunnel-core/psiphon/common"
  16. "github.com/Psiphon-Labs/psiphon-tunnel-core/psiphon/common/prng"
  17. )
  18. // debugHandshake, if set, prints messages sent and received. Key
  19. // exchange messages are printed as if DH were used, so the debug
  20. // messages are wrong when using ECDH.
  21. const debugHandshake = false
  22. // chanSize sets the amount of buffering SSH connections. This is
  23. // primarily for testing: setting chanSize=0 uncovers deadlocks more
  24. // quickly.
  25. const chanSize = 16
  26. // maxPendingPackets sets the maximum number of packets to queue while waiting
  27. // for KEX to complete. This limits the total pending data to maxPendingPackets
  28. // * maxPacket bytes, which is ~16.8MB.
  29. const maxPendingPackets = 64
  30. // keyingTransport is a packet based transport that supports key
  31. // changes. It need not be thread-safe. It should pass through
  32. // msgNewKeys in both directions.
  33. type keyingTransport interface {
  34. packetConn
  35. // prepareKeyChange sets up a key change. The key change for a
  36. // direction will be effected if a msgNewKeys message is sent
  37. // or received.
  38. prepareKeyChange(*algorithms, *kexResult) error
  39. // setStrictMode sets the strict KEX mode, notably triggering
  40. // sequence number resets on sending or receiving msgNewKeys.
  41. // If the sequence number is already > 1 when setStrictMode
  42. // is called, an error is returned.
  43. setStrictMode() error
  44. // setInitialKEXDone indicates to the transport that the initial key exchange
  45. // was completed
  46. setInitialKEXDone()
  47. }
  48. // handshakeTransport implements rekeying on top of a keyingTransport
  49. // and offers a thread-safe writePacket() interface.
  50. type handshakeTransport struct {
  51. conn keyingTransport
  52. config *Config
  53. serverVersion []byte
  54. clientVersion []byte
  55. // hostKeys is non-empty if we are the server. In that case,
  56. // it contains all host keys that can be used to sign the
  57. // connection.
  58. hostKeys []Signer
  59. // publicKeyAuthAlgorithms is non-empty if we are the server. In that case,
  60. // it contains the supported client public key authentication algorithms.
  61. publicKeyAuthAlgorithms []string
  62. // hostKeyAlgorithms is non-empty if we are the client. In that case,
  63. // we accept these key types from the server as host key.
  64. hostKeyAlgorithms []string
  65. // On read error, incoming is closed, and readError is set.
  66. incoming chan []byte
  67. readError error
  68. mu sync.Mutex
  69. // Condition for the above mutex. It is used to notify a completed key
  70. // exchange or a write failure. Writes can wait for this condition while a
  71. // key exchange is in progress.
  72. writeCond *sync.Cond
  73. writeError error
  74. sentInitPacket []byte
  75. sentInitMsg *kexInitMsg
  76. // Used to queue writes when a key exchange is in progress. The length is
  77. // limited by pendingPacketsSize. Once full, writes will block until the key
  78. // exchange is completed or an error occurs. If not empty, it is emptied
  79. // all at once when the key exchange is completed in kexLoop.
  80. pendingPackets [][]byte
  81. writePacketsLeft uint32
  82. writeBytesLeft int64
  83. userAuthComplete bool // whether the user authentication phase is complete
  84. // If the read loop wants to schedule a kex, it pings this
  85. // channel, and the write loop will send out a kex
  86. // message.
  87. requestKex chan struct{}
  88. // If the other side requests or confirms a kex, its kexInit
  89. // packet is sent here for the write loop to find it.
  90. startKex chan *pendingKex
  91. kexLoopDone chan struct{} // closed (with writeError non-nil) when kexLoop exits
  92. // data for host key checking
  93. hostKeyCallback HostKeyCallback
  94. dialAddress string
  95. remoteAddr net.Addr
  96. // bannerCallback is non-empty if we are the client and it has been set in
  97. // ClientConfig. In that case it is called during the user authentication
  98. // dance to handle a custom server's message.
  99. bannerCallback BannerCallback
  100. // Algorithms agreed in the last key exchange.
  101. algorithms *algorithms
  102. // Counters exclusively owned by readLoop.
  103. readPacketsLeft uint32
  104. readBytesLeft int64
  105. // The session ID or nil if first kex did not complete yet.
  106. sessionID []byte
  107. // strictMode indicates if the other side of the handshake indicated
  108. // that we should be following the strict KEX protocol restrictions.
  109. strictMode bool
  110. // [Psiphon]
  111. // Unblocks readLoop blocked on sending to incoming channel.
  112. doSignalCloseReadLoop sync.Once
  113. signalCloseReadLoop chan struct{}
  114. }
  115. type pendingKex struct {
  116. otherInit []byte
  117. done chan error
  118. }
  119. func newHandshakeTransport(conn keyingTransport, config *Config, clientVersion, serverVersion []byte) *handshakeTransport {
  120. t := &handshakeTransport{
  121. conn: conn,
  122. serverVersion: serverVersion,
  123. clientVersion: clientVersion,
  124. incoming: make(chan []byte, chanSize),
  125. requestKex: make(chan struct{}, 1),
  126. startKex: make(chan *pendingKex),
  127. kexLoopDone: make(chan struct{}),
  128. // [Psiphon]
  129. signalCloseReadLoop: make(chan struct{}),
  130. config: config,
  131. }
  132. t.writeCond = sync.NewCond(&t.mu)
  133. t.resetReadThresholds()
  134. t.resetWriteThresholds()
  135. // We always start with a mandatory key exchange.
  136. t.requestKex <- struct{}{}
  137. return t
  138. }
  139. func newClientTransport(conn keyingTransport, clientVersion, serverVersion []byte, config *ClientConfig, dialAddr string, addr net.Addr) *handshakeTransport {
  140. t := newHandshakeTransport(conn, &config.Config, clientVersion, serverVersion)
  141. t.dialAddress = dialAddr
  142. t.remoteAddr = addr
  143. t.hostKeyCallback = config.HostKeyCallback
  144. t.bannerCallback = config.BannerCallback
  145. if config.HostKeyAlgorithms != nil {
  146. t.hostKeyAlgorithms = config.HostKeyAlgorithms
  147. } else {
  148. t.hostKeyAlgorithms = supportedHostKeyAlgos
  149. }
  150. go t.readLoop()
  151. go t.kexLoop()
  152. return t
  153. }
  154. func newServerTransport(conn keyingTransport, clientVersion, serverVersion []byte, config *ServerConfig) *handshakeTransport {
  155. t := newHandshakeTransport(conn, &config.Config, clientVersion, serverVersion)
  156. t.hostKeys = config.hostKeys
  157. t.publicKeyAuthAlgorithms = config.PublicKeyAuthAlgorithms
  158. go t.readLoop()
  159. go t.kexLoop()
  160. return t
  161. }
  162. func (t *handshakeTransport) getSessionID() []byte {
  163. return t.sessionID
  164. }
  165. // waitSession waits for the session to be established. This should be
  166. // the first thing to call after instantiating handshakeTransport.
  167. func (t *handshakeTransport) waitSession() error {
  168. p, err := t.readPacket()
  169. if err != nil {
  170. return err
  171. }
  172. if p[0] != msgNewKeys {
  173. return fmt.Errorf("ssh: first packet should be msgNewKeys")
  174. }
  175. return nil
  176. }
  177. func (t *handshakeTransport) id() string {
  178. if len(t.hostKeys) > 0 {
  179. return "server"
  180. }
  181. return "client"
  182. }
  183. func (t *handshakeTransport) printPacket(p []byte, write bool) {
  184. action := "got"
  185. if write {
  186. action = "sent"
  187. }
  188. if p[0] == msgChannelData || p[0] == msgChannelExtendedData {
  189. log.Printf("%s %s data (packet %d bytes)", t.id(), action, len(p))
  190. } else {
  191. msg, err := decode(p)
  192. log.Printf("%s %s %T %v (%v)", t.id(), action, msg, msg, err)
  193. }
  194. }
  195. func (t *handshakeTransport) readPacket() ([]byte, error) {
  196. p, ok := <-t.incoming
  197. if !ok {
  198. return nil, t.readError
  199. }
  200. return p, nil
  201. }
  202. func (t *handshakeTransport) readLoop() {
  203. first := true
  204. for {
  205. p, err := t.readOnePacket(first)
  206. first = false
  207. if err != nil {
  208. t.readError = err
  209. close(t.incoming)
  210. break
  211. }
  212. // If this is the first kex, and strict KEX mode is enabled,
  213. // we don't ignore any messages, as they may be used to manipulate
  214. // the packet sequence numbers.
  215. if !(t.sessionID == nil && t.strictMode) && (p[0] == msgIgnore || p[0] == msgDebug) {
  216. continue
  217. }
  218. // [Psiphon]
  219. // Add a closed signal case to interrupt readLoop when blocked on
  220. // sending to incoming.
  221. closed := false
  222. select {
  223. case t.incoming <- p:
  224. case <-t.signalCloseReadLoop:
  225. closed = true
  226. }
  227. if closed {
  228. t.readError = io.EOF
  229. close(t.incoming)
  230. break
  231. }
  232. }
  233. // Stop writers too.
  234. t.recordWriteError(t.readError)
  235. // Unblock the writer should it wait for this.
  236. close(t.startKex)
  237. // Don't close t.requestKex; it's also written to from writePacket.
  238. }
  239. func (t *handshakeTransport) pushPacket(p []byte) error {
  240. if debugHandshake {
  241. t.printPacket(p, true)
  242. }
  243. return t.conn.writePacket(p)
  244. }
  245. func (t *handshakeTransport) getWriteError() error {
  246. t.mu.Lock()
  247. defer t.mu.Unlock()
  248. return t.writeError
  249. }
  250. func (t *handshakeTransport) recordWriteError(err error) {
  251. t.mu.Lock()
  252. defer t.mu.Unlock()
  253. if t.writeError == nil && err != nil {
  254. t.writeError = err
  255. t.writeCond.Broadcast()
  256. }
  257. }
  258. func (t *handshakeTransport) requestKeyExchange() {
  259. select {
  260. case t.requestKex <- struct{}{}:
  261. default:
  262. // something already requested a kex, so do nothing.
  263. }
  264. }
  265. func (t *handshakeTransport) resetWriteThresholds() {
  266. t.writePacketsLeft = packetRekeyThreshold
  267. if t.config.RekeyThreshold > 0 {
  268. t.writeBytesLeft = int64(t.config.RekeyThreshold)
  269. } else if t.algorithms != nil {
  270. t.writeBytesLeft = t.algorithms.w.rekeyBytes()
  271. } else {
  272. t.writeBytesLeft = 1 << 30
  273. }
  274. }
  275. func (t *handshakeTransport) kexLoop() {
  276. write:
  277. for t.getWriteError() == nil {
  278. var request *pendingKex
  279. var sent bool
  280. for request == nil || !sent {
  281. var ok bool
  282. select {
  283. case request, ok = <-t.startKex:
  284. if !ok {
  285. break write
  286. }
  287. case <-t.requestKex:
  288. break
  289. }
  290. if !sent {
  291. if err := t.sendKexInit(); err != nil {
  292. t.recordWriteError(err)
  293. break
  294. }
  295. sent = true
  296. }
  297. }
  298. if err := t.getWriteError(); err != nil {
  299. if request != nil {
  300. request.done <- err
  301. }
  302. break
  303. }
  304. // We're not servicing t.requestKex, but that is OK:
  305. // we never block on sending to t.requestKex.
  306. // We're not servicing t.startKex, but the remote end
  307. // has just sent us a kexInitMsg, so it can't send
  308. // another key change request, until we close the done
  309. // channel on the pendingKex request.
  310. err := t.enterKeyExchange(request.otherInit)
  311. t.mu.Lock()
  312. t.writeError = err
  313. t.sentInitPacket = nil
  314. t.sentInitMsg = nil
  315. t.resetWriteThresholds()
  316. // we have completed the key exchange. Since the
  317. // reader is still blocked, it is safe to clear out
  318. // the requestKex channel. This avoids the situation
  319. // where: 1) we consumed our own request for the
  320. // initial kex, and 2) the kex from the remote side
  321. // caused another send on the requestKex channel,
  322. clear:
  323. for {
  324. select {
  325. case <-t.requestKex:
  326. //
  327. default:
  328. break clear
  329. }
  330. }
  331. request.done <- t.writeError
  332. // kex finished. Push packets that we received while
  333. // the kex was in progress. Don't look at t.startKex
  334. // and don't increment writtenSinceKex: if we trigger
  335. // another kex while we are still busy with the last
  336. // one, things will become very confusing.
  337. for _, p := range t.pendingPackets {
  338. t.writeError = t.pushPacket(p)
  339. if t.writeError != nil {
  340. break
  341. }
  342. }
  343. t.pendingPackets = t.pendingPackets[:0]
  344. // Unblock writePacket if waiting for KEX.
  345. t.writeCond.Broadcast()
  346. t.mu.Unlock()
  347. }
  348. // Unblock reader.
  349. t.conn.Close()
  350. // drain startKex channel. We don't service t.requestKex
  351. // because nobody does blocking sends there.
  352. for request := range t.startKex {
  353. request.done <- t.getWriteError()
  354. }
  355. // Mark that the loop is done so that Close can return.
  356. close(t.kexLoopDone)
  357. }
  358. // The protocol uses uint32 for packet counters, so we can't let them
  359. // reach 1<<32. We will actually read and write more packets than
  360. // this, though: the other side may send more packets, and after we
  361. // hit this limit on writing we will send a few more packets for the
  362. // key exchange itself.
  363. const packetRekeyThreshold = (1 << 31)
  364. func (t *handshakeTransport) resetReadThresholds() {
  365. t.readPacketsLeft = packetRekeyThreshold
  366. if t.config.RekeyThreshold > 0 {
  367. t.readBytesLeft = int64(t.config.RekeyThreshold)
  368. } else if t.algorithms != nil {
  369. t.readBytesLeft = t.algorithms.r.rekeyBytes()
  370. } else {
  371. t.readBytesLeft = 1 << 30
  372. }
  373. }
  374. func (t *handshakeTransport) readOnePacket(first bool) ([]byte, error) {
  375. p, err := t.conn.readPacket()
  376. if err != nil {
  377. return nil, err
  378. }
  379. if t.readPacketsLeft > 0 {
  380. t.readPacketsLeft--
  381. } else {
  382. t.requestKeyExchange()
  383. }
  384. if t.readBytesLeft > 0 {
  385. t.readBytesLeft -= int64(len(p))
  386. } else {
  387. t.requestKeyExchange()
  388. }
  389. if debugHandshake {
  390. t.printPacket(p, false)
  391. }
  392. if first && p[0] != msgKexInit {
  393. return nil, fmt.Errorf("ssh: first packet should be msgKexInit")
  394. }
  395. if p[0] != msgKexInit {
  396. return p, nil
  397. }
  398. firstKex := t.sessionID == nil
  399. kex := pendingKex{
  400. done: make(chan error, 1),
  401. otherInit: p,
  402. }
  403. t.startKex <- &kex
  404. err = <-kex.done
  405. if debugHandshake {
  406. log.Printf("%s exited key exchange (first %v), err %v", t.id(), firstKex, err)
  407. }
  408. if err != nil {
  409. return nil, err
  410. }
  411. t.resetReadThresholds()
  412. // By default, a key exchange is hidden from higher layers by
  413. // translating it into msgIgnore.
  414. successPacket := []byte{msgIgnore}
  415. if firstKex {
  416. // sendKexInit() for the first kex waits for
  417. // msgNewKeys so the authentication process is
  418. // guaranteed to happen over an encrypted transport.
  419. successPacket = []byte{msgNewKeys}
  420. }
  421. return successPacket, nil
  422. }
  423. const (
  424. kexStrictClient = "kex-strict-c-v00@openssh.com"
  425. kexStrictServer = "kex-strict-s-v00@openssh.com"
  426. )
  427. // [Psiphon]
  428. // For testing only. Enables testing support for legacy clients, which have
  429. // only the legacy algorithm lists and no weak-MAC or new-server-algos logic.
  430. // Not safe for concurrent access.
  431. var testLegacyClient = false
  432. // sendKexInit sends a key change message.
  433. func (t *handshakeTransport) sendKexInit() error {
  434. t.mu.Lock()
  435. defer t.mu.Unlock()
  436. if t.sentInitMsg != nil {
  437. // kexInits may be sent either in response to the other side,
  438. // or because our side wants to initiate a key change, so we
  439. // may have already sent a kexInit. In that case, don't send a
  440. // second kexInit.
  441. return nil
  442. }
  443. msg := &kexInitMsg{
  444. CiphersClientServer: t.config.Ciphers,
  445. CiphersServerClient: t.config.Ciphers,
  446. MACsClientServer: t.config.MACs,
  447. MACsServerClient: t.config.MACs,
  448. CompressionClientServer: supportedCompressions,
  449. CompressionServerClient: supportedCompressions,
  450. }
  451. io.ReadFull(rand.Reader, msg.Cookie[:])
  452. // We mutate the KexAlgos slice, in order to add the kex-strict extension algorithm,
  453. // and possibly to add the ext-info extension algorithm. Since the slice may be the
  454. // user owned KeyExchanges, we create our own slice in order to avoid using user
  455. // owned memory by mistake.
  456. msg.KexAlgos = make([]string, 0, len(t.config.KeyExchanges)+2) // room for kex-strict and ext-info
  457. msg.KexAlgos = append(msg.KexAlgos, t.config.KeyExchanges...)
  458. isServer := len(t.hostKeys) > 0
  459. if isServer {
  460. for _, k := range t.hostKeys {
  461. // If k is a MultiAlgorithmSigner, we restrict the signature
  462. // algorithms. If k is a AlgorithmSigner, presume it supports all
  463. // signature algorithms associated with the key format. If k is not
  464. // an AlgorithmSigner, we can only assume it only supports the
  465. // algorithms that matches the key format. (This means that Sign
  466. // can't pick a different default).
  467. keyFormat := k.PublicKey().Type()
  468. switch s := k.(type) {
  469. case MultiAlgorithmSigner:
  470. for _, algo := range algorithmsForKeyFormat(keyFormat) {
  471. if contains(s.Algorithms(), underlyingAlgo(algo)) {
  472. msg.ServerHostKeyAlgos = append(msg.ServerHostKeyAlgos, algo)
  473. }
  474. }
  475. case AlgorithmSigner:
  476. msg.ServerHostKeyAlgos = append(msg.ServerHostKeyAlgos, algorithmsForKeyFormat(keyFormat)...)
  477. default:
  478. msg.ServerHostKeyAlgos = append(msg.ServerHostKeyAlgos, keyFormat)
  479. }
  480. }
  481. if t.sessionID == nil {
  482. msg.KexAlgos = append(msg.KexAlgos, kexStrictServer)
  483. }
  484. } else {
  485. msg.ServerHostKeyAlgos = t.hostKeyAlgorithms
  486. // As a client we opt in to receiving SSH_MSG_EXT_INFO so we know what
  487. // algorithms the server supports for public key authentication. See RFC
  488. // 8308, Section 2.1.
  489. //
  490. // We also send the strict KEX mode extension algorithm, in order to opt
  491. // into the strict KEX mode.
  492. if firstKeyExchange := t.sessionID == nil; firstKeyExchange {
  493. msg.KexAlgos = append(msg.KexAlgos, "ext-info-c")
  494. msg.KexAlgos = append(msg.KexAlgos, kexStrictClient)
  495. }
  496. }
  497. // [Psiphon]
  498. //
  499. // When KEXPRNGSeed is specified, randomize the KEX. The offered
  500. // algorithms are shuffled and truncated. Longer lists are selected with
  501. // higher probability.
  502. //
  503. // When PeerKEXPRNGSeed is specified, the peer is expected to randomize
  504. // its KEX using the specified seed; deterministically adjust own
  505. // randomized KEX to ensure negotiation succeeds.
  506. //
  507. // When NoEncryptThenMACHash is specified, do not use Encrypt-then-MAC
  508. // hash algorithms.
  509. //
  510. // Limitations:
  511. //
  512. // - "ext-info-c" and "kex-strict-c/s-v00@openssh.com" extensions included
  513. // in KexAlgos may be truncated; Psiphon's usage of SSH does not
  514. // request SSH_MSG_EXT_INFO for client authentication and should not
  515. // be vulnerable to downgrade attacks related to stripping
  516. // SSH_MSG_EXT_INFO.
  517. //
  518. // - KEX algorithms are not synchronized with the version identification
  519. // string.
  520. equal := func(list1, list2 []string) bool {
  521. if len(list1) != len(list2) {
  522. return false
  523. }
  524. for i, entry := range list1 {
  525. if list2[i] != entry {
  526. return false
  527. }
  528. }
  529. return true
  530. }
  531. // Psiphon transforms assume that default algorithms are configured.
  532. if (t.config.NoEncryptThenMACHash || t.config.KEXPRNGSeed != nil) &&
  533. (!equal(t.config.KeyExchanges, preferredKexAlgos) ||
  534. !equal(t.config.Ciphers, preferredCiphers) ||
  535. !equal(t.config.MACs, supportedMACs)) {
  536. return errors.New("ssh: custom algorithm preferences not supported")
  537. }
  538. // This is the list of supported non-Encrypt-then-MAC algorithms from
  539. // https://github.com/Psiphon-Labs/psiphon-tunnel-core/blob/3ef11effe6acd9
  540. // 2c3aefd140ee09c42a1f15630b/psiphon/common/crypto/ssh/common.go#L60
  541. //
  542. // With Encrypt-then-MAC hash algorithms, packet length is transmitted in
  543. // plaintext, which aids in traffic analysis.
  544. //
  545. // When using obfuscated SSH, where only the initial, unencrypted
  546. // packets are obfuscated, NoEncryptThenMACHash should be set.
  547. noEncryptThenMACs := []string{"hmac-sha2-256", "hmac-sha2-512", "hmac-sha1", "hmac-sha1-96"}
  548. if t.config.NoEncryptThenMACHash {
  549. msg.MACsClientServer = noEncryptThenMACs
  550. msg.MACsServerClient = noEncryptThenMACs
  551. }
  552. if t.config.KEXPRNGSeed != nil {
  553. permute := func(PRNG *prng.PRNG, list []string) []string {
  554. newList := make([]string, len(list))
  555. perm := PRNG.Perm(len(list))
  556. for i, j := range perm {
  557. newList[j] = list[i]
  558. }
  559. return newList
  560. }
  561. truncate := func(PRNG *prng.PRNG, list []string) []string {
  562. cut := len(list)
  563. for ; cut > 1; cut-- {
  564. if !PRNG.FlipCoin() {
  565. break
  566. }
  567. }
  568. return list[:cut]
  569. }
  570. retain := func(PRNG *prng.PRNG, list []string, item string) []string {
  571. for _, entry := range list {
  572. if entry == item {
  573. return list
  574. }
  575. }
  576. replace := PRNG.Intn(len(list))
  577. list[replace] = item
  578. return list
  579. }
  580. avoid := func(PRNG *prng.PRNG, list, avoidList, addList []string) []string {
  581. // Avoid negotiating items in avoidList, by moving a non-avoid
  582. // item to the front of the list; either by swapping with a
  583. // later, non-avoid item, or inserting a new item.
  584. if len(list) < 1 {
  585. return list
  586. }
  587. if !common.Contains(avoidList, list[0]) {
  588. // The first item isn't on the avoid list.
  589. return list
  590. }
  591. for i := 1; i < len(list); i++ {
  592. if !common.Contains(avoidList, list[i]) {
  593. // Swap with a later, existing non-avoid item.
  594. list[0], list[i] = list[i], list[0]
  595. return list
  596. }
  597. }
  598. for _, item := range permute(PRNG, addList) {
  599. if !common.Contains(avoidList, item) {
  600. // Insert a randomly selected non-avoid item.
  601. return append([]string{item}, list...)
  602. }
  603. }
  604. // Can't avoid.
  605. return list
  606. }
  607. addSome := func(PRNG *prng.PRNG, list, addList []string) []string {
  608. newList := list
  609. for _, item := range addList {
  610. if PRNG.FlipCoin() {
  611. index := PRNG.Range(0, len(newList))
  612. newList = append(
  613. newList[:index],
  614. append([]string{item}, newList[index:]...)...)
  615. }
  616. }
  617. return newList
  618. }
  619. toFront := func(list []string, item string) []string {
  620. for index, existingItem := range list {
  621. if existingItem == item {
  622. list[0], list[index] = list[index], list[0]
  623. return list
  624. }
  625. }
  626. return append([]string{item}, list...)
  627. }
  628. firstKexAlgo := func(kexAlgos []string) (string, bool) {
  629. for _, kexAlgo := range kexAlgos {
  630. switch kexAlgo {
  631. case "ext-info-c",
  632. "kex-strict-c-v00@openssh.com",
  633. "kex-strict-s-v00@openssh.com":
  634. // These extensions are not KEX algorithms
  635. default:
  636. return kexAlgo, true
  637. }
  638. }
  639. return "", false
  640. }
  641. selectKexAlgos := func(PRNG *prng.PRNG, kexAlgos []string) []string {
  642. kexAlgos = truncate(PRNG, permute(PRNG, kexAlgos))
  643. // Ensure an actual KEX algorithm is always selected
  644. if _, ok := firstKexAlgo(kexAlgos); ok {
  645. return kexAlgos
  646. }
  647. return retain(PRNG, kexAlgos, permute(PRNG, preferredKexAlgos)[0])
  648. }
  649. // Downgrade servers to use the algorithm lists used previously in
  650. // commits before 435a6a3f. This ensures that (a) the PeerKEXPRNGSeed
  651. // mechanism used in all existing clients correctly predicts the
  652. // server's algorithms; (b) random truncation by the server doesn't
  653. // select only new algorithms unknown to existing clients.
  654. //
  655. // New algorithms are then randomly inserted only after the legacy
  656. // lists are processed in legacy PRNG state order.
  657. legacyServerKexAlgos := []string{
  658. kexAlgoCurve25519SHA256LibSSH,
  659. kexAlgoECDH256, kexAlgoECDH384, kexAlgoECDH521,
  660. kexAlgoDH14SHA256, kexAlgoDH14SHA1,
  661. }
  662. legacyServerCiphers := []string{
  663. "aes128-gcm@openssh.com",
  664. chacha20Poly1305ID,
  665. "aes128-ctr", "aes192-ctr", "aes256-ctr",
  666. }
  667. legacyServerMACs := []string{
  668. "hmac-sha2-256-etm@openssh.com",
  669. "hmac-sha2-256", "hmac-sha1", "hmac-sha1-96",
  670. }
  671. legacyServerNoEncryptThenMACs := []string{
  672. "hmac-sha2-256", "hmac-sha1", "hmac-sha1-96",
  673. }
  674. if t.config.NoEncryptThenMACHash {
  675. legacyServerMACs = legacyServerNoEncryptThenMACs
  676. }
  677. PRNG := prng.NewPRNGWithSeed(t.config.KEXPRNGSeed)
  678. startingKexAlgos := msg.KexAlgos
  679. startingCiphers := msg.CiphersClientServer
  680. startingMACs := msg.MACsClientServer
  681. // testLegacyClient: legacy clients are older clients which start with
  682. // the same algorithm lists as legacyServer and have neither the
  683. // newServer-algorithm nor the weak-MAC KEX prediction logic.
  684. if isServer || testLegacyClient {
  685. startingKexAlgos = legacyServerKexAlgos
  686. startingCiphers = legacyServerCiphers
  687. startingMACs = legacyServerMACs
  688. if t.config.NoEncryptThenMACHash {
  689. startingMACs = legacyServerNoEncryptThenMACs
  690. }
  691. }
  692. kexAlgos := selectKexAlgos(PRNG, startingKexAlgos)
  693. ciphers := truncate(PRNG, permute(PRNG, startingCiphers))
  694. MACs := truncate(PRNG, permute(PRNG, startingMACs))
  695. var hostKeyAlgos []string
  696. if isServer {
  697. hostKeyAlgos = permute(PRNG, msg.ServerHostKeyAlgos)
  698. } else {
  699. // Must offer KeyAlgoRSA to Psiphon server.
  700. hostKeyAlgos = retain(
  701. PRNG,
  702. truncate(PRNG, permute(PRNG, msg.ServerHostKeyAlgos)),
  703. KeyAlgoRSA)
  704. }
  705. // To ensure compatibility with server KEX prediction in legacy
  706. // clients, all preceeding PRNG operations must be performed in the
  707. // given order, and all before the following operations.
  708. // Avoid negotiating weak MAC algorithms. Servers will ensure that no
  709. // weakMACs are the highest priority item. Clients will make
  710. // adjustments after predicting the server KEX.
  711. weakMACs := []string{"hmac-sha1-96"}
  712. if isServer {
  713. MACs = avoid(PRNG, MACs, weakMACs, startingMACs)
  714. }
  715. // Randomly insert new algorithms. For servers, the preceeding legacy
  716. // operations will ensure selection of at least one legacy algorithm
  717. // of each type, ensuring compatibility with legacy clients.
  718. newServerKexAlgos := []string{
  719. kexAlgoCurve25519SHA256, kexAlgoDH16SHA512,
  720. "kex-strict-s-v00@openssh.com",
  721. }
  722. newServerCiphers := []string{
  723. gcm256CipherID,
  724. }
  725. newServerMACs := []string{
  726. "hmac-sha2-512-etm@openssh.com", "hmac-sha2-512",
  727. }
  728. newServerNoEncryptThenMACs := []string{
  729. "hmac-sha2-512",
  730. }
  731. if t.config.NoEncryptThenMACHash {
  732. newServerMACs = newServerNoEncryptThenMACs
  733. }
  734. if isServer {
  735. kexAlgos = addSome(PRNG, kexAlgos, newServerKexAlgos)
  736. ciphers = addSome(PRNG, ciphers, newServerCiphers)
  737. MACs = addSome(PRNG, MACs, newServerMACs)
  738. }
  739. msg.KexAlgos = kexAlgos
  740. msg.CiphersClientServer = ciphers
  741. msg.CiphersServerClient = ciphers
  742. msg.MACsClientServer = MACs
  743. msg.MACsServerClient = MACs
  744. msg.ServerHostKeyAlgos = hostKeyAlgos
  745. if !isServer && t.config.PeerKEXPRNGSeed != nil {
  746. // Generate the server KEX and make adjustments if negotiation
  747. // would fail. This assumes that PeerKEXPRNGSeed remains static
  748. // (in Psiphon, the peer is the server and PeerKEXPRNGSeed is
  749. // derived from the server entry); and that the PRNG is invoked
  750. // in the exact same order on the server (i.e., the code block
  751. // immediately above is what the peer runs); and that the server
  752. // sets NoEncryptThenMACHash in the same cases.
  753. //
  754. // Note that only the client sends "ext-info-c"
  755. // and "kex-strict-c-v00@openssh.com" and only the server
  756. // sends "kex-strict-s-v00@openssh.com", so these will never
  757. // match and do not need to be filtered out before findCommon.
  758. PeerPRNG := prng.NewPRNGWithSeed(t.config.PeerKEXPRNGSeed)
  759. startingKexAlgos := legacyServerKexAlgos
  760. startingCiphers := legacyServerCiphers
  761. startingMACs := legacyServerMACs
  762. if t.config.NoEncryptThenMACHash {
  763. startingMACs = legacyServerNoEncryptThenMACs
  764. }
  765. // The server populates msg.ServerHostKeyAlgos based on the host
  766. // key type, which, for Psiphon servers, is "ssh-rsa", so
  767. // algorithmsForKeyFormat("ssh-rsa") predicts the server
  768. // msg.ServerHostKeyAlgos value.
  769. startingHostKeyAlgos := algorithmsForKeyFormat("ssh-rsa")
  770. serverKexAlgos := selectKexAlgos(PeerPRNG, startingKexAlgos)
  771. serverCiphers := truncate(PeerPRNG, permute(PeerPRNG, startingCiphers))
  772. serverMACs := truncate(PeerPRNG, permute(PeerPRNG, startingMACs))
  773. if !testLegacyClient {
  774. // This value is not used, but the identical PRNG operation must be
  775. // performed in order to predict the PeerPRNG state.
  776. _ = permute(PeerPRNG, startingHostKeyAlgos)
  777. serverMACs = avoid(PeerPRNG, serverMACs, weakMACs, startingMACs)
  778. serverKexAlgos = addSome(PeerPRNG, serverKexAlgos, newServerKexAlgos)
  779. serverCiphers = addSome(PeerPRNG, serverCiphers, newServerCiphers)
  780. serverMACs = addSome(PeerPRNG, serverMACs, newServerMACs)
  781. }
  782. // Adjust to ensure compatibility with the server KEX.
  783. if _, err := findCommon("", msg.KexAlgos, serverKexAlgos); err != nil {
  784. if kexAlgo, ok := firstKexAlgo(serverKexAlgos); ok {
  785. kexAlgos = retain(PRNG, msg.KexAlgos, kexAlgo)
  786. }
  787. }
  788. if _, err := findCommon("", ciphers, serverCiphers); err != nil {
  789. ciphers = retain(PRNG, ciphers, serverCiphers[0])
  790. }
  791. if _, err := findCommon("", MACs, serverMACs); err != nil {
  792. MACs = retain(PRNG, MACs, serverMACs[0])
  793. }
  794. // Avoid negotiating weak MAC algorithms.
  795. //
  796. // Legacy clients, without this logic, may still select only weak
  797. // MACs or predict only weak MACs for the server KEX.
  798. commonMAC, _ := findCommon("", MACs, serverMACs)
  799. if common.Contains(weakMACs, commonMAC) {
  800. // serverMACs[0] is not in weakMACs.
  801. MACs = toFront(MACs, serverMACs[0])
  802. }
  803. msg.KexAlgos = kexAlgos
  804. msg.CiphersClientServer = ciphers
  805. msg.CiphersServerClient = ciphers
  806. msg.MACsClientServer = MACs
  807. msg.MACsServerClient = MACs
  808. }
  809. // Offer "zlib@openssh.com", which is offered by OpenSSH. Compression
  810. // is not actually implemented, but since "zlib@openssh.com"
  811. // compression is delayed until after authentication
  812. // (https://www.openssh.com/txt/draft-miller-secsh-compression-
  813. // delayed-00.txt), an unauthenticated probe of the SSH server will
  814. // not detect this. "none" is always included to ensure negotiation
  815. // succeeds.
  816. if PRNG.FlipCoin() {
  817. compressions := permute(PRNG, []string{"none", "zlib@openssh.com"})
  818. msg.CompressionClientServer = compressions
  819. msg.CompressionServerClient = compressions
  820. }
  821. }
  822. packet := Marshal(msg)
  823. // writePacket destroys the contents, so save a copy.
  824. packetCopy := make([]byte, len(packet))
  825. copy(packetCopy, packet)
  826. if err := t.pushPacket(packetCopy); err != nil {
  827. return err
  828. }
  829. t.sentInitMsg = msg
  830. t.sentInitPacket = packet
  831. return nil
  832. }
  833. var errSendBannerPhase = errors.New("ssh: SendAuthBanner outside of authentication phase")
  834. func (t *handshakeTransport) writePacket(p []byte) error {
  835. t.mu.Lock()
  836. defer t.mu.Unlock()
  837. switch p[0] {
  838. case msgKexInit:
  839. return errors.New("ssh: only handshakeTransport can send kexInit")
  840. case msgNewKeys:
  841. return errors.New("ssh: only handshakeTransport can send newKeys")
  842. case msgUserAuthBanner:
  843. if t.userAuthComplete {
  844. return errSendBannerPhase
  845. }
  846. case msgUserAuthSuccess:
  847. t.userAuthComplete = true
  848. }
  849. if t.writeError != nil {
  850. return t.writeError
  851. }
  852. if t.sentInitMsg != nil {
  853. if len(t.pendingPackets) < maxPendingPackets {
  854. // Copy the packet so the writer can reuse the buffer.
  855. cp := make([]byte, len(p))
  856. copy(cp, p)
  857. t.pendingPackets = append(t.pendingPackets, cp)
  858. return nil
  859. }
  860. for t.sentInitMsg != nil {
  861. // Block and wait for KEX to complete or an error.
  862. t.writeCond.Wait()
  863. if t.writeError != nil {
  864. return t.writeError
  865. }
  866. }
  867. }
  868. if t.writeBytesLeft > 0 {
  869. t.writeBytesLeft -= int64(len(p))
  870. } else {
  871. t.requestKeyExchange()
  872. }
  873. if t.writePacketsLeft > 0 {
  874. t.writePacketsLeft--
  875. } else {
  876. t.requestKeyExchange()
  877. }
  878. if err := t.pushPacket(p); err != nil {
  879. t.writeError = err
  880. t.writeCond.Broadcast()
  881. }
  882. return nil
  883. }
  884. func (t *handshakeTransport) Close() error {
  885. // Close the connection. This should cause the readLoop goroutine to wake up
  886. // and close t.startKex, which will shut down kexLoop if running.
  887. err := t.conn.Close()
  888. // [Psiphon]
  889. // Interrupt any blocked readers or writers.
  890. t.interrupt(err)
  891. // Wait for the kexLoop goroutine to complete.
  892. // At that point we know that the readLoop goroutine is complete too,
  893. // because kexLoop itself waits for readLoop to close the startKex channel.
  894. <-t.kexLoopDone
  895. return err
  896. }
  897. // [Psiphon]
  898. // interrupt unblocks any goroutines waiting on readLoop/writePacket when
  899. // the underlying transport is shutting down and a KEX may be in progress.
  900. func (t *handshakeTransport) interrupt(err error) {
  901. if err == nil {
  902. err = io.EOF
  903. }
  904. // Interrupt readLoop if blocked on sending to t.incoming.
  905. t.doSignalCloseReadLoop.Do(func() {
  906. close(t.signalCloseReadLoop)
  907. })
  908. // Interrupt writePacket if blocked on t.writeCond.Wait awaiting a KEX.
  909. // Call recordWriteError to ensure t.writeError is set, if not already;
  910. // and unconditionally Broadcast as well, in case the condition in
  911. // recordWriteError skips that.
  912. t.recordWriteError(err)
  913. t.writeCond.Broadcast()
  914. }
  915. func (t *handshakeTransport) enterKeyExchange(otherInitPacket []byte) error {
  916. if debugHandshake {
  917. log.Printf("%s entered key exchange", t.id())
  918. }
  919. otherInit := &kexInitMsg{}
  920. if err := Unmarshal(otherInitPacket, otherInit); err != nil {
  921. return err
  922. }
  923. magics := handshakeMagics{
  924. clientVersion: t.clientVersion,
  925. serverVersion: t.serverVersion,
  926. clientKexInit: otherInitPacket,
  927. serverKexInit: t.sentInitPacket,
  928. }
  929. clientInit := otherInit
  930. serverInit := t.sentInitMsg
  931. isClient := len(t.hostKeys) == 0
  932. if isClient {
  933. clientInit, serverInit = serverInit, clientInit
  934. magics.clientKexInit = t.sentInitPacket
  935. magics.serverKexInit = otherInitPacket
  936. }
  937. var err error
  938. t.algorithms, err = findAgreedAlgorithms(isClient, clientInit, serverInit)
  939. if err != nil {
  940. return err
  941. }
  942. if t.sessionID == nil && ((isClient && contains(serverInit.KexAlgos, kexStrictServer)) || (!isClient && contains(clientInit.KexAlgos, kexStrictClient))) &&
  943. // [Psiphon]
  944. // When KEX randomization omits "kex-strict-c/s-v00@openssh.com"
  945. // (see comment in sendKexInit), do not enable strict mode.
  946. ((isClient && contains(t.sentInitMsg.KexAlgos, kexStrictClient)) || (!isClient && contains(t.sentInitMsg.KexAlgos, kexStrictServer))) {
  947. t.strictMode = true
  948. if err := t.conn.setStrictMode(); err != nil {
  949. return err
  950. }
  951. }
  952. // We don't send FirstKexFollows, but we handle receiving it.
  953. //
  954. // RFC 4253 section 7 defines the kex and the agreement method for
  955. // first_kex_packet_follows. It states that the guessed packet
  956. // should be ignored if the "kex algorithm and/or the host
  957. // key algorithm is guessed wrong (server and client have
  958. // different preferred algorithm), or if any of the other
  959. // algorithms cannot be agreed upon". The other algorithms have
  960. // already been checked above so the kex algorithm and host key
  961. // algorithm are checked here.
  962. if otherInit.FirstKexFollows && (clientInit.KexAlgos[0] != serverInit.KexAlgos[0] || clientInit.ServerHostKeyAlgos[0] != serverInit.ServerHostKeyAlgos[0]) {
  963. // other side sent a kex message for the wrong algorithm,
  964. // which we have to ignore.
  965. if _, err := t.conn.readPacket(); err != nil {
  966. return err
  967. }
  968. }
  969. kex, ok := kexAlgoMap[t.algorithms.kex]
  970. if !ok {
  971. return fmt.Errorf("ssh: unexpected key exchange algorithm %v", t.algorithms.kex)
  972. }
  973. var result *kexResult
  974. if len(t.hostKeys) > 0 {
  975. result, err = t.server(kex, &magics)
  976. } else {
  977. result, err = t.client(kex, &magics)
  978. }
  979. if err != nil {
  980. return err
  981. }
  982. firstKeyExchange := t.sessionID == nil
  983. if firstKeyExchange {
  984. t.sessionID = result.H
  985. }
  986. result.SessionID = t.sessionID
  987. if err := t.conn.prepareKeyChange(t.algorithms, result); err != nil {
  988. return err
  989. }
  990. if err = t.conn.writePacket([]byte{msgNewKeys}); err != nil {
  991. return err
  992. }
  993. // On the server side, after the first SSH_MSG_NEWKEYS, send a SSH_MSG_EXT_INFO
  994. // message with the server-sig-algs extension if the client supports it. See
  995. // RFC 8308, Sections 2.4 and 3.1, and [PROTOCOL], Section 1.9.
  996. if !isClient && firstKeyExchange && contains(clientInit.KexAlgos, "ext-info-c") {
  997. supportedPubKeyAuthAlgosList := strings.Join(t.publicKeyAuthAlgorithms, ",")
  998. extInfo := &extInfoMsg{
  999. NumExtensions: 2,
  1000. Payload: make([]byte, 0, 4+15+4+len(supportedPubKeyAuthAlgosList)+4+16+4+1),
  1001. }
  1002. extInfo.Payload = appendInt(extInfo.Payload, len("server-sig-algs"))
  1003. extInfo.Payload = append(extInfo.Payload, "server-sig-algs"...)
  1004. extInfo.Payload = appendInt(extInfo.Payload, len(supportedPubKeyAuthAlgosList))
  1005. extInfo.Payload = append(extInfo.Payload, supportedPubKeyAuthAlgosList...)
  1006. extInfo.Payload = appendInt(extInfo.Payload, len("ping@openssh.com"))
  1007. extInfo.Payload = append(extInfo.Payload, "ping@openssh.com"...)
  1008. extInfo.Payload = appendInt(extInfo.Payload, 1)
  1009. extInfo.Payload = append(extInfo.Payload, "0"...)
  1010. if err := t.conn.writePacket(Marshal(extInfo)); err != nil {
  1011. return err
  1012. }
  1013. }
  1014. if packet, err := t.conn.readPacket(); err != nil {
  1015. return err
  1016. } else if packet[0] != msgNewKeys {
  1017. return unexpectedMessageError(msgNewKeys, packet[0])
  1018. }
  1019. if firstKeyExchange {
  1020. // Indicates to the transport that the first key exchange is completed
  1021. // after receiving SSH_MSG_NEWKEYS.
  1022. t.conn.setInitialKEXDone()
  1023. }
  1024. return nil
  1025. }
  1026. // algorithmSignerWrapper is an AlgorithmSigner that only supports the default
  1027. // key format algorithm.
  1028. //
  1029. // This is technically a violation of the AlgorithmSigner interface, but it
  1030. // should be unreachable given where we use this. Anyway, at least it returns an
  1031. // error instead of panicing or producing an incorrect signature.
  1032. type algorithmSignerWrapper struct {
  1033. Signer
  1034. }
  1035. func (a algorithmSignerWrapper) SignWithAlgorithm(rand io.Reader, data []byte, algorithm string) (*Signature, error) {
  1036. if algorithm != underlyingAlgo(a.PublicKey().Type()) {
  1037. return nil, errors.New("ssh: internal error: algorithmSignerWrapper invoked with non-default algorithm")
  1038. }
  1039. return a.Sign(rand, data)
  1040. }
  1041. func pickHostKey(hostKeys []Signer, algo string) AlgorithmSigner {
  1042. for _, k := range hostKeys {
  1043. if s, ok := k.(MultiAlgorithmSigner); ok {
  1044. if !contains(s.Algorithms(), underlyingAlgo(algo)) {
  1045. continue
  1046. }
  1047. }
  1048. if algo == k.PublicKey().Type() {
  1049. return algorithmSignerWrapper{k}
  1050. }
  1051. k, ok := k.(AlgorithmSigner)
  1052. if !ok {
  1053. continue
  1054. }
  1055. for _, a := range algorithmsForKeyFormat(k.PublicKey().Type()) {
  1056. if algo == a {
  1057. return k
  1058. }
  1059. }
  1060. }
  1061. return nil
  1062. }
  1063. func (t *handshakeTransport) server(kex kexAlgorithm, magics *handshakeMagics) (*kexResult, error) {
  1064. hostKey := pickHostKey(t.hostKeys, t.algorithms.hostKey)
  1065. if hostKey == nil {
  1066. return nil, errors.New("ssh: internal error: negotiated unsupported signature type")
  1067. }
  1068. r, err := kex.Server(t.conn, t.config.Rand, magics, hostKey, t.algorithms.hostKey)
  1069. return r, err
  1070. }
  1071. func (t *handshakeTransport) client(kex kexAlgorithm, magics *handshakeMagics) (*kexResult, error) {
  1072. result, err := kex.Client(t.conn, t.config.Rand, magics)
  1073. if err != nil {
  1074. return nil, err
  1075. }
  1076. hostKey, err := ParsePublicKey(result.HostKey)
  1077. if err != nil {
  1078. return nil, err
  1079. }
  1080. if err := verifyHostKeySignature(hostKey, t.algorithms.hostKey, result); err != nil {
  1081. return nil, err
  1082. }
  1083. err = t.hostKeyCallback(t.dialAddress, t.remoteAddr, hostKey)
  1084. if err != nil {
  1085. return nil, err
  1086. }
  1087. return result, nil
  1088. }