net-ssh 2.4.0 → 2.5.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|