net-ssh 2.2.2 → 2.3.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -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