net-ssh 4.1.0 → 6.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (111) hide show
  1. checksums.yaml +5 -5
  2. checksums.yaml.gz.sig +0 -0
  3. data.tar.gz.sig +0 -0
  4. data/.gitignore +5 -0
  5. data/.rubocop.yml +8 -2
  6. data/.rubocop_todo.yml +405 -552
  7. data/.travis.yml +23 -22
  8. data/CHANGES.txt +112 -1
  9. data/Gemfile +1 -7
  10. data/{Gemfile.norbnacl → Gemfile.noed25519} +1 -1
  11. data/Manifest +4 -5
  12. data/README.md +287 -0
  13. data/Rakefile +40 -29
  14. data/appveyor.yml +12 -6
  15. data/lib/net/ssh.rb +68 -32
  16. data/lib/net/ssh/authentication/agent.rb +234 -222
  17. data/lib/net/ssh/authentication/certificate.rb +175 -164
  18. data/lib/net/ssh/authentication/constants.rb +17 -14
  19. data/lib/net/ssh/authentication/ed25519.rb +162 -141
  20. data/lib/net/ssh/authentication/ed25519_loader.rb +32 -29
  21. data/lib/net/ssh/authentication/key_manager.rb +40 -9
  22. data/lib/net/ssh/authentication/methods/abstract.rb +53 -47
  23. data/lib/net/ssh/authentication/methods/hostbased.rb +32 -33
  24. data/lib/net/ssh/authentication/methods/keyboard_interactive.rb +1 -1
  25. data/lib/net/ssh/authentication/methods/none.rb +10 -10
  26. data/lib/net/ssh/authentication/methods/password.rb +13 -13
  27. data/lib/net/ssh/authentication/methods/publickey.rb +56 -55
  28. data/lib/net/ssh/authentication/pageant.rb +468 -465
  29. data/lib/net/ssh/authentication/pub_key_fingerprint.rb +43 -0
  30. data/lib/net/ssh/authentication/session.rb +130 -122
  31. data/lib/net/ssh/buffer.rb +345 -312
  32. data/lib/net/ssh/buffered_io.rb +163 -163
  33. data/lib/net/ssh/config.rb +316 -238
  34. data/lib/net/ssh/connection/channel.rb +670 -650
  35. data/lib/net/ssh/connection/constants.rb +30 -26
  36. data/lib/net/ssh/connection/event_loop.rb +108 -105
  37. data/lib/net/ssh/connection/keepalive.rb +54 -50
  38. data/lib/net/ssh/connection/session.rb +682 -671
  39. data/lib/net/ssh/connection/term.rb +180 -176
  40. data/lib/net/ssh/errors.rb +101 -99
  41. data/lib/net/ssh/key_factory.rb +195 -108
  42. data/lib/net/ssh/known_hosts.rb +161 -152
  43. data/lib/net/ssh/loggable.rb +57 -55
  44. data/lib/net/ssh/packet.rb +82 -78
  45. data/lib/net/ssh/prompt.rb +55 -53
  46. data/lib/net/ssh/proxy/command.rb +104 -89
  47. data/lib/net/ssh/proxy/errors.rb +12 -8
  48. data/lib/net/ssh/proxy/http.rb +93 -91
  49. data/lib/net/ssh/proxy/https.rb +42 -39
  50. data/lib/net/ssh/proxy/jump.rb +50 -47
  51. data/lib/net/ssh/proxy/socks4.rb +0 -2
  52. data/lib/net/ssh/proxy/socks5.rb +11 -12
  53. data/lib/net/ssh/service/forward.rb +370 -317
  54. data/lib/net/ssh/test.rb +83 -77
  55. data/lib/net/ssh/test/channel.rb +146 -142
  56. data/lib/net/ssh/test/extensions.rb +150 -146
  57. data/lib/net/ssh/test/kex.rb +35 -31
  58. data/lib/net/ssh/test/local_packet.rb +48 -44
  59. data/lib/net/ssh/test/packet.rb +87 -84
  60. data/lib/net/ssh/test/remote_packet.rb +35 -31
  61. data/lib/net/ssh/test/script.rb +173 -171
  62. data/lib/net/ssh/test/socket.rb +59 -55
  63. data/lib/net/ssh/transport/algorithms.rb +430 -364
  64. data/lib/net/ssh/transport/cipher_factory.rb +95 -91
  65. data/lib/net/ssh/transport/constants.rb +33 -25
  66. data/lib/net/ssh/transport/ctr.rb +33 -11
  67. data/lib/net/ssh/transport/hmac.rb +15 -13
  68. data/lib/net/ssh/transport/hmac/abstract.rb +82 -63
  69. data/lib/net/ssh/transport/hmac/sha2_256.rb +7 -11
  70. data/lib/net/ssh/transport/hmac/sha2_256_96.rb +4 -8
  71. data/lib/net/ssh/transport/hmac/sha2_256_etm.rb +12 -0
  72. data/lib/net/ssh/transport/hmac/sha2_512.rb +6 -9
  73. data/lib/net/ssh/transport/hmac/sha2_512_96.rb +4 -8
  74. data/lib/net/ssh/transport/hmac/sha2_512_etm.rb +12 -0
  75. data/lib/net/ssh/transport/identity_cipher.rb +55 -51
  76. data/lib/net/ssh/transport/kex.rb +14 -13
  77. data/lib/net/ssh/transport/kex/abstract.rb +123 -0
  78. data/lib/net/ssh/transport/kex/abstract5656.rb +72 -0
  79. data/lib/net/ssh/transport/kex/curve25519_sha256.rb +38 -0
  80. data/lib/net/ssh/transport/kex/curve25519_sha256_loader.rb +30 -0
  81. data/lib/net/ssh/transport/kex/diffie_hellman_group14_sha1.rb +33 -40
  82. data/lib/net/ssh/transport/kex/diffie_hellman_group1_sha1.rb +112 -217
  83. data/lib/net/ssh/transport/kex/diffie_hellman_group_exchange_sha1.rb +53 -62
  84. data/lib/net/ssh/transport/kex/diffie_hellman_group_exchange_sha256.rb +5 -9
  85. data/lib/net/ssh/transport/kex/ecdh_sha2_nistp256.rb +36 -90
  86. data/lib/net/ssh/transport/kex/ecdh_sha2_nistp384.rb +18 -10
  87. data/lib/net/ssh/transport/kex/ecdh_sha2_nistp521.rb +18 -10
  88. data/lib/net/ssh/transport/key_expander.rb +29 -25
  89. data/lib/net/ssh/transport/openssl.rb +116 -116
  90. data/lib/net/ssh/transport/packet_stream.rb +223 -190
  91. data/lib/net/ssh/transport/server_version.rb +64 -66
  92. data/lib/net/ssh/transport/session.rb +306 -257
  93. data/lib/net/ssh/transport/state.rb +198 -196
  94. data/lib/net/ssh/verifiers/accept_new.rb +35 -0
  95. data/lib/net/ssh/verifiers/accept_new_or_local_tunnel.rb +34 -0
  96. data/lib/net/ssh/verifiers/always.rb +56 -0
  97. data/lib/net/ssh/verifiers/never.rb +21 -0
  98. data/lib/net/ssh/version.rb +55 -53
  99. data/net-ssh-public_cert.pem +18 -19
  100. data/net-ssh.gemspec +12 -11
  101. data/support/ssh_tunnel_bug.rb +2 -2
  102. metadata +86 -75
  103. metadata.gz.sig +0 -0
  104. data/Gemfile.norbnacl.lock +0 -41
  105. data/README.rdoc +0 -169
  106. data/lib/net/ssh/ruby_compat.rb +0 -24
  107. data/lib/net/ssh/verifiers/lenient.rb +0 -30
  108. data/lib/net/ssh/verifiers/null.rb +0 -12
  109. data/lib/net/ssh/verifiers/secure.rb +0 -52
  110. data/lib/net/ssh/verifiers/strict.rb +0 -24
  111. data/support/arcfour_check.rb +0 -20
