net-ssh 2.2.2 → 2.3.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.
@@ -1,4 +1,8 @@
1
1
 
2
+ === 2.3.0 / 11 Jan 2012
3
+
4
+ * Support for hmac-sha2 and diffie-hellman-group-exchange-sha256 [Ryosuke Yamazaki]
5
+
2
6
  === 2.2.2 / 04 Jan 2012
3
7
 
4
8
  * Fixed: Connection hangs on ServerVersion.new(socket, logger) [muffl0n]
data/Manifest CHANGED
@@ -54,10 +54,16 @@ lib/net/ssh/transport/hmac/md5_96.rb
54
54
  lib/net/ssh/transport/hmac/none.rb
55
55
  lib/net/ssh/transport/hmac/sha1.rb
56
56
  lib/net/ssh/transport/hmac/sha1_96.rb
57
+ lib/net/ssh/transport/hmac/sha2_256.rb
58
+ lib/net/ssh/transport/hmac/sha2_256_96.rb
59
+ lib/net/ssh/transport/hmac/sha2_512.rb
60
+ lib/net/ssh/transport/hmac/sha2_512_96.rb
57
61
  lib/net/ssh/transport/identity_cipher.rb
62
+ lib/net/ssh/transport/key_expander.rb
58
63
  lib/net/ssh/transport/kex.rb
59
64
  lib/net/ssh/transport/kex/diffie_hellman_group1_sha1.rb
60
65
  lib/net/ssh/transport/kex/diffie_hellman_group_exchange_sha1.rb
66
+ lib/net/ssh/transport/kex/diffie_hellman_group_exchange_sha256.rb
61
67
  lib/net/ssh/transport/openssl.rb
62
68
  lib/net/ssh/transport/packet_stream.rb
63
69
  lib/net/ssh/transport/server_version.rb
@@ -98,8 +104,13 @@ test/transport/hmac/test_md5_96.rb
98
104
  test/transport/hmac/test_none.rb
99
105
  test/transport/hmac/test_sha1.rb
100
106
  test/transport/hmac/test_sha1_96.rb
107
+ test/transport/hmac/test_sha2_256.rb
108
+ test/transport/hmac/test_sha2_256_96.rb
109
+ test/transport/hmac/test_sha2_512.rb
110
+ test/transport/hmac/test_sha2_512_96.rb
101
111
  test/transport/kex/test_diffie_hellman_group1_sha1.rb
102
112
  test/transport/kex/test_diffie_hellman_group_exchange_sha1.rb
113
+ test/transport/kex/test_diffie_hellman_group_exchange_sha256.rb
103
114
  test/transport/test_algorithms.rb
104
115
  test/transport/test_cipher_factory.rb
105
116
  test/transport/test_hmac.rb
@@ -24,11 +24,14 @@ module Net; module SSH; module Transport
24
24
  ALGORITHMS = {
25
25
  :host_key => %w(ssh-rsa ssh-dss),
26
26
  :kex => %w(diffie-hellman-group-exchange-sha1
27
- diffie-hellman-group1-sha1),
27
+ diffie-hellman-group1-sha1
28
+ diffie-hellman-group-exchange-sha256),
28
29
  :encryption => %w(aes128-cbc 3des-cbc blowfish-cbc cast128-cbc
29
30
  aes192-cbc aes256-cbc rijndael-cbc@lysator.liu.se
30
31
  idea-cbc none arcfour128 arcfour256),
31
- :hmac => %w(hmac-sha1 hmac-md5 hmac-sha1-96 hmac-md5-96 none),
32
+ :hmac => %w(hmac-sha1 hmac-md5 hmac-sha1-96 hmac-md5-96
33
+ hmac-sha2-256 hmac-sha2-512 hmac-sha2-256-96
34
+ hmac-sha2-512-96 none),
32
35
  :compression => %w(none zlib@openssh.com zlib),
33
36
  :language => %w()
34
37
  }
@@ -345,14 +348,13 @@ module Net; module SSH; module Transport
345
348
  mac_key_client = key["E"]
346
349
  mac_key_server = key["F"]
347
350
 
348
- parameters = { :iv => iv_client, :key => key_client, :shared => secret,
349
- :hash => hash, :digester => digester }
351
+ parameters = { :shared => secret, :hash => hash, :digester => digester }
350
352
 
