net-ssh 5.0.2 → 6.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (76) hide show
  1. checksums.yaml +4 -4
  2. checksums.yaml.gz.sig +0 -0
  3. data.tar.gz.sig +0 -0
  4. data/.gitignore +1 -0
  5. data/.rubocop.yml +8 -2
  6. data/.rubocop_todo.yml +392 -379
  7. data/.travis.yml +22 -22
  8. data/CHANGES.txt +63 -0
  9. data/Manifest +0 -1
  10. data/README.md +287 -0
  11. data/Rakefile +1 -2
  12. data/appveyor.yml +4 -2
  13. data/lib/net/ssh.rb +13 -4
  14. data/lib/net/ssh/authentication/agent.rb +9 -3
  15. data/lib/net/ssh/authentication/certificate.rb +10 -1
  16. data/lib/net/ssh/authentication/ed25519.rb +75 -46
  17. data/lib/net/ssh/authentication/ed25519_loader.rb +1 -1
  18. data/lib/net/ssh/authentication/key_manager.rb +35 -6
  19. data/lib/net/ssh/authentication/methods/keyboard_interactive.rb +3 -1
  20. data/lib/net/ssh/authentication/methods/publickey.rb +2 -0
  21. data/lib/net/ssh/authentication/pub_key_fingerprint.rb +0 -1
  22. data/lib/net/ssh/authentication/session.rb +9 -6
  23. data/lib/net/ssh/buffer.rb +41 -10
  24. data/lib/net/ssh/buffered_io.rb +0 -1
  25. data/lib/net/ssh/config.rb +68 -35
  26. data/lib/net/ssh/connection/channel.rb +17 -5
  27. data/lib/net/ssh/connection/event_loop.rb +0 -1
  28. data/lib/net/ssh/connection/session.rb +7 -4
  29. data/lib/net/ssh/key_factory.rb +104 -17
  30. data/lib/net/ssh/known_hosts.rb +41 -26
  31. data/lib/net/ssh/loggable.rb +2 -2
  32. data/lib/net/ssh/proxy/command.rb +0 -1
  33. data/lib/net/ssh/proxy/socks5.rb +0 -1
  34. data/lib/net/ssh/service/forward.rb +2 -1
  35. data/lib/net/ssh/test.rb +8 -7
  36. data/lib/net/ssh/test/extensions.rb +2 -0
  37. data/lib/net/ssh/transport/algorithms.rb +161 -105
  38. data/lib/net/ssh/transport/cipher_factory.rb +11 -27
  39. data/lib/net/ssh/transport/constants.rb +10 -6
  40. data/lib/net/ssh/transport/ctr.rb +1 -7
  41. data/lib/net/ssh/transport/hmac.rb +15 -13
  42. data/lib/net/ssh/transport/hmac/abstract.rb +16 -0
  43. data/lib/net/ssh/transport/hmac/sha2_256.rb +7 -11
  44. data/lib/net/ssh/transport/hmac/sha2_256_96.rb +4 -8
  45. data/lib/net/ssh/transport/hmac/sha2_256_etm.rb +12 -0
  46. data/lib/net/ssh/transport/hmac/sha2_512.rb +6 -9
  47. data/lib/net/ssh/transport/hmac/sha2_512_96.rb +4 -8
  48. data/lib/net/ssh/transport/hmac/sha2_512_etm.rb +12 -0
  49. data/lib/net/ssh/transport/kex.rb +14 -11
  50. data/lib/net/ssh/transport/kex/abstract.rb +123 -0
  51. data/lib/net/ssh/transport/kex/abstract5656.rb +72 -0
  52. data/lib/net/ssh/transport/kex/curve25519_sha256.rb +38 -0
  53. data/lib/net/ssh/transport/kex/curve25519_sha256_loader.rb +30 -0
  54. data/lib/net/ssh/transport/kex/diffie_hellman_group14_sha1.rb +1 -15
  55. data/lib/net/ssh/transport/kex/diffie_hellman_group1_sha1.rb +9 -118
  56. data/lib/net/ssh/transport/kex/diffie_hellman_group_exchange_sha1.rb +0 -6
  57. data/lib/net/ssh/transport/kex/diffie_hellman_group_exchange_sha256.rb +5 -9
  58. data/lib/net/ssh/transport/kex/ecdh_sha2_nistp256.rb +18 -79
  59. data/lib/net/ssh/transport/kex/ecdh_sha2_nistp384.rb +5 -4
  60. data/lib/net/ssh/transport/kex/ecdh_sha2_nistp521.rb +5 -4
  61. data/lib/net/ssh/transport/openssl.rb +106 -93
  62. data/lib/net/ssh/transport/packet_stream.rb +52 -20
  63. data/lib/net/ssh/transport/session.rb +26 -4
  64. data/lib/net/ssh/transport/state.rb +1 -1
  65. data/lib/net/ssh/verifiers/accept_new.rb +7 -0
  66. data/lib/net/ssh/verifiers/always.rb +4 -0
  67. data/lib/net/ssh/verifiers/never.rb +4 -0
  68. data/lib/net/ssh/version.rb +3 -3
  69. data/net-ssh-public_cert.pem +18 -19
  70. data/net-ssh.gemspec +9 -7
  71. metadata +56 -40
  72. metadata.gz.sig +0 -0
  73. data/Gemfile.noed25519.lock +0 -41
  74. data/README.rdoc +0 -169
  75. data/lib/net/ssh/ruby_compat.rb +0 -13
  76. data/support/arcfour_check.rb +0 -20
