kex.go 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809
  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"
  7. "crypto/ecdsa"
  8. "crypto/elliptic"
  9. "crypto/rand"
  10. "crypto/subtle"
  11. "encoding/binary"
  12. "errors"
  13. "fmt"
  14. "io"
  15. "math/big"
  16. "golang.org/x/crypto/curve25519"
  17. )
  18. const (
  19. kexAlgoDH1SHA1 = "diffie-hellman-group1-sha1"
  20. kexAlgoDH14SHA1 = "diffie-hellman-group14-sha1"
  21. kexAlgoDH14SHA256 = "diffie-hellman-group14-sha256"
  22. kexAlgoECDH256 = "ecdh-sha2-nistp256"
  23. kexAlgoECDH384 = "ecdh-sha2-nistp384"
  24. kexAlgoECDH521 = "ecdh-sha2-nistp521"
  25. kexAlgoCurve25519SHA256 = "curve25519-sha256@libssh.org"
  26. // For the following kex only the client half contains a production
  27. // ready implementation. The server half only consists of a minimal
  28. // implementation to satisfy the automated tests.
  29. kexAlgoDHGEXSHA1 = "diffie-hellman-group-exchange-sha1"
  30. kexAlgoDHGEXSHA256 = "diffie-hellman-group-exchange-sha256"
  31. )
  32. // kexResult captures the outcome of a key exchange.
  33. type kexResult struct {
  34. // Session hash. See also RFC 4253, section 8.
  35. H []byte
  36. // Shared secret. See also RFC 4253, section 8.
  37. K []byte
  38. // Host key as hashed into H.
  39. HostKey []byte
  40. // Signature of H.
  41. Signature []byte
  42. // A cryptographic hash function that matches the security
  43. // level of the key exchange algorithm. It is used for
  44. // calculating H, and for deriving keys from H and K.
  45. Hash crypto.Hash
  46. // The session ID, which is the first H computed. This is used
  47. // to derive key material inside the transport.
  48. SessionID []byte
  49. }
  50. // handshakeMagics contains data that is always included in the
  51. // session hash.
  52. type handshakeMagics struct {
  53. clientVersion, serverVersion []byte
  54. clientKexInit, serverKexInit []byte
  55. }
  56. func (m *handshakeMagics) write(w io.Writer) {
  57. writeString(w, m.clientVersion)
  58. writeString(w, m.serverVersion)
  59. writeString(w, m.clientKexInit)
  60. writeString(w, m.serverKexInit)
  61. }
  62. // kexAlgorithm abstracts different key exchange algorithms.
  63. type kexAlgorithm interface {
  64. // Server runs server-side key agreement, signing the result
  65. // with a hostkey.
  66. Server(p packetConn, rand io.Reader, magics *handshakeMagics, s Signer) (*kexResult, error)
  67. // Client runs the client-side key agreement. Caller is
  68. // responsible for verifying the host key signature.
  69. Client(p packetConn, rand io.Reader, magics *handshakeMagics) (*kexResult, error)
  70. }
  71. // dhGroup is a multiplicative group suitable for implementing Diffie-Hellman key agreement.
  72. type dhGroup struct {
  73. g, p, pMinus1 *big.Int
  74. // [Psiphon]
  75. hashFunc crypto.Hash
  76. }
  77. func (group *dhGroup) diffieHellman(theirPublic, myPrivate *big.Int) (*big.Int, error) {
  78. if theirPublic.Cmp(bigOne) <= 0 || theirPublic.Cmp(group.pMinus1) >= 0 {
  79. return nil, errors.New("ssh: DH parameter out of bounds")
  80. }
  81. return new(big.Int).Exp(theirPublic, myPrivate, group.p), nil
  82. }
  83. func (group *dhGroup) Client(c packetConn, randSource io.Reader, magics *handshakeMagics) (*kexResult, error) {
  84. // [Psiphon]
  85. hashFunc := group.hashFunc
  86. var x *big.Int
  87. for {
  88. var err error
  89. if x, err = rand.Int(randSource, group.pMinus1); err != nil {
  90. return nil, err
  91. }
  92. if x.Sign() > 0 {
  93. break
  94. }
  95. }
  96. X := new(big.Int).Exp(group.g, x, group.p)
  97. kexDHInit := kexDHInitMsg{
  98. X: X,
  99. }
  100. if err := c.writePacket(Marshal(&kexDHInit)); err != nil {
  101. return nil, err
  102. }
  103. packet, err := c.readPacket()
  104. if err != nil {
  105. return nil, err
  106. }
  107. var kexDHReply kexDHReplyMsg
  108. if err = Unmarshal(packet, &kexDHReply); err != nil {
  109. return nil, err
  110. }
  111. ki, err := group.diffieHellman(kexDHReply.Y, x)
  112. if err != nil {
  113. return nil, err
  114. }
  115. h := hashFunc.New()
  116. magics.write(h)
  117. writeString(h, kexDHReply.HostKey)
  118. writeInt(h, X)
  119. writeInt(h, kexDHReply.Y)
  120. K := make([]byte, intLength(ki))
  121. marshalInt(K, ki)
  122. h.Write(K)
  123. return &kexResult{
  124. H: h.Sum(nil),
  125. K: K,
  126. HostKey: kexDHReply.HostKey,
  127. Signature: kexDHReply.Signature,
  128. Hash: hashFunc,
  129. }, nil
  130. }
  131. func (group *dhGroup) Server(c packetConn, randSource io.Reader, magics *handshakeMagics, priv Signer) (result *kexResult, err error) {
  132. // [Psiphon]
  133. hashFunc := group.hashFunc
  134. packet, err := c.readPacket()
  135. if err != nil {
  136. return
  137. }
  138. var kexDHInit kexDHInitMsg
  139. if err = Unmarshal(packet, &kexDHInit); err != nil {
  140. return
  141. }
  142. var y *big.Int
  143. for {
  144. if y, err = rand.Int(randSource, group.pMinus1); err != nil {
  145. return
  146. }
  147. if y.Sign() > 0 {
  148. break
  149. }
  150. }
  151. Y := new(big.Int).Exp(group.g, y, group.p)
  152. ki, err := group.diffieHellman(kexDHInit.X, y)
  153. if err != nil {
  154. return nil, err
  155. }
  156. hostKeyBytes := priv.PublicKey().Marshal()
  157. h := hashFunc.New()
  158. magics.write(h)
  159. writeString(h, hostKeyBytes)
  160. writeInt(h, kexDHInit.X)
  161. writeInt(h, Y)
  162. K := make([]byte, intLength(ki))
  163. marshalInt(K, ki)
  164. h.Write(K)
  165. H := h.Sum(nil)
  166. // H is already a hash, but the hostkey signing will apply its
  167. // own key-specific hash algorithm.
  168. sig, err := signAndMarshal(priv, randSource, H)
  169. if err != nil {
  170. return nil, err
  171. }
  172. kexDHReply := kexDHReplyMsg{
  173. HostKey: hostKeyBytes,
  174. Y: Y,
  175. Signature: sig,
  176. }
  177. packet = Marshal(&kexDHReply)
  178. err = c.writePacket(packet)
  179. return &kexResult{
  180. H: H,
  181. K: K,
  182. HostKey: hostKeyBytes,
  183. Signature: sig,
  184. Hash: hashFunc,
  185. }, err
  186. }
  187. // ecdh performs Elliptic Curve Diffie-Hellman key exchange as
  188. // described in RFC 5656, section 4.
  189. type ecdh struct {
  190. curve elliptic.Curve
  191. }
  192. func (kex *ecdh) Client(c packetConn, rand io.Reader, magics *handshakeMagics) (*kexResult, error) {
  193. ephKey, err := ecdsa.GenerateKey(kex.curve, rand)
  194. if err != nil {
  195. return nil, err
  196. }
  197. kexInit := kexECDHInitMsg{
  198. ClientPubKey: elliptic.Marshal(kex.curve, ephKey.PublicKey.X, ephKey.PublicKey.Y),
  199. }
  200. serialized := Marshal(&kexInit)
  201. if err := c.writePacket(serialized); err != nil {
  202. return nil, err
  203. }
  204. packet, err := c.readPacket()
  205. if err != nil {
  206. return nil, err
  207. }
  208. var reply kexECDHReplyMsg
  209. if err = Unmarshal(packet, &reply); err != nil {
  210. return nil, err
  211. }
  212. x, y, err := unmarshalECKey(kex.curve, reply.EphemeralPubKey)
  213. if err != nil {
  214. return nil, err
  215. }
  216. // generate shared secret
  217. secret, _ := kex.curve.ScalarMult(x, y, ephKey.D.Bytes())
  218. h := ecHash(kex.curve).New()
  219. magics.write(h)
  220. writeString(h, reply.HostKey)
  221. writeString(h, kexInit.ClientPubKey)
  222. writeString(h, reply.EphemeralPubKey)
  223. K := make([]byte, intLength(secret))
  224. marshalInt(K, secret)
  225. h.Write(K)
  226. return &kexResult{
  227. H: h.Sum(nil),
  228. K: K,
  229. HostKey: reply.HostKey,
  230. Signature: reply.Signature,
  231. Hash: ecHash(kex.curve),
  232. }, nil
  233. }
  234. // unmarshalECKey parses and checks an EC key.
  235. func unmarshalECKey(curve elliptic.Curve, pubkey []byte) (x, y *big.Int, err error) {
  236. x, y = elliptic.Unmarshal(curve, pubkey)
  237. if x == nil {
  238. return nil, nil, errors.New("ssh: elliptic.Unmarshal failure")
  239. }
  240. if !validateECPublicKey(curve, x, y) {
  241. return nil, nil, errors.New("ssh: public key not on curve")
  242. }
  243. return x, y, nil
  244. }
  245. // validateECPublicKey checks that the point is a valid public key for
  246. // the given curve. See [SEC1], 3.2.2
  247. func validateECPublicKey(curve elliptic.Curve, x, y *big.Int) bool {
  248. if x.Sign() == 0 && y.Sign() == 0 {
  249. return false
  250. }
  251. if x.Cmp(curve.Params().P) >= 0 {
  252. return false
  253. }
  254. if y.Cmp(curve.Params().P) >= 0 {
  255. return false
  256. }
  257. if !curve.IsOnCurve(x, y) {
  258. return false
  259. }
  260. // We don't check if N * PubKey == 0, since
  261. //
  262. // - the NIST curves have cofactor = 1, so this is implicit.
  263. // (We don't foresee an implementation that supports non NIST
  264. // curves)
  265. //
  266. // - for ephemeral keys, we don't need to worry about small
  267. // subgroup attacks.
  268. return true
  269. }
  270. func (kex *ecdh) Server(c packetConn, rand io.Reader, magics *handshakeMagics, priv Signer) (result *kexResult, err error) {
  271. packet, err := c.readPacket()
  272. if err != nil {
  273. return nil, err
  274. }
  275. var kexECDHInit kexECDHInitMsg
  276. if err = Unmarshal(packet, &kexECDHInit); err != nil {
  277. return nil, err
  278. }
  279. clientX, clientY, err := unmarshalECKey(kex.curve, kexECDHInit.ClientPubKey)
  280. if err != nil {
  281. return nil, err
  282. }
  283. // We could cache this key across multiple users/multiple
  284. // connection attempts, but the benefit is small. OpenSSH
  285. // generates a new key for each incoming connection.
  286. ephKey, err := ecdsa.GenerateKey(kex.curve, rand)
  287. if err != nil {
  288. return nil, err
  289. }
  290. hostKeyBytes := priv.PublicKey().Marshal()
  291. serializedEphKey := elliptic.Marshal(kex.curve, ephKey.PublicKey.X, ephKey.PublicKey.Y)
  292. // generate shared secret
  293. secret, _ := kex.curve.ScalarMult(clientX, clientY, ephKey.D.Bytes())
  294. h := ecHash(kex.curve).New()
  295. magics.write(h)
  296. writeString(h, hostKeyBytes)
  297. writeString(h, kexECDHInit.ClientPubKey)
  298. writeString(h, serializedEphKey)
  299. K := make([]byte, intLength(secret))
  300. marshalInt(K, secret)
  301. h.Write(K)
  302. H := h.Sum(nil)
  303. // H is already a hash, but the hostkey signing will apply its
  304. // own key-specific hash algorithm.
  305. sig, err := signAndMarshal(priv, rand, H)
  306. if err != nil {
  307. return nil, err
  308. }
  309. reply := kexECDHReplyMsg{
  310. EphemeralPubKey: serializedEphKey,
  311. HostKey: hostKeyBytes,
  312. Signature: sig,
  313. }
  314. serialized := Marshal(&reply)
  315. if err := c.writePacket(serialized); err != nil {
  316. return nil, err
  317. }
  318. return &kexResult{
  319. H: H,
  320. K: K,
  321. HostKey: reply.HostKey,
  322. Signature: sig,
  323. Hash: ecHash(kex.curve),
  324. }, nil
  325. }
  326. var kexAlgoMap = map[string]kexAlgorithm{}
  327. func init() {
  328. // This is the group called diffie-hellman-group1-sha1 in RFC
  329. // 4253 and Oakley Group 2 in RFC 2409.
  330. p, _ := new(big.Int).SetString("FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD129024E088A67CC74020BBEA63B139B22514A08798E3404DDEF9519B3CD3A431B302B0A6DF25F14374FE1356D6D51C245E485B576625E7EC6F44C42E9A637ED6B0BFF5CB6F406B7EDEE386BFB5A899FA5AE9F24117C4B1FE649286651ECE65381FFFFFFFFFFFFFFFF", 16)
  331. kexAlgoMap[kexAlgoDH1SHA1] = &dhGroup{
  332. g: new(big.Int).SetInt64(2),
  333. p: p,
  334. pMinus1: new(big.Int).Sub(p, bigOne),
  335. hashFunc: crypto.SHA1,
  336. }
  337. // This is the group called diffie-hellman-group14-sha1 in RFC
  338. // 4253 and Oakley Group 14 in RFC 3526.
  339. p, _ = new(big.Int).SetString("FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD129024E088A67CC74020BBEA63B139B22514A08798E3404DDEF9519B3CD3A431B302B0A6DF25F14374FE1356D6D51C245E485B576625E7EC6F44C42E9A637ED6B0BFF5CB6F406B7EDEE386BFB5A899FA5AE9F24117C4B1FE649286651ECE45B3DC2007CB8A163BF0598DA48361C55D39A69163FA8FD24CF5F83655D23DCA3AD961C62F356208552BB9ED529077096966D670C354E4ABC9804F1746C08CA18217C32905E462E36CE3BE39E772C180E86039B2783A2EC07A28FB5C55DF06F4C52C9DE2BCBF6955817183995497CEA956AE515D2261898FA051015728E5A8AACAA68FFFFFFFFFFFFFFFF", 16)
  340. kexAlgoMap[kexAlgoDH14SHA1] = &dhGroup{
  341. g: new(big.Int).SetInt64(2),
  342. p: p,
  343. pMinus1: new(big.Int).Sub(p, bigOne),
  344. hashFunc: crypto.SHA1,
  345. }
  346. // [Psiphon]
  347. // RFC 8268:
  348. // > The method of key exchange used for the name "diffie-hellman-
  349. // > group14-sha256" is the same as that for "diffie-hellman-group14-sha1"
  350. // > except that the SHA256 hash algorithm is used.
  351. kexAlgoMap[kexAlgoDH14SHA256] = &dhGroup{
  352. g: new(big.Int).SetInt64(2),
  353. p: p,
  354. pMinus1: new(big.Int).Sub(p, bigOne),
  355. hashFunc: crypto.SHA256,
  356. }
  357. kexAlgoMap[kexAlgoECDH521] = &ecdh{elliptic.P521()}
  358. kexAlgoMap[kexAlgoECDH384] = &ecdh{elliptic.P384()}
  359. kexAlgoMap[kexAlgoECDH256] = &ecdh{elliptic.P256()}
  360. kexAlgoMap[kexAlgoCurve25519SHA256] = &curve25519sha256{}
  361. kexAlgoMap[kexAlgoDHGEXSHA1] = &dhGEXSHA{hashFunc: crypto.SHA1}
  362. kexAlgoMap[kexAlgoDHGEXSHA256] = &dhGEXSHA{hashFunc: crypto.SHA256}
  363. }
  364. // curve25519sha256 implements the curve25519-sha256@libssh.org key
  365. // agreement protocol, as described in
  366. // https://git.libssh.org/projects/libssh.git/tree/doc/curve25519-sha256@libssh.org.txt
  367. type curve25519sha256 struct{}
  368. type curve25519KeyPair struct {
  369. priv [32]byte
  370. pub [32]byte
  371. }
  372. func (kp *curve25519KeyPair) generate(rand io.Reader) error {
  373. if _, err := io.ReadFull(rand, kp.priv[:]); err != nil {
  374. return err
  375. }
  376. curve25519.ScalarBaseMult(&kp.pub, &kp.priv)
  377. return nil
  378. }
  379. // curve25519Zeros is just an array of 32 zero bytes so that we have something
  380. // convenient to compare against in order to reject curve25519 points with the
  381. // wrong order.
  382. var curve25519Zeros [32]byte
  383. func (kex *curve25519sha256) Client(c packetConn, rand io.Reader, magics *handshakeMagics) (*kexResult, error) {
  384. var kp curve25519KeyPair
  385. if err := kp.generate(rand); err != nil {
  386. return nil, err
  387. }
  388. if err := c.writePacket(Marshal(&kexECDHInitMsg{kp.pub[:]})); err != nil {
  389. return nil, err
  390. }
  391. packet, err := c.readPacket()
  392. if err != nil {
  393. return nil, err
  394. }
  395. var reply kexECDHReplyMsg
  396. if err = Unmarshal(packet, &reply); err != nil {
  397. return nil, err
  398. }
  399. if len(reply.EphemeralPubKey) != 32 {
  400. return nil, errors.New("ssh: peer's curve25519 public value has wrong length")
  401. }
  402. var servPub, secret [32]byte
  403. copy(servPub[:], reply.EphemeralPubKey)
  404. curve25519.ScalarMult(&secret, &kp.priv, &servPub)
  405. if subtle.ConstantTimeCompare(secret[:], curve25519Zeros[:]) == 1 {
  406. return nil, errors.New("ssh: peer's curve25519 public value has wrong order")
  407. }
  408. h := crypto.SHA256.New()
  409. magics.write(h)
  410. writeString(h, reply.HostKey)
  411. writeString(h, kp.pub[:])
  412. writeString(h, reply.EphemeralPubKey)
  413. ki := new(big.Int).SetBytes(secret[:])
  414. K := make([]byte, intLength(ki))
  415. marshalInt(K, ki)
  416. h.Write(K)
  417. return &kexResult{
  418. H: h.Sum(nil),
  419. K: K,
  420. HostKey: reply.HostKey,
  421. Signature: reply.Signature,
  422. Hash: crypto.SHA256,
  423. }, nil
  424. }
  425. func (kex *curve25519sha256) Server(c packetConn, rand io.Reader, magics *handshakeMagics, priv Signer) (result *kexResult, err error) {
  426. packet, err := c.readPacket()
  427. if err != nil {
  428. return
  429. }
  430. var kexInit kexECDHInitMsg
  431. if err = Unmarshal(packet, &kexInit); err != nil {
  432. return
  433. }
  434. if len(kexInit.ClientPubKey) != 32 {
  435. return nil, errors.New("ssh: peer's curve25519 public value has wrong length")
  436. }
  437. var kp curve25519KeyPair
  438. if err := kp.generate(rand); err != nil {
  439. return nil, err
  440. }
  441. var clientPub, secret [32]byte
  442. copy(clientPub[:], kexInit.ClientPubKey)
  443. curve25519.ScalarMult(&secret, &kp.priv, &clientPub)
  444. if subtle.ConstantTimeCompare(secret[:], curve25519Zeros[:]) == 1 {
  445. return nil, errors.New("ssh: peer's curve25519 public value has wrong order")
  446. }
  447. hostKeyBytes := priv.PublicKey().Marshal()
  448. h := crypto.SHA256.New()
  449. magics.write(h)
  450. writeString(h, hostKeyBytes)
  451. writeString(h, kexInit.ClientPubKey)
  452. writeString(h, kp.pub[:])
  453. ki := new(big.Int).SetBytes(secret[:])
  454. K := make([]byte, intLength(ki))
  455. marshalInt(K, ki)
  456. h.Write(K)
  457. H := h.Sum(nil)
  458. sig, err := signAndMarshal(priv, rand, H)
  459. if err != nil {
  460. return nil, err
  461. }
  462. reply := kexECDHReplyMsg{
  463. EphemeralPubKey: kp.pub[:],
  464. HostKey: hostKeyBytes,
  465. Signature: sig,
  466. }
  467. if err := c.writePacket(Marshal(&reply)); err != nil {
  468. return nil, err
  469. }
  470. return &kexResult{
  471. H: H,
  472. K: K,
  473. HostKey: hostKeyBytes,
  474. Signature: sig,
  475. Hash: crypto.SHA256,
  476. }, nil
  477. }
  478. // dhGEXSHA implements the diffie-hellman-group-exchange-sha1 and
  479. // diffie-hellman-group-exchange-sha256 key agreement protocols,
  480. // as described in RFC 4419
  481. type dhGEXSHA struct {
  482. g, p *big.Int
  483. hashFunc crypto.Hash
  484. }
  485. const (
  486. dhGroupExchangeMinimumBits = 2048
  487. dhGroupExchangePreferredBits = 2048
  488. dhGroupExchangeMaximumBits = 8192
  489. )
  490. func (gex *dhGEXSHA) diffieHellman(theirPublic, myPrivate *big.Int) (*big.Int, error) {
  491. if theirPublic.Sign() <= 0 || theirPublic.Cmp(gex.p) >= 0 {
  492. return nil, fmt.Errorf("ssh: DH parameter out of bounds")
  493. }
  494. return new(big.Int).Exp(theirPublic, myPrivate, gex.p), nil
  495. }
  496. func (gex dhGEXSHA) Client(c packetConn, randSource io.Reader, magics *handshakeMagics) (*kexResult, error) {
  497. // Send GexRequest
  498. kexDHGexRequest := kexDHGexRequestMsg{
  499. MinBits: dhGroupExchangeMinimumBits,
  500. PreferedBits: dhGroupExchangePreferredBits,
  501. MaxBits: dhGroupExchangeMaximumBits,
  502. }
  503. if err := c.writePacket(Marshal(&kexDHGexRequest)); err != nil {
  504. return nil, err
  505. }
  506. // Receive GexGroup
  507. packet, err := c.readPacket()
  508. if err != nil {
  509. return nil, err
  510. }
  511. var kexDHGexGroup kexDHGexGroupMsg
  512. if err = Unmarshal(packet, &kexDHGexGroup); err != nil {
  513. return nil, err
  514. }
  515. // reject if p's bit length < dhGroupExchangeMinimumBits or > dhGroupExchangeMaximumBits
  516. if kexDHGexGroup.P.BitLen() < dhGroupExchangeMinimumBits || kexDHGexGroup.P.BitLen() > dhGroupExchangeMaximumBits {
  517. return nil, fmt.Errorf("ssh: server-generated gex p is out of range (%d bits)", kexDHGexGroup.P.BitLen())
  518. }
  519. gex.p = kexDHGexGroup.P
  520. gex.g = kexDHGexGroup.G
  521. // Check if g is safe by verifing that g > 1 and g < p - 1
  522. one := big.NewInt(1)
  523. var pMinusOne = &big.Int{}
  524. pMinusOne.Sub(gex.p, one)
  525. if gex.g.Cmp(one) != 1 && gex.g.Cmp(pMinusOne) != -1 {
  526. return nil, fmt.Errorf("ssh: server provided gex g is not safe")
  527. }
  528. // Send GexInit
  529. var pHalf = &big.Int{}
  530. pHalf.Rsh(gex.p, 1)
  531. x, err := rand.Int(randSource, pHalf)
  532. if err != nil {
  533. return nil, err
  534. }
  535. X := new(big.Int).Exp(gex.g, x, gex.p)
  536. kexDHGexInit := kexDHGexInitMsg{
  537. X: X,
  538. }
  539. if err := c.writePacket(Marshal(&kexDHGexInit)); err != nil {
  540. return nil, err
  541. }
  542. // Receive GexReply
  543. packet, err = c.readPacket()
  544. if err != nil {
  545. return nil, err
  546. }
  547. var kexDHGexReply kexDHGexReplyMsg
  548. if err = Unmarshal(packet, &kexDHGexReply); err != nil {
  549. return nil, err
  550. }
  551. kInt, err := gex.diffieHellman(kexDHGexReply.Y, x)
  552. if err != nil {
  553. return nil, err
  554. }
  555. // Check if k is safe by verifing that k > 1 and k < p - 1
  556. if kInt.Cmp(one) != 1 && kInt.Cmp(pMinusOne) != -1 {
  557. return nil, fmt.Errorf("ssh: derived k is not safe")
  558. }
  559. h := gex.hashFunc.New()
  560. magics.write(h)
  561. writeString(h, kexDHGexReply.HostKey)
  562. binary.Write(h, binary.BigEndian, uint32(dhGroupExchangeMinimumBits))
  563. binary.Write(h, binary.BigEndian, uint32(dhGroupExchangePreferredBits))
  564. binary.Write(h, binary.BigEndian, uint32(dhGroupExchangeMaximumBits))
  565. writeInt(h, gex.p)
  566. writeInt(h, gex.g)
  567. writeInt(h, X)
  568. writeInt(h, kexDHGexReply.Y)
  569. K := make([]byte, intLength(kInt))
  570. marshalInt(K, kInt)
  571. h.Write(K)
  572. return &kexResult{
  573. H: h.Sum(nil),
  574. K: K,
  575. HostKey: kexDHGexReply.HostKey,
  576. Signature: kexDHGexReply.Signature,
  577. Hash: gex.hashFunc,
  578. }, nil
  579. }
  580. // Server half implementation of the Diffie Hellman Key Exchange with SHA1 and SHA256.
  581. //
  582. // This is a minimal implementation to satisfy the automated tests.
  583. func (gex dhGEXSHA) Server(c packetConn, randSource io.Reader, magics *handshakeMagics, priv Signer) (result *kexResult, err error) {
  584. // Receive GexRequest
  585. packet, err := c.readPacket()
  586. if err != nil {
  587. return
  588. }
  589. var kexDHGexRequest kexDHGexRequestMsg
  590. if err = Unmarshal(packet, &kexDHGexRequest); err != nil {
  591. return
  592. }
  593. // smoosh the user's preferred size into our own limits
  594. if kexDHGexRequest.PreferedBits > dhGroupExchangeMaximumBits {
  595. kexDHGexRequest.PreferedBits = dhGroupExchangeMaximumBits
  596. }
  597. if kexDHGexRequest.PreferedBits < dhGroupExchangeMinimumBits {
  598. kexDHGexRequest.PreferedBits = dhGroupExchangeMinimumBits
  599. }
  600. // fix min/max if they're inconsistent. technically, we could just pout
  601. // and hang up, but there's no harm in giving them the benefit of the
  602. // doubt and just picking a bitsize for them.
  603. if kexDHGexRequest.MinBits > kexDHGexRequest.PreferedBits {
  604. kexDHGexRequest.MinBits = kexDHGexRequest.PreferedBits
  605. }
  606. if kexDHGexRequest.MaxBits < kexDHGexRequest.PreferedBits {
  607. kexDHGexRequest.MaxBits = kexDHGexRequest.PreferedBits
  608. }
  609. // Send GexGroup
  610. // This is the group called diffie-hellman-group14-sha1 in RFC
  611. // 4253 and Oakley Group 14 in RFC 3526.
  612. p, _ := new(big.Int).SetString("FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD129024E088A67CC74020BBEA63B139B22514A08798E3404DDEF9519B3CD3A431B302B0A6DF25F14374FE1356D6D51C245E485B576625E7EC6F44C42E9A637ED6B0BFF5CB6F406B7EDEE386BFB5A899FA5AE9F24117C4B1FE649286651ECE45B3DC2007CB8A163BF0598DA48361C55D39A69163FA8FD24CF5F83655D23DCA3AD961C62F356208552BB9ED529077096966D670C354E4ABC9804F1746C08CA18217C32905E462E36CE3BE39E772C180E86039B2783A2EC07A28FB5C55DF06F4C52C9DE2BCBF6955817183995497CEA956AE515D2261898FA051015728E5A8AACAA68FFFFFFFFFFFFFFFF", 16)
  613. gex.p = p
  614. gex.g = big.NewInt(2)
  615. kexDHGexGroup := kexDHGexGroupMsg{
  616. P: gex.p,
  617. G: gex.g,
  618. }
  619. if err := c.writePacket(Marshal(&kexDHGexGroup)); err != nil {
  620. return nil, err
  621. }
  622. // Receive GexInit
  623. packet, err = c.readPacket()
  624. if err != nil {
  625. return
  626. }
  627. var kexDHGexInit kexDHGexInitMsg
  628. if err = Unmarshal(packet, &kexDHGexInit); err != nil {
  629. return
  630. }
  631. var pHalf = &big.Int{}
  632. pHalf.Rsh(gex.p, 1)
  633. y, err := rand.Int(randSource, pHalf)
  634. if err != nil {
  635. return
  636. }
  637. Y := new(big.Int).Exp(gex.g, y, gex.p)
  638. kInt, err := gex.diffieHellman(kexDHGexInit.X, y)
  639. if err != nil {
  640. return nil, err
  641. }
  642. hostKeyBytes := priv.PublicKey().Marshal()
  643. h := gex.hashFunc.New()
  644. magics.write(h)
  645. writeString(h, hostKeyBytes)
  646. binary.Write(h, binary.BigEndian, uint32(dhGroupExchangeMinimumBits))
  647. binary.Write(h, binary.BigEndian, uint32(dhGroupExchangePreferredBits))
  648. binary.Write(h, binary.BigEndian, uint32(dhGroupExchangeMaximumBits))
  649. writeInt(h, gex.p)
  650. writeInt(h, gex.g)
  651. writeInt(h, kexDHGexInit.X)
  652. writeInt(h, Y)
  653. K := make([]byte, intLength(kInt))
  654. marshalInt(K, kInt)
  655. h.Write(K)
  656. H := h.Sum(nil)
  657. // H is already a hash, but the hostkey signing will apply its
  658. // own key-specific hash algorithm.
  659. sig, err := signAndMarshal(priv, randSource, H)
  660. if err != nil {
  661. return nil, err
  662. }
  663. kexDHGexReply := kexDHGexReplyMsg{
  664. HostKey: hostKeyBytes,
  665. Y: Y,
  666. Signature: sig,
  667. }
  668. packet = Marshal(&kexDHGexReply)
  669. err = c.writePacket(packet)
  670. return &kexResult{
  671. H: H,
  672. K: K,
  673. HostKey: hostKeyBytes,
  674. Signature: sig,
  675. Hash: gex.hashFunc,
  676. }, err
  677. }