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.
Files changed (37) hide show
  1. data/CHANGELOG.rdoc +21 -0
  2. data/Manifest +11 -0
  3. data/lib/net/ssh/authentication/key_manager.rb +1 -1
  4. data/lib/net/ssh/authentication/session.rb +12 -4
  5. data/lib/net/ssh/buffer.rb +12 -2
  6. data/lib/net/ssh/key_factory.rb +7 -2
  7. data/lib/net/ssh/known_hosts.rb +12 -2
  8. data/lib/net/ssh/ruby_compat.rb +8 -0
  9. data/lib/net/ssh/transport/algorithms.rb +22 -1
  10. data/lib/net/ssh/transport/cipher_factory.rb +32 -5
  11. data/lib/net/ssh/transport/constants.rb +3 -1
  12. data/lib/net/ssh/transport/ctr.rb +95 -0
  13. data/lib/net/ssh/transport/hmac.rb +8 -5
  14. data/lib/net/ssh/transport/hmac/ripemd160.rb +13 -0
  15. data/lib/net/ssh/transport/kex.rb +11 -0
  16. data/lib/net/ssh/transport/kex/diffie_hellman_group14_sha1.rb +44 -0
  17. data/lib/net/ssh/transport/kex/diffie_hellman_group1_sha1.rb +11 -3
  18. data/lib/net/ssh/transport/kex/ecdh_sha2_nistp256.rb +93 -0
  19. data/lib/net/ssh/transport/kex/ecdh_sha2_nistp384.rb +13 -0
  20. data/lib/net/ssh/transport/kex/ecdh_sha2_nistp521.rb +13 -0
  21. data/lib/net/ssh/transport/openssl.rb +111 -1
  22. data/lib/net/ssh/version.rb +1 -1
  23. data/net-ssh.gemspec +12 -4
  24. data/test/authentication/test_key_manager.rb +48 -1
  25. data/test/test_buffer.rb +92 -2
  26. data/test/test_key_factory.rb +42 -0
  27. data/test/transport/hmac/test_ripemd160.rb +34 -0
  28. data/test/transport/kex/test_diffie_hellman_group14_sha1.rb +13 -0
  29. data/test/transport/kex/test_ecdh_sha2_nistp256.rb +161 -0
  30. data/test/transport/kex/test_ecdh_sha2_nistp384.rb +37 -0
  31. data/test/transport/kex/test_ecdh_sha2_nistp521.rb +37 -0
  32. data/test/transport/test_algorithms.rb +41 -19
  33. data/test/transport/test_cipher_factory.rb +255 -27
  34. data/test/transport/test_packet_stream.rb +1009 -0
  35. metadata +13 -4
  36. data/lib/net/ssh/authentication/agent/java_pageant.rb +0 -85
  37. data/lib/net/ssh/authentication/agent/socket.rb +0 -170
@@ -290,7 +290,7 @@ class TestBuffer < Test::Unit::TestCase
290
290
  key.pub_key = 0xeeccaa8866442200
291
291
 
292
292
  buffer.write_key(key)
293
- assert_equal "start\0\0\0\7ssh-dss\0\0\0\011\0\xff\xee\xdd\xcc\xbb\xaa\x99\x88\0\0\0\010\x77\x66\x55\x44\x33\x22\x11\x00\0\0\0\011\0\xff\xdd\xbb\x99\x77\x55\x33\x11\0\0\0\011\0\xee\xcc\xaa\x88\x66\x44\x22\x00", buffer.to_s
293
+ assert_equal "start\0\0\0\7ssh-dss\0\0\0\011\0\xff\xee\xdd\xcc\xbb\xaa\x99\x88\0\0\0\010\x77\x66\x55\x44\x33\x22\x11\x00\0\0\0\011\0\xff\xdd\xbb\x99\x77\x55\x33\x11\0\0\0\011\0\xee\xcc\xaa\x88\x66\x44\x22\x00", buffer.to_s
294
294
  end
295
295
 
296
296
  def test_write_rsa_key_should_write_argument_to_end_of_buffer
@@ -304,6 +304,67 @@ class TestBuffer < Test::Unit::TestCase
304
304
  assert_equal "start\0\0\0\7ssh-rsa\0\0\0\011\0\xff\xee\xdd\xcc\xbb\xaa\x99\x88\0\0\0\010\x77\x66\x55\x44\x33\x22\x11\x00", buffer.to_s
