net-ssh 5.2.0 → 7.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (122) hide show
  1. checksums.yaml +5 -5
  2. checksums.yaml.gz.sig +0 -0
  3. data/.dockerignore +6 -0
  4. data/.github/config/rubocop_linter_action.yml +4 -0
  5. data/.github/workflows/ci-with-docker.yml +44 -0
  6. data/.github/workflows/ci.yml +87 -0
  7. data/.github/workflows/rubocop.yml +13 -0
  8. data/.gitignore +3 -0
  9. data/.rubocop.yml +16 -2
  10. data/.rubocop_todo.yml +623 -511
  11. data/CHANGES.txt +50 -2
  12. data/Dockerfile +27 -0
  13. data/Dockerfile.openssl3 +17 -0
  14. data/Gemfile +2 -0
  15. data/Gemfile.noed25519 +2 -0
  16. data/Manifest +0 -1
  17. data/README.md +293 -0
  18. data/Rakefile +6 -2
  19. data/appveyor.yml +4 -2
  20. data/docker-compose.yml +23 -0
  21. data/lib/net/ssh/authentication/agent.rb +29 -13
  22. data/lib/net/ssh/authentication/certificate.rb +19 -7
  23. data/lib/net/ssh/authentication/constants.rb +0 -1
  24. data/lib/net/ssh/authentication/ed25519.rb +13 -8
  25. data/lib/net/ssh/authentication/ed25519_loader.rb +5 -8
  26. data/lib/net/ssh/authentication/key_manager.rb +73 -32
  27. data/lib/net/ssh/authentication/methods/abstract.rb +12 -3
  28. data/lib/net/ssh/authentication/methods/hostbased.rb +3 -5
  29. data/lib/net/ssh/authentication/methods/keyboard_interactive.rb +5 -3
  30. data/lib/net/ssh/authentication/methods/none.rb +6 -9
  31. data/lib/net/ssh/authentication/methods/password.rb +2 -3
  32. data/lib/net/ssh/authentication/methods/publickey.rb +56 -16
  33. data/lib/net/ssh/authentication/pageant.rb +97 -97
  34. data/lib/net/ssh/authentication/pub_key_fingerprint.rb +2 -3
  35. data/lib/net/ssh/authentication/session.rb +27 -23
  36. data/lib/net/ssh/buffer.rb +51 -40
  37. data/lib/net/ssh/buffered_io.rb +24 -26
  38. data/lib/net/ssh/config.rb +82 -50
  39. data/lib/net/ssh/connection/channel.rb +101 -87
  40. data/lib/net/ssh/connection/constants.rb +0 -4
  41. data/lib/net/ssh/connection/event_loop.rb +30 -25
  42. data/lib/net/ssh/connection/keepalive.rb +12 -12
  43. data/lib/net/ssh/connection/session.rb +115 -111
  44. data/lib/net/ssh/connection/term.rb +56 -58
  45. data/lib/net/ssh/errors.rb +12 -12
  46. data/lib/net/ssh/key_factory.rb +10 -13
  47. data/lib/net/ssh/known_hosts.rb +106 -39
  48. data/lib/net/ssh/loggable.rb +10 -11
  49. data/lib/net/ssh/packet.rb +1 -1
  50. data/lib/net/ssh/prompt.rb +9 -11
  51. data/lib/net/ssh/proxy/command.rb +1 -2
  52. data/lib/net/ssh/proxy/errors.rb +2 -4
  53. data/lib/net/ssh/proxy/http.rb +18 -20
  54. data/lib/net/ssh/proxy/https.rb +8 -10
  55. data/lib/net/ssh/proxy/jump.rb +8 -10
  56. data/lib/net/ssh/proxy/socks4.rb +2 -4
  57. data/lib/net/ssh/proxy/socks5.rb +3 -6
  58. data/lib/net/ssh/service/forward.rb +9 -8
  59. data/lib/net/ssh/test/channel.rb +24 -26
  60. data/lib/net/ssh/test/extensions.rb +35 -35
  61. data/lib/net/ssh/test/kex.rb +6 -8
  62. data/lib/net/ssh/test/local_packet.rb +0 -2
  63. data/lib/net/ssh/test/packet.rb +3 -3
  64. data/lib/net/ssh/test/remote_packet.rb +6 -8
  65. data/lib/net/ssh/test/script.rb +25 -27
  66. data/lib/net/ssh/test/socket.rb +12 -15
  67. data/lib/net/ssh/test.rb +7 -7
  68. data/lib/net/ssh/transport/algorithms.rb +100 -58
  69. data/lib/net/ssh/transport/cipher_factory.rb +34 -50
  70. data/lib/net/ssh/transport/constants.rb +13 -9
  71. data/lib/net/ssh/transport/ctr.rb +8 -14
  72. data/lib/net/ssh/transport/hmac/abstract.rb +20 -5
  73. data/lib/net/ssh/transport/hmac/md5.rb +0 -2
  74. data/lib/net/ssh/transport/hmac/md5_96.rb +0 -2
  75. data/lib/net/ssh/transport/hmac/none.rb +0 -2
  76. data/lib/net/ssh/transport/hmac/ripemd160.rb +0 -2
  77. data/lib/net/ssh/transport/hmac/sha1.rb +0 -2
  78. data/lib/net/ssh/transport/hmac/sha1_96.rb +0 -2
  79. data/lib/net/ssh/transport/hmac/sha2_256.rb +7 -11
  80. data/lib/net/ssh/transport/hmac/sha2_256_96.rb +4 -8
  81. data/lib/net/ssh/transport/hmac/sha2_256_etm.rb +12 -0
  82. data/lib/net/ssh/transport/hmac/sha2_512.rb +6 -9
  83. data/lib/net/ssh/transport/hmac/sha2_512_96.rb +4 -8
  84. data/lib/net/ssh/transport/hmac/sha2_512_etm.rb +12 -0
  85. data/lib/net/ssh/transport/hmac.rb +13 -11
  86. data/lib/net/ssh/transport/identity_cipher.rb +11 -13
  87. data/lib/net/ssh/transport/kex/abstract.rb +130 -0
  88. data/lib/net/ssh/transport/kex/abstract5656.rb +72 -0
  89. data/lib/net/ssh/transport/kex/curve25519_sha256.rb +39 -0
  90. data/lib/net/ssh/transport/kex/curve25519_sha256_loader.rb +30 -0
  91. data/lib/net/ssh/transport/kex/diffie_hellman_group14_sha1.rb +5 -19
  92. data/lib/net/ssh/transport/kex/diffie_hellman_group14_sha256.rb +11 -0
  93. data/lib/net/ssh/transport/kex/diffie_hellman_group1_sha1.rb +30 -139
  94. data/lib/net/ssh/transport/kex/diffie_hellman_group_exchange_sha1.rb +1 -8
  95. data/lib/net/ssh/transport/kex/diffie_hellman_group_exchange_sha256.rb +5 -9
  96. data/lib/net/ssh/transport/kex/ecdh_sha2_nistp256.rb +20 -81
  97. data/lib/net/ssh/transport/kex/ecdh_sha2_nistp384.rb +5 -4
  98. data/lib/net/ssh/transport/kex/ecdh_sha2_nistp521.rb +5 -4
  99. data/lib/net/ssh/transport/kex.rb +15 -10
  100. data/lib/net/ssh/transport/key_expander.rb +7 -8
  101. data/lib/net/ssh/transport/openssl.rb +149 -127
  102. data/lib/net/ssh/transport/packet_stream.rb +50 -16
  103. data/lib/net/ssh/transport/server_version.rb +17 -16
  104. data/lib/net/ssh/transport/session.rb +9 -7
  105. data/lib/net/ssh/transport/state.rb +44 -44
  106. data/lib/net/ssh/verifiers/accept_new.rb +0 -2
  107. data/lib/net/ssh/verifiers/accept_new_or_local_tunnel.rb +1 -2
  108. data/lib/net/ssh/verifiers/always.rb +6 -4
  109. data/lib/net/ssh/verifiers/never.rb +0 -2
  110. data/lib/net/ssh/version.rb +3 -3
  111. data/lib/net/ssh.rb +12 -8
  112. data/net-ssh-public_cert.pem +8 -8
  113. data/net-ssh.gemspec +9 -7
  114. data/support/ssh_tunnel_bug.rb +3 -3
  115. data.tar.gz.sig +0 -0
  116. metadata +55 -30
  117. metadata.gz.sig +0 -0
  118. data/.travis.yml +0 -53
  119. data/Gemfile.noed25519.lock +0 -41
  120. data/README.rdoc +0 -194
  121. data/lib/net/ssh/ruby_compat.rb +0 -13
  122. data/support/arcfour_check.rb +0 -20