@@ -19,30 +19,17 @@ module Net
19
19
  "idea-cbc" => "idea-cbc",
20
20
  "cast128-cbc" => "cast-cbc",
21
21
  "rijndael-cbc@lysator.liu.se" => "aes-256-cbc",
22
- "arcfour128" => "rc4",
23
- "arcfour256" => "rc4",
24
- "arcfour512" => "rc4",
25
- "arcfour" => "rc4",
26
-
27
22
  "3des-ctr" => "des-ede3",
28
23
  "blowfish-ctr" => "bf-ecb",
29
-
30
- "aes256-ctr" => ::OpenSSL::Cipher.ciphers.include?("aes-256-ctr") ? "aes-256-ctr" : "aes-256-ecb",
31
- "aes192-ctr" => ::OpenSSL::Cipher.ciphers.include?("aes-192-ctr") ? "aes-192-ctr" : "aes-192-ecb",
32
- "aes128-ctr" => ::OpenSSL::Cipher.ciphers.include?("aes-128-ctr") ? "aes-128-ctr" : "aes-128-ecb",
33
- "cast128-ctr" => "cast5-ecb",
34
-
35
- "none" => "none"
36
- }
37
-
38
- # Ruby's OpenSSL bindings always return a key length of 16 for RC4 ciphers
39
- # resulting in the error: OpenSSL::CipherError: key length too short.
40
- # The following ciphers will override this key length.
41
- KEY_LEN_OVERRIDE = {
42
- "arcfour256" => 32,
43
- "arcfour512" => 64
24
+
25
+ 'aes256-ctr' => 'aes-256-ctr',
26
+ 'aes192-ctr' => 'aes-192-ctr',
27
+ 'aes128-ctr' => 'aes-128-ctr',
28
+ 'cast128-ctr' => 'cast5-ecb',
29
+
30
+ 'none' => 'none'
44
31
  }
45
-
32
+
46
33
  # Returns true if the underlying OpenSSL library supports the given cipher,
47
34
  # and false otherwise.
48
35
  def self.supported?(name)
@@ -72,12 +59,11 @@ module Net
72
59
  cipher = Net::SSH::Transport::OpenSSLAESCTR.new(cipher)
73
60
  end
74
61
  end
75
- cipher.iv = Net::SSH::Transport::KeyExpander.expand_key(cipher.iv_len, options[:iv], options) if ossl_name != "rc4"
62
+ cipher.iv = Net::SSH::Transport::KeyExpander.expand_key(cipher.iv_len, options[:iv], options)
76
63
 
77
- key_len = KEY_LEN_OVERRIDE[name] || cipher.key_len
64
+ key_len = cipher.key_len
78
65
  cipher.key_len = key_len
79
66
  cipher.key = Net::SSH::Transport::KeyExpander.expand_key(key_len, options[:key], options)
80
- cipher.update(" " * 1536) if (ossl_name == "rc4" && name != "arcfour")
81
67
 
82
68
  return cipher
83
69
  end
@@ -94,13 +80,11 @@ module Net
94
80
  result << 0 if options[:iv_len]
95
81
  else
96
82
  cipher = OpenSSL::Cipher.new(ossl_name)
97
- key_len = KEY_LEN_OVERRIDE[name] || cipher.key_len
83
+ key_len = cipher.key_len
98
84
  cipher.key_len = key_len
99
85
 
100
86
  block_size =
101
87
  case ossl_name
102
- when "rc4"
103
- 8
104
88
  when /\-ctr/