305
305
  end
306
306
 
307
+ if defined?(OpenSSL::PKey::EC)
308
+ def test_read_key_blob_should_read_ecdsa_sha2_nistp256_keys
309
+ random_ecdsa_sha2_nistp256 { |buffer|
310
+ buffer.read_keyblob("ecdsa-sha2-nistp256")
311
+ }
312
+ end
313
+ def test_read_key_blob_should_read_ecdsa_sha2_nistp384_keys
314
+ random_ecdsa_sha2_nistp384 { |buffer|
315
+ buffer.read_keyblob("ecdsa-sha2-nistp384")
316
+ }
317
+ end
318
+ def test_read_key_blob_should_read_ecdsa_sha2_nistp521_keys
319
+ random_ecdsa_sha2_nistp521 { |buffer|
320
+ buffer.read_keyblob("ecdsa-sha2-nistp521")
321
+ }
322
+ end
323
+
324
+ def test_read_key_should_read_ecdsa_sha2_nistp256_key_type_and_keyblob
325
+ random_ecdsa_sha2_nistp256 do |buffer|
326
+ b2 = Net::SSH::Buffer.from(:string, "ecdsa-sha2-nistp256", :raw, buffer)
327
+ b2.read_key
328
+ end
329
+ end
330
+ def test_read_key_should_read_ecdsa_sha2_nistp384_key_type_and_keyblob
331
+ random_ecdsa_sha2_nistp384 do |buffer|
332
+ b2 = Net::SSH::Buffer.from(:string, "ecdsa-sha2-nistp384", :raw, buffer)
333
+ b2.read_key
334
+ end
335
+ end
336
+ def test_read_key_should_read_ecdsa_sha2_nistp521_key_type_and_keyblob
337
+ random_ecdsa_sha2_nistp521 do |buffer|
338
+ b2 = Net::SSH::Buffer.from(:string, "ecdsa-sha2-nistp521", :raw, buffer)
339
+ b2.read_key
340
+ end
341
+ end
342
+
343
+ def test_write_ecdsa_sha2_nistp256_key_should_write_argument_to_end_of_buffer
344
+ buffer = new("start")
345
+ key = OpenSSL::PKey::EC.new("-----BEGIN EC PRIVATE KEY-----\nMHcCAQEEIISGj5vAJCWt2KPI8NwaWVDSNLl2vbRxDIOkY+n6O0VVoAoGCCqGSM49\nAwEHoUQDQgAEnKbs0yEogTKT4QRu8T9nb2svl2mEWXb6g224oCpD2o6TYNXNw54H\nmWkdCv+kFCqSlfSi5fqFhrXdfEY6zSzQYQ==\n-----END EC PRIVATE KEY-----\n")
346
+
347
+ buffer.write_key(key)
348
+ assert_equal "start\000\000\000\023ecdsa-sha2-nistp256\000\000\000\bnistp256\000\000\000A\004\234\246\354\323!(\2012\223\341\004n\361?gok/\227i\204Yv\372\203m\270\240*C\332\216\223`\325\315\303\236\a\231i\035\n\377\244\024*\222\225\364\242\345\372\205\206\265\335|F:\315,\320a", buffer.to_s
349
+ end
350
+
351
+ def test_write_ecdsa_sha2_nistp384_key_should_write_argument_to_end_of_buffer
352
+ buffer = new("start")
353
+ key = OpenSSL::PKey::EC.new("-----BEGIN EC PRIVATE KEY-----\nMIGkAgEBBDBAfxJpzhsR7O+wMol6BcDgualR8rJBvYegUDYbBUrDnPzDx2/gD1lZ\nnwG1FuD2s9igBwYFK4EEACKhZANiAATsfiU4Kxyvvj1DdvFYsdDnZIT7loRlan9I\n8geCWPPl6x7NFRP+awrnTaarMgieGqxG8IQaIA0SsDOICfbDBkuatRi0S1Et/in4\nZwVEZvO81Ro5YSrjuUDAsytnI6OXS28=\n-----END EC PRIVATE KEY-----\n")
354
+
355
+ buffer.write_key(key)
356
+ assert_equal "start\000\000\000\023ecdsa-sha2-nistp384\000\000\000\bnistp384\000\000\000a\004\354~%8+\034\257\276=Cv\361X\261\320\347d\204\373\226\204ej\177H\362\a\202X\363\345\353\036\315\025\023\376k\n\347M\246\2532\b\236\032\254F\360\204\032 \r\022\2603\210\t\366\303\006K\232\265\030\264KQ-\376)\370g\005Df\363\274\325\0329a*\343\271@\300\263+g#\243\227Ko", buffer.to_s
357
+ end
358
+
359
+ def test_write_ecdsa_sha2_nistp521_key_should_write_argument_to_end_of_buffer
360
+ buffer = new("start")
361
+ key = OpenSSL::PKey::EC.new("-----BEGIN EC PRIVATE KEY-----\nMIHbAgEBBEGhnQF/SFo4Vym88HnCfc6BR8WwYqDh9wNTPeqzR8auxIpp0GKQlCG2\nuHzyteJX5/YalV8empYhEzNmNLNn8x7j0aAHBgUrgQQAI6GBiQOBhgAEAYygOgV9\nVI8UyLQ3BDlv+rb3es+ufrIcj++cqcc9QcmRn237NiWRr/1NKy2AKijsEdACtZXo\nxPC0x9Vs9ieC2oR+ANOBubcxPl2giDnBYm8ywAmmlXsP5ByAM17k97CzW5O+Z/uO\nbxGUzzhoXTNcjqpAckhRVKdnh6FL/rKelT0tBYi+\n-----END EC PRIVATE KEY-----\n")
362
+
363
+ buffer.write_key(key)
364
+ assert_equal "start\000\000\000\023ecdsa-sha2-nistp521\000\000\000\bnistp521\000\000\000\205\004\001\214\240:\005}T\217\024\310\2647\0049o\372\266\367z\317\256~\262\034\217\357\234\251\307=A\311\221\237m\3736%\221\257\375M+-\200*(\354\021\320\002\265\225\350\304\360\264\307\325l\366'\202\332\204~\000\323\201\271\2671>]\240\2109\301bo2\300\t\246\225{\017\344\034\2003^\344\367\260\263[\223\276g\373\216o\021\224\3178h]3\\\216\252@rHQT\247g\207\241K\376\262\236\225=-\005\210\276", buffer.to_s
365
+ end
366
+ end
367
+
307
368
  private