@@ -1,20 +1,12 @@
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'
1
+ require 'net/ssh/transport/kex/abstract'
6
2
 
7
3
  module Net
8
4
  module SSH
9
5
  module Transport
10
6
  module Kex
11
-
12
7
  # A key-exchange service implementing the "diffie-hellman-group1-sha1"
13
8
  # key-exchange algorithm.
14
- class DiffieHellmanGroup1SHA1
15
- include Loggable
16
- include Constants
17
-
9
+ class DiffieHellmanGroup1SHA1 < Abstract
18
10
  # The value of 'P', as a string, in hexadecimal
19
11
  P_s = "FFFFFFFF" "FFFFFFFF" "C90FDAA2" "2168C234" +
20
12
  "C4C6628B" "80DC1CD1" "29024E08" "8A67CC74" +
@@ -31,67 +23,18 @@ module Net
31
23
  # The group constant
32
24
  G = 2
33
25
 
34
- attr_reader :p
35
- attr_reader :g
36
- attr_reader :digester
37
- attr_reader :algorithms
38
- attr_reader :connection
39
- attr_reader :data
40
- attr_reader :dh
41
-
42
- # Create a new instance of the DiffieHellmanGroup1SHA1 algorithm.
43
- # The data is a Hash of symbols representing information
44
- # required by this algorithm, which was acquired during earlier
45
- # processing.
46
- def initialize(algorithms, connection, data)
47
- @p = get_p
48
- @g = get_g
49
-
50
- @digester = OpenSSL::Digest::SHA1
51
- @algorithms = algorithms
52
- @connection = connection
53
-
54
- @data = data.dup
55
- @dh = generate_key
56
- @logger = @data.delete(:logger)
57
- end
58
-
59
- # Perform the key-exchange for the given session, with the given
60
- # data. This method will return a hash consisting of the
61
- # following keys:
62
- #
63
- # * :session_id
64
- # * :server_key
65
- # * :shared_secret
66
- # * :hashing_algorithm
67
- #
68
- # The caller is expected to be able to understand how to use these
69
- # deliverables.
70
- def exchange_keys
71
- result = send_kexinit
72
- verify_server_key(result[:server_key])
73
- session_id = verify_signature(result)
74
- confirm_newkeys
75
-
76
- return { session_id: session_id,
77
- server_key: result[:server_key],
78
- shared_secret: result[:shared_secret],
79
- hashing_algorithm: digester }
26
+ def digester
27
+ OpenSSL::Digest::SHA1
80
28
  end