351
- cipher_client = CipherFactory.get(encryption_client, parameters.merge(:encrypt => true))
353
+ cipher_client = CipherFactory.get(encryption_client, parameters.merge(:iv => iv_client, :key => key_client, :encrypt => true))
352
354
  cipher_server = CipherFactory.get(encryption_server, parameters.merge(:iv => iv_server, :key => key_server, :decrypt => true))
353
355
 
354
- mac_client = HMAC.get(hmac_client, mac_key_client)
355
- mac_server = HMAC.get(hmac_server, mac_key_server)
356
+ mac_client = HMAC.get(hmac_client, mac_key_client, parameters)
357
+ mac_server = HMAC.get(hmac_server, mac_key_server, parameters)
356
358
 
357
359
  session.configure_client :cipher => cipher_client, :hmac => mac_client,
358
360
  :compression => normalize_compression_name(compression_client),
@@ -381,4 +383,4 @@ module Net; module SSH; module Transport
381
383
  end
382
384
  end
383
385
  end
384
- end; end; end
386
+ end; end; end
@@ -1,4 +1,5 @@
1
1
  require 'openssl'
2
+ require 'net/ssh/transport/key_expander'
2
3
  require 'net/ssh/transport/identity_cipher'
3
4
 
4
5
  module Net; module SSH; module Transport
@@ -50,10 +51,10 @@ module Net; module SSH; module Transport
50
51
  cipher.send(options[:encrypt] ? :encrypt : :decrypt)
51
52
 
52
53
  cipher.padding = 0
53
- cipher.iv = make_key(cipher.iv_len, options[:iv], options) if ossl_name != "rc4"
54
+ cipher.iv = Net::SSH::Transport::KeyExpander.expand_key(cipher.iv_len, options[:iv], options) if ossl_name != "rc4"
54
55
  key_len = KEY_LEN_OVERRIDE[name] || cipher.key_len
55
56
  cipher.key_len = key_len
56
- cipher.key = make_key(key_len, options[:key], options)
57
+ cipher.key = Net::SSH::Transport::KeyExpander.expand_key(key_len, options[:key], options)
57
58
  cipher.update(" " * 1536) if ossl_name == "rc4"
58
59
 
59
60
  return cipher
@@ -73,25 +74,6 @@ module Net; module SSH; module Transport
73
74
 
74
75
  return [key_len, ossl_name=="rc4" ? 8 : cipher.block_size]
75
76
  end
76
-
77
- private
78
-
79
- # Generate a key value in accordance with the SSH2 specification.
80
- def self.make_key(bytes, start, options={})
81
- k = start[0, bytes]
82
-
83
- digester = options[:digester] or raise 'No digester supplied'
84
- shared = options[:shared] or raise 'No shared secret supplied'
85
- hash = options[:hash] or raise 'No hash supplied'
86
-
87
- while k.length < bytes
88
- step = digester.digest(shared + hash + k)
89
- bytes_needed = bytes - k.length
90
- k << step[0, bytes_needed]
91
- end
92
-
93
- return k
94
- end
95
77
  end
96
78
 
97
79
  end; end; end
@@ -1,7 +1,12 @@
1
+ require 'net/ssh/transport/key_expander'
1
2
  require 'net/ssh/transport/hmac/md5'
2
3
  require 'net/ssh/transport/hmac/md5_96'
3
4
  require 'net/ssh/transport/hmac/sha1'
4
5
  require 'net/ssh/transport/hmac/sha1_96'
6
+ require 'net/ssh/transport/hmac/sha2_256'
7
+ require 'net/ssh/transport/hmac/sha2_256_96'
8
+ require 'net/ssh/transport/hmac/sha2_512'
9
+ require 'net/ssh/transport/hmac/sha2_512_96'
5
10
  require 'net/ssh/transport/hmac/none'
6
11
 
7
12
  # Implements a simple factory interface for fetching hmac implementations, or
@@ -16,11 +21,17 @@ module Net::SSH::Transport::HMAC
16
21
  'none' => None
17
22
  }
18
23
 
