LEFT | RIGHT |
1 // Copyright 2011 The Go Authors. All rights reserved. | 1 // Copyright 2011 The Go Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style | 2 // Use of this source code is governed by a BSD-style |
3 // license that can be found in the LICENSE file. | 3 // license that can be found in the LICENSE file. |
4 | 4 |
5 package ssh | 5 package ssh |
6 | 6 |
7 import ( | 7 import ( |
8 "bytes" | 8 "bytes" |
9 "crypto" | 9 "crypto" |
10 "crypto/ecdsa" | 10 "crypto/ecdsa" |
11 "crypto/elliptic" | 11 "crypto/elliptic" |
12 "crypto/rand" | 12 "crypto/rand" |
13 "encoding/binary" | 13 "encoding/binary" |
14 "errors" | 14 "errors" |
15 "io" | 15 "io" |
16 "math/big" | 16 "math/big" |
17 "net" | 17 "net" |
18 "sync" | 18 "sync" |
19 | 19 |
20 _ "crypto/sha1" | 20 _ "crypto/sha1" |
21 ) | 21 ) |
22 | 22 |
23 type ServerConfig struct { | 23 type ServerConfig struct { |
24 » hostKeys []PrivateKey | 24 » hostKeys []Signer |
25 | 25 |
26 // Rand provides the source of entropy for key exchange. If Rand is | 26 // Rand provides the source of entropy for key exchange. If Rand is |
27 // nil, the cryptographic random reader in package crypto/rand will | 27 // nil, the cryptographic random reader in package crypto/rand will |
28 // be used. | 28 // be used. |
29 Rand io.Reader | 29 Rand io.Reader |
30 | 30 |
31 // NoClientAuth is true if clients are allowed to connect without | 31 // NoClientAuth is true if clients are allowed to connect without |
32 // authenticating. | 32 // authenticating. |
33 NoClientAuth bool | 33 NoClientAuth bool |
34 | 34 |
(...skipping 22 matching lines...) Expand all Loading... |
57 | 57 |
58 func (c *ServerConfig) rand() io.Reader { | 58 func (c *ServerConfig) rand() io.Reader { |
59 if c.Rand == nil { | 59 if c.Rand == nil { |
60 return rand.Reader | 60 return rand.Reader |
61 } | 61 } |
62 return c.Rand | 62 return c.Rand |
63 } | 63 } |
64 | 64 |
65 // AddHostKey adds a private key as a host key. If an existing host | 65 // AddHostKey adds a private key as a host key. If an existing host |
66 // key exists with the same algorithm, it is overwritten. | 66 // key exists with the same algorithm, it is overwritten. |
67 func (s *ServerConfig) AddHostKey(key PrivateKey) { | 67 func (s *ServerConfig) AddHostKey(key Signer) { |
68 for i, k := range s.hostKeys { | 68 for i, k := range s.hostKeys { |
69 if k.PublicKey().PublicKeyAlgo() == key.PublicKey().PublicKeyAlg
o() { | 69 if k.PublicKey().PublicKeyAlgo() == key.PublicKey().PublicKeyAlg
o() { |
70 s.hostKeys[i] = key | 70 s.hostKeys[i] = key |
71 return | 71 return |
72 } | 72 } |
73 } | 73 } |
74 | 74 |
75 s.hostKeys = append(s.hostKeys, key) | 75 s.hostKeys = append(s.hostKeys, key) |
76 } | 76 } |
77 | 77 |
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
135 func Server(c net.Conn, config *ServerConfig) *ServerConn { | 135 func Server(c net.Conn, config *ServerConfig) *ServerConn { |
136 return &ServerConn{ | 136 return &ServerConn{ |
137 transport: newTransport(c, config.rand()), | 137 transport: newTransport(c, config.rand()), |
138 channels: make(map[uint32]*serverChan), | 138 channels: make(map[uint32]*serverChan), |
139 config: config, | 139 config: config, |
140 } | 140 } |
141 } | 141 } |
142 | 142 |
143 // kexECDH performs Elliptic Curve Diffie-Hellman key agreement on a | 143 // kexECDH performs Elliptic Curve Diffie-Hellman key agreement on a |
144 // ServerConnection, as documented in RFC 5656, section 4. | 144 // ServerConnection, as documented in RFC 5656, section 4. |
145 func (s *ServerConn) kexECDH(curve elliptic.Curve, magics *handshakeMagics, priv
PrivateKey) (result *kexResult, err error) { | 145 func (s *ServerConn) kexECDH(curve elliptic.Curve, magics *handshakeMagics, priv
Signer) (result *kexResult, err error) { |
146 packet, err := s.readPacket() | 146 packet, err := s.readPacket() |
147 if err != nil { | 147 if err != nil { |
148 return | 148 return |
149 } | 149 } |
150 | 150 |
151 var kexECDHInit kexECDHInitMsg | 151 var kexECDHInit kexECDHInitMsg |
152 if err = unmarshal(&kexECDHInit, packet, msgKexECDHInit); err != nil { | 152 if err = unmarshal(&kexECDHInit, packet, msgKexECDHInit); err != nil { |
153 return | 153 return |
154 } | 154 } |
155 | 155 |
(...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
243 // - the NIST curves have cofactor = 1, so this is implicit. | 243 // - the NIST curves have cofactor = 1, so this is implicit. |
244 // (We don't forsee an implementation that supports non NIST | 244 // (We don't forsee an implementation that supports non NIST |
245 // curves) | 245 // curves) |
246 // | 246 // |
247 // - for ephemeral keys, we don't need to worry about small | 247 // - for ephemeral keys, we don't need to worry about small |
248 // subgroup attacks. | 248 // subgroup attacks. |
249 return true | 249 return true |
250 } | 250 } |
251 | 251 |
252 // kexDH performs Diffie-Hellman key agreement on a ServerConnection. | 252 // kexDH performs Diffie-Hellman key agreement on a ServerConnection. |
253 func (s *ServerConn) kexDH(group *dhGroup, hashFunc crypto.Hash, magics *handsha
keMagics, priv PrivateKey) (result *kexResult, err error) { | 253 func (s *ServerConn) kexDH(group *dhGroup, hashFunc crypto.Hash, magics *handsha
keMagics, priv Signer) (result *kexResult, err error) { |
254 packet, err := s.readPacket() | 254 packet, err := s.readPacket() |
255 if err != nil { | 255 if err != nil { |
256 return | 256 return |
257 } | 257 } |
258 var kexDHInit kexDHInitMsg | 258 var kexDHInit kexDHInitMsg |
259 if err = unmarshal(&kexDHInit, packet, msgKexDHInit); err != nil { | 259 if err = unmarshal(&kexDHInit, packet, msgKexDHInit); err != nil { |
260 return | 260 return |
261 } | 261 } |
262 | 262 |
263 y, err := rand.Int(s.config.rand(), group.p) | 263 y, err := rand.Int(s.config.rand(), group.p) |
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
306 return &kexResult{ | 306 return &kexResult{ |
307 H: H, | 307 H: H, |
308 K: K, | 308 K: K, |
309 HostKey: hostKeyBytes, | 309 HostKey: hostKeyBytes, |
310 Hash: hashFunc, | 310 Hash: hashFunc, |
311 }, nil | 311 }, nil |
312 } | 312 } |
313 | 313 |
314 // signAndMarshal signs the data with the appropriate algorithm, | 314 // signAndMarshal signs the data with the appropriate algorithm, |
315 // and serializes the result in SSH wire format. | 315 // and serializes the result in SSH wire format. |
316 func signAndMarshal(k PrivateKey, rand io.Reader, data []byte) ([]byte, error) { | 316 func signAndMarshal(k Signer, rand io.Reader, data []byte) ([]byte, error) { |
317 sig, err := k.Sign(rand, data) | 317 sig, err := k.Sign(rand, data) |
318 if err != nil { | 318 if err != nil { |
319 return nil, err | 319 return nil, err |
320 } | 320 } |
321 | 321 |
322 return serializeSignature(k.PublicKey().PrivateKeyAlgo(), sig), nil | 322 return serializeSignature(k.PublicKey().PrivateKeyAlgo(), sig), nil |
323 } | 323 } |
324 | 324 |
325 // serverVersion is the fixed identification string that Server will use. | 325 // serverVersion is the fixed identification string that Server will use. |
326 var serverVersion = []byte("SSH-2.0-Go\r\n") | 326 var serverVersion = []byte("SSH-2.0-Go\r\n") |
(...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
401 return errors.New("ssh: no common algorithms") | 401 return errors.New("ssh: no common algorithms") |
402 } | 402 } |
403 if clientKexInit.FirstKexFollows && kexAlgo != clientKexInit.KexAlgos[0]
{ | 403 if clientKexInit.FirstKexFollows && kexAlgo != clientKexInit.KexAlgos[0]
{ |
404 // The client sent a Kex message for the wrong algorithm, | 404 // The client sent a Kex message for the wrong algorithm, |
405 // which we have to ignore. | 405 // which we have to ignore. |
406 if _, err = s.readPacket(); err != nil { | 406 if _, err = s.readPacket(); err != nil { |
407 return | 407 return |
408 } | 408 } |
409 } | 409 } |
410 | 410 |
411 » var hostKey PrivateKey | 411 » var hostKey Signer |
412 for _, k := range s.config.hostKeys { | 412 for _, k := range s.config.hostKeys { |
413 if hostKeyAlgo == k.PublicKey().PublicKeyAlgo() { | 413 if hostKeyAlgo == k.PublicKey().PublicKeyAlgo() { |
414 hostKey = k | 414 hostKey = k |
415 } | 415 } |
416 } | 416 } |
417 | 417 |
418 var magics handshakeMagics | 418 var magics handshakeMagics |
419 magics.serverVersion = serverVersion[:len(serverVersion)-2] | 419 magics.serverVersion = serverVersion[:len(serverVersion)-2] |
420 magics.clientVersion = s.ClientVersion | 420 magics.clientVersion = s.ClientVersion |
421 magics.serverKexInit = marshal(msgKexInit, serverKexInit) | 421 magics.serverKexInit = marshal(msgKexInit, serverKexInit) |
(...skipping 455 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
877 func Listen(network, addr string, config *ServerConfig) (*Listener, error) { | 877 func Listen(network, addr string, config *ServerConfig) (*Listener, error) { |
878 l, err := net.Listen(network, addr) | 878 l, err := net.Listen(network, addr) |
879 if err != nil { | 879 if err != nil { |
880 return nil, err | 880 return nil, err |
881 } | 881 } |
882 return &Listener{ | 882 return &Listener{ |
883 l, | 883 l, |
884 config, | 884 config, |
885 }, nil | 885 }, nil |
886 } | 886 } |
LEFT | RIGHT |