81
29
 
82
30
  private
83
31
 
84
- def get_p
85
- OpenSSL::BN.new(P_s, P_r)
86
- end
87
-
88
- def get_g
89
- G
90
- end
91
-
92
- # Returns the DH key parameters for the current connection.
32
+ # Returns the DH key parameters for the current connection. [p, q]
93
33
  def get_parameters
94
- [p, g]
34
+ [
35
+ OpenSSL::BN.new(self.class::P_s, self.class::P_r),
36
+ self.class::G
37
+ ]
95
38
  end
96
39
 
97
40
  # Returns the INIT/REPLY constants used by this algorithm.
@@ -116,26 +59,26 @@ module Net
116
59
 
117
60
  # Generate a DH key with a private key consisting of the given
118
61
  # number of bytes.
119
- def generate_key #:nodoc:
120
- dh = OpenSSL::PKey::DH.new
121
-
122
- if dh.respond_to?(:set_pqg)
123
- p, g = get_parameters
124
- dh.set_pqg(p, nil, g)
62
+ def generate_key # :nodoc:
63
+ p, g = get_parameters
64
+
65
+ asn1 = OpenSSL::ASN1::Sequence(
66
+ [
67
+ OpenSSL::ASN1::Integer(p),
68
+ OpenSSL::ASN1::Integer(g)
69
+ ]
70
+ )
71
+
72
+ dh_params = OpenSSL::PKey::DH.new(asn1.to_der)
73
+ # XXX No private key size check! In theory the latter call should work but fails on OpenSSL 3.0 as
74
+ # dh_paramgen_subprime_len is now reserved for DHX algorithm
75
+ # key = OpenSSL::PKey.generate_key(dh_params, "dh_paramgen_subprime_len" => data[:need_bytes]/8)
76
+ if OpenSSL::PKey.respond_to?(:generate_key)
77
+ OpenSSL::PKey.generate_key(dh_params)
125
78
  else