24
+ # add mapping to sha2 hmac algorithms if they're available
25
+ MAP['hmac-sha2-256'] = SHA2_256 if defined?(::Net::SSH::Transport::HMAC::SHA2_256)
26
+ MAP['hmac-sha2-256-96'] = SHA2_256_96 if defined?(::Net::SSH::Transport::HMAC::SHA2_256_96)
27
+ MAP['hmac-sha2-512'] = SHA2_512 if defined?(::Net::SSH::Transport::HMAC::SHA2_512)
28
+ MAP['hmac-sha2-512-96'] = SHA2_512_96 if defined?(::Net::SSH::Transport::HMAC::SHA2_512_96)
29
+
19
30
  # Retrieves a new hmac instance of the given SSH type (+name+). If +key+ is
20
31
  # given, the new instance will be initialized with that key.
21
- def self.get(name, key="")
32
+ def self.get(name, key="", parameters = {})
22
33
  impl = MAP[name] or raise ArgumentError, "hmac not found: #{name.inspect}"
23
- impl.new(key)
34
+ impl.new(Net::SSH::Transport::KeyExpander.expand_key(impl.key_length, key, parameters))
24
35
  end
25
36
 
26
37
  # Retrieves the key length for the hmac of the given SSH type (+name+).
@@ -28,4 +39,4 @@ module Net::SSH::Transport::HMAC
28
39
  impl = MAP[name] or raise ArgumentError, "hmac not found: #{name.inspect}"
29
40
  impl.key_length
30
41
  end
31
- end
42
+ end
@@ -0,0 +1,15 @@
1
+ require 'net/ssh/transport/hmac/abstract'
2
+
3
+ if defined?(OpenSSL::Digest::SHA256) # need openssl support
4
+ module Net::SSH::Transport::HMAC
5
+
6
+ # The SHA-256 HMAC algorithm. This has a mac and key length of 32, and
7
+ # uses the SHA-256 digest algorithm.
8
+ class SHA2_256 < Abstract
9
+ mac_length 32
10
+ key_length 32
11
+ digest_class OpenSSL::Digest::SHA256
12
+ end
13
+
14
+ end
15
+ end
@@ -0,0 +1,13 @@
1
+ require 'net/ssh/transport/hmac/abstract'
2
+
3
+ module Net::SSH::Transport::HMAC
4
+
5
+ if defined?(SHA2_256) # need openssl support
6
+ # The SHA256-96 HMAC algorithm. This returns only the first 12 bytes of
7
+ # the digest.
8
+ class SHA2_256_96 < SHA2_256
9
+ mac_length 12
10
+ end
11
+ end
12
+
13
+ end
@@ -0,0 +1,14 @@
1
+ require 'net/ssh/transport/hmac/abstract'
2
+
3
+ module Net::SSH::Transport::HMAC
4
+
5
+ if defined?(OpenSSL::Digest::SHA512) # need openssl support
6
+ # The SHA-512 HMAC algorithm. This has a mac and key length of 64, and
7
+ # uses the SHA-512 digest algorithm.
8
+ class SHA2_512 < Abstract
9
+ mac_length 64
10
+ key_length 64
11
+ digest_class OpenSSL::Digest::SHA512
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,13 @@
1
+ require 'net/ssh/transport/hmac/abstract'
2
+
3
+ module Net::SSH::Transport::HMAC
4
+
5
+ if defined?(SHA2_512) # need openssl support
6
+ # The SHA2-512-96 HMAC algorithm. This returns only the first 12 bytes of
7
+ # the digest.
8
+ class SHA2_512_96 < SHA2_512
9
+ mac_length 12
10
+ end
11
+ end
12
+
13
+ end
@@ -1,5 +1,6 @@
1
1
  require 'net/ssh/transport/kex/diffie_hellman_group1_sha1'
2
2
  require 'net/ssh/transport/kex/diffie_hellman_group_exchange_sha1'
3
+ require 'net/ssh/transport/kex/diffie_hellman_group_exchange_sha256'
3
4
 
4
5
  module Net::SSH::Transport
5
6
  module Kex
@@ -7,7 +8,10 @@ module Net::SSH::Transport
7
8
  # to their corresponding implementors.
