Rietveld Code Review Tool
Help | Bug tracker | Discussion group | Source code | Sign in
(1164)

Delta Between Two Patch Sets: ssh/server.go

Issue 13338044: code review 13338044: go.crypto/ssh: introduce PrivateKey method. (Closed)
Left Patch Set: diff -r c923f02daf74 https://code.google.com/p/go.crypto Created 10 years, 6 months ago
Right Patch Set: diff -r c923f02daf74 https://code.google.com/p/go.crypto Created 10 years, 6 months ago
Left:
Right:
Use n/p to move between diff chunks; N/P to move between comments. Please Sign in to add in-line comments.
Jump to:
Left: Side by side diff | Download
Right: Side by side diff | Download
« no previous file with change/comment | « ssh/keys_test.go ('k') | ssh/test/keys_test.go » ('j') | no next file with change/comment »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
LEFTRIGHT
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
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
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 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
188 writeString(h, serializedEphKey) 188 writeString(h, serializedEphKey)
189 189
190 K := make([]byte, intLength(secret)) 190 K := make([]byte, intLength(secret))
191 marshalInt(K, secret) 191 marshalInt(K, secret)
192 h.Write(K) 192 h.Write(K)
193 193
194 H := h.Sum(nil) 194 H := h.Sum(nil)
195 195
196 // H is already a hash, but the hostkey signing will apply its 196 // H is already a hash, but the hostkey signing will apply its
197 // own key specific hash algorithm. 197 // own key specific hash algorithm.
198 » sig, err := MarshaledSignature(priv, s.config.rand(), H) 198 » sig, err := signAndMarshal(priv, s.config.rand(), H)
199 if err != nil { 199 if err != nil {
200 return nil, err 200 return nil, err
201 } 201 }
202 202
203 reply := kexECDHReplyMsg{ 203 reply := kexECDHReplyMsg{
204 EphemeralPubKey: serializedEphKey, 204 EphemeralPubKey: serializedEphKey,
205 HostKey: hostKeyBytes, 205 HostKey: hostKeyBytes,
206 Signature: sig, 206 Signature: sig,
207 } 207 }
208 208
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
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 19 matching lines...) Expand all
283 writeInt(h, Y) 283 writeInt(h, Y)
284 284
285 K := make([]byte, intLength(kInt)) 285 K := make([]byte, intLength(kInt))
286 marshalInt(K, kInt) 286 marshalInt(K, kInt)
287 h.Write(K) 287 h.Write(K)
288 288
289 H := h.Sum(nil) 289 H := h.Sum(nil)
290 290
291 // H is already a hash, but the hostkey signing will apply its 291 // H is already a hash, but the hostkey signing will apply its
292 // own key specific hash algorithm. 292 // own key specific hash algorithm.
293 » sig, err := MarshaledSignature(priv, s.config.rand(), H) 293 » sig, err := signAndMarshal(priv, s.config.rand(), H)
294 if err != nil { 294 if err != nil {
295 return nil, err 295 return nil, err
296 } 296 }
297 297
298 kexDHReply := kexDHReplyMsg{ 298 kexDHReply := kexDHReplyMsg{
299 HostKey: hostKeyBytes, 299 HostKey: hostKeyBytes,
300 Y: Y, 300 Y: Y,
301 Signature: sig, 301 Signature: sig,
302 } 302 }
303 packet = marshal(msgKexDHReply, kexDHReply) 303 packet = marshal(msgKexDHReply, kexDHReply)
304 304
305 err = s.writePacket(packet) 305 err = s.writePacket(packet)
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 // MarshaledSignature 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 MarshaledSignature(k PrivateKey, rand io.Reader, data []byte) ([]byte, erro r) { 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().PublicKeyAlgo(), 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")
327 327
328 // Handshake performs an SSH transport and client authentication on the given Se rverConn. 328 // Handshake performs an SSH transport and client authentication on the given Se rverConn.
329 func (s *ServerConn) Handshake() (err error) { 329 func (s *ServerConn) Handshake() (err error) {
330 if _, err = s.Write(serverVersion); err != nil { 330 if _, err = s.Write(serverVersion); err != nil {
331 return 331 return
332 } 332 }
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
369 func (s *ServerConn) clientInitHandshake(clientKexInit *kexInitMsg, clientKexIni tPacket []byte) (err error) { 369 func (s *ServerConn) clientInitHandshake(clientKexInit *kexInitMsg, clientKexIni tPacket []byte) (err error) {
370 serverKexInit := kexInitMsg{ 370 serverKexInit := kexInitMsg{
371 KexAlgos: s.config.Crypto.kexes(), 371 KexAlgos: s.config.Crypto.kexes(),
372 CiphersClientServer: s.config.Crypto.ciphers(), 372 CiphersClientServer: s.config.Crypto.ciphers(),
373 CiphersServerClient: s.config.Crypto.ciphers(), 373 CiphersServerClient: s.config.Crypto.ciphers(),
374 MACsClientServer: s.config.Crypto.macs(), 374 MACsClientServer: s.config.Crypto.macs(),
375 MACsServerClient: s.config.Crypto.macs(), 375 MACsServerClient: s.config.Crypto.macs(),
376 CompressionClientServer: supportedCompressions, 376 CompressionClientServer: supportedCompressions,
377 CompressionServerClient: supportedCompressions, 377 CompressionServerClient: supportedCompressions,
378 } 378 }
379 // algo => key.
380 hostKeys := map[string]PrivateKey{}
381 for _, k := range s.config.hostKeys { 379 for _, k := range s.config.hostKeys {
382 serverKexInit.ServerHostKeyAlgos = append( 380 serverKexInit.ServerHostKeyAlgos = append(
383 » » » serverKexInit.ServerHostKeyAlgos, k.PublicKey().PrivateK eyAlgo()) 381 » » » serverKexInit.ServerHostKeyAlgos, k.PublicKey().PublicKe yAlgo())
384 » » hostKeys[k.PublicKey().PrivateKeyAlgo()] = k
385 } 382 }
386 383
387 serverKexInitPacket := marshal(msgKexInit, serverKexInit) 384 serverKexInitPacket := marshal(msgKexInit, serverKexInit)
388 if err = s.writePacket(serverKexInitPacket); err != nil { 385 if err = s.writePacket(serverKexInitPacket); err != nil {
389 return 386 return
390 } 387 }
391 388
392 if clientKexInitPacket == nil { 389 if clientKexInitPacket == nil {
393 clientKexInit = new(kexInitMsg) 390 clientKexInit = new(kexInitMsg)
394 if clientKexInitPacket, err = s.readPacket(); err != nil { 391 if clientKexInitPacket, err = s.readPacket(); err != nil {
395 return 392 return
396 } 393 }
397 if err = unmarshal(clientKexInit, clientKexInitPacket, msgKexIni t); err != nil { 394 if err = unmarshal(clientKexInit, clientKexInitPacket, msgKexIni t); err != nil {
398 return 395 return
399 } 396 }
400 } 397 }
401 398
402 kexAlgo, hostKeyAlgo, ok := findAgreedAlgorithms(s.transport, clientKexI nit, &serverKexInit) 399 kexAlgo, hostKeyAlgo, ok := findAgreedAlgorithms(s.transport, clientKexI nit, &serverKexInit)
403 if !ok { 400 if !ok {
404 return errors.New("ssh: no common algorithms") 401 return errors.New("ssh: no common algorithms")
405 } 402 }
406 if clientKexInit.FirstKexFollows && kexAlgo != clientKexInit.KexAlgos[0] { 403 if clientKexInit.FirstKexFollows && kexAlgo != clientKexInit.KexAlgos[0] {
407 // The client sent a Kex message for the wrong algorithm, 404 // The client sent a Kex message for the wrong algorithm,
408 // which we have to ignore. 405 // which we have to ignore.
409 if _, err = s.readPacket(); err != nil { 406 if _, err = s.readPacket(); err != nil {
410 return 407 return
411 } 408 }
412 } 409 }
413 410
414 » hostKey := hostKeys[hostKeyAlgo] 411 » var hostKey Signer
412 » for _, k := range s.config.hostKeys {
413 » » if hostKeyAlgo == k.PublicKey().PublicKeyAlgo() {
414 » » » hostKey = k
415 » » }
416 » }
415 417
416 var magics handshakeMagics 418 var magics handshakeMagics
417 magics.serverVersion = serverVersion[:len(serverVersion)-2] 419 magics.serverVersion = serverVersion[:len(serverVersion)-2]
418 magics.clientVersion = s.ClientVersion 420 magics.clientVersion = s.ClientVersion
419 magics.serverKexInit = marshal(msgKexInit, serverKexInit) 421 magics.serverKexInit = marshal(msgKexInit, serverKexInit)
420 magics.clientKexInit = clientKexInitPacket 422 magics.clientKexInit = clientKexInitPacket
421 423
422 var result *kexResult 424 var result *kexResult
423 switch kexAlgo { 425 switch kexAlgo {
424 case kexAlgoECDH256: 426 case kexAlgoECDH256:
(...skipping 450 matching lines...) Expand 10 before | Expand all | Expand 10 after
875 func Listen(network, addr string, config *ServerConfig) (*Listener, error) { 877 func Listen(network, addr string, config *ServerConfig) (*Listener, error) {
876 l, err := net.Listen(network, addr) 878 l, err := net.Listen(network, addr)
877 if err != nil { 879 if err != nil {
878 return nil, err 880 return nil, err
879 } 881 }
880 return &Listener{ 882 return &Listener{
881 l, 883 l,
882 config, 884 config,
883 }, nil 885 }, nil
884 } 886 }
LEFTRIGHT

Powered by Google App Engine
RSS Feeds Recent Issues | This issue
This is Rietveld f62528b