@@ -0,0 +1,38 @@
1
+ gem 'x25519' # raise if the gem x25519 is not installed
2
+
3
+ require 'x25519'
4
+ require 'net/ssh/transport/constants'
5
+ require 'net/ssh/transport/kex/abstract5656'
6
+
7
+ module Net
8
+ module SSH
9
+ module Transport
10
+ module Kex
11
+ # A key-exchange service implementing the "curve25519-sha256@libssh.org"
12
+ # key-exchange algorithm. (defined in https://tools.ietf.org/html/draft-ietf-curdle-ssh-curves-06)
13
+ class Curve25519Sha256 < Abstract5656
14
+ def digester
15
+ OpenSSL::Digest::SHA256
16
+ end
17
+
18
+ private
19
+
20
+ def generate_key #:nodoc:
21
+ ::X25519::Scalar.generate
22
+ end
23
+
24
+ ## string Q_C, client's ephemeral public key octet string
25
+ def ecdh_public_key_bytes
26
+ ecdh.public_key.to_bytes
27
+ end
28
+
29
+ # compute shared secret from server's public key and client's private key
30
+ def compute_shared_secret(server_ecdh_pubkey)
31
+ pk = ::X25519::MontgomeryU.new(server_ecdh_pubkey)
32
+ OpenSSL::BN.new(ecdh.diffie_hellman(pk).to_bytes, 2)
33
+ end
34
+ end
35
+ end
36
+ end
37
+ end
38
+ end
@@ -0,0 +1,30 @@
1
+ module Net
2
+ module SSH
3
+ module Transport
4
+ module Kex
5
+ # Loads Curve25519Sha256 support which requires optinal dependencies
6
+ module Curve25519Sha256Loader
7
+ begin
8
+ require 'net/ssh/transport/kex/curve25519_sha256'
9
+ LOADED = true
10
+ ERROR = nil
11
+ rescue LoadError => e
12
+ ERROR = e
13
+ LOADED = false
14
+ end
15
+
16
+ def self.raiseUnlessLoaded(message)
17
+ description = ERROR.is_a?(LoadError) ? dependenciesRequiredForX25519 : ''
18
+ description << "#{ERROR.class} : \"#{ERROR.message}\"\n" if ERROR
19
+ raise NotImplementedError, "#{message}\n#{description}" unless LOADED
20
+ end
21
+
22
+ def self.dependenciesRequiredForX25519
23
+ result = "net-ssh requires the following gems for x25519 support:\n"
24
+ result << " * x25519\n"
25
+ end
26
+ end
27
+ end
28
+ end
29
+ end
30
+ end
@@ -1,44 +1,37 @@
1
1
  require 'net/ssh/transport/kex/diffie_hellman_group1_sha1'