126
- dh.p, dh.g = get_parameters
127
- end
128
-
129
- dh.generate_key!
130
- until dh.valid? && dh.priv_key.num_bytes == data[:need_bytes]
131
- if dh.respond_to?(:set_key)
132
- dh.set_key(nil, OpenSSL::BN.rand(data[:need_bytes] * 8))
133
- else
134
- dh.priv_key = OpenSSL::BN.rand(data[:need_bytes] * 8)
135
- end
136
- dh.generate_key!
79
+ dh_params.generate_key!
80
+ dh_params
137
81
  end
138
- dh
139
82
  end
140
83
 
141
84
  # Send the KEXDH_INIT message, and expect the KEXDH_REPLY. Return the
@@ -143,7 +86,7 @@ module Net
143
86
  #
144
87
  # Parse the buffer from a KEXDH_REPLY message, returning a hash of
145
88
  # the extracted values.
146
- def send_kexinit #:nodoc:
89
+ def send_kexinit # :nodoc:
147
90
  init, reply = get_message_types
148
91
 
149
92
  # send the KEXDH_INIT message
@@ -165,66 +108,14 @@ module Net
165
108
  sig_type = sig_buffer.read_string
166
109
  if sig_type != algorithms.host_key_format
167
110
  raise Net::SSH::Exception,
168
- "host key algorithm mismatch for signature " +
169
- "'#{sig_type}' != '#{algorithms.host_key_format}'"
111
+ "host key algorithm mismatch for signature " +
112
+ "'#{sig_type}' != '#{algorithms.host_key_format}'"
170
113
  end
171
114
  result[:server_sig] = sig_buffer.read_string
172
115
 
173
116
  return result
174
117
  end
175
-
176
- # Verify that the given key is of the expected type, and that it
177
- # really is the key for the session's host. Raise Net::SSH::Exception
178
- # if it is not.
179
- def verify_server_key(key) #:nodoc:
180
- if key.ssh_type != algorithms.host_key
181
- raise Net::SSH::Exception,
182
- "host key algorithm mismatch " +
183
- "'#{key.ssh_type}' != '#{algorithms.host_key}'"
184
- end
185
-
186
- blob, fingerprint = generate_key_fingerprint(key)
187
-
188
- raise Net::SSH::Exception, "host key verification failed" unless connection.host_key_verifier.verify(key: key, key_blob: blob, fingerprint: fingerprint, session: connection)
189
- end
190
-
191
- def generate_key_fingerprint(key)
192
- blob = Net::SSH::Buffer.from(:key, key).to_s
193
-
194
- fingerprint = Net::SSH::Authentication::PubKeyFingerprint.fingerprint(blob, @connection.options[:fingerprint_hash] || 'SHA256')
195
-
196
- [blob, fingerprint]
197
- rescue ::Exception => e
198
- [nil, "(could not generate fingerprint: #{e.message})"]
199
- end
200
-
201
- # Verify the signature that was received. Raise Net::SSH::Exception
202
- # if the signature could not be verified. Otherwise, return the new
203
- # session-id.
204
- def verify_signature(result) #:nodoc:
205
- response = build_signature_buffer(result)
206
-
207
- hash = @digester.digest(response.to_s)
208
-
209
- raise Net::SSH::Exception, "could not verify server signature" unless connection.host_key_verifier.verify_signature { result[:server_key].ssh_do_verify(result[:server_sig], hash) }
210
-
211
- return hash
212
- end
213
-
214
- # Send the NEWKEYS message, and expect the NEWKEYS message in
215
- # reply.
216
- def confirm_newkeys #:nodoc:
217
- # send own NEWKEYS message first (the wodSSHServer won't send first)
218
- response = Net::SSH::Buffer.new
219
- response.write_byte(NEWKEYS)
220
- connection.send_message(response)
221
-
222
- # wait for the server's NEWKEYS message
223
- buffer = connection.next_message
224
- raise Net::SSH::Exception, "expected NEWKEYS" unless buffer.type == NEWKEYS
225
- end
226
118
  end
