net-ssh 2.4.0 → 2.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/CHANGELOG.rdoc +21 -0
- data/Manifest +11 -0
- data/lib/net/ssh/authentication/key_manager.rb +1 -1
- data/lib/net/ssh/authentication/session.rb +12 -4
- data/lib/net/ssh/buffer.rb +12 -2
- data/lib/net/ssh/key_factory.rb +7 -2
- data/lib/net/ssh/known_hosts.rb +12 -2
- data/lib/net/ssh/ruby_compat.rb +8 -0
- data/lib/net/ssh/transport/algorithms.rb +22 -1
- data/lib/net/ssh/transport/cipher_factory.rb +32 -5
- data/lib/net/ssh/transport/constants.rb +3 -1
- data/lib/net/ssh/transport/ctr.rb +95 -0
- data/lib/net/ssh/transport/hmac.rb +8 -5
- data/lib/net/ssh/transport/hmac/ripemd160.rb +13 -0
- data/lib/net/ssh/transport/kex.rb +11 -0
- data/lib/net/ssh/transport/kex/diffie_hellman_group14_sha1.rb +44 -0
- data/lib/net/ssh/transport/kex/diffie_hellman_group1_sha1.rb +11 -3
- data/lib/net/ssh/transport/kex/ecdh_sha2_nistp256.rb +93 -0
- data/lib/net/ssh/transport/kex/ecdh_sha2_nistp384.rb +13 -0
- data/lib/net/ssh/transport/kex/ecdh_sha2_nistp521.rb +13 -0
- data/lib/net/ssh/transport/openssl.rb +111 -1
- data/lib/net/ssh/version.rb +1 -1
- data/net-ssh.gemspec +12 -4
- data/test/authentication/test_key_manager.rb +48 -1
- data/test/test_buffer.rb +92 -2
- data/test/test_key_factory.rb +42 -0
- data/test/transport/hmac/test_ripemd160.rb +34 -0
- data/test/transport/kex/test_diffie_hellman_group14_sha1.rb +13 -0
- data/test/transport/kex/test_ecdh_sha2_nistp256.rb +161 -0
- data/test/transport/kex/test_ecdh_sha2_nistp384.rb +37 -0
- data/test/transport/kex/test_ecdh_sha2_nistp521.rb +37 -0
- data/test/transport/test_algorithms.rb +41 -19
- data/test/transport/test_cipher_factory.rb +255 -27
- data/test/transport/test_packet_stream.rb +1009 -0
- metadata +13 -4
- data/lib/net/ssh/authentication/agent/java_pageant.rb +0 -85
- data/lib/net/ssh/authentication/agent/socket.rb +0 -170
@@ -0,0 +1,13 @@
|
|
1
|
+
require 'net/ssh/transport/hmac/abstract'
|
2
|
+
|
3
|
+
module Net::SSH::Transport::HMAC
|
4
|
+
|
5
|
+
# The RIPEMD-160 HMAC algorithm. This has a mac and key length of 20, and
|
6
|
+
# uses the RIPEMD-160 digest algorithm.
|
7
|
+
class RIPEMD160 < Abstract
|
8
|
+
mac_length 20
|
9
|
+
key_length 20
|
10
|
+
digest_class OpenSSL::Digest::RIPEMD160
|
11
|
+
end
|
12
|
+
|
13
|
+
end
|
@@ -1,4 +1,5 @@
|
|
1
1
|
require 'net/ssh/transport/kex/diffie_hellman_group1_sha1'
|
2
|
+
require 'net/ssh/transport/kex/diffie_hellman_group14_sha1'
|
2
3
|
require 'net/ssh/transport/kex/diffie_hellman_group_exchange_sha1'
|
3
4
|
require 'net/ssh/transport/kex/diffie_hellman_group_exchange_sha256'
|
4
5
|
|
@@ -9,9 +10,19 @@ module Net::SSH::Transport
|
|
9
10
|
MAP = {
|
10
11
|
'diffie-hellman-group-exchange-sha1' => DiffieHellmanGroupExchangeSHA1,
|
11
12
|
'diffie-hellman-group1-sha1' => DiffieHellmanGroup1SHA1,
|
13
|
+
'diffie-hellman-group14-sha1' => DiffieHellmanGroup14SHA1,
|
12
14
|
}
|
13
15
|
if defined?(DiffieHellmanGroupExchangeSHA256)
|
14
16
|
MAP['diffie-hellman-group-exchange-sha256'] = DiffieHellmanGroupExchangeSHA256
|
15
17
|
end
|
18
|
+
if defined?(OpenSSL::PKey::EC)
|
19
|
+
require 'net/ssh/transport/kex/ecdh_sha2_nistp256'
|
20
|
+
require 'net/ssh/transport/kex/ecdh_sha2_nistp384'
|
21
|
+
require 'net/ssh/transport/kex/ecdh_sha2_nistp521'
|
22
|
+
|
23
|
+
MAP['ecdh-sha2-nistp256'] = EcdhSHA2NistP256
|
24
|
+
MAP['ecdh-sha2-nistp384'] = EcdhSHA2NistP384
|
25
|
+
MAP['ecdh-sha2-nistp521'] = EcdhSHA2NistP521
|
26
|
+
end
|
16
27
|
end
|
17
28
|
end
|
@@ -0,0 +1,44 @@
|
|
1
|
+
require 'net/ssh/transport/kex/diffie_hellman_group1_sha1'
|
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
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end; end; end; end
|
@@ -40,8 +40,8 @@ module Net; module SSH; module Transport; module Kex
|
|
40
40
|
# required by this algorithm, which was acquired during earlier
|
41
41
|
# processing.
|
42
42
|
def initialize(algorithms, connection, data)
|
43
|
-
@p =
|
44
|
-
@g =
|
43
|
+
@p = get_p
|
44
|
+
@g = get_g
|
45
45
|
|
46
46
|
@digester = OpenSSL::Digest::SHA1
|
47
47
|
@algorithms = algorithms
|
@@ -76,7 +76,15 @@ module Net; module SSH; module Transport; module Kex
|
|
76
76
|
end
|
77
77
|
|
78
78
|
private
|
79
|
-
|
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
|
+
|
80
88
|
# Returns the DH key parameters for the current connection.
|
81
89
|
def get_parameters
|
82
90
|
[p, g]
|
@@ -0,0 +1,93 @@
|
|
1
|
+
require 'net/ssh/transport/constants'
|
2
|
+
require 'net/ssh/transport/kex/diffie_hellman_group1_sha1'
|
3
|
+
|
4
|
+
module Net; module SSH; module Transport; module Kex
|
5
|
+
|
6
|
+
# A key-exchange service implementing the "ecdh-sha2-nistp256"
|
7
|
+
# key-exchange algorithm. (defined in RFC 5656)
|
8
|
+
class EcdhSHA2NistP256 < DiffieHellmanGroup1SHA1
|
9
|
+
include Constants, Loggable
|
10
|
+
|
11
|
+
attr_reader :ecdh
|
12
|
+
|
13
|
+
def digester
|
14
|
+
OpenSSL::Digest::SHA256
|
15
|
+
end
|
16
|
+
|
17
|
+
def curve_name
|
18
|
+
OpenSSL::PKey::EC::CurveNameAlias['nistp256']
|
19
|
+
end
|
20
|
+
|
21
|
+
def initialize(algorithms, connection, data)
|
22
|
+
@algorithms = algorithms
|
23
|
+
@connection = connection
|
24
|
+
|
25
|
+
@digester = digester
|
26
|
+
@data = data.dup
|
27
|
+
@ecdh = generate_key
|
28
|
+
@logger = @data.delete(:logger)
|
29
|
+
end
|
30
|
+
|
31
|
+
private
|
32
|
+
|
33
|
+
def get_message_types
|
34
|
+
[KEXECDH_INIT, KEXECDH_REPLY]
|
35
|
+
end
|
36
|
+
|
37
|
+
def build_signature_buffer(result)
|
38
|
+
response = Net::SSH::Buffer.new
|
39
|
+
response.write_string data[:client_version_string],
|
40
|
+
data[:server_version_string],
|
41
|
+
data[:client_algorithm_packet],
|
42
|
+
data[:server_algorithm_packet],
|
43
|
+
result[:key_blob],
|
44
|
+
ecdh.public_key.to_bn.to_s(2),
|
45
|
+
result[:server_ecdh_pubkey]
|
46
|
+
response.write_bignum result[:shared_secret]
|
47
|
+
response
|
48
|
+
end
|
49
|
+
|
50
|
+
def generate_key #:nodoc:
|
51
|
+
OpenSSL::PKey::EC.new(curve_name).generate_key
|
52
|
+
end
|
53
|
+
|
54
|
+
def send_kexinit #:nodoc:
|
55
|
+
init, reply = get_message_types
|
56
|
+
|
57
|
+
# send the KEXECDH_INIT message
|
58
|
+
## byte SSH_MSG_KEX_ECDH_INIT
|
59
|
+
## string Q_C, client's ephemeral public key octet string
|
60
|
+
buffer = Net::SSH::Buffer.from(:byte, init, :string, ecdh.public_key.to_bn.to_s(2))
|
61
|
+
connection.send_message(buffer)
|
62
|
+
|
63
|
+
# expect the following KEXECDH_REPLY message
|
64
|
+
## byte SSH_MSG_KEX_ECDH_REPLY
|
65
|
+
## string K_S, server's public host key
|
66
|
+
## string Q_S, server's ephemeral public key octet string
|
67
|
+
## string the signature on the exchange hash
|
68
|
+
buffer = connection.next_message
|
69
|
+
raise Net::SSH::Exception, "expected REPLY" unless buffer.type == reply
|
70
|
+
|
71
|
+
result = Hash.new
|
72
|
+
result[:key_blob] = buffer.read_string
|
73
|
+
result[:server_key] = Net::SSH::Buffer.new(result[:key_blob]).read_key
|
74
|
+
result[:server_ecdh_pubkey] = buffer.read_string
|
75
|
+
|
76
|
+
# compute shared secret from server's public key and client's private key
|
77
|
+
pk = OpenSSL::PKey::EC::Point.new(OpenSSL::PKey::EC.new(curve_name).group,
|
78
|
+
OpenSSL::BN.new(result[:server_ecdh_pubkey], 2))
|
79
|
+
result[:shared_secret] = OpenSSL::BN.new(ecdh.dh_compute_key(pk), 2)
|
80
|
+
|
81
|
+
sig_buffer = Net::SSH::Buffer.new(buffer.read_string)
|
82
|
+
sig_type = sig_buffer.read_string
|
83
|
+
if sig_type != algorithms.host_key
|
84
|
+
raise Net::SSH::Exception,
|
85
|
+
"host key algorithm mismatch for signature " +
|
86
|
+
"'#{sig_type}' != '#{algorithms.host_key}'"
|
87
|
+
end
|
88
|
+
result[:server_sig] = sig_buffer.read_string
|
89
|
+
|
90
|
+
return result
|
91
|
+
end
|
92
|
+
end
|
93
|
+
end; end; end; end
|
@@ -0,0 +1,13 @@
|
|
1
|
+
module Net; module SSH; module Transport; module Kex
|
2
|
+
|
3
|
+
# A key-exchange service implementing the "ecdh-sha2-nistp256"
|
4
|
+
# key-exchange algorithm. (defined in RFC 5656)
|
5
|
+
class EcdhSHA2NistP384 < EcdhSHA2NistP256
|
6
|
+
def digester
|
7
|
+
OpenSSL::Digest::SHA384
|
8
|
+
end
|
9
|
+
def curve_name
|
10
|
+
OpenSSL::PKey::EC::CurveNameAlias['nistp384']
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end; end; end; end
|
@@ -0,0 +1,13 @@
|
|
1
|
+
module Net; module SSH; module Transport; module Kex
|
2
|
+
|
3
|
+
# A key-exchange service implementing the "ecdh-sha2-nistp521"
|
4
|
+
# key-exchange algorithm. (defined in RFC 5656)
|
5
|
+
class EcdhSHA2NistP521 < EcdhSHA2NistP256
|
6
|
+
def digester
|
7
|
+
OpenSSL::Digest::SHA512
|
8
|
+
end
|
9
|
+
def curve_name
|
10
|
+
OpenSSL::PKey::EC::CurveNameAlias['nistp521']
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end; end; end; end
|
@@ -1,3 +1,4 @@
|
|
1
|
+
# -*- coding: utf-8 -*-
|
1
2
|
require 'openssl'
|
2
3
|
|
3
4
|
module OpenSSL
|
@@ -122,6 +123,115 @@ module OpenSSL
|
|
122
123
|
end
|
123
124
|
end
|
124
125
|
|
125
|
-
|
126
|
+
if defined?(OpenSSL::PKey::EC)
|
127
|
+
# This class is originally defined in the OpenSSL module. As needed, methods
|
128
|
+
# have been added to it by the Net::SSH module for convenience in dealing
|
129
|
+
# with SSH functionality.
|
130
|
+
class EC
|
131
|
+
CurveNameAlias = {
|
132
|
+
"nistp256" => "prime256v1",
|
133
|
+
"nistp384" => "secp384r1",
|
134
|
+
"nistp521" => "secp521r1",
|
135
|
+
}
|
136
|
+
|
137
|
+
CurveNameAliasInv = {
|
138
|
+
"prime256v1" => "nistp256",
|
139
|
+
"secp384r1" => "nistp384",
|
140
|
+
"secp521r1" => "nistp521",
|
141
|
+
}
|
142
|
+
|
143
|
+
def self.read_keyblob(curve_name_in_type, buffer)
|
144
|
+
curve_name_in_key = buffer.read_string
|
145
|
+
unless curve_name_in_type == curve_name_in_key
|
146
|
+
raise Net::SSH::Exception, "curve name mismatched (`#{curve_name_in_key}' with `#{curve_name_in_type}')"
|
147
|
+
end
|
148
|
+
public_key_oct = buffer.read_string
|
149
|
+
begin
|
150
|
+
key = OpenSSL::PKey::EC.new(OpenSSL::PKey::EC::CurveNameAlias[curve_name_in_key])
|
151
|
+
group = key.group
|
152
|
+
point = OpenSSL::PKey::EC::Point.new(group, OpenSSL::BN.new(public_key_oct, 2))
|
153
|
+
key.public_key = point
|
154
|
+
|
155
|
+
return key
|
156
|
+
rescue OpenSSL::PKey::ECError => e
|
157
|
+
raise NotImplementedError, "unsupported key type `#{type}'"
|
158
|
+
end
|
159
|
+
|
160
|
+
end
|
161
|
+
|
162
|
+
# Returns the description of this key type used by the
|
163
|
+
# SSH2 protocol, like "ecdsa-sha2-nistp256"
|
164
|
+
def ssh_type
|
165
|
+
"ecdsa-sha2-#{CurveNameAliasInv[self.group.curve_name]}"
|
166
|
+
end
|
126
167
|
|
168
|
+
def digester
|
169
|
+
if self.group.curve_name =~ /^[a-z]+(\d+)\w*\z/
|
170
|
+
curve_size = $1.to_i
|
171
|
+
if curve_size <= 256
|
172
|
+
OpenSSL::Digest::SHA256.new
|
173
|
+
elsif curve_size <= 384
|
174
|
+
OpenSSL::Digest::SHA384.new
|
175
|
+
else
|
176
|
+
OpenSSL::Digest::SHA512.new
|
177
|
+
end
|
178
|
+
else
|
179
|
+
OpenSSL::Digest::SHA256.new
|
180
|
+
end
|
181
|
+
end
|
182
|
+
private :digester
|
183
|
+
|
184
|
+
# Converts the key to a blob, according to the SSH2 protocol.
|
185
|
+
def to_blob
|
186
|
+
@blob ||= Net::SSH::Buffer.from(:string, ssh_type,
|
187
|
+
:string, CurveNameAliasInv[self.group.curve_name],
|
188
|
+
:string, self.public_key.to_bn.to_s(2)).to_s
|
189
|
+
@blob
|
190
|
+
end
|
191
|
+
|
192
|
+
# Verifies the given signature matches the given data.
|
193
|
+
def ssh_do_verify(sig, data)
|
194
|
+
digest = digester.digest(data)
|
195
|
+
a1sig = nil
|
196
|
+
|
197
|
+
begin
|
198
|
+
sig_r_len = sig[0,4].unpack("H*")[0].to_i(16)
|
199
|
+
sig_l_len = sig[4+sig_r_len,4].unpack("H*")[0].to_i(16)
|
200
|
+
|
201
|
+
sig_r = sig[4,sig_r_len].unpack("H*")[0]
|
202
|
+
sig_s = sig[4+sig_r_len+4,sig_l_len].unpack("H*")[0]
|
203
|
+
|
204
|
+
a1sig = OpenSSL::ASN1::Sequence([
|
205
|
+
OpenSSL::ASN1::Integer(sig_r.to_i(16)),
|
206
|
+
OpenSSL::ASN1::Integer(sig_s.to_i(16)),
|
207
|
+
])
|
208
|
+
rescue
|
209
|
+
end
|
210
|
+
|
211
|
+
if a1sig == nil
|
212
|
+
return false
|
213
|
+
else
|
214
|
+
dsa_verify_asn1(digest, a1sig.to_der)
|
215
|
+
end
|
216
|
+
end
|
217
|
+
|
218
|
+
# Returns the signature for the given data.
|
219
|
+
def ssh_do_sign(data)
|
220
|
+
digest = digester.digest(data)
|
221
|
+
sig = dsa_sign_asn1(digest)
|
222
|
+
a1sig = OpenSSL::ASN1.decode( sig )
|
223
|
+
|
224
|
+
sig_r = a1sig.value[0].value
|
225
|
+
sig_s = a1sig.value[1].value
|
226
|
+
|
227
|
+
return Net::SSH::Buffer.from(:bignum, sig_r, :bignum, sig_s).to_s
|
228
|
+
end
|
229
|
+
end
|
230
|
+
else
|
231
|
+
class OpenSSL::PKey::ECError < RuntimeError
|
232
|
+
# for compatibility with interpreters
|
233
|
+
# without EC support (i.e. JRuby)
|
234
|
+
end
|
235
|
+
end
|
236
|
+
end
|
127
237
|
end
|
data/lib/net/ssh/version.rb
CHANGED
data/net-ssh.gemspec
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
@spec = Gem::Specification.new do |s|
|
2
2
|
s.name = "net-ssh"
|
3
3
|
s.rubyforge_project = 'net-ssh'
|
4
|
-
s.version = "2.
|
4
|
+
s.version = "2.5.0"
|
5
5
|
s.summary = "Net::SSH: a pure-Ruby implementation of the SSH2 client protocol."
|
6
6
|
s.description = s.summary + " It allows you to write programs that invoke and interact with processes on remote servers, via SSH2."
|
7
7
|
s.authors = ["Jamis Buck", "Delano Mandelbaum"]
|
@@ -31,8 +31,6 @@
|
|
31
31
|
THANKS.rdoc
|
32
32
|
lib/net/ssh.rb
|
33
33
|
lib/net/ssh/authentication/agent.rb
|
34
|
-
lib/net/ssh/authentication/agent/java_pageant.rb
|
35
|
-
lib/net/ssh/authentication/agent/socket.rb
|
36
34
|
lib/net/ssh/authentication/constants.rb
|
37
35
|
lib/net/ssh/authentication/key_manager.rb
|
38
36
|
lib/net/ssh/authentication/methods/abstract.rb
|
@@ -74,11 +72,13 @@
|
|
74
72
|
lib/net/ssh/transport/algorithms.rb
|
75
73
|
lib/net/ssh/transport/cipher_factory.rb
|
76
74
|
lib/net/ssh/transport/constants.rb
|
75
|
+
lib/net/ssh/transport/ctr.rb
|
77
76
|
lib/net/ssh/transport/hmac.rb
|
78
77
|
lib/net/ssh/transport/hmac/abstract.rb
|
79
78
|
lib/net/ssh/transport/hmac/md5.rb
|
80
79
|
lib/net/ssh/transport/hmac/md5_96.rb
|
81
80
|
lib/net/ssh/transport/hmac/none.rb
|
81
|
+
lib/net/ssh/transport/hmac/ripemd160.rb
|
82
82
|
lib/net/ssh/transport/hmac/sha1.rb
|
83
83
|
lib/net/ssh/transport/hmac/sha1_96.rb
|
84
84
|
lib/net/ssh/transport/hmac/sha2_256.rb
|
@@ -89,8 +89,12 @@
|
|
89
89
|
lib/net/ssh/transport/key_expander.rb
|
90
90
|
lib/net/ssh/transport/kex.rb
|
91
91
|
lib/net/ssh/transport/kex/diffie_hellman_group1_sha1.rb
|
92
|
+
lib/net/ssh/transport/kex/diffie_hellman_group14_sha1.rb
|
92
93
|
lib/net/ssh/transport/kex/diffie_hellman_group_exchange_sha1.rb
|
93
94
|
lib/net/ssh/transport/kex/diffie_hellman_group_exchange_sha256.rb
|
95
|
+
lib/net/ssh/transport/kex/ecdh_sha2_nistp256.rb
|
96
|
+
lib/net/ssh/transport/kex/ecdh_sha2_nistp384.rb
|
97
|
+
lib/net/ssh/transport/kex/ecdh_sha2_nistp521.rb
|
94
98
|
lib/net/ssh/transport/openssl.rb
|
95
99
|
lib/net/ssh/transport/packet_stream.rb
|
96
100
|
lib/net/ssh/transport/server_version.rb
|
@@ -129,6 +133,7 @@
|
|
129
133
|
test/transport/hmac/test_md5.rb
|
130
134
|
test/transport/hmac/test_md5_96.rb
|
131
135
|
test/transport/hmac/test_none.rb
|
136
|
+
test/transport/hmac/test_ripemd160.rb
|
132
137
|
test/transport/hmac/test_sha1.rb
|
133
138
|
test/transport/hmac/test_sha1_96.rb
|
134
139
|
test/transport/hmac/test_sha2_256.rb
|
@@ -136,8 +141,12 @@
|
|
136
141
|
test/transport/hmac/test_sha2_512.rb
|
137
142
|
test/transport/hmac/test_sha2_512_96.rb
|
138
143
|
test/transport/kex/test_diffie_hellman_group1_sha1.rb
|
144
|
+
test/transport/kex/test_diffie_hellman_group14_sha1.rb
|
139
145
|
test/transport/kex/test_diffie_hellman_group_exchange_sha1.rb
|
140
146
|
test/transport/kex/test_diffie_hellman_group_exchange_sha256.rb
|
147
|
+
test/transport/kex/test_ecdh_sha2_nistp256.rb
|
148
|
+
test/transport/kex/test_ecdh_sha2_nistp384.rb
|
149
|
+
test/transport/kex/test_ecdh_sha2_nistp521.rb
|
141
150
|
test/transport/test_algorithms.rb
|
142
151
|
test/transport/test_cipher_factory.rb
|
143
152
|
test/transport/test_hmac.rb
|
@@ -148,5 +157,4 @@
|
|
148
157
|
test/transport/test_state.rb
|
149
158
|
)
|
150
159
|
|
151
|
-
|
152
160
|
end
|
@@ -62,6 +62,28 @@ module Authentication
|
|
62
62
|
assert_equal({:from => :agent}, manager.known_identities[dsa])
|
63
63
|
end
|
64
64
|
|
65
|
+
if defined?(OpenSSL::PKey::EC)
|
66
|
+
def test_identities_with_ecdsa_should_load_from_agent
|
67
|
+
manager.stubs(:agent).returns(agent_with_ecdsa_keys)
|
68
|
+
|
69
|
+
identities = []
|
70
|
+
manager.each_identity { |identity| identities << identity }
|
71
|
+
assert_equal 5, identities.length
|
72
|
+
|
73
|
+
assert_equal rsa.to_blob, identities[0].to_blob
|
74
|
+
assert_equal dsa.to_blob, identities[1].to_blob
|
75
|
+
assert_equal ecdsa_sha2_nistp256.to_blob, identities[2].to_blob
|
76
|
+
assert_equal ecdsa_sha2_nistp384.to_blob, identities[3].to_blob
|
77
|
+
assert_equal ecdsa_sha2_nistp521.to_blob, identities[4].to_blob
|
78
|
+
|
79
|
+
assert_equal({:from => :agent}, manager.known_identities[rsa])
|
80
|
+
assert_equal({:from => :agent}, manager.known_identities[dsa])
|
81
|
+
assert_equal({:from => :agent}, manager.known_identities[ecdsa_sha2_nistp256])
|
82
|
+
assert_equal({:from => :agent}, manager.known_identities[ecdsa_sha2_nistp384])
|
83
|
+
assert_equal({:from => :agent}, manager.known_identities[ecdsa_sha2_nistp521])
|
84
|
+
end
|
85
|
+
end
|
86
|
+
|
65
87
|
def test_only_identities_with_key_files_should_load_from_agent_of_keys_only_set
|
66
88
|
manager(:keys_only => true).stubs(:agent).returns(agent)
|
67
89
|
|
@@ -139,7 +161,11 @@ module Authentication
|
|
139
161
|
Net::SSH::KeyFactory.expects(:load_private_key).with(name, nil, any_of(true, false)).returns(key).at_least_once
|
140
162
|
end
|
141
163
|
|
142
|
-
|
164
|
+
# do not override OpenSSL::PKey::EC#public_key
|
165
|
+
# (it will be called in transport/openssl.rb.)
|
166
|
+
unless defined?(OpenSSL::PKey::EC) && key.public_key.kind_of?(OpenSSL::PKey::EC::Point)
|
167
|
+
key.stubs(:public_key).returns(key)
|
168
|
+
end
|
143
169
|
end
|
144
170
|
|
145
171
|
def stub_file_public_key(name, key)
|
@@ -158,10 +184,31 @@ module Authentication
|
|
158
184
|
@dsa ||= OpenSSL::PKey::DSA.new(512)
|
159
185
|
end
|
160
186
|
|
187
|
+
if defined?(OpenSSL::PKey::EC)
|
188
|
+
def ecdsa_sha2_nistp256
|
189
|
+
@ecdsa_sha2_nistp256 ||= OpenSSL::PKey::EC.new("prime256v1").generate_key
|
190
|
+
end
|
191
|
+
|
192
|
+
def ecdsa_sha2_nistp384
|
193
|
+
@ecdsa_sha2_nistp384 ||= OpenSSL::PKey::EC.new("secp384r1").generate_key
|
194
|
+
end
|
195
|
+
|
196
|
+
def ecdsa_sha2_nistp521
|
197
|
+
@ecdsa_sha2_nistp521 ||= OpenSSL::PKey::EC.new("secp521r1").generate_key
|
198
|
+
end
|
199
|
+
end
|
200
|
+
|
161
201
|
def agent
|
162
202
|
@agent ||= stub("agent", :identities => [rsa, dsa])
|
163
203
|
end
|
164
204
|
|
205
|
+
def agent_with_ecdsa_keys
|
206
|
+
@agent ||= stub("agent", :identities => [rsa, dsa,
|
207
|
+
ecdsa_sha2_nistp256,
|
208
|
+
ecdsa_sha2_nistp384,
|
209
|
+
ecdsa_sha2_nistp521])
|
210
|
+
end
|
211
|
+
|
165
212
|
def manager(options = {})
|
166
213
|
@manager ||= Net::SSH::Authentication::KeyManager.new(nil, options)
|
167
214
|
end
|