2
2
 
3
- module Net; module SSH; module Transport; module Kex
4
-
5
- # A key-exchange service implementing the "diffie-hellman-group14-sha1"
6
- # key-exchange algorithm. (defined in RFC 4253)
7
- class DiffieHellmanGroup14SHA1 < DiffieHellmanGroup1SHA1
8
- include Constants, Loggable
9
-
10
- # The value of 'P', as a string, in hexadecimal
11
- P_s = "FFFFFFFF" "FFFFFFFF" "C90FDAA2" "2168C234" +
12
- "C4C6628B" "80DC1CD1" "29024E08" "8A67CC74" +
13
- "020BBEA6" "3B139B22" "514A0879" "8E3404DD" +
14
- "EF9519B3" "CD3A431B" "302B0A6D" "F25F1437" +
15
- "4FE1356D" "6D51C245" "E485B576" "625E7EC6" +
16
- "F44C42E9" "A637ED6B" "0BFF5CB6" "F406B7ED" +
17
- "EE386BFB" "5A899FA5" "AE9F2411" "7C4B1FE6" +
18
- "49286651" "ECE45B3D" "C2007CB8" "A163BF05" +
19
- "98DA4836" "1C55D39A" "69163FA8" "FD24CF5F" +
20
- "83655D23" "DCA3AD96" "1C62F356" "208552BB" +
21
- "9ED52907" "7096966D" "670C354E" "4ABC9804" +
22
- "F1746C08" "CA18217C" "32905E46" "2E36CE3B" +
23
- "E39E772C" "180E8603" "9B2783A2" "EC07A28F" +
24
- "B5C55DF0" "6F4C52C9" "DE2BCBF6" "95581718" +
25
- "3995497C" "EA956AE5" "15D22618" "98FA0510" +
26
- "15728E5A" "8AACAA68" "FFFFFFFF" "FFFFFFFF"
27
-
28
- # The radix in which P_s represents the value of P
29
- P_r = 16
30
-
31
- # The group constant
32
- G = 2
33
-
34
- private
35
-
36
- def get_p
37
- OpenSSL::BN.new(P_s, P_r)
38
- end
39
-
40
- def get_g
41
- G
3
+ module Net
4
+ module SSH
5
+ module Transport
6
+ module Kex
7
+ # A key-exchange service implementing the "diffie-hellman-group14-sha1"
8
+ # key-exchange algorithm. (defined in RFC 4253)
9
+ class DiffieHellmanGroup14SHA1 < DiffieHellmanGroup1SHA1
10
+ # The value of 'P', as a string, in hexadecimal
11
+ P_s = "FFFFFFFF" "FFFFFFFF" "C90FDAA2" "2168C234" +
12
+ "C4C6628B" "80DC1CD1" "29024E08" "8A67CC74" +
13
+ "020BBEA6" "3B139B22" "514A0879" "8E3404DD" +
14
+ "EF9519B3" "CD3A431B" "302B0A6D" "F25F1437" +
15
+ "4FE1356D" "6D51C245" "E485B576" "625E7EC6" +
16
+ "F44C42E9" "A637ED6B" "0BFF5CB6" "F406B7ED" +
17
+ "EE386BFB" "5A899FA5" "AE9F2411" "7C4B1FE6" +
18
+ "49286651" "ECE45B3D" "C2007CB8" "A163BF05" +
19
+ "98DA4836" "1C55D39A" "69163FA8" "FD24CF5F" +
20
+ "83655D23" "DCA3AD96" "1C62F356" "208552BB" +
21
+ "9ED52907" "7096966D" "670C354E" "4ABC9804" +
22
+ "F1746C08" "CA18217C" "32905E46" "2E36CE3B" +
23
+ "E39E772C" "180E8603" "9B2783A2" "EC07A28F" +
24
+ "B5C55DF0" "6F4C52C9" "DE2BCBF6" "95581718" +
25
+ "3995497C" "EA956AE5" "15D22618" "98FA0510" +
26
+ "15728E5A" "8AACAA68" "FFFFFFFF" "FFFFFFFF"
27
+
28
+ # The radix in which P_s represents the value of P
29
+ P_r = 16
30
+
31
+ # The group constant
32
+ G = 2
33
+ end
34
+ end
42
35
  end