8
9
  MAP = {
9
10
  'diffie-hellman-group-exchange-sha1' => DiffieHellmanGroupExchangeSHA1,
10
- 'diffie-hellman-group1-sha1' => DiffieHellmanGroup1SHA1
11
+ 'diffie-hellman-group1-sha1' => DiffieHellmanGroup1SHA1,
11
12
  }
13
+ if defined?(DiffieHellmanGroupExchangeSHA256)
14
+ MAP['diffie-hellman-group-exchange-sha256'] = DiffieHellmanGroupExchangeSHA256
15
+ end
12
16
  end
13
- end
17
+ end
@@ -19,7 +19,10 @@ module Net::SSH::Transport::Kex
19
19
 
20
20
  # Compute the number of bits needed for the given number of bytes.
21
21
  def compute_need_bits
22
- need_bits = data[:need_bytes] * 8
22
+
23
+ # for Compatibility: OpenSSH requires (need_bits * 2 + 1) length of parameter
24
+ need_bits = data[:need_bytes] * 8 * 2 + 1
25
+
23
26
  if need_bits < MINIMUM_BITS
24
27
  need_bits = MINIMUM_BITS
25
28
  elsif need_bits > MAXIMUM_BITS
@@ -74,4 +77,4 @@ module Net::SSH::Transport::Kex
74
77
  end
75
78
  end
76
79
 
77
- end
80
+ end
@@ -0,0 +1,15 @@
1
+ require 'net/ssh/transport/kex/diffie_hellman_group_exchange_sha1'
2
+
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
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,26 @@
1
+ module Net; module SSH; module Transport
2
+ module KeyExpander
3
+
4
+ # Generate a key value in accordance with the SSH2 specification.
5
+ # (RFC4253 7.2. "Output from Key Exchange")
6
+ def self.expand_key(bytes, start, options={})
7
+ if bytes == 0
8
+ return ""
9
+ end
10
+
11
+ k = start[0, bytes]
12
+
13
+ digester = options[:digester] or raise 'No digester supplied'
14
+ shared = options[:shared] or raise 'No shared secret supplied'
15
+ hash = options[:hash] or raise 'No hash supplied'
16
+
17
+ while k.length < bytes
18
+ step = digester.digest(shared + hash + k)
19
+ bytes_needed = bytes - k.length
20
+ k << step[0, bytes_needed]
21
+ end
22
+
23
+ return k
24
+ end
25
+ end
26
+ end; end; end
@@ -48,10 +48,10 @@ module Net; module SSH
48
48
  MAJOR = 2
49
49
 
50
50
  # The minor component of this version of the Net::SSH library
51
- MINOR = 2
51
+ MINOR = 3
52
52
 
53
53
  # The tiny component of this version of the Net::SSH library
54
- TINY = 2
54
+ TINY = 0
55
55
 
56
56
  # The current version of the Net::SSH library as a Version instance
57
57
  CURRENT = new(MAJOR, MINOR, TINY)
@@ -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.2.2"
4
+ s.version = "2.3.0"
5
5
  s.summary = "Net::SSH: a pure-Ruby implementation of the SSH2 client protocol."
6
6
  s.description = s.summary
7
7
  s.authors = ["Jamis Buck", "Delano Mandelbaum"]
@@ -74,10 +74,16 @@
74
74
  lib/net/ssh/transport/hmac/none.rb
75
75
  lib/net/ssh/transport/hmac/sha1.rb
76
76
  lib/net/ssh/transport/hmac/sha1_96.rb
77
+ lib/net/ssh/transport/hmac/sha2_256.rb
78
+ lib/net/ssh/transport/hmac/sha2_256_96.rb
79
+ lib/net/ssh/transport/hmac/sha2_512.rb
80
+ lib/net/ssh/transport/hmac/sha2_512_96.rb
77
81
  lib/net/ssh/transport/identity_cipher.rb
82
+ lib/net/ssh/transport/key_expander.rb
78
83
  lib/net/ssh/transport/kex.rb
79
84
  lib/net/ssh/transport/kex/diffie_hellman_group1_sha1.rb
80
85
  lib/net/ssh/transport/kex/diffie_hellman_group_exchange_sha1.rb
86
+ lib/net/ssh/transport/kex/diffie_hellman_group_exchange_sha256.rb
81
87
  lib/net/ssh/transport/openssl.rb