227
-
228
119
  end
229
120
  end
230
121
  end
@@ -3,18 +3,12 @@ require 'net/ssh/transport/constants'
3
3
  require 'net/ssh/transport/kex/diffie_hellman_group1_sha1'
4
4
 
5
5
  module Net::SSH::Transport::Kex
6
-
7
6
  # A key-exchange service implementing the
8
7
  # "diffie-hellman-group-exchange-sha1" key-exchange algorithm.
9
8
  class DiffieHellmanGroupExchangeSHA1 < DiffieHellmanGroup1SHA1
10
9
  MINIMUM_BITS = 1024
11
10
  MAXIMUM_BITS = 8192
12
11
 
13
- KEXDH_GEX_GROUP = 31
14
- KEXDH_GEX_INIT = 32
15
- KEXDH_GEX_REPLY = 33
16
- KEXDH_GEX_REQUEST = 34
17
-
18
12
  private
19
13
 
20
14
  # Compute the number of bits needed for the given number of bytes.
@@ -40,7 +34,7 @@ module Net::SSH::Transport::Kex
40
34
 
41
35
  # request the DH key parameters for the given number of bits.
42
36
  buffer = Net::SSH::Buffer.from(:byte, KEXDH_GEX_REQUEST, :long, data[:minimum_dh_bits],
43
- :long, data[:need_bits], :long, MAXIMUM_BITS)
37
+ :long, data[:need_bits], :long, MAXIMUM_BITS)
44
38
  connection.send_message(buffer)
45
39
 
46
40
  buffer = connection.next_message
@@ -75,5 +69,4 @@ module Net::SSH::Transport::Kex
75
69
  response
76
70
  end
77
71
  end
78
-
79
72
  end
@@ -1,15 +1,11 @@
1
1
  require 'net/ssh/transport/kex/diffie_hellman_group_exchange_sha1'
2
2
 
3
3
  module Net::SSH::Transport::Kex
4
- if defined?(OpenSSL::Digest::SHA256)
5
- # A key-exchange service implementing the
6
- # "diffie-hellman-group-exchange-sha256" key-exchange algorithm.
7
- class DiffieHellmanGroupExchangeSHA256 < DiffieHellmanGroupExchangeSHA1
8
- def initialize(*args)
9
- super(*args)
10
-
11
- @digester = OpenSSL::Digest::SHA256
12
- end
4
+ # A key-exchange service implementing the
5
+ # "diffie-hellman-group-exchange-sha256" key-exchange algorithm.
6
+ class DiffieHellmanGroupExchangeSHA256 < DiffieHellmanGroupExchangeSHA1
7
+ def digester
8
+ OpenSSL::Digest::SHA256
13
9
  end
14
10
  end
15
11
  end
@@ -1,97 +1,36 @@
1
- require 'net/ssh/transport/constants'
2
- require 'net/ssh/transport/kex/diffie_hellman_group1_sha1'
1
+ require 'net/ssh/transport/kex/abstract5656'
3
2
 
4
- module Net
5
- module SSH
6
- module Transport
3
+ module Net
4
+ module SSH
5
+ module Transport
7
6
  module Kex
8
-
9
7
  # A key-exchange service implementing the "ecdh-sha2-nistp256"
10
8
  # key-exchange algorithm. (defined in RFC 5656)
11
- class EcdhSHA2NistP256 < DiffieHellmanGroup1SHA1
12
- include Loggable
13
- include Constants
14
-
15
- attr_reader :ecdh
16
-
9
+ class EcdhSHA2NistP256 < Abstract5656
17
10
  def digester
18
11
  OpenSSL::Digest::SHA256
19
12
  end
20
-
13
+
21
14
  def curve_name
22
15
  OpenSSL::PKey::EC::CurveNameAlias['nistp256']
23
16
  end