43
36
  end
44
- end; end; end; end
37
+ end
@@ -1,227 +1,122 @@
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; module SSH; module Transport; module Kex
8
-
9
- # A key-exchange service implementing the "diffie-hellman-group1-sha1"
10
- # key-exchange algorithm.
11
- class DiffieHellmanGroup1SHA1
12
- include Constants, Loggable
13
-
14
- # The value of 'P', as a string, in hexadecimal
15
- P_s = "FFFFFFFF" "FFFFFFFF" "C90FDAA2" "2168C234" +
16
- "C4C6628B" "80DC1CD1" "29024E08" "8A67CC74" +
17
- "020BBEA6" "3B139B22" "514A0879" "8E3404DD" +
18
- "EF9519B3" "CD3A431B" "302B0A6D" "F25F1437" +
19
- "4FE1356D" "6D51C245" "E485B576" "625E7EC6" +
20
- "F44C42E9" "A637ED6B" "0BFF5CB6" "F406B7ED" +
21
- "EE386BFB" "5A899FA5" "AE9F2411" "7C4B1FE6" +
22
- "49286651" "ECE65381" "FFFFFFFF" "FFFFFFFF"
23
-
24
- # The radix in which P_s represents the value of P
25
- P_r = 16
26
-
27
- # The group constant
28
- G = 2
29
-
30
- attr_reader :p
31
- attr_reader :g
32
- attr_reader :digester
33
- attr_reader :algorithms
34
- attr_reader :connection
35
- attr_reader :data
36
- attr_reader :dh
37
-
38
- # Create a new instance of the DiffieHellmanGroup1SHA1 algorithm.
39
- # The data is a Hash of symbols representing information
40
- # required by this algorithm, which was acquired during earlier
41
- # processing.
42
- def initialize(algorithms, connection, data)
43
- @p = get_p
44
- @g = get_g
45
-
46
- @digester = OpenSSL::Digest::SHA1
47
- @algorithms = algorithms
48
- @connection = connection
49
-
50
- @data = data.dup
51
- @dh = generate_key
52
- @logger = @data.delete(:logger)
53
- end
54
-
55
- # Perform the key-exchange for the given session, with the given
56
- # data. This method will return a hash consisting of the
57
- # following keys:
58
- #
59
- # * :session_id
60
- # * :server_key
61
- # * :shared_secret
62
- # * :hashing_algorithm
63
- #
64
- # The caller is expected to be able to understand how to use these
65
- # deliverables.
66
- def exchange_keys
67
- result = send_kexinit
68
- verify_server_key(result[:server_key])
69
- session_id = verify_signature(result)
70
- confirm_newkeys
71
-
72
- return { session_id: session_id,
73
- server_key: result[:server_key],
74
- shared_secret: result[:shared_secret],
75
- hashing_algorithm: digester }
76
- end
77
-
78
- private
79
-
80
- def get_p
81
- OpenSSL::BN.new(P_s, P_r)
82
- end
83
-
84
- def get_g
85
- G
86
- end
87
-
88
- # Returns the DH key parameters for the current connection.
89
- def get_parameters
90
- [p, g]
91
- end
92
-
93
- # Returns the INIT/REPLY constants used by this algorithm.
94
- def get_message_types
95
- [KEXDH_INIT, KEXDH_REPLY]
96
- end
97
-
98
- # Build the signature buffer to use when verifying a signature from
99
- # the server.
100
- def build_signature_buffer(result)
101
- response = Net::SSH::Buffer.new
102
- response.write_string data[:client_version_string],
103
- data[:server_version_string],
104
- data[:client_algorithm_packet],
105
- data[:server_algorithm_packet],
106
- result[:key_blob]
107
- response.write_bignum dh.pub_key,
108
- result[:server_dh_pubkey],
109
- result[:shared_secret]
110
- response
111
- end
112
-
113
- # Generate a DH key with a private key consisting of the given
114
- # number of bytes.
115
- def generate_key #:nodoc:
116
- dh = OpenSSL::PKey::DH.new
117
-
118
- if dh.respond_to?(:set_pqg)
119
- p, g = get_parameters
120
- dh.set_pqg(p, nil, g)
121
- else
122
- dh.p, dh.g = get_parameters
123
- end
124
-
125
- dh.generate_key!
126
- until dh.valid? && dh.priv_key.num_bytes == data[:need_bytes]
127
- if dh.respond_to?(:set_key)
128
- dh.set_key(nil, OpenSSL::BN.rand(data[:need_bytes] * 8))
129
- else
130
- dh.priv_key = OpenSSL::BN.rand(data[:need_bytes] * 8)
1
+ require 'net/ssh/transport/kex/abstract'
2
+
3
+ module Net
4
+ module SSH
5
+ module Transport
6
+ module Kex
7
+ # A key-exchange service implementing the "diffie-hellman-group1-sha1"
8
+ # key-exchange algorithm.
9
+ class DiffieHellmanGroup1SHA1 < Abstract
10
+ # The value of 'P', as a string, in hexadecimal
11
+ P_s = "FFFFFFFF" "FFFFFFFF" "C90FDAA2" "2168C234" +
12
+ "C4C6628B" "80DC1CD1" "29024E08" "8A67CC74" +
13
+ "020BBEA6" "3B139B22" "514A0879" "8E3404DD" +
14
+ "EF9519B3" "CD3A431B" "302B0A6D" "F25F1437" +
15
+ "4FE1356D" "6D51C245" "E485B576" "625E7EC6" +
16
+ "F44C42E9" "A637ED6B" "0BFF5CB6" "F406B7ED" +
17
+ "EE386BFB" "5A899FA5" "AE9F2411" "7C4B1FE6" +
18
+ "49286651" "ECE65381" "FFFFFFFF" "FFFFFFFF"
19
+
20
+ # The radix in which P_s represents the value of P
21
+ P_r = 16
22
+
23
+ # The group constant
24
+ G = 2
25
+
26
+ def digester
27
+ OpenSSL::Digest::SHA1
131
28
  end
