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.
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