24
-
25
- def initialize(algorithms, connection, data)
26
- @algorithms = algorithms
27
- @connection = connection
28
-
29
- @digester = digester
30
- @data = data.dup
31
- @ecdh = generate_key
32
- @logger = @data.delete(:logger)
33
- end
34
-
17
+
35
18
  private
36
-
37
- def get_message_types
38
- [KEXECDH_INIT, KEXECDH_REPLY]
39
- end
40
-
41
- def build_signature_buffer(result)
42
- response = Net::SSH::Buffer.new
43
- response.write_string data[:client_version_string],
44
- data[:server_version_string],
45
- data[:client_algorithm_packet],
46
- data[:server_algorithm_packet],
47
- result[:key_blob],
48
- ecdh.public_key.to_bn.to_s(2),
49
- result[:server_ecdh_pubkey]
50
- response.write_bignum result[:shared_secret]
51
- response
52
- end
53
-
54
- def generate_key #:nodoc:
55
- OpenSSL::PKey::EC.new(curve_name).generate_key
19
+
20
+ def generate_key # :nodoc:
21
+ OpenSSL::PKey::EC.generate(curve_name)
56
22
  end
57
-
58
- def send_kexinit #:nodoc:
59
- init, reply = get_message_types
60
-
61
- # send the KEXECDH_INIT message
62
- ## byte SSH_MSG_KEX_ECDH_INIT
63
- ## string Q_C, client's ephemeral public key octet string
64
- buffer = Net::SSH::Buffer.from(:byte, init, :mstring, ecdh.public_key.to_bn.to_s(2))
65
- connection.send_message(buffer)
66
-
67
- # expect the following KEXECDH_REPLY message
68
- ## byte SSH_MSG_KEX_ECDH_REPLY
69
- ## string K_S, server's public host key
70
- ## string Q_S, server's ephemeral public key octet string
71
- ## string the signature on the exchange hash
72
- buffer = connection.next_message
73
- raise Net::SSH::Exception, "expected REPLY" unless buffer.type == reply
74
-
75
- result = Hash.new
76
- result[:key_blob] = buffer.read_string
77
- result[:server_key] = Net::SSH::Buffer.new(result[:key_blob]).read_key
78
- result[:server_ecdh_pubkey] = buffer.read_string
79
-
80
- # compute shared secret from server's public key and client's private key
23
+
24
+ # compute shared secret from server's public key and client's private key
25
+ def compute_shared_secret(server_ecdh_pubkey)
81
26
  pk = OpenSSL::PKey::EC::Point.new(OpenSSL::PKey::EC.new(curve_name).group,
82
- OpenSSL::BN.new(result[:server_ecdh_pubkey], 2))
83
- result[:shared_secret] = OpenSSL::BN.new(ecdh.dh_compute_key(pk), 2)
84
-
85
- sig_buffer = Net::SSH::Buffer.new(buffer.read_string)
86
- sig_type = sig_buffer.read_string
87
- if sig_type != algorithms.host_key_format
88
- raise Net::SSH::Exception,
89
- "host key algorithm mismatch for signature " +
90
- "'#{sig_type}' != '#{algorithms.host_key_format}'"
91
- end
92
- result[:server_sig] = sig_buffer.read_string
93
-
94
- return result
27
+ OpenSSL::BN.new(server_ecdh_pubkey, 2))
28
+ OpenSSL::BN.new(ecdh.dh_compute_key(pk), 2)
29
+ end
30
+
31
+ ## string Q_C, client's ephemeral public key octet string
32
+ def ecdh_public_key_bytes
33
+ ecdh.public_key.to_bn.to_s(2)
95
34
  end
96
35
  end
97
36
  end
@@ -1,8 +1,9 @@
1
- module Net
2
- module SSH
3
- module Transport
4
- module Kex
1
+ require 'net/ssh/transport/kex/ecdh_sha2_nistp256'
5
2
 
3
+ module Net
4
+ module SSH
5
+ module Transport
6
+ module Kex
6
7
  # A key-exchange service implementing the "ecdh-sha2-nistp256"
7
8
  # key-exchange algorithm. (defined in RFC 5656)
8
9
  class EcdhSHA2NistP384 < EcdhSHA2NistP256
@@ -1,8 +1,9 @@
1
- module Net
2
- module SSH
3
- module Transport
4
- module Kex
1
+ require 'net/ssh/transport/kex/ecdh_sha2_nistp256'
5
2
 
