本站源代码
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

790 lines
21KB

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