82
88
  lib/net/ssh/transport/packet_stream.rb
83
89
  lib/net/ssh/transport/server_version.rb
@@ -91,7 +97,6 @@
91
97
  setup.rb
92
98
  support/arcfour_check.rb
93
99
  support/ssh_tunnel_bug.rb
94
- test/README.txt
95
100
  test/authentication/methods/common.rb
96
101
  test/authentication/methods/test_abstract.rb
97
102
  test/authentication/methods/test_hostbased.rb
@@ -106,12 +111,9 @@
106
111
  test/configs/exact_match
107
112
  test/configs/host_plus
108
113
  test/configs/multihost
109
- test/configs/nohost
110
- test/configs/numeric_host
111
114
  test/configs/wild_cards
112
115
  test/connection/test_channel.rb
113
116
  test/connection/test_session.rb
114
- test/manual/test_forward.rb
115
117
  test/test_all.rb
116
118
  test/test_buffer.rb
117
119
  test/test_buffered_io.rb
@@ -122,8 +124,13 @@
122
124
  test/transport/hmac/test_none.rb
123
125
  test/transport/hmac/test_sha1.rb
124
126
  test/transport/hmac/test_sha1_96.rb
127
+ test/transport/hmac/test_sha2_256.rb
128
+ test/transport/hmac/test_sha2_256_96.rb
129
+ test/transport/hmac/test_sha2_512.rb
130
+ test/transport/hmac/test_sha2_512_96.rb
125
131
  test/transport/kex/test_diffie_hellman_group1_sha1.rb
126
132
  test/transport/kex/test_diffie_hellman_group_exchange_sha1.rb
133
+ test/transport/kex/test_diffie_hellman_group_exchange_sha256.rb
127
134
  test/transport/test_algorithms.rb
128
135
  test/transport/test_cipher_factory.rb
129
136
  test/transport/test_hmac.rb
@@ -0,0 +1,35 @@
1
+ require 'common'
2
+ require 'net/ssh/transport/hmac/sha2_256'
3
+
4
+ module Transport; module HMAC
5
+
6
+ class TestSHA2_256 < Test::Unit::TestCase
7
+ def test_expected_digest_class
8
+ assert_equal OpenSSL::Digest::SHA256, subject.digest_class
9
+ assert_equal OpenSSL::Digest::SHA256, subject.new.digest_class
10
+ end
11
+
12
+ def test_expected_key_length
13
+ assert_equal 32, subject.key_length
14
+ assert_equal 32, subject.new.key_length
15
+ end
16
+
17
+ def test_expected_mac_length
18
+ assert_equal 32, subject.mac_length
19
+ assert_equal 32, subject.new.mac_length
20
+ end
21
+
22
+ def test_expected_digest
23
+ hmac = subject.new("1234567890123456")
24
+ assert_equal "\x16^>\x9FhO}\xB1>(\xBAF\xFBW\xB8\xF2\xFA\x824+\xC0\x94\x95\xC2\r\xE6\x88/\xEF\t\xF5%", hmac.digest("hello world")
25
+
26
+ end
27
+
28
+ private
29
+
30
+ def subject
31
+ Net::SSH::Transport::HMAC::SHA2_256
32
+ end
33
+ end
34
+
35
+ end; end
@@ -0,0 +1,25 @@
1
+ require 'common'
2
+ require 'transport/hmac/test_sha2_256'
3
+ require 'net/ssh/transport/hmac/sha2_256_96'
4
+
5
+ module Transport; module HMAC
6
+
7
+ class TestSHA2_256_96 < TestSHA2_256
8
+ def test_expected_mac_length
9
+ assert_equal 12, subject.mac_length
10
+ assert_equal 12, subject.new.mac_length
11
+ end
12
+
13
+ def test_expected_digest
14
+ hmac = subject.new("1234567890123456")
15
+ assert_equal "\x16^>\x9FhO}\xB1>(\xBAF", hmac.digest("hello world")
16
+ end
17
+
18
+ private
19
+
20
+ def subject
21
+ Net::SSH::Transport::HMAC::SHA2_256_96
22
+ end
23
+ end
24
+
25
+ end; end