diff options
| author | Ryosuke Yamazaki <ryosuke.yamazaki@mac.com> | 2011-12-15 11:33:30 +0900 |
|---|---|---|
| committer | Ryosuke Yamazaki <ryosuke.yamazaki@mac.com> | 2011-12-15 11:33:30 +0900 |
| commit | 34af68b7f2726ed142c6b6f6b5704c1de562804e (patch) | |
| tree | 29995127cfcb88e26585fccdc7d544cc080ef351 /lib | |
| parent | 881d6217cc0a4093d815ac9ab0252733afd9eecc (diff) | |
| download | net-ssh-34af68b7f2726ed142c6b6f6b5704c1de562804e.tar.gz | |
fix for hmac key deriving bug
Diffstat (limited to 'lib')
| -rw-r--r-- | lib/net/ssh/transport/algorithms.rb | 10 | ||||
| -rw-r--r-- | lib/net/ssh/transport/hmac.rb | 40 |
2 files changed, 43 insertions, 7 deletions
diff --git a/lib/net/ssh/transport/algorithms.rb b/lib/net/ssh/transport/algorithms.rb index 9c7f8d0..004a82b 100644 --- a/lib/net/ssh/transport/algorithms.rb +++ b/lib/net/ssh/transport/algorithms.rb @@ -28,7 +28,9 @@ module Net; module SSH; module Transport :encryption => %w(aes128-cbc 3des-cbc blowfish-cbc cast128-cbc aes192-cbc aes256-cbc rijndael-cbc@lysator.liu.se idea-cbc none arcfour128 arcfour256), - :hmac => %w(hmac-sha1 hmac-md5 hmac-sha1-96 hmac-md5-96 none), + :hmac => %w(hmac-sha1 hmac-md5 hmac-sha1-96 hmac-md5-96 + hmac-sha2-256 hmac-sha2-512 hmac-sha2-256-96 + hmac-sha2-512-96 none), :compression => %w(none zlib@openssh.com zlib), :language => %w() } @@ -351,8 +353,8 @@ module Net; module SSH; module Transport cipher_client = CipherFactory.get(encryption_client, parameters.merge(:encrypt => true)) cipher_server = CipherFactory.get(encryption_server, parameters.merge(:iv => iv_server, :key => key_server, :decrypt => true)) - mac_client = HMAC.get(hmac_client, mac_key_client) - mac_server = HMAC.get(hmac_server, mac_key_server) + mac_client = HMAC.get(hmac_client, mac_key_client, parameters) + mac_server = HMAC.get(hmac_server, mac_key_server, parameters) session.configure_client :cipher => cipher_client, :hmac => mac_client, :compression => normalize_compression_name(compression_client), @@ -381,4 +383,4 @@ module Net; module SSH; module Transport end end end -end; end; end
\ No newline at end of file +end; end; end diff --git a/lib/net/ssh/transport/hmac.rb b/lib/net/ssh/transport/hmac.rb index 262db73..c2a79f4 100644 --- a/lib/net/ssh/transport/hmac.rb +++ b/lib/net/ssh/transport/hmac.rb @@ -2,6 +2,10 @@ require 'net/ssh/transport/hmac/md5' require 'net/ssh/transport/hmac/md5_96' require 'net/ssh/transport/hmac/sha1' require 'net/ssh/transport/hmac/sha1_96' +require 'net/ssh/transport/hmac/sha2_256' +require 'net/ssh/transport/hmac/sha2_256_96' +require 'net/ssh/transport/hmac/sha2_512' +require 'net/ssh/transport/hmac/sha2_512_96' require 'net/ssh/transport/hmac/none' # Implements a simple factory interface for fetching hmac implementations, or @@ -16,11 +20,19 @@ module Net::SSH::Transport::HMAC 'none' => None } + # add mapping to sha2 hmac algorithms if they're available + MAP['hmac-sha2-256'] = SHA2_256 if defined?(::Net::SSH::Transport::HMAC::SHA2_256) + MAP['hmac-sha2-256-96'] = SHA2_256_96 if defined?(::Net::SSH::Transport::HMAC::SHA2_256_96) + MAP['hmac-sha2-512'] = SHA2_512 if defined?(::Net::SSH::Transport::HMAC::SHA2_512) + MAP['hmac-sha2-512-96'] = SHA2_512_96 if defined?(::Net::SSH::Transport::HMAC::SHA2_512_96) + # Retrieves a new hmac instance of the given SSH type (+name+). If +key+ is # given, the new instance will be initialized with that key. - def self.get(name, key="") + def self.get(name, key="", parameters = {}) + puts "digest key len: " + key.length.to_s impl = MAP[name] or raise ArgumentError, "hmac not found: #{name.inspect}" - impl.new(key) + + impl.new(make_key(impl.key_length, key, parameters)) end # Retrieves the key length for the hmac of the given SSH type (+name+). @@ -28,4 +40,26 @@ module Net::SSH::Transport::HMAC impl = MAP[name] or raise ArgumentError, "hmac not found: #{name.inspect}" impl.key_length end -end
\ No newline at end of file + + # XXX copied + # Generate a key value in accordance with the SSH2 specification. + def self.make_key(bytes, start, options={}) + if bytes == 0 + return "" + end + + k = start[0, bytes] + + digester = options[:digester] or raise 'No digester supplied' + shared = options[:shared] or raise 'No shared secret supplied' + hash = options[:hash] or raise 'No hash supplied' + + while k.length < bytes + step = digester.digest(shared + hash + k) + bytes_needed = bytes - k.length + k << step[0, bytes_needed] + end + + return k + end +end |