105
89
  Net::SSH::Transport::OpenSSLAESCTR.block_size
106
90
  else
@@ -2,11 +2,10 @@ module Net
2
2
  module SSH
3
3
  module Transport
4
4
  module Constants
5
-
6
5
  #--
7
6
  # Transport layer generic messages
8
7
  #++
9
-
8
+
10
9
  DISCONNECT = 1
11
10
  IGNORE = 2
12
11
  UNIMPLEMENTED = 3
@@ -17,19 +16,24 @@ module Net
17
16
  #--
18
17
  # Algorithm negotiation messages
19
18
  #++
20
-
19
+
21
20
  KEXINIT = 20
22
21
  NEWKEYS = 21
23
-
22
+
24
23
  #--
25
24
  # Key exchange method specific messages
26
25
  #++
27
-
26
+
28
27
  KEXDH_INIT = 30
29
28
  KEXDH_REPLY = 31
30
-
29
+
31
30
  KEXECDH_INIT = 30
32
31
  KEXECDH_REPLY = 31
32
+
33
+ KEXDH_GEX_GROUP = 31
34
+ KEXDH_GEX_INIT = 32
35
+ KEXDH_GEX_REPLY = 33
36
+ KEXDH_GEX_REQUEST = 34
33
37
  end
34
38
  end
35
39
  end
@@ -88,14 +88,8 @@ module Net::SSH::Transport
88
88
  end
89
89
 
90
90
  def final
91
- unless @remaining.empty?
92
- s = xor!(@remaining, _update(@counter))
93
- else
94
- s = ""
95
- end
96
-
91
+ s = @remaining.empty? ? '' : xor!(@remaining, _update(@counter))
97
92
  @remaining = ""
98
-
99
93
  s
100
94
  end
101
95
 
@@ -7,6 +7,8 @@ require 'net/ssh/transport/hmac/sha2_256'
7
7
  require 'net/ssh/transport/hmac/sha2_256_96'
8
8
  require 'net/ssh/transport/hmac/sha2_512'
9
9
  require 'net/ssh/transport/hmac/sha2_512_96'
10
+ require 'net/ssh/transport/hmac/sha2_256_etm'
11
+ require 'net/ssh/transport/hmac/sha2_512_etm'
10
12
  require 'net/ssh/transport/hmac/ripemd160'
11
13
  require 'net/ssh/transport/hmac/none'
12
14
 
@@ -15,21 +17,21 @@ require 'net/ssh/transport/hmac/none'
15
17
  module Net::SSH::Transport::HMAC
16
18
  # The mapping of SSH hmac algorithms to their implementations
17
19
  MAP = {
18
- 'hmac-md5' => MD5,
19
- 'hmac-md5-96' => MD5_96,
20
- 'hmac-sha1' => SHA1,
21
- 'hmac-sha1-96' => SHA1_96,
22
- 'hmac-ripemd160' => RIPEMD160,
23
- 'hmac-ripemd160@openssh.com' => RIPEMD160,
24
- 'none' => None
20
+ 'hmac-md5' => MD5,
21
+ 'hmac-md5-96' => MD5_96,
22
+ 'hmac-sha1' => SHA1,
23
+ 'hmac-sha1-96' => SHA1_96,
24
+ 'hmac-sha2-256' => SHA2_256,
25
+ 'hmac-sha2-256-96' => SHA2_256_96,
26
+ 'hmac-sha2-512' => SHA2_512,
27
+ 'hmac-sha2-512-96' => SHA2_512_96,
28
+ 'hmac-sha2-256-etm@openssh.com' => SHA2_256_Etm,
29
+ 'hmac-sha2-512-etm@openssh.com' => SHA2_512_Etm,
30
+ 'hmac-ripemd160' => RIPEMD160,
31
+ 'hmac-ripemd160@openssh.com' => RIPEMD160,
32
+ 'none' => None
25
33
  }
26
34
 
27
- # add mapping to sha2 hmac algorithms if they're available
28
- MAP['hmac-sha2-256'] = SHA2_256 if defined?(::Net::SSH::Transport::HMAC::SHA2_256)
29
- MAP['hmac-sha2-256-96'] = SHA2_256_96 if defined?(::Net::SSH::Transport::HMAC::SHA2_256_96)
30
- MAP['hmac-sha2-512'] = SHA2_512 if defined?(::Net::SSH::Transport::HMAC::SHA2_512)
31
- MAP['hmac-sha2-512-96'] = SHA2_512_96 if defined?(::Net::SSH::Transport::HMAC::SHA2_512_96)
32
-
33
35
  # Retrieves a new hmac instance of the given SSH type (+name+). If +key+ is