3
+ module Net
4
+ module SSH
5
+ module Transport
6
+ module Kex
6
7
  # A key-exchange service implementing the "ecdh-sha2-nistp521"
7
8
  # key-exchange algorithm. (defined in RFC 5656)
8
9
  class EcdhSHA2NistP521 < EcdhSHA2NistP256
@@ -1,26 +1,31 @@
1
1
  require 'net/ssh/transport/kex/diffie_hellman_group1_sha1'
2
2
  require 'net/ssh/transport/kex/diffie_hellman_group14_sha1'
3
+ require 'net/ssh/transport/kex/diffie_hellman_group14_sha256'
3
4
  require 'net/ssh/transport/kex/diffie_hellman_group_exchange_sha1'
4
5
  require 'net/ssh/transport/kex/diffie_hellman_group_exchange_sha256'
6
+ require 'net/ssh/transport/kex/ecdh_sha2_nistp256'
7
+ require 'net/ssh/transport/kex/ecdh_sha2_nistp384'
8
+ require 'net/ssh/transport/kex/ecdh_sha2_nistp521'
9
+ require 'net/ssh/transport/kex/curve25519_sha256_loader'
5
10
 
6
11
  module Net::SSH::Transport
7
12
  module Kex
8
13
  # Maps the supported key-exchange algorithms as named by the SSH protocol
9
14
  # to their corresponding implementors.
10
15
  MAP = {
16
+ 'diffie-hellman-group1-sha1' => DiffieHellmanGroup1SHA1,
17
+ 'diffie-hellman-group14-sha1' => DiffieHellmanGroup14SHA1,
18
+ 'diffie-hellman-group14-sha256' => DiffieHellmanGroup14SHA256,
11
19
  'diffie-hellman-group-exchange-sha1' => DiffieHellmanGroupExchangeSHA1,
12
- 'diffie-hellman-group1-sha1' => DiffieHellmanGroup1SHA1,
13
- 'diffie-hellman-group14-sha1' => DiffieHellmanGroup14SHA1
20
+ 'diffie-hellman-group-exchange-sha256' => DiffieHellmanGroupExchangeSHA256,
21
+ 'ecdh-sha2-nistp256' => EcdhSHA2NistP256,
22
+ 'ecdh-sha2-nistp384' => EcdhSHA2NistP384,
23
+ 'ecdh-sha2-nistp521' => EcdhSHA2NistP521
14
24
  }
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
25
 
21
- MAP['ecdh-sha2-nistp256'] = EcdhSHA2NistP256
22
- MAP['ecdh-sha2-nistp384'] = EcdhSHA2NistP384
23
- MAP['ecdh-sha2-nistp521'] = EcdhSHA2NistP521
26
+ if Net::SSH::Transport::Kex::Curve25519Sha256Loader::LOADED
27
+ MAP['curve25519-sha256'] = Curve25519Sha256
28
+ MAP['curve25519-sha256@libssh.org'] = Curve25519Sha256
24
29
  end
25
30
  end
26
31
  end
@@ -1,28 +1,27 @@
1
- module Net
2
- module SSH
1
+ module Net
2
+ module SSH
3
3
  module Transport
4
4
  module KeyExpander
5
-
6
5
  # Generate a key value in accordance with the SSH2 specification.
7
6
  # (RFC4253 7.2. "Output from Key Exchange")
8
- def self.expand_key(bytes, start, options={})
7
+ def self.expand_key(bytes, start, options = {})
9
8
  if bytes == 0
10
9
  return ""
11
10
  end
12
-
11
+
13
12
  k = start[0, bytes]
14
13
  return k if k.length >= bytes
15
-
14
+
16
15
  digester = options[:digester] or raise 'No digester supplied'
17
16
  shared = options[:shared] or raise 'No shared secret supplied'
18
17
  hash = options[:hash] or raise 'No hash supplied'
19
-
18
+
20
19
  while k.length < bytes
21
20
  step = digester.digest(shared + hash + k)
22
21
  bytes_needed = bytes - k.length
23
22
  k << step[0, bytes_needed]
24
23
  end
25
-
24
+
26
25
  return k
27
26
  end
28
27
  end