132
- dh.generate_key!
133
- end
134
- dh
135
- end
136
29
 
137
- # Send the KEXDH_INIT message, and expect the KEXDH_REPLY. Return the
138
- # resulting buffer.
139
- #
140
- # Parse the buffer from a KEXDH_REPLY message, returning a hash of
141
- # the extracted values.
142
- def send_kexinit #:nodoc:
143
- init, reply = get_message_types
144
-
145
- # send the KEXDH_INIT message
146
- buffer = Net::SSH::Buffer.from(:byte, init, :bignum, dh.pub_key)
147
- connection.send_message(buffer)
148
-
149
- # expect the KEXDH_REPLY message
150
- buffer = connection.next_message
151
- raise Net::SSH::Exception, "expected REPLY" unless buffer.type == reply
152
-
153
- result = Hash.new
154
-
155
- result[:key_blob] = buffer.read_string
156
- result[:server_key] = Net::SSH::Buffer.new(result[:key_blob]).read_key
157
- result[:server_dh_pubkey] = buffer.read_bignum
158
- result[:shared_secret] = OpenSSL::BN.new(dh.compute_key(result[:server_dh_pubkey]), 2)
159
-
160
- sig_buffer = Net::SSH::Buffer.new(buffer.read_string)
161
- sig_type = sig_buffer.read_string
162
- if sig_type != algorithms.host_key
163
- raise Net::SSH::Exception,
164
- "host key algorithm mismatch for signature " +
165
- "'#{sig_type}' != '#{algorithms.host_key}'"
166
- end
167
- result[:server_sig] = sig_buffer.read_string
168
-
169
- return result
170
- end
171
-
172
- # Verify that the given key is of the expected type, and that it
173
- # really is the key for the session's host. Raise Net::SSH::Exception
174
- # if it is not.
175
- def verify_server_key(key) #:nodoc:
176
- if key.ssh_type != algorithms.host_key
177
- raise Net::SSH::Exception,
178
- "host key algorithm mismatch " +
179
- "'#{key.ssh_type}' != '#{algorithms.host_key}'"
180
- end
30
+ private
181
31
 