308
369
 
309
370
  def random_rsa
@@ -330,7 +391,36 @@ class TestBuffer < Test::Unit::TestCase
330
391
  assert_equal n4, key.pub_key
331
392
  end
332
393
 
394
+ if defined?(OpenSSL::PKey::EC)
395
+ def random_ecdsa_sha2_nistp256
396
+ k = OpenSSL::PKey::EC.new("prime256v1").generate_key
397
+ buffer = Net::SSH::Buffer.from(:string, "nistp256",
398
+ :string, k.public_key.to_bn.to_s(2))
399
+ key = yield(buffer)
400
+ assert_equal "ecdsa-sha2-nistp256", key.ssh_type
401
+ assert_equal k.public_key, key.public_key
402
+ end
403
+
404
+ def random_ecdsa_sha2_nistp384
405
+ k = OpenSSL::PKey::EC.new("secp384r1").generate_key
406
+ buffer = Net::SSH::Buffer.from(:string, "nistp384",
407
+ :string, k.public_key.to_bn.to_s(2))
408
+ key = yield(buffer)
409
+ assert_equal "ecdsa-sha2-nistp384", key.ssh_type
410
+ assert_equal k.public_key, key.public_key
411
+ end
412
+
413
+ def random_ecdsa_sha2_nistp521
414
+ k = OpenSSL::PKey::EC.new("secp521r1").generate_key
415
+ buffer = Net::SSH::Buffer.from(:string, "nistp521",
416
+ :string, k.public_key.to_bn.to_s(2))
417
+ key = yield(buffer)
418
+ assert_equal "ecdsa-sha2-nistp521", key.ssh_type
419
+ assert_equal k.public_key, key.public_key
420
+ end
421
+ end
422
+
333
423
  def new(*args)
334
424
  Net::SSH::Buffer.new(*args)
335
425
  end
336
- end
426
+ end
@@ -55,6 +55,34 @@ class TestKeyFactory < Test::Unit::TestCase
55
55
  assert_equal rsa_key.to_blob, Net::SSH::KeyFactory.load_public_key(@key_file).to_blob