34
36
  # given, the new instance will be initialized with that key.
35
37
  def self.get(name, key="", parameters = {})
@@ -9,6 +9,18 @@ module Net
9
9
  # The base class of all OpenSSL-based HMAC algorithm wrappers.
10
10
  class Abstract
11
11
  class <<self
12
+ def etm(*v)
13
+ @etm = false if !defined?(@etm)
14
+ if v.empty?
15
+ @etm = superclass.etm if @etm.nil? && superclass.respond_to?(:etm)
16
+ return @etm
17
+ elsif v.length == 1
18
+ @etm = v.first
19
+ else
20
+ raise ArgumentError, "wrong number of arguments (#{v.length} for 1)"
21
+ end
22
+ end
23
+
12
24
  def key_length(*v)
13
25
  @key_length = nil if !defined?(@key_length)
14
26
  if v.empty?
@@ -46,6 +58,10 @@ module Net
46
58
  end
47
59
  end
48
60
 
61
+ def etm
62
+ self.class.etm
63
+ end
64
+
49
65
  def key_length
50
66
  self.class.key_length
51
67
  end
@@ -1,15 +1,11 @@
1
1
  require 'net/ssh/transport/hmac/abstract'
2
2
 
3
- if defined?(OpenSSL::Digest::SHA256) # need openssl support
4
- module Net::SSH::Transport::HMAC
5
-
6
- # The SHA-256 HMAC algorithm. This has a mac and key length of 32, and
7
- # uses the SHA-256 digest algorithm.
8
- class SHA2_256 < Abstract
9
- mac_length 32
10
- key_length 32
11
- digest_class OpenSSL::Digest::SHA256
12
- end
13
-
3
+ module Net::SSH::Transport::HMAC
4
+ # The SHA-256 HMAC algorithm. This has a mac and key length of 32, and
5
+ # uses the SHA-256 digest algorithm.
6
+ class SHA2_256 < Abstract
7
+ mac_length 32
8
+ key_length 32
9
+ digest_class OpenSSL::Digest::SHA256
14
10
  end
15
11
  end
@@ -1,13 +1,9 @@
1
1
  require 'net/ssh/transport/hmac/abstract'
2
2
 
3
3
  module Net::SSH::Transport::HMAC
4
-
5
- if defined?(SHA2_256) # need openssl support
6
- # The SHA256-96 HMAC algorithm. This returns only the first 12 bytes of
7
- # the digest.
8
- class SHA2_256_96 < SHA2_256
9
- mac_length 12
10
- end
4
+ # The SHA256-96 HMAC algorithm. This returns only the first 12 bytes of
5
+ # the digest.
6
+ class SHA2_256_96 < SHA2_256
7
+ mac_length 12
11
8
  end
12
-
13
9
  end
@@ -0,0 +1,12 @@
1
+ require 'net/ssh/transport/hmac/abstract'
2
+
3
+ module Net::SSH::Transport::HMAC
4
+ # The SHA-256 Encrypt-Then-Mac HMAC algorithm. This has a mac and
5
+ # key length of 32, and uses the SHA-256 digest algorithm.
6
+ class SHA2_256_Etm < Abstract
7
+ etm true
8
+ mac_length 32
9
+ key_length 32
10
+ digest_class OpenSSL::Digest::SHA256
11
+ end
12
+ end
@@ -1,14 +1,11 @@
1
1
  require 'net/ssh/transport/hmac/abstract'
2
2
 
3
3
  module Net::SSH::Transport::HMAC
4
-
5
- if defined?(OpenSSL::Digest::SHA512) # need openssl support
6
- # The SHA-512 HMAC algorithm. This has a mac and key length of 64, and
7
- # uses the SHA-512 digest algorithm.
8
- class SHA2_512 < Abstract
9
- mac_length 64
10
- key_length 64
11
- digest_class OpenSSL::Digest::SHA512
12
- end
4
+ # The SHA-512 HMAC algorithm. This has a mac and key length of 64, and
5
+ # uses the SHA-512 digest algorithm.
6
+ class SHA2_512 < Abstract
7
+ mac_length 64
8
+ key_length 64
9
+ digest_class OpenSSL::Digest::SHA512
13
10
  end
14
11
  end
@@ -1,13 +1,9 @@
1
1
  require 'net/ssh/transport/hmac/abstract'