182
- blob, fingerprint = generate_key_fingerprint(key)
183
-
184
- unless connection.host_key_verifier.verify(key: key, key_blob: blob, fingerprint: fingerprint, session: connection)
185
- raise Net::SSH::Exception, "host key verification failed"
186
- end
187
- end
188
-
189
- def generate_key_fingerprint(key)
190
- blob = Net::SSH::Buffer.from(:key, key).to_s
191
- fingerprint = OpenSSL::Digest::MD5.hexdigest(blob).scan(/../).join(":")
32
+ # Returns the DH key parameters for the current connection. [p, q]
33
+ def get_parameters
34
+ [
35
+ OpenSSL::BN.new(self.class::P_s, self.class::P_r),
36
+ self.class::G
37
+ ]
38
+ end
192
39
 
193
- [blob, fingerprint]
194
- rescue ::Exception => e
195
- [nil, "(could not generate fingerprint: #{e.message})"]
196
- end
40
+ # Returns the INIT/REPLY constants used by this algorithm.
41
+ def get_message_types
42
+ [KEXDH_INIT, KEXDH_REPLY]
43
+ end
197
44
 
198
- # Verify the signature that was received. Raise Net::SSH::Exception
199
- # if the signature could not be verified. Otherwise, return the new
200
- # session-id.
201
- def verify_signature(result) #:nodoc:
202
- response = build_signature_buffer(result)
45
+ # Build the signature buffer to use when verifying a signature from
46
+ # the server.
47
+ def build_signature_buffer(result)
48
+ response = Net::SSH::Buffer.new
49
+ response.write_string data[:client_version_string],
50
+ data[:server_version_string],
51
+ data[:client_algorithm_packet],
52
+ data[:server_algorithm_packet],
53
+ result[:key_blob]
54
+ response.write_bignum dh.pub_key,
55
+ result[:server_dh_pubkey],
56
+ result[:shared_secret]
57
+ response
58
+ end
203
59
 