56
56
  end
57
57
 
58
+ if defined?(OpenSSL::PKey::EC)
59
+ def test_load_unencrypted_private_ecdsa_sha2_nistp256_key_should_return_key
60
+ File.expects(:read).with("/key-file").returns(ecdsa_sha2_nistp256_key.to_pem)
61
+ assert_equal ecdsa_sha2_nistp256_key.to_der, Net::SSH::KeyFactory.load_private_key("/key-file").to_der
62
+ end
63
+ def test_load_unencrypted_private_ecdsa_sha2_nistp384_key_should_return_key
64
+ File.expects(:read).with("/key-file").returns(ecdsa_sha2_nistp384_key.to_pem)
65
+ assert_equal ecdsa_sha2_nistp384_key.to_der, Net::SSH::KeyFactory.load_private_key("/key-file").to_der
66
+ end
67
+ def test_load_unencrypted_private_ecdsa_sha2_nistp521_key_should_return_key
68
+ File.expects(:read).with("/key-file").returns(ecdsa_sha2_nistp521_key.to_pem)
69
+ assert_equal ecdsa_sha2_nistp521_key.to_der, Net::SSH::KeyFactory.load_private_key("/key-file").to_der
70
+ end
71
+
72
+ def test_load_public_ecdsa_sha2_nistp256_key_should_return_key
73
+ File.expects(:read).with("/key-file").returns(public(ecdsa_sha2_nistp256_key))
74
+ assert_equal ecdsa_sha2_nistp256_key.to_blob, Net::SSH::KeyFactory.load_public_key("/key-file").to_blob
75
+ end
76
+ def test_load_public_ecdsa_sha2_nistp384_key_should_return_key
77
+ File.expects(:read).with("/key-file").returns(public(ecdsa_sha2_nistp384_key))
78
+ assert_equal ecdsa_sha2_nistp384_key.to_blob, Net::SSH::KeyFactory.load_public_key("/key-file").to_blob
79
+ end
80
+ def test_load_public_ecdsa_sha2_nistp521_key_should_return_key
81
+ File.expects(:read).with("/key-file").returns(public(ecdsa_sha2_nistp521_key))
82
+ assert_equal ecdsa_sha2_nistp521_key.to_blob, Net::SSH::KeyFactory.load_public_key("/key-file").to_blob
83
+ end
84
+ end
85
+
58
86
  private
59
87
 
60
88
  def rsa_key
@@ -67,6 +95,20 @@ class TestKeyFactory < Test::Unit::TestCase
67
95
  @dsa_key ||= OpenSSL::PKey::DSA.new("0\201\367\002\001\000\002A\000\203\316/\037u\272&J\265\003l3\315d\324h\372{\t8\252#\331_\026\006\035\270\266\255\343\353Z\302\276\335\336\306\220\375\202L\244\244J\206>\346\b\315\211\302L\246x\247u\a\376\366\345\302\016#\002\025\000\244\274\302\221Og\275/\302+\356\346\360\024\373wI\2573\361\002@\027\215\270r*\f\213\350C\245\021:\350 \006\\\376\345\022`\210b\262\3643\023XLKS\320\370\002\276\347A\nU\204\276\324\256`=\026\240\330\306J\316V\213\024\e\030\215\355\006\037q\337\356ln\002@\017\257\034\f\260\333'S\271#\237\230E\321\312\027\021\226\331\251Vj\220\305\316\036\v\266+\000\230\270\177B\003?t\a\305]e\344\261\334\023\253\323\251\223M\2175)a(\004\"lI8\312\303\307\a\002\024_\aznW\345\343\203V\326\246ua\203\376\201o\350\302\002")
68
96
  end
69
97
 
