kex.go 21 KB

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