2
2
 
3
3
  module Net::SSH::Transport::HMAC
4
-
5
- if defined?(SHA2_512) # need openssl support
6
- # The SHA2-512-96 HMAC algorithm. This returns only the first 12 bytes of
7
- # the digest.
8
- class SHA2_512_96 < SHA2_512
9
- mac_length 12
10
- end
4
+ # The SHA2-512-96 HMAC algorithm. This returns only the first 12 bytes of
5
+ # the digest.
6
+ class SHA2_512_96 < SHA2_512
7
+ mac_length 12
11
8
  end
12
-
13
9
  end
@@ -0,0 +1,12 @@
1
+ require 'net/ssh/transport/hmac/abstract'
2
+
3
+ module Net::SSH::Transport::HMAC
4
+ # The SHA-512 Encrypt-Then-Mac HMAC algorithm. This has a mac and
5
+ # key length of 64, and uses the SHA-512 digest algorithm.
6
+ class SHA2_512_Etm < Abstract
7
+ etm true
8
+ mac_length 64
9
+ key_length 64
10
+ digest_class OpenSSL::Digest::SHA512
11
+ end
12
+ end
@@ -2,25 +2,28 @@ require 'net/ssh/transport/kex/diffie_hellman_group1_sha1'
2
2
  require 'net/ssh/transport/kex/diffie_hellman_group14_sha1'
3
3
  require 'net/ssh/transport/kex/diffie_hellman_group_exchange_sha1'
4
4
  require 'net/ssh/transport/kex/diffie_hellman_group_exchange_sha256'
5
+ require 'net/ssh/transport/kex/ecdh_sha2_nistp256'
6
+ require 'net/ssh/transport/kex/ecdh_sha2_nistp384'
7
+ require 'net/ssh/transport/kex/ecdh_sha2_nistp521'
8
+ require 'net/ssh/transport/kex/curve25519_sha256_loader'
5
9
 
6
10
  module Net::SSH::Transport
7
11
  module Kex
8
12
  # Maps the supported key-exchange algorithms as named by the SSH protocol
9
13
  # to their corresponding implementors.
10
14
  MAP = {
11
- 'diffie-hellman-group-exchange-sha1' => DiffieHellmanGroupExchangeSHA1,
12
- 'diffie-hellman-group1-sha1' => DiffieHellmanGroup1SHA1,
13
- 'diffie-hellman-group14-sha1' => DiffieHellmanGroup14SHA1
15
+ 'diffie-hellman-group1-sha1' => DiffieHellmanGroup1SHA1,
16
+ 'diffie-hellman-group14-sha1' => DiffieHellmanGroup14SHA1,
17
+ 'diffie-hellman-group-exchange-sha1' => DiffieHellmanGroupExchangeSHA1,
18
+ 'diffie-hellman-group-exchange-sha256' => DiffieHellmanGroupExchangeSHA256,
19
+ 'ecdh-sha2-nistp256' => EcdhSHA2NistP256,
20
+ 'ecdh-sha2-nistp384' => EcdhSHA2NistP384,
21
+ 'ecdh-sha2-nistp521' => EcdhSHA2NistP521
14
22
  }
15
- MAP['diffie-hellman-group-exchange-sha256'] = DiffieHellmanGroupExchangeSHA256 if defined?(DiffieHellmanGroupExchangeSHA256)
16
- if defined?(OpenSSL::PKey::EC)
17
- require 'net/ssh/transport/kex/ecdh_sha2_nistp256'
18
- require 'net/ssh/transport/kex/ecdh_sha2_nistp384'
19
- require 'net/ssh/transport/kex/ecdh_sha2_nistp521'
20
23
 
21
- MAP['ecdh-sha2-nistp256'] = EcdhSHA2NistP256
22
- MAP['ecdh-sha2-nistp384'] = EcdhSHA2NistP384
23
- MAP['ecdh-sha2-nistp521'] = EcdhSHA2NistP521
24
+ if Net::SSH::Transport::Kex::Curve25519Sha256Loader::LOADED
25
+ MAP['curve25519-sha256'] = Curve25519Sha256
26
+ MAP['curve25519-sha256@libssh.org'] = Curve25519Sha256
24
27
  end
25
28
  end
26
29
  end