98
+ if defined?(OpenSSL::PKey::EC)
99
+ def ecdsa_sha2_nistp256_key
100
+ @ecdsa_sha2_nistp256_key ||= OpenSSL::PKey::EC.new("-----BEGIN EC PRIVATE KEY-----\nMHcCAQEEINv6pPVLlkqvT1v5MJlWgaSWGwqupISG4U79bUXQDNCaoAoGCCqGSM49\nAwEHoUQDQgAElqubvi/GkSme+bwtncU1NiE0dWQ0EO07VufUQg8lUJ5+Fi6f96qa\n95T1zwOMQhY1h8PP9rQIZr4S48vN/ZnQLw==\n-----END EC PRIVATE KEY-----\n")
101
+ end
102
+
103
+ def ecdsa_sha2_nistp384_key
104
+ @ecdsa_sha2_nistp384_key ||= OpenSSL::PKey::EC.new("-----BEGIN EC PRIVATE KEY-----\nMIGkAgEBBDBxwkmydCn4mP4KMhlMpeBvIroQolWKVNoRPXpG7brFgK+Yiikqw8wd\nIZW5OlL4y3mgBwYFK4EEACKhZANiAARkoIR1oABi+aQJbKcmvzeYSKURQOyXM0HU\nR4T68v4hd/lJE4fFQRczj3wAaECe9u3CWI/oDlow4Vr0vab82ZGjIoblxblKQWYl\nyzENgzl226waGg1bLBo8Auilyf1B5yI=\n-----END EC PRIVATE KEY-----\n")
105
+ end
106
+
107
+ def ecdsa_sha2_nistp521_key
108
+ @ecdsa_sha2_nistp521_key ||= OpenSSL::PKey::EC.new("-----BEGIN EC PRIVATE KEY-----\nMIHbAgEBBEHQ2i7kjEGQHQB4pUQW9a2eCLWR2S5Go8U3CDyfbRCrYEp/pTSgI8uu\nMXyR3bf3SjqFQgZ6MZk5lkyrissJuwmvZKAHBgUrgQQAI6GBiQOBhgAEAN14FACK\nbs/KTqw4rxijeozGTVJTh1hNzBl2XaIhM4Fv8o3fE/pvogymyFu53GCng6gC4dmx\n/hycF41iIM29xVKPAeBnRNl6MdFBjuthOmE8eCRezgk1Bak8aBDUrzNT8OQssscw\npvQK4nc6ga/wTDaQGy5kV8tCOHNs2wKH+p2LpWTJ\n-----END EC PRIVATE KEY-----\n")
109
+ end
110
+ end
111
+
70
112
  def encrypted(key, password)
71
113
  key.export(OpenSSL::Cipher::Cipher.new("des-ede3-cbc"), password)
72
114
  end
