@@ -19,6 +19,21 @@ import (
1919 "golang.org/x/crypto/curve25519"
2020)
2121
22+ const (
23+ // This is the group called diffie-hellman-group1-sha1 in RFC 4253 and
24+ // Oakley Group 2 in RFC 2409.
25+ oakleyGroup2 = "FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD129024E088A67CC74020BBEA63B139B22514A08798E3404DDEF9519B3CD3A431B302B0A6DF25F14374FE1356D6D51C245E485B576625E7EC6F44C42E9A637ED6B0BFF5CB6F406B7EDEE386BFB5A899FA5AE9F24117C4B1FE649286651ECE65381FFFFFFFFFFFFFFFF"
26+ // This is the group called diffie-hellman-group14-sha1 in RFC 4253 and
27+ // Oakley Group 14 in RFC 3526.
28+ oakleyGroup14 = "FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD129024E088A67CC74020BBEA63B139B22514A08798E3404DDEF9519B3CD3A431B302B0A6DF25F14374FE1356D6D51C245E485B576625E7EC6F44C42E9A637ED6B0BFF5CB6F406B7EDEE386BFB5A899FA5AE9F24117C4B1FE649286651ECE45B3DC2007CB8A163BF0598DA48361C55D39A69163FA8FD24CF5F83655D23DCA3AD961C62F356208552BB9ED529077096966D670C354E4ABC9804F1746C08CA18217C32905E462E36CE3BE39E772C180E86039B2783A2EC07A28FB5C55DF06F4C52C9DE2BCBF6955817183995497CEA956AE515D2261898FA051015728E5A8AACAA68FFFFFFFFFFFFFFFF"
29+ // This is the group called diffie-hellman-group15-sha512 in RFC 8268 and
30+ // Oakley Group 15 in RFC 3526.
31+ oakleyGroup15 = "FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD129024E088A67CC74020BBEA63B139B22514A08798E3404DDEF9519B3CD3A431B302B0A6DF25F14374FE1356D6D51C245E485B576625E7EC6F44C42E9A637ED6B0BFF5CB6F406B7EDEE386BFB5A899FA5AE9F24117C4B1FE649286651ECE45B3DC2007CB8A163BF0598DA48361C55D39A69163FA8FD24CF5F83655D23DCA3AD961C62F356208552BB9ED529077096966D670C354E4ABC9804F1746C08CA18217C32905E462E36CE3BE39E772C180E86039B2783A2EC07A28FB5C55DF06F4C52C9DE2BCBF6955817183995497CEA956AE515D2261898FA051015728E5A8AAAC42DAD33170D04507A33A85521ABDF1CBA64ECFB850458DBEF0A8AEA71575D060C7DB3970F85A6E1E4C7ABF5AE8CDB0933D71E8C94E04A25619DCEE3D2261AD2EE6BF12FFA06D98A0864D87602733EC86A64521F2B18177B200CBBE117577A615D6C770988C0BAD946E208E24FA074E5AB3143DB5BFCE0FD108E4B82D120A93AD2CAFFFFFFFFFFFFFFFF"
32+ // This is the group called diffie-hellman-group16-sha512 in RFC 8268 and
33+ // Oakley Group 16 in RFC 3526.
34+ oakleyGroup16 = "FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD129024E088A67CC74020BBEA63B139B22514A08798E3404DDEF9519B3CD3A431B302B0A6DF25F14374FE1356D6D51C245E485B576625E7EC6F44C42E9A637ED6B0BFF5CB6F406B7EDEE386BFB5A899FA5AE9F24117C4B1FE649286651ECE45B3DC2007CB8A163BF0598DA48361C55D39A69163FA8FD24CF5F83655D23DCA3AD961C62F356208552BB9ED529077096966D670C354E4ABC9804F1746C08CA18217C32905E462E36CE3BE39E772C180E86039B2783A2EC07A28FB5C55DF06F4C52C9DE2BCBF6955817183995497CEA956AE515D2261898FA051015728E5A8AAAC42DAD33170D04507A33A85521ABDF1CBA64ECFB850458DBEF0A8AEA71575D060C7DB3970F85A6E1E4C7ABF5AE8CDB0933D71E8C94E04A25619DCEE3D2261AD2EE6BF12FFA06D98A0864D87602733EC86A64521F2B18177B200CBBE117577A615D6C770988C0BAD946E208E24FA074E5AB3143DB5BFCE0FD108E4B82D120A92108011A723C12A787E6D788719A10BDBA5B2699C327186AF4E23C1A946834B6150BDA2583E9CA2AD44CE8DBBBC2DB04DE8EF92E8EFC141FBECAA6287C59474E6BC05D99B2964FA090C3A2233BA186515BE7ED1F612970CEE2D7AFB81BDD762170481CD0069127D5B05AA993B4EA988D8FDDC186FFB7DC90A6C08F4DF435C934063199FFFFFFFFFFFFFFFF"
35+ )
36+
2237// kexResult captures the outcome of a key exchange.
2338type kexResult struct {
2439 // Session hash. See also RFC 4253, section 8.
@@ -384,20 +399,15 @@ func ecHash(curve elliptic.Curve) crypto.Hash {
384399var kexAlgoMap = map [string ]kexAlgorithm {}
385400
386401func init () {
387- // This is the group called diffie-hellman-group1-sha1 in
388- // RFC 4253 and Oakley Group 2 in RFC 2409.
389- p , _ := new (big.Int ).SetString ("FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD129024E088A67CC74020BBEA63B139B22514A08798E3404DDEF9519B3CD3A431B302B0A6DF25F14374FE1356D6D51C245E485B576625E7EC6F44C42E9A637ED6B0BFF5CB6F406B7EDEE386BFB5A899FA5AE9F24117C4B1FE649286651ECE65381FFFFFFFFFFFFFFFF" , 16 )
402+ p , _ := new (big.Int ).SetString (oakleyGroup2 , 16 )
390403 kexAlgoMap [InsecureKeyExchangeDH1SHA1 ] = & dhGroup {
391404 g : new (big.Int ).SetInt64 (2 ),
392405 p : p ,
393406 pMinus1 : new (big.Int ).Sub (p , bigOne ),
394407 hashFunc : crypto .SHA1 ,
395408 }
396409
397- // This are the groups called diffie-hellman-group14-sha1 and
398- // diffie-hellman-group14-sha256 in RFC 4253 and RFC 8268,
399- // and Oakley Group 14 in RFC 3526.
400- p , _ = new (big.Int ).SetString ("FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD129024E088A67CC74020BBEA63B139B22514A08798E3404DDEF9519B3CD3A431B302B0A6DF25F14374FE1356D6D51C245E485B576625E7EC6F44C42E9A637ED6B0BFF5CB6F406B7EDEE386BFB5A899FA5AE9F24117C4B1FE649286651ECE45B3DC2007CB8A163BF0598DA48361C55D39A69163FA8FD24CF5F83655D23DCA3AD961C62F356208552BB9ED529077096966D670C354E4ABC9804F1746C08CA18217C32905E462E36CE3BE39E772C180E86039B2783A2EC07A28FB5C55DF06F4C52C9DE2BCBF6955817183995497CEA956AE515D2261898FA051015728E5A8AACAA68FFFFFFFFFFFFFFFF" , 16 )
410+ p , _ = new (big.Int ).SetString (oakleyGroup14 , 16 )
401411 group14 := & dhGroup {
402412 g : new (big.Int ).SetInt64 (2 ),
403413 p : p ,
@@ -413,9 +423,7 @@ func init() {
413423 hashFunc : crypto .SHA256 ,
414424 }
415425
416- // This is the group called diffie-hellman-group16-sha512 in RFC
417- // 8268 and Oakley Group 16 in RFC 3526.
418- p , _ = new (big.Int ).SetString ("FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD129024E088A67CC74020BBEA63B139B22514A08798E3404DDEF9519B3CD3A431B302B0A6DF25F14374FE1356D6D51C245E485B576625E7EC6F44C42E9A637ED6B0BFF5CB6F406B7EDEE386BFB5A899FA5AE9F24117C4B1FE649286651ECE45B3DC2007CB8A163BF0598DA48361C55D39A69163FA8FD24CF5F83655D23DCA3AD961C62F356208552BB9ED529077096966D670C354E4ABC9804F1746C08CA18217C32905E462E36CE3BE39E772C180E86039B2783A2EC07A28FB5C55DF06F4C52C9DE2BCBF6955817183995497CEA956AE515D2261898FA051015728E5A8AAAC42DAD33170D04507A33A85521ABDF1CBA64ECFB850458DBEF0A8AEA71575D060C7DB3970F85A6E1E4C7ABF5AE8CDB0933D71E8C94E04A25619DCEE3D2261AD2EE6BF12FFA06D98A0864D87602733EC86A64521F2B18177B200CBBE117577A615D6C770988C0BAD946E208E24FA074E5AB3143DB5BFCE0FD108E4B82D120A92108011A723C12A787E6D788719A10BDBA5B2699C327186AF4E23C1A946834B6150BDA2583E9CA2AD44CE8DBBBC2DB04DE8EF92E8EFC141FBECAA6287C59474E6BC05D99B2964FA090C3A2233BA186515BE7ED1F612970CEE2D7AFB81BDD762170481CD0069127D5B05AA993B4EA988D8FDDC186FFB7DC90A6C08F4DF435C934063199FFFFFFFFFFFFFFFF" , 16 )
426+ p , _ = new (big.Int ).SetString (oakleyGroup16 , 16 )
419427
420428 kexAlgoMap [KeyExchangeDH16SHA512 ] = & dhGroup {
421429 g : new (big.Int ).SetInt64 (2 ),
@@ -583,9 +591,9 @@ const (
583591func (gex * dhGEXSHA ) Client (c packetConn , randSource io.Reader , magics * handshakeMagics ) (* kexResult , error ) {
584592 // Send GexRequest
585593 kexDHGexRequest := kexDHGexRequestMsg {
586- MinBits : dhGroupExchangeMinimumBits ,
587- PreferedBits : dhGroupExchangePreferredBits ,
588- MaxBits : dhGroupExchangeMaximumBits ,
594+ MinBits : dhGroupExchangeMinimumBits ,
595+ PreferredBits : dhGroupExchangePreferredBits ,
596+ MaxBits : dhGroupExchangeMaximumBits ,
589597 }
590598 if err := c .writePacket (Marshal (& kexDHGexRequest )); err != nil {
591599 return nil , err
@@ -672,9 +680,7 @@ func (gex *dhGEXSHA) Client(c packetConn, randSource io.Reader, magics *handshak
672680}
673681
674682// Server half implementation of the Diffie Hellman Key Exchange with SHA1 and SHA256.
675- //
676- // This is a minimal implementation to satisfy the automated tests.
677- func (gex dhGEXSHA ) Server (c packetConn , randSource io.Reader , magics * handshakeMagics , priv AlgorithmSigner , algo string ) (result * kexResult , err error ) {
683+ func (gex * dhGEXSHA ) Server (c packetConn , randSource io.Reader , magics * handshakeMagics , priv AlgorithmSigner , algo string ) (result * kexResult , err error ) {
678684 // Receive GexRequest
679685 packet , err := c .readPacket ()
680686 if err != nil {
@@ -684,13 +690,32 @@ func (gex dhGEXSHA) Server(c packetConn, randSource io.Reader, magics *handshake
684690 if err = Unmarshal (packet , & kexDHGexRequest ); err != nil {
685691 return
686692 }
693+ // We check that the request received is valid and that the MaxBits
694+ // requested are at least equal to our supported minimum. This is the same
695+ // check done in OpenSSH:
696+ // https://github.com/openssh/openssh-portable/blob/80a2f64b/kexgexs.c#L94
697+ //
698+ // Furthermore, we also check that the required MinBits are less than or
699+ // equal to 4096 because we can use up to Oakley Group 16.
700+ if kexDHGexRequest .MaxBits < kexDHGexRequest .MinBits || kexDHGexRequest .PreferredBits < kexDHGexRequest .MinBits ||
701+ kexDHGexRequest .MaxBits < kexDHGexRequest .PreferredBits || kexDHGexRequest .MaxBits < dhGroupExchangeMinimumBits ||
702+ kexDHGexRequest .MinBits > 4096 {
703+ return nil , fmt .Errorf ("ssh: DH GEX request out of range, min: %d, max: %d, preferred: %d" , kexDHGexRequest .MinBits ,
704+ kexDHGexRequest .MaxBits , kexDHGexRequest .PreferredBits )
705+ }
706+
707+ var p * big.Int
708+ // We hardcode sending Oakley Group 14 (2048 bits), Oakley Group 15 (3072
709+ // bits) or Oakley Group 16 (4096 bits), based on the requested max size.
710+ if kexDHGexRequest .MaxBits < 3072 {
711+ p , _ = new (big.Int ).SetString (oakleyGroup14 , 16 )
712+ } else if kexDHGexRequest .MaxBits < 4096 {
713+ p , _ = new (big.Int ).SetString (oakleyGroup15 , 16 )
714+ } else {
715+ p , _ = new (big.Int ).SetString (oakleyGroup16 , 16 )
716+ }
687717
688- // Send GexGroup
689- // This is the group called diffie-hellman-group14-sha1 in RFC
690- // 4253 and Oakley Group 14 in RFC 3526.
691- p , _ := new (big.Int ).SetString ("FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD129024E088A67CC74020BBEA63B139B22514A08798E3404DDEF9519B3CD3A431B302B0A6DF25F14374FE1356D6D51C245E485B576625E7EC6F44C42E9A637ED6B0BFF5CB6F406B7EDEE386BFB5A899FA5AE9F24117C4B1FE649286651ECE45B3DC2007CB8A163BF0598DA48361C55D39A69163FA8FD24CF5F83655D23DCA3AD961C62F356208552BB9ED529077096966D670C354E4ABC9804F1746C08CA18217C32905E462E36CE3BE39E772C180E86039B2783A2EC07A28FB5C55DF06F4C52C9DE2BCBF6955817183995497CEA956AE515D2261898FA051015728E5A8AACAA68FFFFFFFFFFFFFFFF" , 16 )
692718 g := big .NewInt (2 )
693-
694719 msg := & kexDHGexGroupMsg {
695720 P : p ,
696721 G : g ,
@@ -728,9 +753,9 @@ func (gex dhGEXSHA) Server(c packetConn, randSource io.Reader, magics *handshake
728753 h := gex .hashFunc .New ()
729754 magics .write (h )
730755 writeString (h , hostKeyBytes )
731- binary .Write (h , binary .BigEndian , uint32 ( dhGroupExchangeMinimumBits ) )
732- binary .Write (h , binary .BigEndian , uint32 ( dhGroupExchangePreferredBits ) )
733- binary .Write (h , binary .BigEndian , uint32 ( dhGroupExchangeMaximumBits ) )
756+ binary .Write (h , binary .BigEndian , kexDHGexRequest . MinBits )
757+ binary .Write (h , binary .BigEndian , kexDHGexRequest . PreferredBits )
758+ binary .Write (h , binary .BigEndian , kexDHGexRequest . MaxBits )
734759 writeInt (h , p )
735760 writeInt (h , g )
736761 writeInt (h , kexDHGexInit .X )
0 commit comments