@@ -0,0 +1,123 @@
1
+ require 'net/ssh/buffer'
2
+ require 'net/ssh/errors'
3
+ require 'net/ssh/loggable'
4
+ require 'net/ssh/transport/openssl'
5
+ require 'net/ssh/transport/constants'
6
+
7
+ module Net
8
+ module SSH
9
+ module Transport
10
+ module Kex
11
+ # Abstract class that implement Diffie-Hellman Key Exchange
12
+ # See https://tools.ietf.org/html/rfc4253#page-21
13
+ class Abstract
14
+ include Loggable
15
+ include Constants
16
+
17
+ attr_reader :algorithms
18
+ attr_reader :connection
19
+ attr_reader :data
20
+ attr_reader :dh
21
+
22
+ # Create a new instance of the Diffie-Hellman Key Exchange algorithm.
23
+ # The Diffie-Hellman (DH) key exchange provides a shared secret that
24
+ # cannot be determined by either party alone. The key exchange is
25
+ # combined with a signature with the host key to provide host
26
+ # authentication.
27
+ def initialize(algorithms, connection, data)
28
+ @algorithms = algorithms
29
+ @connection = connection
30
+
31
+ @data = data.dup
32
+ @dh = generate_key
33
+ @logger = @data.delete(:logger)
34
+ end
35
+
36
+ # Perform the key-exchange for the given session, with the given
37
+ # data. This method will return a hash consisting of the
38
+ # following keys:
39
+ #
40
+ # * :session_id
41
+ # * :server_key
42
+ # * :shared_secret
43
+ # * :hashing_algorithm
44
+ #
45
+ # The caller is expected to be able to understand how to use these
46
+ # deliverables.
47
+ def exchange_keys
48
+ result = send_kexinit
49
+ verify_server_key(result[:server_key])
50
+ session_id = verify_signature(result)
51
+ confirm_newkeys
52
+
53
+ {
54
+ session_id: session_id,
55
+ server_key: result[:server_key],
56
+ shared_secret: result[:shared_secret],
57
+ hashing_algorithm: digester
58
+ }
59
+ end
60
+
61
+ def digester
62
+ raise NotImplementedError, 'abstract class: digester not implemented'
63
+ end
64
+
65
+ private
66
+
67
+ # Verify that the given key is of the expected type, and that it
68
+ # really is the key for the session's host. Raise Net::SSH::Exception
69
+ # if it is not.
70
+ def verify_server_key(key) #:nodoc:
71
+ if key.ssh_type != algorithms.host_key
72
+ raise Net::SSH::Exception, "host key algorithm mismatch '#{key.ssh_type}' != '#{algorithms.host_key}'"
73
+ end
74
+
75
+ blob, fingerprint = generate_key_fingerprint(key)
76
+
77
+ unless connection.host_key_verifier.verify(key: key, key_blob: blob, fingerprint: fingerprint, session: connection)
78
+ raise Net::SSH::Exception, 'host key verification failed'
79
+ end
80
+ end
81
+
82
+ def generate_key_fingerprint(key)
83
+ blob = Net::SSH::Buffer.from(:key, key).to_s
84
+
85
+ fingerprint = Net::SSH::Authentication::PubKeyFingerprint.fingerprint(blob, @connection.options[:fingerprint_hash] || 'SHA256')
86
+
87
+ [blob, fingerprint]
88
+ rescue StandardError => e
89
+ [nil, "(could not generate fingerprint: #{e.message})"]
90
+ end
91
+
92
+ # Verify the signature that was received. Raise Net::SSH::Exception
93
+ # if the signature could not be verified. Otherwise, return the new
94
+ # session-id.
95
+ def verify_signature(result) #:nodoc:
96
+ response = build_signature_buffer(result)
97
+
98
+ hash = digester.digest(response.to_s)
99
+
100
+ unless connection.host_key_verifier.verify_signature { result[:server_key].ssh_do_verify(result[:server_sig], hash) }
101
+ raise Net::SSH::Exception, 'could not verify server signature'
102
+ end
103
+
104
+ hash
105
+ end
106
+
107
+ # Send the NEWKEYS message, and expect the NEWKEYS message in
108
+ # reply.
109
+ def confirm_newkeys #:nodoc:
110
+ # send own NEWKEYS message first (the wodSSHServer won't send first)
111
+ response = Net::SSH::Buffer.new
112
+ response.write_byte(NEWKEYS)
113
+ connection.send_message(response)
114
+
115
+ # wait for the server's NEWKEYS message
116
+ buffer = connection.next_message
117
+ raise Net::SSH::Exception, 'expected NEWKEYS' unless buffer.type == NEWKEYS
118
+ end
119
+ end
120
+ end
121
+ end
122
+ end
123
+ end