204
- hash = @digester.digest(response.to_s)
60
+ # Generate a DH key with a private key consisting of the given
61
+ # number of bytes.
62
+ def generate_key #:nodoc:
63
+ dh = OpenSSL::PKey::DH.new
64
+
65
+ if dh.respond_to?(:set_pqg)
66
+ p, g = get_parameters
67
+ dh.set_pqg(p, nil, g)
68
+ else
69
+ dh.p, dh.g = get_parameters
70
+ end
71
+
72
+ dh.generate_key!
73
+ until dh.valid? && dh.priv_key.num_bytes == data[:need_bytes]
74
+ if dh.respond_to?(:set_key)
75
+ dh.set_key(nil, OpenSSL::BN.rand(data[:need_bytes] * 8))
76
+ else
77
+ dh.priv_key = OpenSSL::BN.rand(data[:need_bytes] * 8)
78
+ end
79
+ dh.generate_key!
80
+ end
81
+ dh
82
+ end
205
83
 
206
- unless result[:server_key].ssh_do_verify(result[:server_sig], hash)
207
- raise Net::SSH::Exception, "could not verify server signature"
84
+ # Send the KEXDH_INIT message, and expect the KEXDH_REPLY. Return the
85
+ # resulting buffer.
86
+ #
87
+ # Parse the buffer from a KEXDH_REPLY message, returning a hash of
88
+ # the extracted values.
89
+ def send_kexinit #:nodoc:
90
+ init, reply = get_message_types
91
+
92
+ # send the KEXDH_INIT message
93
+ buffer = Net::SSH::Buffer.from(:byte, init, :bignum, dh.pub_key)
94
+ connection.send_message(buffer)
95
+
96
+ # expect the KEXDH_REPLY message
97
+ buffer = connection.next_message
98
+ raise Net::SSH::Exception, "expected REPLY" unless buffer.type == reply
99
+
100
+ result = Hash.new
101
+
102
+ result[:key_blob] = buffer.read_string
103
+ result[:server_key] = Net::SSH::Buffer.new(result[:key_blob]).read_key
104
+ result[:server_dh_pubkey] = buffer.read_bignum
105
+ result[:shared_secret] = OpenSSL::BN.new(dh.compute_key(result[:server_dh_pubkey]), 2)
106
+
107
+ sig_buffer = Net::SSH::Buffer.new(buffer.read_string)
108
+ sig_type = sig_buffer.read_string
109
+ if sig_type != algorithms.host_key_format
110
+ raise Net::SSH::Exception,
111
+ "host key algorithm mismatch for signature " +
112
+ "'#{sig_type}' != '#{algorithms.host_key_format}'"
113
+ end
114
+ result[:server_sig] = sig_buffer.read_string
115
+
116
+ return result
117
+ end
208
118
  end
209
-
210
- return hash
211
- end
212
-
213
- # Send the NEWKEYS message, and expect the NEWKEYS message in
214
- # reply.
215
- def confirm_newkeys #:nodoc:
216
- # send own NEWKEYS message first (the wodSSHServer won't send first)
217
- response = Net::SSH::Buffer.new
218
- response.write_byte(NEWKEYS)
219
- connection.send_message(response)
220
-
221
- # wait for the server's NEWKEYS message
222
- buffer = connection.next_message
223
- raise Net::SSH::Exception, "expected NEWKEYS" unless buffer.type == NEWKEYS
224
119
  end
120
+ end
225
121
  end
226
-
227
- end; end; end; end
122
+ end