@@ -0,0 +1,34 @@
1
+ require 'common'
2
+ require 'net/ssh/transport/hmac/ripemd160'
3
+
4
+ module Transport; module HMAC
5
+
6
+ class TestRipemd160 < Test::Unit::TestCase
7
+ def test_expected_digest_class
8
+ assert_equal OpenSSL::Digest::RIPEMD160, subject.digest_class
9
+ assert_equal OpenSSL::Digest::RIPEMD160, subject.new.digest_class
10
+ end
11
+
12
+ def test_expected_key_length
13
+ assert_equal 20, subject.key_length
14
+ assert_equal 20, subject.new.key_length
15
+ end
16
+
17
+ def test_expected_mac_length
18
+ assert_equal 20, subject.mac_length
19
+ assert_equal 20, subject.new.mac_length
20
+ end
21
+
22
+ def test_expected_digest
23
+ hmac = subject.new("1234567890123456")
24
+ assert_equal "\xE4\x10\t\xB3\xD8,\x14\xA0k\x10\xB5\x0F?\x0E\x96q\x02\x16;E", hmac.digest("hello world")
25
+ end
26
+
27
+ private
28
+
29
+ def subject
30
+ Net::SSH::Transport::HMAC::RIPEMD160
31
+ end
32
+ end
33
+
34
+ end; end
@@ -0,0 +1,13 @@
1
+ require 'common'
2
+ require 'net/ssh/transport/kex/diffie_hellman_group14_sha1'
3
+ require 'transport/kex/test_diffie_hellman_group1_sha1'
4
+ require 'ostruct'
5
+
6
+ module Transport; module Kex
7
+
8
+ class TestDiffieHellmanGroup14SHA1 < TestDiffieHellmanGroup1SHA1
9
+ def subject
10
+ Net::SSH::Transport::Kex::DiffieHellmanGroup14SHA1
11
+ end
12
+ end
13
+ end; end
@@ -0,0 +1,161 @@
1
+ require 'openssl'
2
+
3
+ unless defined?(OpenSSL::PKey::EC)
4
+ puts "Skipping tests for ecdh-sha2-nistp256 key exchange"
5
+ else
6
+ require 'common'
7
+ require 'transport/kex/test_diffie_hellman_group1_sha1'
8
+ require 'net/ssh/transport/kex/ecdh_sha2_nistp256'
9
+ require 'ostruct'
10
+
11
+ module Transport; module Kex
12
+
13
+ class TestEcdhSHA2NistP256 < Test::Unit::TestCase
14
+ include Net::SSH::Transport::Constants
15
+
16
+ def setup
17
+ @ecdh = @algorithms = @connection = @server_key =
18
+ @packet_data = @shared_secret = nil
19
+ end
20
+
21
+ def test_exchange_keys_should_return_expected_results_when_successful
22
+ result = exchange!
23
+ assert_equal session_id, result[:session_id]
24
+ assert_equal server_host_key.to_blob, result[:server_key].to_blob
25
+ assert_equal shared_secret, result[:shared_secret]
26
+ assert_equal digester, result[:hashing_algorithm]
27
+ end
28
+
29
+ def test_exchange_keys_with_unverifiable_host_should_raise_exception
30
+ connection.verifier { false }
31
+ assert_raises(Net::SSH::Exception) { exchange! }
32
+ end
33
+
34
+ def test_exchange_keys_with_signature_key_type_mismatch_should_raise_exception
35
+ assert_raises(Net::SSH::Exception) { exchange! :key_type => "ssh-dss" }
36
+ end
37
+
38
+ def test_exchange_keys_with_host_key_type_mismatch_should_raise_exception
39
+ algorithms :host_key => "ssh-dss"
40
+ assert_raises(Net::SSH::Exception) { exchange! :key_type => "ssh-dss" }
41
+ end
42
+
43
+ def test_exchange_keys_when_server_signature_could_not_be_verified_should_raise_exception
44
+ @signature = "1234567890"
45
+ assert_raises(Net::SSH::Exception) { exchange! }
46
+ end
47
+
48
+ def test_exchange_keys_should_pass_expected_parameters_to_host_key_verifier
49
+ verified = false
50
+ connection.verifier do |data|
51
+ verified = true
52
+ assert_equal server_host_key.to_blob, data[:key].to_blob
53
+
54
+ blob = b(:key, data[:key]).to_s
55
+ fingerprint = OpenSSL::Digest::MD5.hexdigest(blob).scan(/../).join(":")
56
+
57
+ assert_equal blob, data[:key_blob]
58
+ assert_equal fingerprint, data[:fingerprint]
59
+ assert_equal connection, data[:session]
60
+
61
+ true
62
+ end
63
+
64
+ assert_nothing_raised { exchange! }
65
+ assert verified
66
+ end
67
+
68
+ private
69
+
70
+ def digester
71
+ OpenSSL::Digest::SHA256
72
+ end
73
+
74
+ def subject
75
+ Net::SSH::Transport::Kex::EcdhSHA2NistP256
76
+ end
77
+
78
+ def ecparam
79
+ "prime256v1"
80
+ end
81
+
82
+ def key_type
83
+ "ecdsa-sha2-nistp256"
84
+ end
85
+
86
+ def exchange!(options={})
87
+ connection.expect do |t, buffer|
88
+ assert_equal KEXECDH_INIT, buffer.type
89
+ assert_equal ecdh.ecdh.public_key.to_bn.to_s(2), buffer.read_string
90
+ t.return(KEXECDH_REPLY,
91
+ :string, b(:key, server_host_key),
92
+ :string, server_ecdh_pubkey.to_bn.to_s(2),
93
+ :string, b(:string, options[:key_type] || key_type,
94
+ :string, signature))
95
+ connection.expect do |t2, buffer2|
96
+ assert_equal NEWKEYS, buffer2.type
97
+ t2.return(NEWKEYS)
98
+ end
99
+ end
100
+ ecdh.exchange_keys
101
+ end
102
+
103
+ def ecdh
104
+ @ecdh ||= subject.new(algorithms, connection, packet_data)
105
+ end
106
+
107
+ def algorithms(options={})
108
+ @algorithms ||= OpenStruct.new(:host_key => options[:server_host_key] || "ecdsa-sha2-nistp256")
109
+ end
110
+
111
+ def connection
112
+ @connection ||= MockTransport.new
113
+ end
114
+
115
+ def server_key
116
+ @server_key ||= OpenSSL::PKey::EC.new(ecparam).generate_key
117
+ end
118
+
119
+ def server_host_key
120
+ @server_host_key ||= OpenSSL::PKey::EC.new("prime256v1").generate_key
121
+ end
122
+
123
+ def packet_data
124
+ @packet_data ||= { :client_version_string => "client version string",
125
+ :server_version_string => "server version string",
126
+ :server_algorithm_packet => "server algorithm packet",
127
+ :client_algorithm_packet => "client algorithm packet" }
128
+ end
129
+
130
+ def server_ecdh_pubkey
131
+ @server_ecdh_pubkey ||= server_key.public_key
132
+ end
133
+
134
+ def shared_secret
135
+ @shared_secret ||= OpenSSL::BN.new(ecdh.ecdh.dh_compute_key(server_ecdh_pubkey), 2)
136
+ end
137
+
138
+ def session_id
139
+ @session_id ||= begin
140
+ buffer = Net::SSH::Buffer.from(:string, packet_data[:client_version_string],
141
+ :string, packet_data[:server_version_string],
142
+ :string, packet_data[:client_algorithm_packet],
143
+ :string, packet_data[:server_algorithm_packet],
144
+ :string, Net::SSH::Buffer.from(:key, server_host_key),
145
+ :string, ecdh.ecdh.public_key.to_bn.to_s(2),
146
+ :string, server_ecdh_pubkey.to_bn.to_s(2),
147
+ :bignum, shared_secret)
148
+ digester.digest(buffer.to_s)
149
+ end
150
+ end
151
+
152
+ def signature
153
+ @signature ||= server_host_key.ssh_do_sign(session_id)
154
+ end
155
+
156
+ def b(*args)
157
+ Net::SSH::Buffer.from(*args)
158
+ end
159
+ end
160
+ end; end;
161
+ end
@@ -0,0 +1,37 @@
1
+ require 'openssl'
2
+
3
+ unless defined?(OpenSSL::PKey::EC)
4
+ puts "Skipping tests for ecdh-sha2-nistp384 key exchange"
5
+ else
6
+ module Transport; module Kex
7
+ class TestEcdhSHA2NistP384 < TestEcdhSHA2NistP256
8
+
9
+ def setup
10
+ @ecdh = @algorithms = @connection = @server_key =
11
+ @packet_data = @shared_secret = nil
12
+ end
13
+
14
+ def test_exchange_keys_should_return_expected_results_when_successful
15
+ result = exchange!
16
+ assert_equal session_id, result[:session_id]
17
+ assert_equal server_host_key.to_blob, result[:server_key].to_blob
18
+ assert_equal shared_secret, result[:shared_secret]
19
+ assert_equal digester, result[:hashing_algorithm]
20
+ end
21
+
22
+ private
23
+
24
+ def digester
25
+ OpenSSL::Digest::SHA384
26
+ end
27
+
28
+ def subject
29
+ Net::SSH::Transport::Kex::EcdhSHA2NistP384
30
+ end
31
+
32
+ def ecparam
33
+ "secp384r1"
34
+ end
35
+ end
36
+ end; end
37
+ end
@@ -0,0 +1,37 @@
1
+ require 'openssl'
2
+
3
+ unless defined?(OpenSSL::PKey::EC)
4
+ puts "Skipping tests for ecdh-sha2-nistp521 key exchange"
5
+ else
6
+ module Transport; module Kex
7
+ class TestEcdhSHA2NistP521 < TestEcdhSHA2NistP256
8
+
9
+ def setup
10
+ @ecdh = @algorithms = @connection = @server_key =
11
+ @packet_data = @shared_secret = nil
12
+ end
13
+
14
+ def test_exchange_keys_should_return_expected_results_when_successful
15
+ result = exchange!
16
+ assert_equal session_id, result[:session_id]
17
+ assert_equal server_host_key.to_blob, result[:server_key].to_blob
18
+ assert_equal shared_secret, result[:shared_secret]
19
+ assert_equal digester, result[:hashing_algorithm]
20
+ end
21
+
22
+ private
23
+
24
+ def digester
25
+ OpenSSL::Digest::SHA512
26
+ end
27
+
28
+ def subject
29
+ Net::SSH::Transport::Kex::EcdhSHA2NistP521
30
+ end
31
+
32
+ def ecparam
33
+ "secp521r1"
34
+ end
35
+ end
36
+ end; end
37
+ end