Permalink
Browse files

Merged addalgos

  • Loading branch information...
2 parents c6aec69 + 3a74662 commit 17709188e36e701d6f44dd74b61d6b294148956b @delano delano committed May 24, 2012
Showing with 2,434 additions and 206 deletions.
  1. +11 −0 Manifest
  2. +1 −1 lib/net/ssh/authentication/key_manager.rb
  3. +12 −4 lib/net/ssh/authentication/session.rb
  4. +12 −2 lib/net/ssh/buffer.rb
  5. +7 −2 lib/net/ssh/key_factory.rb
  6. +12 −2 lib/net/ssh/known_hosts.rb
  7. +8 −0 lib/net/ssh/ruby_compat.rb
  8. +22 −1 lib/net/ssh/transport/algorithms.rb
  9. +32 −5 lib/net/ssh/transport/cipher_factory.rb
  10. +3 −1 lib/net/ssh/transport/constants.rb
  11. +95 −0 lib/net/ssh/transport/ctr.rb
  12. +8 −5 lib/net/ssh/transport/hmac.rb
  13. +13 −0 lib/net/ssh/transport/hmac/ripemd160.rb
  14. +11 −0 lib/net/ssh/transport/kex.rb
  15. +44 −0 lib/net/ssh/transport/kex/diffie_hellman_group14_sha1.rb
  16. +11 −3 lib/net/ssh/transport/kex/diffie_hellman_group1_sha1.rb
  17. +93 −0 lib/net/ssh/transport/kex/ecdh_sha2_nistp256.rb
  18. +13 −0 lib/net/ssh/transport/kex/ecdh_sha2_nistp384.rb
  19. +13 −0 lib/net/ssh/transport/kex/ecdh_sha2_nistp521.rb
  20. +111 −1 lib/net/ssh/transport/openssl.rb
  21. +132 −129 net-ssh.gemspec
  22. +48 −1 test/authentication/test_key_manager.rb
  23. +1 −1 test/manual/test_forward.rb
  24. +92 −2 test/test_buffer.rb
  25. +42 −0 test/test_key_factory.rb
  26. +34 −0 test/transport/hmac/test_ripemd160.rb
  27. +13 −0 test/transport/kex/test_diffie_hellman_group14_sha1.rb
  28. +161 −0 test/transport/kex/test_ecdh_sha2_nistp256.rb
  29. +37 −0 test/transport/kex/test_ecdh_sha2_nistp384.rb
  30. +37 −0 test/transport/kex/test_ecdh_sha2_nistp521.rb
  31. +41 −19 test/transport/test_algorithms.rb
  32. +255 −27 test/transport/test_cipher_factory.rb
  33. +1,009 −0 test/transport/test_packet_stream.rb
View
11 Manifest
@@ -47,11 +47,13 @@ lib/net/ssh/test/socket.rb
lib/net/ssh/transport/algorithms.rb
lib/net/ssh/transport/cipher_factory.rb
lib/net/ssh/transport/constants.rb
+lib/net/ssh/transport/ctr.rb
lib/net/ssh/transport/hmac.rb
lib/net/ssh/transport/hmac/abstract.rb
lib/net/ssh/transport/hmac/md5.rb
lib/net/ssh/transport/hmac/md5_96.rb
lib/net/ssh/transport/hmac/none.rb
+lib/net/ssh/transport/hmac/ripemd160.rb
lib/net/ssh/transport/hmac/sha1.rb
lib/net/ssh/transport/hmac/sha1_96.rb
lib/net/ssh/transport/hmac/sha2_256.rb
@@ -62,8 +64,12 @@ lib/net/ssh/transport/identity_cipher.rb
lib/net/ssh/transport/key_expander.rb
lib/net/ssh/transport/kex.rb
lib/net/ssh/transport/kex/diffie_hellman_group1_sha1.rb
+lib/net/ssh/transport/kex/diffie_hellman_group14_sha1.rb
lib/net/ssh/transport/kex/diffie_hellman_group_exchange_sha1.rb
lib/net/ssh/transport/kex/diffie_hellman_group_exchange_sha256.rb
+lib/net/ssh/transport/kex/ecdh_sha2_nistp256.rb
+lib/net/ssh/transport/kex/ecdh_sha2_nistp384.rb
+lib/net/ssh/transport/kex/ecdh_sha2_nistp521.rb
lib/net/ssh/transport/openssl.rb
lib/net/ssh/transport/packet_stream.rb
lib/net/ssh/transport/server_version.rb
@@ -102,15 +108,20 @@ test/test_key_factory.rb
test/transport/hmac/test_md5.rb
test/transport/hmac/test_md5_96.rb
test/transport/hmac/test_none.rb
+test/transport/hmac/test_ripemd160.rb
test/transport/hmac/test_sha1.rb
test/transport/hmac/test_sha1_96.rb
test/transport/hmac/test_sha2_256.rb
test/transport/hmac/test_sha2_256_96.rb
test/transport/hmac/test_sha2_512.rb
test/transport/hmac/test_sha2_512_96.rb
test/transport/kex/test_diffie_hellman_group1_sha1.rb
+test/transport/kex/test_diffie_hellman_group14_sha1.rb
test/transport/kex/test_diffie_hellman_group_exchange_sha1.rb
test/transport/kex/test_diffie_hellman_group_exchange_sha256.rb
+test/transport/kex/test_ecdh_sha2_nistp256.rb
+test/transport/kex/test_ecdh_sha2_nistp384.rb
+test/transport/kex/test_ecdh_sha2_nistp521.rb
test/transport/test_algorithms.rb
test/transport/test_cipher_factory.rb
test/transport/test_hmac.rb
View
2 lib/net/ssh/authentication/key_manager.rb
@@ -222,7 +222,7 @@ def load_identities(identities, ask_passphrase)
identity
end
- rescue OpenSSL::PKey::RSAError, OpenSSL::PKey::DSAError => e
+ rescue OpenSSL::PKey::RSAError, OpenSSL::PKey::DSAError, OpenSSL::PKey::ECError => e
if ask_passphrase
process_identity_loading_error(identity, e)
nil
View
16 lib/net/ssh/authentication/session.rb
@@ -128,13 +128,21 @@ def expect_message(type)
private
+ # Returns an array of paths to the key files usually defined
+ # by system default.
+ def default_keys
+ if defined?(OpenSSL::PKey::EC)
+ %w(~/.ssh/id_dsa ~/.ssh/id_rsa ~/.ssh/id_ecdsa
+ ~/.ssh2/id_dsa ~/.ssh2/id_rsa ~/.ssh2/id_ecdsa)
+ else
+ %w(~/.ssh/id_dsa ~/.ssh/id_rsa ~/.ssh2/id_dsa ~/.ssh2/id_rsa)
+ end
+ end
+
# Returns an array of paths to the key files that should be used when
# attempting any key-based authentication mechanism.
def keys
- Array(
- options[:keys] ||
- %w(~/.ssh/id_dsa ~/.ssh/id_rsa ~/.ssh2/id_dsa ~/.ssh2/id_rsa)
- )
+ Array(options[:keys] || default_keys)
end
# Returns an array of the key data that should be used when
View
14 lib/net/ssh/buffer.rb
@@ -240,7 +240,7 @@ def read_key
end
# Read a keyblob of the given type from the buffer, and return it as
- # a key. Only RSA and DSA keys are supported.
+ # a key. Only RSA, DSA, and ECDSA keys are supported.
def read_keyblob(type)
case type
when "ssh-dss"
@@ -255,6 +255,16 @@ def read_keyblob(type)
key.e = read_bignum
key.n = read_bignum
+ when /^ecdsa\-sha2\-(\w*)$/
+ unless defined?(OpenSSL::PKey::EC)
+ raise NotImplementedError, "unsupported key type `#{type}'"
+ else
+ begin
+ key = OpenSSL::PKey::EC.read_keyblob($1, self)
+ rescue OpenSSL::PKey::ECError => e
+ raise NotImplementedError, "unsupported key type `#{type}'"
+ end
+ end
else
raise NotImplementedError, "unsupported key type `#{type}'"
end
@@ -337,4 +347,4 @@ def write_key(*key)
self
end
end
-end; end;
+end; end;
View
9 lib/net/ssh/key_factory.rb
@@ -17,8 +17,11 @@ class KeyFactory
MAP = {
"dh" => OpenSSL::PKey::DH,
"rsa" => OpenSSL::PKey::RSA,
- "dsa" => OpenSSL::PKey::DSA
+ "dsa" => OpenSSL::PKey::DSA,
}
+ if defined?(OpenSSL::PKey::EC)
+ MAP["ecdsa"] = OpenSSL::PKey::EC
+ end
class <<self
include Prompt
@@ -49,6 +52,8 @@ def load_data_private_key(data, passphrase=nil, ask_passphrase=true, filename=""
key_type = OpenSSL::PKey::DSA
elsif data.match(/-----BEGIN RSA PRIVATE KEY-----/)
key_type = OpenSSL::PKey::RSA
+ elsif data.match(/-----BEGIN EC PRIVATE KEY-----/) && defined?(OpenSSL::PKey::EC)
+ key_type = OpenSSL::PKey::EC
elsif data.match(/-----BEGIN (.*) PRIVATE KEY-----/)
raise OpenSSL::PKey::PKeyError, "not a supported key type '#{$1}'"
else
@@ -60,7 +65,7 @@ def load_data_private_key(data, passphrase=nil, ask_passphrase=true, filename=""
begin
return key_type.new(data, passphrase || 'invalid')
- rescue OpenSSL::PKey::RSAError, OpenSSL::PKey::DSAError => e
+ rescue OpenSSL::PKey::RSAError, OpenSSL::PKey::DSAError, OpenSSL::PKey::ECError => e
if encrypted_key && ask_passphrase
tries += 1
if tries <= 3
View
14 lib/net/ssh/known_hosts.rb
@@ -11,6 +11,16 @@ module Net; module SSH
# by consumers of the library.
class KnownHosts
class <<self
+
+ if defined?(OpenSSL::PKey::EC)
+ SUPPORTED_TYPE = %w(ssh-rsa ssh-dss
+ ecdsa-sha2-nistp256
+ ecdsa-sha2-nistp384
+ ecdsa-sha2-nistp521)
+ else
+ SUPPORTED_TYPE = %w(ssh-rsa ssh-dss)
+ end
+
# Searches all known host files (see KnownHosts.hostfiles) for all keys
# of the given host. Returns an array of keys found.
def search_for(host, options={})
@@ -104,7 +114,7 @@ def keys_for(host)
scanner.skip(/\s*/)
type = scanner.scan(/\S+/)
- next unless %w(ssh-rsa ssh-dss).include?(type)
+ next unless SUPPORTED_TYPE.include?(type)
scanner.skip(/\s*/)
blob = scanner.rest.unpack("m*").first
@@ -126,4 +136,4 @@ def add(host, key)
end
end
-end; end
+end; end
View
8 lib/net/ssh/ruby_compat.rb
@@ -5,6 +5,14 @@ class String
def getbyte(index)
self[index]
end
+ def setbyte(index, c)
+ self[index] = c
+ end
+ end
+ if RUBY_VERSION < "1.8.7"
+ def bytesize
+ self.size
+ end
end
end
View
23 lib/net/ssh/transport/algorithms.rb
@@ -25,16 +25,37 @@ class Algorithms
:host_key => %w(ssh-rsa ssh-dss),
:kex => %w(diffie-hellman-group-exchange-sha1
diffie-hellman-group1-sha1
+ diffie-hellman-group14-sha1
diffie-hellman-group-exchange-sha256),
:encryption => %w(aes128-cbc 3des-cbc blowfish-cbc cast128-cbc
aes192-cbc aes256-cbc rijndael-cbc@lysator.liu.se
- idea-cbc none arcfour128 arcfour256),
+ idea-cbc none arcfour128 arcfour256 arcfour
+ aes128-ctr aes192-ctr aes256-ctr
+ camellia128-cbc camellia192-cbc camellia256-cbc
+ camellia128-cbc@openssh.org
+ camellia192-cbc@openssh.org
+ camellia256-cbc@openssh.org
+ camellia128-ctr camellia192-ctr camellia256-ctr
+ camellia128-ctr@openssh.org
+ camellia192-ctr@openssh.org
+ camellia256-ctr@openssh.org
+ cast128-ctr blowfish-ctr 3des-ctr
+ ),
:hmac => %w(hmac-sha1 hmac-md5 hmac-sha1-96 hmac-md5-96
+ hmac-ripemd160 hmac-ripemd160@openssh.com
hmac-sha2-256 hmac-sha2-512 hmac-sha2-256-96
hmac-sha2-512-96 none),
:compression => %w(none zlib@openssh.com zlib),
:language => %w()
}
+ if defined?(OpenSSL::PKey::EC)
+ ALGORITHMS[:host_key] += %w(ecdsa-sha2-nistp256
+ ecdsa-sha2-nistp384
+ ecdsa-sha2-nistp521)
+ ALGORITHMS[:kex] += %w(ecdh-sha2-nistp256
+ ecdh-sha2-nistp384
+ ecdh-sha2-nistp521)
+ end
# The underlying transport layer session that supports this object
attr_reader :session
View
37 lib/net/ssh/transport/cipher_factory.rb
@@ -1,4 +1,5 @@
require 'openssl'
+require 'net/ssh/transport/ctr.rb'
require 'net/ssh/transport/key_expander'
require 'net/ssh/transport/identity_cipher'
@@ -19,17 +20,39 @@ class CipherFactory
"arcfour128" => "rc4",
"arcfour256" => "rc4",
"arcfour512" => "rc4",
- "none" => "none"
+ "arcfour" => "rc4",
+ "camellia128-cbc" => "camellia-128-cbc",
+ "camellia192-cbc" => "camellia-192-cbc",
+ "camellia256-cbc" => "camellia-256-cbc",
+ "camellia128-cbc@openssh.org" => "camellia-128-cbc",
+ "camellia192-cbc@openssh.org" => "camellia-192-cbc",
+ "camellia256-cbc@openssh.org" => "camellia-256-cbc",
+
+ "3des-ctr" => "des-ede3",
+ "blowfish-ctr" => "bf-ecb",
+ "aes256-ctr" => "aes-256-ecb",
+ "aes192-ctr" => "aes-192-ecb",
+ "aes128-ctr" => "aes-128-ecb",
+ "cast128-ctr" => "cast5-ecb",
+ "camellia128-ctr" => "camellia-128-ecb",
+ "camellia192-ctr" => "camellia-192-ecb",
+ "camellia256-ctr" => "camellia-256-ecb",
+ "camellia128-ctr@openssh.org" => "camellia-128-ecb",
+ "camellia192-ctr@openssh.org" => "camellia-192-ecb",
+ "camellia256-ctr@openssh.org" => "camellia-256-ecb",
+
+ "none" => "none",
}
-
+
# Ruby's OpenSSL bindings always return a key length of 16 for RC4 ciphers
# resulting in the error: OpenSSL::CipherError: key length too short.
# The following ciphers will override this key length.
KEY_LEN_OVERRIDE = {
"arcfour256" => 32,
"arcfour512" => 64
}
-
+
+
# Returns true if the underlying OpenSSL library supports the given cipher,
# and false otherwise.
def self.supported?(name)
@@ -46,16 +69,20 @@ def self.supported?(name)
def self.get(name, options={})
ossl_name = SSH_TO_OSSL[name] or raise NotImplementedError, "unimplemented cipher `#{name}'"
return IdentityCipher if ossl_name == "none"
-
cipher = OpenSSL::Cipher::Cipher.new(ossl_name)
+
cipher.send(options[:encrypt] ? :encrypt : :decrypt)
cipher.padding = 0
+
+ cipher.extend(Net::SSH::Transport::CTR) if (name =~ /-ctr(@openssh.org)?$/)
+
cipher.iv = Net::SSH::Transport::KeyExpander.expand_key(cipher.iv_len, options[:iv], options) if ossl_name != "rc4"
+
key_len = KEY_LEN_OVERRIDE[name] || cipher.key_len
cipher.key_len = key_len
cipher.key = Net::SSH::Transport::KeyExpander.expand_key(key_len, options[:key], options)
- cipher.update(" " * 1536) if ossl_name == "rc4"
+ cipher.update(" " * 1536) if (ossl_name == "rc4" && name != "arcfour")
return cipher
end
View
4 lib/net/ssh/transport/constants.rb
@@ -26,5 +26,7 @@ module Constants
KEXDH_INIT = 30
KEXDH_REPLY = 31
+ KEXECDH_INIT = 30
+ KEXECDH_REPLY = 31
end
-end; end; end
+end; end; end
View
95 lib/net/ssh/transport/ctr.rb
@@ -0,0 +1,95 @@
+require 'openssl'
+
+module Net::SSH::Transport
+
+ # Pure-Ruby implementation of Stateful Decryption Counter(SDCTR) Mode
+ # for Block Ciphers. See RFC4344 for detail.
+ module CTR
+ def self.extended(orig)
+ orig.instance_eval {
+ @remaining = ""
+ @counter = nil
+ @counter_len = orig.block_size
+ orig.encrypt
+ orig.padding = 0
+ }
+
+ class <<orig
+ alias :_update :update
+ private :_update
+ undef :update
+
+ def iv
+ @counter
+ end
+
+ def iv_len
+ block_size
+ end
+
+ def iv=(iv_s)
+ @counter = iv_s if @counter.nil?
+ end
+
+ def encrypt
+ # DO NOTHING (always set to "encrypt")
+ end
+
+ def decrypt
+ # DO NOTHING (always set to "encrypt")
+ end
+
+ def padding=(pad)
+ # DO NOTHING (always 0)
+ end
+
+ def reset
+ @remaining = ""
+ end
+
+ def update(data)
+ @remaining += data
+
+ encrypted = ""
+
+ while @remaining.bytesize >= block_size
+ encrypted += xor!(@remaining.slice!(0, block_size),
+ _update(@counter))
+ increment_counter!
+ end
+
+ encrypted
+ end
+
+ def final
+ unless @remaining.empty?
+ s = xor!(@remaining, _update(@counter))
+ else
+ s = ""
+ end
+
+ @remaining = ""
+
+ s
+ end
+
+ private
+
+ def xor!(s1, s2)
+ s = []
+ s1.unpack('Q*').zip(s2.unpack('Q*')) {|a,b| s.push(a^b) }
+ s.pack('Q*')
+ end
+
+ def increment_counter!
+ c = @counter_len
+ while ((c -= 1) > 0)
+ if @counter.setbyte(c, (@counter.getbyte(c) + 1) & 0xff) != 0
+ break
+ end
+ end
+ end
+ end
+ end
+ end
+end
View
13 lib/net/ssh/transport/hmac.rb
@@ -7,18 +7,21 @@
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/ripemd160'
require 'net/ssh/transport/hmac/none'
# Implements a simple factory interface for fetching hmac implementations, or
# for finding the key lengths for hmac implementations.s
module Net::SSH::Transport::HMAC
# The mapping of SSH hmac algorithms to their implementations
MAP = {
- 'hmac-md5' => MD5,
- 'hmac-md5-96' => MD5_96,
- 'hmac-sha1' => SHA1,
- 'hmac-sha1-96' => SHA1_96,
- 'none' => None
+ 'hmac-md5' => MD5,
+ 'hmac-md5-96' => MD5_96,
+ 'hmac-sha1' => SHA1,
+ 'hmac-sha1-96' => SHA1_96,
+ 'hmac-ripemd160' => RIPEMD160,
+ 'hmac-ripemd160@openssh.com' => RIPEMD160,
+ 'none' => None
}
# add mapping to sha2 hmac algorithms if they're available
View
13 lib/net/ssh/transport/hmac/ripemd160.rb
@@ -0,0 +1,13 @@
+require 'net/ssh/transport/hmac/abstract'
+
+module Net::SSH::Transport::HMAC
+
+ # The RIPEMD-160 HMAC algorithm. This has a mac and key length of 20, and
+ # uses the RIPEMD-160 digest algorithm.
+ class RIPEMD160 < Abstract
+ mac_length 20
+ key_length 20
+ digest_class OpenSSL::Digest::RIPEMD160
+ end
+
+end
View
11 lib/net/ssh/transport/kex.rb
@@ -1,4 +1,5 @@
require 'net/ssh/transport/kex/diffie_hellman_group1_sha1'
+require 'net/ssh/transport/kex/diffie_hellman_group14_sha1'
require 'net/ssh/transport/kex/diffie_hellman_group_exchange_sha1'
require 'net/ssh/transport/kex/diffie_hellman_group_exchange_sha256'
@@ -9,9 +10,19 @@ module Kex
MAP = {
'diffie-hellman-group-exchange-sha1' => DiffieHellmanGroupExchangeSHA1,
'diffie-hellman-group1-sha1' => DiffieHellmanGroup1SHA1,
+ 'diffie-hellman-group14-sha1' => DiffieHellmanGroup14SHA1,
}
if defined?(DiffieHellmanGroupExchangeSHA256)
MAP['diffie-hellman-group-exchange-sha256'] = DiffieHellmanGroupExchangeSHA256
end
+ if defined?(OpenSSL::PKey::EC)
+ require 'net/ssh/transport/kex/ecdh_sha2_nistp256'
+ require 'net/ssh/transport/kex/ecdh_sha2_nistp384'
+ require 'net/ssh/transport/kex/ecdh_sha2_nistp521'
+
+ MAP['ecdh-sha2-nistp256'] = EcdhSHA2NistP256
+ MAP['ecdh-sha2-nistp384'] = EcdhSHA2NistP384
+ MAP['ecdh-sha2-nistp521'] = EcdhSHA2NistP521
+ end
end
end
View
44 lib/net/ssh/transport/kex/diffie_hellman_group14_sha1.rb
@@ -0,0 +1,44 @@
+require 'net/ssh/transport/kex/diffie_hellman_group1_sha1'
+
+module Net; module SSH; module Transport; module Kex
+
+ # A key-exchange service implementing the "diffie-hellman-group14-sha1"
+ # key-exchange algorithm. (defined in RFC 4253)
+ class DiffieHellmanGroup14SHA1 < DiffieHellmanGroup1SHA1
+ include Constants, Loggable
+
+ # The value of 'P', as a string, in hexadecimal
+ P_s = "FFFFFFFF" "FFFFFFFF" "C90FDAA2" "2168C234" +
+ "C4C6628B" "80DC1CD1" "29024E08" "8A67CC74" +
+ "020BBEA6" "3B139B22" "514A0879" "8E3404DD" +
+ "EF9519B3" "CD3A431B" "302B0A6D" "F25F1437" +
+ "4FE1356D" "6D51C245" "E485B576" "625E7EC6" +
+ "F44C42E9" "A637ED6B" "0BFF5CB6" "F406B7ED" +
+ "EE386BFB" "5A899FA5" "AE9F2411" "7C4B1FE6" +
+ "49286651" "ECE45B3D" "C2007CB8" "A163BF05" +
+ "98DA4836" "1C55D39A" "69163FA8" "FD24CF5F" +
+ "83655D23" "DCA3AD96" "1C62F356" "208552BB" +
+ "9ED52907" "7096966D" "670C354E" "4ABC9804" +
+ "F1746C08" "CA18217C" "32905E46" "2E36CE3B" +
+ "E39E772C" "180E8603" "9B2783A2" "EC07A28F" +
+ "B5C55DF0" "6F4C52C9" "DE2BCBF6" "95581718" +
+ "3995497C" "EA956AE5" "15D22618" "98FA0510" +
+ "15728E5A" "8AACAA68" "FFFFFFFF" "FFFFFFFF"
+
+ # The radix in which P_s represents the value of P
+ P_r = 16
+
+ # The group constant
+ G = 2
+
+ private
+
+ def get_p
+ OpenSSL::BN.new(P_s, P_r)
+ end
+
+ def get_g
+ G
+ end
+ end
+end; end; end; end
View
14 lib/net/ssh/transport/kex/diffie_hellman_group1_sha1.rb
@@ -40,8 +40,8 @@ class DiffieHellmanGroup1SHA1
# required by this algorithm, which was acquired during earlier
# processing.
def initialize(algorithms, connection, data)
- @p = OpenSSL::BN.new(P_s, P_r)
- @g = G
+ @p = get_p
+ @g = get_g
@digester = OpenSSL::Digest::SHA1
@algorithms = algorithms
@@ -76,7 +76,15 @@ def exchange_keys
end
private
-
+
+ def get_p
+ OpenSSL::BN.new(P_s, P_r)
+ end
+
+ def get_g
+ G
+ end
+
# Returns the DH key parameters for the current connection.
def get_parameters
[p, g]
View
93 lib/net/ssh/transport/kex/ecdh_sha2_nistp256.rb
@@ -0,0 +1,93 @@
+require 'net/ssh/transport/constants'
+require 'net/ssh/transport/kex/diffie_hellman_group1_sha1'
+
+module Net; module SSH; module Transport; module Kex
+
+ # A key-exchange service implementing the "ecdh-sha2-nistp256"
+ # key-exchange algorithm. (defined in RFC 5656)
+ class EcdhSHA2NistP256 < DiffieHellmanGroup1SHA1
+ include Constants, Loggable
+
+ attr_reader :ecdh
+
+ def digester
+ OpenSSL::Digest::SHA256
+ end
+
+ def curve_name
+ OpenSSL::PKey::EC::CurveNameAlias['nistp256']
+ end
+
+ def initialize(algorithms, connection, data)
+ @algorithms = algorithms
+ @connection = connection
+
+ @digester = digester
+ @data = data.dup
+ @ecdh = generate_key
+ @logger = @data.delete(:logger)
+ end
+
+ private
+
+ def get_message_types
+ [KEXECDH_INIT, KEXECDH_REPLY]
+ end
+
+ def build_signature_buffer(result)
+ response = Net::SSH::Buffer.new
+ response.write_string data[:client_version_string],
+ data[:server_version_string],
+ data[:client_algorithm_packet],
+ data[:server_algorithm_packet],
+ result[:key_blob],
+ ecdh.public_key.to_bn.to_s(2),
+ result[:server_ecdh_pubkey]
+ response.write_bignum result[:shared_secret]
+ response
+ end
+
+ def generate_key #:nodoc:
+ OpenSSL::PKey::EC.new(curve_name).generate_key
+ end
+
+ def send_kexinit #:nodoc:
+ init, reply = get_message_types
+
+ # send the KEXECDH_INIT message
+ ## byte SSH_MSG_KEX_ECDH_INIT
+ ## string Q_C, client's ephemeral public key octet string
+ buffer = Net::SSH::Buffer.from(:byte, init, :string, ecdh.public_key.to_bn.to_s(2))
+ connection.send_message(buffer)
+
+ # expect the following KEXECDH_REPLY message
+ ## byte SSH_MSG_KEX_ECDH_REPLY
+ ## string K_S, server's public host key
+ ## string Q_S, server's ephemeral public key octet string
+ ## string the signature on the exchange hash
+ buffer = connection.next_message
+ raise Net::SSH::Exception, "expected REPLY" unless buffer.type == reply
+
+ result = Hash.new
+ result[:key_blob] = buffer.read_string
+ result[:server_key] = Net::SSH::Buffer.new(result[:key_blob]).read_key
+ result[:server_ecdh_pubkey] = buffer.read_string
+
+ # compute shared secret from server's public key and client's private key
+ pk = OpenSSL::PKey::EC::Point.new(OpenSSL::PKey::EC.new(curve_name).group,
+ OpenSSL::BN.new(result[:server_ecdh_pubkey], 2))
+ result[:shared_secret] = OpenSSL::BN.new(ecdh.dh_compute_key(pk), 2)
+
+ sig_buffer = Net::SSH::Buffer.new(buffer.read_string)
+ sig_type = sig_buffer.read_string
+ if sig_type != algorithms.host_key
+ raise Net::SSH::Exception,
+ "host key algorithm mismatch for signature " +
+ "'#{sig_type}' != '#{algorithms.host_key}'"
+ end
+ result[:server_sig] = sig_buffer.read_string
+
+ return result
+ end
+ end
+end; end; end; end
View
13 lib/net/ssh/transport/kex/ecdh_sha2_nistp384.rb
@@ -0,0 +1,13 @@
+module Net; module SSH; module Transport; module Kex
+
+ # A key-exchange service implementing the "ecdh-sha2-nistp256"
+ # key-exchange algorithm. (defined in RFC 5656)
+ class EcdhSHA2NistP384 < EcdhSHA2NistP256
+ def digester
+ OpenSSL::Digest::SHA384
+ end
+ def curve_name
+ OpenSSL::PKey::EC::CurveNameAlias['nistp384']
+ end
+ end
+end; end; end; end
View
13 lib/net/ssh/transport/kex/ecdh_sha2_nistp521.rb
@@ -0,0 +1,13 @@
+module Net; module SSH; module Transport; module Kex
+
+ # A key-exchange service implementing the "ecdh-sha2-nistp521"
+ # key-exchange algorithm. (defined in RFC 5656)
+ class EcdhSHA2NistP521 < EcdhSHA2NistP256
+ def digester
+ OpenSSL::Digest::SHA512
+ end
+ def curve_name
+ OpenSSL::PKey::EC::CurveNameAlias['nistp521']
+ end
+ end
+end; end; end; end
View
112 lib/net/ssh/transport/openssl.rb
@@ -1,3 +1,4 @@
+# -*- coding: utf-8 -*-
require 'openssl'
module OpenSSL
@@ -122,6 +123,115 @@ def ssh_do_sign(data)
end
end
- end
+ if defined?(OpenSSL::PKey::EC)
+ # This class is originally defined in the OpenSSL module. As needed, methods
+ # have been added to it by the Net::SSH module for convenience in dealing
+ # with SSH functionality.
+ class EC
+ CurveNameAlias = {
+ "nistp256" => "prime256v1",
+ "nistp384" => "secp384r1",
+ "nistp521" => "secp521r1",
+ }
+
+ CurveNameAliasInv = {
+ "prime256v1" => "nistp256",
+ "secp384r1" => "nistp384",
+ "secp521r1" => "nistp521",
+ }
+
+ def self.read_keyblob(curve_name_in_type, buffer)
+ curve_name_in_key = buffer.read_string
+ unless curve_name_in_type == curve_name_in_key
+ raise Net::SSH::Exception, "curve name mismatched (`#{curve_name_in_key}' with `#{curve_name_in_type}')"
+ end
+ public_key_oct = buffer.read_string
+ begin
+ key = OpenSSL::PKey::EC.new(OpenSSL::PKey::EC::CurveNameAlias[curve_name_in_key])
+ group = key.group
+ point = OpenSSL::PKey::EC::Point.new(group, OpenSSL::BN.new(public_key_oct, 2))
+ key.public_key = point
+
+ return key
+ rescue OpenSSL::PKey::ECError => e
+ raise NotImplementedError, "unsupported key type `#{type}'"
+ end
+
+ end
+
+ # Returns the description of this key type used by the
+ # SSH2 protocol, like "ecdsa-sha2-nistp256"
+ def ssh_type
+ "ecdsa-sha2-#{CurveNameAliasInv[self.group.curve_name]}"
+ end
+ def digester
+ if self.group.curve_name =~ /^[a-z]+(\d+)\w*\z/
+ curve_size = $1.to_i
+ if curve_size <= 256
+ OpenSSL::Digest::SHA256.new
+ elsif curve_size <= 384
+ OpenSSL::Digest::SHA384.new
+ else
+ OpenSSL::Digest::SHA512.new
+ end
+ else
+ OpenSSL::Digest::SHA256.new
+ end
+ end
+ private :digester
+
+ # Converts the key to a blob, according to the SSH2 protocol.
+ def to_blob
+ @blob ||= Net::SSH::Buffer.from(:string, ssh_type,
+ :string, CurveNameAliasInv[self.group.curve_name],
+ :string, self.public_key.to_bn.to_s(2)).to_s
+ @blob
+ end
+
+ # Verifies the given signature matches the given data.
+ def ssh_do_verify(sig, data)
+ digest = digester.digest(data)
+ a1sig = nil
+
+ begin
+ sig_r_len = sig[0,4].unpack("H*")[0].to_i(16)
+ sig_l_len = sig[4+sig_r_len,4].unpack("H*")[0].to_i(16)
+
+ sig_r = sig[4,sig_r_len].unpack("H*")[0]
+ sig_s = sig[4+sig_r_len+4,sig_l_len].unpack("H*")[0]
+
+ a1sig = OpenSSL::ASN1::Sequence([
+ OpenSSL::ASN1::Integer(sig_r.to_i(16)),
+ OpenSSL::ASN1::Integer(sig_s.to_i(16)),
+ ])
+ rescue
+ end
+
+ if a1sig == nil
+ return false
+ else
+ dsa_verify_asn1(digest, a1sig.to_der)
+ end
+ end
+
+ # Returns the signature for the given data.
+ def ssh_do_sign(data)
+ digest = digester.digest(data)
+ sig = dsa_sign_asn1(digest)
+ a1sig = OpenSSL::ASN1.decode( sig )
+
+ sig_r = a1sig.value[0].value
+ sig_s = a1sig.value[1].value
+
+ return Net::SSH::Buffer.from(:bignum, sig_r, :bignum, sig_s).to_s
+ end
+ end
+ else
+ class OpenSSL::PKey::ECError < RuntimeError
+ # for compatibility with interpreters
+ # without EC support (i.e. JRuby)
+ end
+ end
+ end
end
View
261 net-ssh.gemspec
@@ -24,134 +24,137 @@
# = MANIFEST =
s.files = %w(
CHANGELOG.rdoc
-Manifest
-README.rdoc
-Rakefile
-Rudyfile
-THANKS.rdoc
-lib/net/ssh.rb
-lib/net/ssh/authentication/agent.rb
-lib/net/ssh/authentication/agent/java_pageant.rb
-lib/net/ssh/authentication/agent/socket.rb
-lib/net/ssh/authentication/constants.rb
-lib/net/ssh/authentication/key_manager.rb
-lib/net/ssh/authentication/methods/abstract.rb
-lib/net/ssh/authentication/methods/hostbased.rb
-lib/net/ssh/authentication/methods/keyboard_interactive.rb
-lib/net/ssh/authentication/methods/password.rb
-lib/net/ssh/authentication/methods/publickey.rb
-lib/net/ssh/authentication/pageant.rb
-lib/net/ssh/authentication/session.rb
-lib/net/ssh/buffer.rb
-lib/net/ssh/buffered_io.rb
-lib/net/ssh/config.rb
-lib/net/ssh/connection/channel.rb
-lib/net/ssh/connection/constants.rb
-lib/net/ssh/connection/session.rb
-lib/net/ssh/connection/term.rb
-lib/net/ssh/errors.rb
-lib/net/ssh/key_factory.rb
-lib/net/ssh/known_hosts.rb
-lib/net/ssh/loggable.rb
-lib/net/ssh/packet.rb
-lib/net/ssh/prompt.rb
-lib/net/ssh/proxy/command.rb
-lib/net/ssh/proxy/errors.rb
-lib/net/ssh/proxy/http.rb
-lib/net/ssh/proxy/socks4.rb
-lib/net/ssh/proxy/socks5.rb
-lib/net/ssh/ruby_compat.rb
-lib/net/ssh/service/forward.rb
-lib/net/ssh/test.rb
-lib/net/ssh/test/channel.rb
-lib/net/ssh/test/extensions.rb
-lib/net/ssh/test/kex.rb
-lib/net/ssh/test/local_packet.rb
-lib/net/ssh/test/packet.rb
-lib/net/ssh/test/remote_packet.rb
-lib/net/ssh/test/script.rb
-lib/net/ssh/test/socket.rb
-lib/net/ssh/transport/algorithms.rb
-lib/net/ssh/transport/cipher_factory.rb
-lib/net/ssh/transport/constants.rb
-lib/net/ssh/transport/hmac.rb
-lib/net/ssh/transport/hmac/abstract.rb
-lib/net/ssh/transport/hmac/md5.rb
-lib/net/ssh/transport/hmac/md5_96.rb
-lib/net/ssh/transport/hmac/none.rb
-lib/net/ssh/transport/hmac/sha1.rb
-lib/net/ssh/transport/hmac/sha1_96.rb
-lib/net/ssh/transport/hmac/sha2_256.rb
-lib/net/ssh/transport/hmac/sha2_256_96.rb
-lib/net/ssh/transport/hmac/sha2_512.rb
-lib/net/ssh/transport/hmac/sha2_512_96.rb
-lib/net/ssh/transport/identity_cipher.rb
-lib/net/ssh/transport/kex.rb
-lib/net/ssh/transport/kex/diffie_hellman_group1_sha1.rb
-lib/net/ssh/transport/kex/diffie_hellman_group_exchange_sha1.rb
-lib/net/ssh/transport/kex/diffie_hellman_group_exchange_sha256.rb
-lib/net/ssh/transport/key_expander.rb
-lib/net/ssh/transport/openssl.rb
-lib/net/ssh/transport/packet_stream.rb
-lib/net/ssh/transport/server_version.rb
-lib/net/ssh/transport/session.rb
-lib/net/ssh/transport/state.rb
-lib/net/ssh/verifiers/lenient.rb
-lib/net/ssh/verifiers/null.rb
-lib/net/ssh/verifiers/strict.rb
-lib/net/ssh/version.rb
-net-ssh.gemspec
-setup.rb
-support/arcfour_check.rb
-support/ssh_tunnel_bug.rb
-test/README.txt
-test/authentication/methods/common.rb
-test/authentication/methods/test_abstract.rb
-test/authentication/methods/test_hostbased.rb
-test/authentication/methods/test_keyboard_interactive.rb
-test/authentication/methods/test_password.rb
-test/authentication/methods/test_publickey.rb
-test/authentication/test_agent.rb
-test/authentication/test_key_manager.rb
-test/authentication/test_session.rb
-test/common.rb
-test/configs/eqsign
-test/configs/exact_match
-test/configs/host_plus
-test/configs/multihost
-test/configs/nohost
-test/configs/numeric_host
-test/configs/wild_cards
-test/connection/test_channel.rb
-test/connection/test_session.rb
-test/manual/test_forward.rb
-test/start/test_transport.rb
-test/test_all.rb
-test/test_buffer.rb
-test/test_buffered_io.rb
-test/test_config.rb
-test/test_key_factory.rb
-test/transport/hmac/test_md5.rb
-test/transport/hmac/test_md5_96.rb
-test/transport/hmac/test_none.rb
-test/transport/hmac/test_sha1.rb
-test/transport/hmac/test_sha1_96.rb
-test/transport/hmac/test_sha2_256.rb
-test/transport/hmac/test_sha2_256_96.rb
-test/transport/hmac/test_sha2_512.rb
-test/transport/hmac/test_sha2_512_96.rb
-test/transport/kex/test_diffie_hellman_group1_sha1.rb
-test/transport/kex/test_diffie_hellman_group_exchange_sha1.rb
-test/transport/kex/test_diffie_hellman_group_exchange_sha256.rb
-test/transport/test_algorithms.rb
-test/transport/test_cipher_factory.rb
-test/transport/test_hmac.rb
-test/transport/test_identity_cipher.rb
-test/transport/test_packet_stream.rb
-test/transport/test_server_version.rb
-test/transport/test_session.rb
-test/transport/test_state.rb
-)
-
+ Manifest
+ README.rdoc
+ Rakefile
+ Rudyfile
+ THANKS.rdoc
+ lib/net/ssh.rb
+ lib/net/ssh/authentication/agent.rb
+ lib/net/ssh/authentication/constants.rb
+ lib/net/ssh/authentication/key_manager.rb
+ lib/net/ssh/authentication/methods/abstract.rb
+ lib/net/ssh/authentication/methods/hostbased.rb
+ lib/net/ssh/authentication/methods/keyboard_interactive.rb
+ lib/net/ssh/authentication/methods/password.rb
+ lib/net/ssh/authentication/methods/publickey.rb
+ lib/net/ssh/authentication/pageant.rb
+ lib/net/ssh/authentication/session.rb
+ lib/net/ssh/buffer.rb
+ lib/net/ssh/buffered_io.rb
+ lib/net/ssh/config.rb
+ lib/net/ssh/connection/channel.rb
+ lib/net/ssh/connection/constants.rb
+ lib/net/ssh/connection/session.rb
+ lib/net/ssh/connection/term.rb
+ lib/net/ssh/errors.rb
+ lib/net/ssh/key_factory.rb
+ lib/net/ssh/known_hosts.rb
+ lib/net/ssh/loggable.rb
+ lib/net/ssh/packet.rb
+ lib/net/ssh/prompt.rb
+ lib/net/ssh/proxy/command.rb
+ lib/net/ssh/proxy/errors.rb
+ lib/net/ssh/proxy/http.rb
+ lib/net/ssh/proxy/socks4.rb
+ lib/net/ssh/proxy/socks5.rb
+ lib/net/ssh/ruby_compat.rb
+ lib/net/ssh/service/forward.rb
+ lib/net/ssh/test.rb
+ lib/net/ssh/test/channel.rb
+ lib/net/ssh/test/extensions.rb
+ lib/net/ssh/test/kex.rb
+ lib/net/ssh/test/local_packet.rb
+ lib/net/ssh/test/packet.rb
+ lib/net/ssh/test/remote_packet.rb
+ lib/net/ssh/test/script.rb
+ lib/net/ssh/test/socket.rb
+ lib/net/ssh/transport/algorithms.rb
+ lib/net/ssh/transport/cipher_factory.rb
+ lib/net/ssh/transport/constants.rb
+ lib/net/ssh/transport/ctr.rb
+ lib/net/ssh/transport/hmac.rb
+ lib/net/ssh/transport/hmac/abstract.rb
+ lib/net/ssh/transport/hmac/md5.rb
+ lib/net/ssh/transport/hmac/md5_96.rb
+ lib/net/ssh/transport/hmac/none.rb
+ lib/net/ssh/transport/hmac/ripemd160.rb
+ lib/net/ssh/transport/hmac/sha1.rb
+ lib/net/ssh/transport/hmac/sha1_96.rb
+ lib/net/ssh/transport/hmac/sha2_256.rb
+ lib/net/ssh/transport/hmac/sha2_256_96.rb
+ lib/net/ssh/transport/hmac/sha2_512.rb
+ lib/net/ssh/transport/hmac/sha2_512_96.rb
+ lib/net/ssh/transport/identity_cipher.rb
+ lib/net/ssh/transport/key_expander.rb
+ lib/net/ssh/transport/kex.rb
+ lib/net/ssh/transport/kex/diffie_hellman_group1_sha1.rb
+ lib/net/ssh/transport/kex/diffie_hellman_group14_sha1.rb
+ lib/net/ssh/transport/kex/diffie_hellman_group_exchange_sha1.rb
+ lib/net/ssh/transport/kex/diffie_hellman_group_exchange_sha256.rb
+ lib/net/ssh/transport/kex/ecdh_sha2_nistp256.rb
+ lib/net/ssh/transport/kex/ecdh_sha2_nistp384.rb
+ lib/net/ssh/transport/kex/ecdh_sha2_nistp521.rb
+ lib/net/ssh/transport/openssl.rb
+ lib/net/ssh/transport/packet_stream.rb
+ lib/net/ssh/transport/server_version.rb
+ lib/net/ssh/transport/session.rb
+ lib/net/ssh/transport/state.rb
+ lib/net/ssh/verifiers/lenient.rb
+ lib/net/ssh/verifiers/null.rb
+ lib/net/ssh/verifiers/strict.rb
+ lib/net/ssh/version.rb
+ net-ssh.gemspec
+ setup.rb
+ support/arcfour_check.rb
+ support/ssh_tunnel_bug.rb
+ test/authentication/methods/common.rb
+ test/authentication/methods/test_abstract.rb
+ test/authentication/methods/test_hostbased.rb
+ test/authentication/methods/test_keyboard_interactive.rb
+ test/authentication/methods/test_password.rb
+ test/authentication/methods/test_publickey.rb
+ test/authentication/test_agent.rb
+ test/authentication/test_key_manager.rb
+ test/authentication/test_session.rb
+ test/common.rb
+ test/configs/eqsign
+ test/configs/exact_match
+ test/configs/host_plus
+ test/configs/multihost
+ test/configs/wild_cards
+ test/connection/test_channel.rb
+ test/connection/test_session.rb
+ test/test_all.rb
+ test/test_buffer.rb
+ test/test_buffered_io.rb
+ test/test_config.rb
+ test/test_key_factory.rb
+ test/transport/hmac/test_md5.rb
+ test/transport/hmac/test_md5_96.rb
+ test/transport/hmac/test_none.rb
+ test/transport/hmac/test_ripemd160.rb
+ test/transport/hmac/test_sha1.rb
+ test/transport/hmac/test_sha1_96.rb
+ test/transport/hmac/test_sha2_256.rb
+ test/transport/hmac/test_sha2_256_96.rb
+ test/transport/hmac/test_sha2_512.rb
+ test/transport/hmac/test_sha2_512_96.rb
+ test/transport/kex/test_diffie_hellman_group1_sha1.rb
+ test/transport/kex/test_diffie_hellman_group14_sha1.rb
+ test/transport/kex/test_diffie_hellman_group_exchange_sha1.rb
+ test/transport/kex/test_diffie_hellman_group_exchange_sha256.rb
+ test/transport/kex/test_ecdh_sha2_nistp256.rb
+ test/transport/kex/test_ecdh_sha2_nistp384.rb
+ test/transport/kex/test_ecdh_sha2_nistp521.rb
+ test/transport/test_algorithms.rb
+ test/transport/test_cipher_factory.rb
+ test/transport/test_hmac.rb
+ test/transport/test_identity_cipher.rb
+ test/transport/test_packet_stream.rb
+ test/transport/test_server_version.rb
+ test/transport/test_session.rb
+ test/transport/test_state.rb
+ )
end
View
49 test/authentication/test_key_manager.rb
@@ -62,6 +62,28 @@ def test_identities_should_load_from_agent
assert_equal({:from => :agent}, manager.known_identities[dsa])
end
+ if defined?(OpenSSL::PKey::EC)
+ def test_identities_with_ecdsa_should_load_from_agent
+ manager.stubs(:agent).returns(agent_with_ecdsa_keys)
+
+ identities = []
+ manager.each_identity { |identity| identities << identity }
+ assert_equal 5, identities.length
+
+ assert_equal rsa.to_blob, identities[0].to_blob
+ assert_equal dsa.to_blob, identities[1].to_blob
+ assert_equal ecdsa_sha2_nistp256.to_blob, identities[2].to_blob
+ assert_equal ecdsa_sha2_nistp384.to_blob, identities[3].to_blob
+ assert_equal ecdsa_sha2_nistp521.to_blob, identities[4].to_blob
+
+ assert_equal({:from => :agent}, manager.known_identities[rsa])
+ assert_equal({:from => :agent}, manager.known_identities[dsa])
+ assert_equal({:from => :agent}, manager.known_identities[ecdsa_sha2_nistp256])
+ assert_equal({:from => :agent}, manager.known_identities[ecdsa_sha2_nistp384])
+ assert_equal({:from => :agent}, manager.known_identities[ecdsa_sha2_nistp521])
+ end
+ end
+
def test_only_identities_with_key_files_should_load_from_agent_of_keys_only_set
manager(:keys_only => true).stubs(:agent).returns(agent)
@@ -139,7 +161,11 @@ def stub_file_private_key(name, key, options = {})
Net::SSH::KeyFactory.expects(:load_private_key).with(name, nil, any_of(true, false)).returns(key).at_least_once
end
- key.stubs(:public_key).returns(key)
+ # do not override OpenSSL::PKey::EC#public_key
+ # (it will be called in transport/openssl.rb.)
+ unless defined?(OpenSSL::PKey::EC) && key.public_key.kind_of?(OpenSSL::PKey::EC::Point)
+ key.stubs(:public_key).returns(key)
+ end
end
def stub_file_public_key(name, key)
@@ -158,10 +184,31 @@ def dsa
@dsa ||= OpenSSL::PKey::DSA.new(512)
end
+ if defined?(OpenSSL::PKey::EC)
+ def ecdsa_sha2_nistp256
+ @ecdsa_sha2_nistp256 ||= OpenSSL::PKey::EC.new("prime256v1").generate_key
+ end
+
+ def ecdsa_sha2_nistp384
+ @ecdsa_sha2_nistp384 ||= OpenSSL::PKey::EC.new("secp384r1").generate_key
+ end
+
+ def ecdsa_sha2_nistp521
+ @ecdsa_sha2_nistp521 ||= OpenSSL::PKey::EC.new("secp521r1").generate_key
+ end
+ end
+
def agent
@agent ||= stub("agent", :identities => [rsa, dsa])
end
+ def agent_with_ecdsa_keys
+ @agent ||= stub("agent", :identities => [rsa, dsa,
+ ecdsa_sha2_nistp256,
+ ecdsa_sha2_nistp384,
+ ecdsa_sha2_nistp521])
+ end
+
def manager(options = {})
@manager ||= Net::SSH::Authentication::KeyManager.new(nil, options)
end
View
2 test/manual/test_forward.rb
@@ -27,7 +27,7 @@ def localhost
end
def ssh_start_params
- [localhost ,ENV['USER']] #:verbose => :debug
+ [localhost ,ENV['USER'], {:keys => "~/.ssh/id_rsa", :verbose => :debug}]
end
def find_free_port
View
94 test/test_buffer.rb
@@ -290,7 +290,7 @@ def test_write_dss_key_should_write_argument_to_end_of_buffer
key.pub_key = 0xeeccaa8866442200
buffer.write_key(key)
- 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
+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
end
def test_write_rsa_key_should_write_argument_to_end_of_buffer
@@ -304,6 +304,67 @@ def test_write_rsa_key_should_write_argument_to_end_of_buffer
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
end
+ if defined?(OpenSSL::PKey::EC)
+ def test_read_key_blob_should_read_ecdsa_sha2_nistp256_keys
+ random_ecdsa_sha2_nistp256 { |buffer|
+ buffer.read_keyblob("ecdsa-sha2-nistp256")
+ }
+ end
+ def test_read_key_blob_should_read_ecdsa_sha2_nistp384_keys
+ random_ecdsa_sha2_nistp384 { |buffer|
+ buffer.read_keyblob("ecdsa-sha2-nistp384")
+ }
+ end
+ def test_read_key_blob_should_read_ecdsa_sha2_nistp521_keys
+ random_ecdsa_sha2_nistp521 { |buffer|
+ buffer.read_keyblob("ecdsa-sha2-nistp521")
+ }
+ end
+
+ def test_read_key_should_read_ecdsa_sha2_nistp256_key_type_and_keyblob
+ random_ecdsa_sha2_nistp256 do |buffer|
+ b2 = Net::SSH::Buffer.from(:string, "ecdsa-sha2-nistp256", :raw, buffer)
+ b2.read_key
+ end
+ end
+ def test_read_key_should_read_ecdsa_sha2_nistp384_key_type_and_keyblob
+ random_ecdsa_sha2_nistp384 do |buffer|
+ b2 = Net::SSH::Buffer.from(:string, "ecdsa-sha2-nistp384", :raw, buffer)
+ b2.read_key
+ end
+ end
+ def test_read_key_should_read_ecdsa_sha2_nistp521_key_type_and_keyblob
+ random_ecdsa_sha2_nistp521 do |buffer|
+ b2 = Net::SSH::Buffer.from(:string, "ecdsa-sha2-nistp521", :raw, buffer)
+ b2.read_key
+ end
+ end
+
+ def test_write_ecdsa_sha2_nistp256_key_should_write_argument_to_end_of_buffer
+ buffer = new("start")
+ key = OpenSSL::PKey::EC.new("-----BEGIN EC PRIVATE KEY-----\nMHcCAQEEIISGj5vAJCWt2KPI8NwaWVDSNLl2vbRxDIOkY+n6O0VVoAoGCCqGSM49\nAwEHoUQDQgAEnKbs0yEogTKT4QRu8T9nb2svl2mEWXb6g224oCpD2o6TYNXNw54H\nmWkdCv+kFCqSlfSi5fqFhrXdfEY6zSzQYQ==\n-----END EC PRIVATE KEY-----\n")
+
+ buffer.write_key(key)
+ 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
+ end
+
+ def test_write_ecdsa_sha2_nistp384_key_should_write_argument_to_end_of_buffer
+ buffer = new("start")
+ key = OpenSSL::PKey::EC.new("-----BEGIN EC PRIVATE KEY-----\nMIGkAgEBBDBAfxJpzhsR7O+wMol6BcDgualR8rJBvYegUDYbBUrDnPzDx2/gD1lZ\nnwG1FuD2s9igBwYFK4EEACKhZANiAATsfiU4Kxyvvj1DdvFYsdDnZIT7loRlan9I\n8geCWPPl6x7NFRP+awrnTaarMgieGqxG8IQaIA0SsDOICfbDBkuatRi0S1Et/in4\nZwVEZvO81Ro5YSrjuUDAsytnI6OXS28=\n-----END EC PRIVATE KEY-----\n")
+
+ buffer.write_key(key)
+ 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
+ end
+
+ def test_write_ecdsa_sha2_nistp521_key_should_write_argument_to_end_of_buffer
+ buffer = new("start")
+ 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")
+
+ buffer.write_key(key)
+ 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
+ end
+ end
+
private
def random_rsa
@@ -330,7 +391,36 @@ def random_dss
assert_equal n4, key.pub_key
end
+ if defined?(OpenSSL::PKey::EC)
+ def random_ecdsa_sha2_nistp256
+ k = OpenSSL::PKey::EC.new("prime256v1").generate_key
+ buffer = Net::SSH::Buffer.from(:string, "nistp256",
+ :string, k.public_key.to_bn.to_s(2))
+ key = yield(buffer)
+ assert_equal "ecdsa-sha2-nistp256", key.ssh_type
+ assert_equal k.public_key, key.public_key
+ end
+
+ def random_ecdsa_sha2_nistp384
+ k = OpenSSL::PKey::EC.new("secp384r1").generate_key
+ buffer = Net::SSH::Buffer.from(:string, "nistp384",
+ :string, k.public_key.to_bn.to_s(2))
+ key = yield(buffer)
+ assert_equal "ecdsa-sha2-nistp384", key.ssh_type
+ assert_equal k.public_key, key.public_key
+ end
+
+ def random_ecdsa_sha2_nistp521
+ k = OpenSSL::PKey::EC.new("secp521r1").generate_key
+ buffer = Net::SSH::Buffer.from(:string, "nistp521",
+ :string, k.public_key.to_bn.to_s(2))
+ key = yield(buffer)
+ assert_equal "ecdsa-sha2-nistp521", key.ssh_type
+ assert_equal k.public_key, key.public_key
+ end
+ end
+
def new(*args)
Net::SSH::Buffer.new(*args)
end
-end
+end
View
42 test/test_key_factory.rb
@@ -55,6 +55,34 @@ def test_load_public_rsa_key_should_return_key
assert_equal rsa_key.to_blob, Net::SSH::KeyFactory.load_public_key(@key_file).to_blob
end
+ if defined?(OpenSSL::PKey::EC)
+ def test_load_unencrypted_private_ecdsa_sha2_nistp256_key_should_return_key
+ File.expects(:read).with("/key-file").returns(ecdsa_sha2_nistp256_key.to_pem)
+ assert_equal ecdsa_sha2_nistp256_key.to_der, Net::SSH::KeyFactory.load_private_key("/key-file").to_der
+ end
+ def test_load_unencrypted_private_ecdsa_sha2_nistp384_key_should_return_key
+ File.expects(:read).with("/key-file").returns(ecdsa_sha2_nistp384_key.to_pem)
+ assert_equal ecdsa_sha2_nistp384_key.to_der, Net::SSH::KeyFactory.load_private_key("/key-file").to_der
+ end
+ def test_load_unencrypted_private_ecdsa_sha2_nistp521_key_should_return_key
+ File.expects(:read).with("/key-file").returns(ecdsa_sha2_nistp521_key.to_pem)
+ assert_equal ecdsa_sha2_nistp521_key.to_der, Net::SSH::KeyFactory.load_private_key("/key-file").to_der
+ end
+
+ def test_load_public_ecdsa_sha2_nistp256_key_should_return_key
+ File.expects(:read).with("/key-file").returns(public(ecdsa_sha2_nistp256_key))
+ assert_equal ecdsa_sha2_nistp256_key.to_blob, Net::SSH::KeyFactory.load_public_key("/key-file").to_blob
+ end
+ def test_load_public_ecdsa_sha2_nistp384_key_should_return_key
+ File.expects(:read).with("/key-file").returns(public(ecdsa_sha2_nistp384_key))
+ assert_equal ecdsa_sha2_nistp384_key.to_blob, Net::SSH::KeyFactory.load_public_key("/key-file").to_blob
+ end
+ def test_load_public_ecdsa_sha2_nistp521_key_should_return_key
+ File.expects(:read).with("/key-file").returns(public(ecdsa_sha2_nistp521_key))
+ assert_equal ecdsa_sha2_nistp521_key.to_blob, Net::SSH::KeyFactory.load_public_key("/key-file").to_blob
+ end
+ end
+
private
def rsa_key
@@ -67,6 +95,20 @@ def dsa_key
@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")
end
+ if defined?(OpenSSL::PKey::EC)
+ def ecdsa_sha2_nistp256_key
+ @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")
+ end
+
+ def ecdsa_sha2_nistp384_key
+ @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")
+ end
+
+ def ecdsa_sha2_nistp521_key
+ @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")
+ end
+ end
+
def encrypted(key, password)
key.export(OpenSSL::Cipher::Cipher.new("des-ede3-cbc"), password)
end
View
34 test/transport/hmac/test_ripemd160.rb
@@ -0,0 +1,34 @@
+require 'common'
+require 'net/ssh/transport/hmac/ripemd160'
+
+module Transport; module HMAC
+
+ class TestRipemd160 < Test::Unit::TestCase
+ def test_expected_digest_class
+ assert_equal OpenSSL::Digest::RIPEMD160, subject.digest_class
+ assert_equal OpenSSL::Digest::RIPEMD160, subject.new.digest_class
+ end
+
+ def test_expected_key_length
+ assert_equal 20, subject.key_length
+ assert_equal 20, subject.new.key_length
+ end
+
+ def test_expected_mac_length
+ assert_equal 20, subject.mac_length
+ assert_equal 20, subject.new.mac_length
+ end
+
+ def test_expected_digest
+ hmac = subject.new("1234567890123456")
+ assert_equal "\xE4\x10\t\xB3\xD8,\x14\xA0k\x10\xB5\x0F?\x0E\x96q\x02\x16;E", hmac.digest("hello world")
+ end
+
+ private
+
+ def subject
+ Net::SSH::Transport::HMAC::RIPEMD160
+ end
+ end
+
+end; end
View
13 test/transport/kex/test_diffie_hellman_group14_sha1.rb
@@ -0,0 +1,13 @@
+require 'common'
+require 'net/ssh/transport/kex/diffie_hellman_group14_sha1'
+require 'transport/kex/test_diffie_hellman_group1_sha1'
+require 'ostruct'
+
+module Transport; module Kex
+
+ class TestDiffieHellmanGroup14SHA1 < TestDiffieHellmanGroup1SHA1
+ def subject
+ Net::SSH::Transport::Kex::DiffieHellmanGroup14SHA1
+ end
+ end
+end; end
View
161 test/transport/kex/test_ecdh_sha2_nistp256.rb
@@ -0,0 +1,161 @@
+require 'openssl'
+
+unless defined?(OpenSSL::PKey::EC)
+ puts "Skipping tests for ecdh-sha2-nistp256 key exchange"
+else
+ require 'common'
+ require 'transport/kex/test_diffie_hellman_group1_sha1'
+ require 'net/ssh/transport/kex/ecdh_sha2_nistp256'
+ require 'ostruct'
+
+ module Transport; module Kex
+
+ class TestEcdhSHA2NistP256 < Test::Unit::TestCase
+ include Net::SSH::Transport::Constants
+
+ def setup
+ @ecdh = @algorithms = @connection = @server_key =
+ @packet_data = @shared_secret = nil
+ end
+
+ def test_exchange_keys_should_return_expected_results_when_successful
+ result = exchange!
+ assert_equal session_id, result[:session_id]
+ assert_equal server_host_key.to_blob, result[:server_key].to_blob
+ assert_equal shared_secret, result[:shared_secret]
+ assert_equal digester, result[:hashing_algorithm]
+ end
+
+ def test_exchange_keys_with_unverifiable_host_should_raise_exception
+ connection.verifier { false }
+ assert_raises(Net::SSH::Exception) { exchange! }
+ end
+
+ def test_exchange_keys_with_signature_key_type_mismatch_should_raise_exception
+ assert_raises(Net::SSH::Exception) { exchange! :key_type => "ssh-dss" }
+ end
+
+ def test_exchange_keys_with_host_key_type_mismatch_should_raise_exception
+ algorithms :host_key => "ssh-dss"
+ assert_raises(Net::SSH::Exception) { exchange! :key_type => "ssh-dss" }
+ end
+
+ def test_exchange_keys_when_server_signature_could_not_be_verified_should_raise_exception
+ @signature = "1234567890"
+ assert_raises(Net::SSH::Exception) { exchange! }
+ end
+
+ def test_exchange_keys_should_pass_expected_parameters_to_host_key_verifier
+ verified = false
+ connection.verifier do |data|
+ verified = true
+ assert_equal server_host_key.to_blob, data[:key].to_blob
+
+ blob = b(:key, data[:key]).to_s
+ fingerprint = OpenSSL::Digest::MD5.hexdigest(blob).scan(/../).join(":")
+
+ assert_equal blob, data[:key_blob]
+ assert_equal fingerprint, data[:fingerprint]
+ assert_equal connection, data[:session]
+
+ true
+ end
+
+ assert_nothing_raised { exchange! }
+ assert verified
+ end
+
+ private
+
+ def digester
+ OpenSSL::Digest::SHA256
+ end
+
+ def subject
+ Net::SSH::Transport::Kex::EcdhSHA2NistP256
+ end
+
+ def ecparam
+ "prime256v1"
+ end
+
+ def key_type
+ "ecdsa-sha2-nistp256"
+ end
+
+ def exchange!(options={})
+ connection.expect do |t, buffer|
+ assert_equal KEXECDH_INIT, buffer.type
+ assert_equal ecdh.ecdh.public_key.to_bn.to_s(2), buffer.read_string
+ t.return(KEXECDH_REPLY,
+ :string, b(:key, server_host_key),
+ :string, server_ecdh_pubkey.to_bn.to_s(2),
+ :string, b(:string, options[:key_type] || key_type,
+ :string, signature))
+ connection.expect do |t2, buffer2|
+ assert_equal NEWKEYS, buffer2.type
+ t2.return(NEWKEYS)
+ end
+ end
+ ecdh.exchange_keys
+ end
+
+ def ecdh
+ @ecdh ||= subject.new(algorithms, connection, packet_data)
+ end
+
+ def algorithms(options={})
+ @algorithms ||= OpenStruct.new(:host_key => options[:server_host_key] || "ecdsa-sha2-nistp256")
+ end
+
+ def connection
+ @connection ||= MockTransport.new
+ end
+
+ def server_key
+ @server_key ||= OpenSSL::PKey::EC.new(ecparam).generate_key
+ end
+
+ def server_host_key
+ @server_host_key ||= OpenSSL::PKey::EC.new("prime256v1").generate_key
+ end
+
+ def packet_data
+ @packet_data ||= { :client_version_string => "client version string",
+ :server_version_string => "server version string",
+ :server_algorithm_packet => "server algorithm packet",
+ :client_algorithm_packet => "client algorithm packet" }
+ end
+
+ def server_ecdh_pubkey
+ @server_ecdh_pubkey ||= server_key.public_key
+ end
+
+ def shared_secret
+ @shared_secret ||= OpenSSL::BN.new(ecdh.ecdh.dh_compute_key(server_ecdh_pubkey), 2)
+ end
+
+ def session_id
+ @session_id ||= begin
+ buffer = Net::SSH::Buffer.from(:string, packet_data[:client_version_string],
+ :string, packet_data[:server_version_string],
+ :string, packet_data[:client_algorithm_packet],
+ :string, packet_data[:server_algorithm_packet],
+ :string, Net::SSH::Buffer.from(:key, server_host_key),
+ :string, ecdh.ecdh.public_key.to_bn.to_s(2),
+ :string, server_ecdh_pubkey.to_bn.to_s(2),
+ :bignum, shared_secret)
+ digester.digest(buffer.to_s)
+ end
+ end
+
+ def signature
+ @signature ||= server_host_key.ssh_do_sign(session_id)
+ end
+
+ def b(*args)
+ Net::SSH::Buffer.from(*args)
+ end
+ end
+ end; end;
+end
View
37 test/transport/kex/test_ecdh_sha2_nistp384.rb
@@ -0,0 +1,37 @@
+require 'openssl'
+
+unless defined?(OpenSSL::PKey::EC)
+ puts "Skipping tests for ecdh-sha2-nistp384 key exchange"
+else
+ module Transport; module Kex
+ class TestEcdhSHA2NistP384 < TestEcdhSHA2NistP256
+
+ def setup
+ @ecdh = @algorithms = @connection = @server_key =
+ @packet_data = @shared_secret = nil
+ end
+
+ def test_exchange_keys_should_return_expected_results_when_successful
+ result = exchange!
+ assert_equal session_id, result[:session_id]
+ assert_equal server_host_key.to_blob, result[:server_key].to_blob
+ assert_equal shared_secret, result[:shared_secret]
+ assert_equal digester, result[:hashing_algorithm]
+ end
+
+ private
+
+ def digester
+ OpenSSL::Digest::SHA384
+ end
+
+ def subject
+ Net::SSH::Transport::Kex::EcdhSHA2NistP384
+ end
+
+ def ecparam
+ "secp384r1"
+ end
+ end
+ end; end
+ end
View
37 test/transport/kex/test_ecdh_sha2_nistp521.rb
@@ -0,0 +1,37 @@
+require 'openssl'
+
+unless defined?(OpenSSL::PKey::EC)
+ puts "Skipping tests for ecdh-sha2-nistp521 key exchange"
+else
+ module Transport; module Kex
+ class TestEcdhSHA2NistP521 < TestEcdhSHA2NistP256
+
+ def setup
+ @ecdh = @algorithms = @connection = @server_key =
+ @packet_data = @shared_secret = nil
+ end
+
+ def test_exchange_keys_should_return_expected_results_when_successful
+ result = exchange!
+ assert_equal session_id, result[:session_id]
+ assert_equal server_host_key.to_blob, result[:server_key].to_blob
+ assert_equal shared_secret, result[:shared_secret]
+ assert_equal digester, result[:hashing_algorithm]
+ end
+
+ private
+
+ def digester
+ OpenSSL::Digest::SHA512
+ end
+
+ def subject
+ Net::SSH::Transport::Kex::EcdhSHA2NistP521
+ end
+
+ def ecparam
+ "secp521r1"
+ end
+ end
+ end; end
+end
View
60 test/transport/test_algorithms.rb
@@ -17,13 +17,18 @@ def test_allowed_packets
end
def test_constructor_should_build_default_list_of_preferred_algorithms
- assert_equal %w(ssh-rsa ssh-dss), algorithms[:host_key]
- assert_equal %w(diffie-hellman-group-exchange-sha1 diffie-hellman-group1-sha1 diffie-hellman-group-exchange-sha256), algorithms[:kex]
- assert_equal %w(aes128-cbc 3des-cbc blowfish-cbc cast128-cbc aes192-cbc aes256-cbc rijndael-cbc@lysator.liu.se idea-cbc none arcfour128 arcfour256), algorithms[:encryption]
+ if defined?(OpenSSL::PKey::EC)
+ assert_equal %w(ssh-rsa ssh-dss ecdsa-sha2-nistp256 ecdsa-sha2-nistp384 ecdsa-sha2-nistp521), algorithms[:host_key]
+ assert_equal %w(diffie-hellman-group-exchange-sha1 diffie-hellman-group1-sha1 diffie-hellman-group14-sha1 diffie-hellman-group-exchange-sha256 ecdh-sha2-nistp256 ecdh-sha2-nistp384 ecdh-sha2-nistp521), algorithms[:kex]
+ else
+ assert_equal %w(ssh-rsa ssh-dss), algorithms[:host_key]
+ assert_equal %w(diffie-hellman-group-exchange-sha1 diffie-hellman-group1-sha1 diffie-hellman-group14-sha1 diffie-hellman-group-exchange-sha256), algorithms[:kex]
+ end
+ assert_equal %w(aes128-cbc 3des-cbc blowfish-cbc cast128-cbc aes192-cbc aes256-cbc rijndael-cbc@lysator.liu.se idea-cbc none arcfour128 arcfour256 arcfour aes128-ctr aes192-ctr aes256-ctr camellia128-cbc camellia192-cbc camellia256-cbc camellia128-cbc@openssh.org camellia192-cbc@openssh.org camellia256-cbc@openssh.org camellia128-ctr camellia192-ctr camellia256-ctr camellia128-ctr@openssh.org camellia192-ctr@openssh.org camellia256-ctr@openssh.org cast128-ctr blowfish-ctr 3des-ctr), algorithms[:encryption]
if defined?(OpenSSL::Digest::SHA256)
- assert_equal %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), algorithms[:hmac]
+ assert_equal %w(hmac-sha1 hmac-md5 hmac-sha1-96 hmac-md5-96 hmac-ripemd160 hmac-ripemd160@openssh.com hmac-sha2-256 hmac-sha2-512 hmac-sha2-256-96 hmac-sha2-512-96 none), algorithms[:hmac]
else
- assert_equal %w(hmac-sha1 hmac-md5 hmac-sha1-96 hmac-md5-96 none), algorithms[:hmac]
+ assert_equal %w(hmac-sha1 hmac-md5 hmac-sha1-96 hmac-md5-96 hmac-ripemd160 hmac-ripemd160@openssh.com none), algorithms[:hmac]
end
assert_equal %w(none zlib@openssh.com zlib), algorithms[:compression]
assert_equal %w(), algorithms[:language]
@@ -37,44 +42,56 @@ def test_constructor_should_set_client_and_server_prefs_identically
end
def test_constructor_with_preferred_host_key_type_should_put_preferred_host_key_type_first
- assert_equal %w(ssh-dss ssh-rsa), algorithms(:host_key => "ssh-dss")[:host_key]
+ if defined?(OpenSSL::PKey::EC)
+ assert_equal %w(ssh-dss ssh-rsa ecdsa-sha2-nistp256 ecdsa-sha2-nistp384 ecdsa-sha2-nistp521), algorithms(:host_key => "ssh-dss")[:host_key]
+ else
+ assert_equal %w(ssh-dss ssh-rsa), algorithms(:host_key => "ssh-dss")[:host_key]
+ end
end
def test_constructor_with_known_hosts_reporting_known_host_key_should_use_that_host_key_type
Net::SSH::KnownHosts.expects(:search_for).with("net.ssh.test,127.0.0.1", {}).returns([stub("key", :ssh_type => "ssh-dss")])
- assert_equal %w(ssh-dss ssh-rsa), algorithms[:host_key]
+ if defined?(OpenSSL::PKey::EC)
+ assert_equal %w(ssh-dss ssh-rsa ecdsa-sha2-nistp256 ecdsa-sha2-nistp384 ecdsa-sha2-nistp521), algorithms[:host_key]
+ else
+ assert_equal %w(ssh-dss ssh-rsa), algorithms[:host_key]
+ end
end
def test_constructor_with_unrecognized_host_key_type_should_raise_exception
assert_raises(NotImplementedError) { algorithms(:host_key => "bogus") }
end
def test_constructor_with_preferred_kex_should_put_preferred_kex_first
- assert_equal %w(diffie-hellman-group1-sha1 diffie-hellman-group-exchange-sha1 diffie-hellman-group-exchange-sha256), algorithms(:kex => "diffie-hellman-group1-sha1")[:kex]
+ if defined?(OpenSSL::PKey::EC)
+ assert_equal %w(diffie-hellman-group1-sha1 diffie-hellman-group-exchange-sha1 diffie-hellman-group14-sha1 diffie-hellman-group-exchange-sha256 ecdh-sha2-nistp256 ecdh-sha2-nistp384 ecdh-sha2-nistp521), algorithms(:kex => "diffie-hellman-group1-sha1")[:kex]
+ else
+ assert_equal %w(diffie-hellman-group1-sha1 diffie-hellman-group-exchange-sha1 diffie-hellman-group14-sha1 diffie-hellman-group-exchange-sha256), algorithms(:kex => "diffie-hellman-group1-sha1")[:kex]
+ end
end
def test_constructor_with_unrecognized_kex_should_raise_exception
assert_raises(NotImplementedError) { algorithms(:kex => "bogus") }
end
def test_constructor_with_preferred_encryption_should_put_preferred_encryption_first
- assert_equal %w(aes256-cbc aes128-cbc 3des-cbc blowfish-cbc cast128-cbc aes192-cbc rijndael-cbc@lysator.liu.se idea-cbc none arcfour128 arcfour256), algorithms(:encryption => "aes256-cbc")[:encryption]
+ assert_equal %w(aes256-cbc aes128-cbc 3des-cbc blowfish-cbc cast128-cbc aes192-cbc rijndael-cbc@lysator.liu.se idea-cbc none arcfour128 arcfour256 arcfour aes128-ctr aes192-ctr aes256-ctr camellia128-cbc camellia192-cbc camellia256-cbc camellia128-cbc@openssh.org camellia192-cbc@openssh.org camellia256-cbc@openssh.org camellia128-ctr camellia192-ctr camellia256-ctr camellia128-ctr@openssh.org camellia192-ctr@openssh.org camellia256-ctr@openssh.org cast128-ctr blowfish-ctr 3des-ctr), algorithms(:encryption => "aes256-cbc")[:encryption]
end
def test_constructor_with_multiple_preferred_encryption_should_put_all_preferred_encryption_first
- assert_equal %w(aes256-cbc 3des-cbc idea-cbc aes128-cbc blowfish-cbc cast128-cbc aes192-cbc rijndael-cbc@lysator.liu.se none arcfour128 arcfour256), algorithms(:encryption => %w(aes256-cbc 3des-cbc idea-cbc))[:encryption]
+ assert_equal %w(aes256-cbc 3des-cbc idea-cbc aes128-cbc blowfish-cbc cast128-cbc aes192-cbc rijndael-cbc@lysator.liu.se none arcfour128 arcfour256 arcfour aes128-ctr aes192-ctr aes256-ctr camellia128-cbc camellia192-cbc camellia256-cbc camellia128-cbc@openssh.org camellia192-cbc@openssh.org camellia256-cbc@openssh.org camellia128-ctr camellia192-ctr camellia256-ctr camellia128-ctr@openssh.org camellia192-ctr@openssh.org camellia256-ctr@openssh.org cast128-ctr blowfish-ctr 3des-ctr), algorithms(:encryption => %w(aes256-cbc 3des-cbc idea-cbc))[:encryption]
end
def test_constructor_with_unrecognized_encryption_should_raise_exception
assert_raises(NotImplementedError) { algorithms(:encryption => "bogus") }
end
def test_constructor_with_preferred_hmac_should_put_preferred_hmac_first
- assert_equal %w(hmac-md5-96 hmac-sha1 hmac-md5 hmac-sha1-96 hmac-sha2-256 hmac-sha2-512 hmac-sha2-256-96 hmac-sha2-512-96 none), algorithms(:hmac => "hmac-md5-96")[:hmac]
+ assert_equal %w(hmac-md5-96 hmac-sha1 hmac-md5 hmac-sha1-96 hmac-ripemd160 hmac-ripemd160@openssh.com hmac-sha2-256 hmac-sha2-512 hmac-sha2-256-96 hmac-sha2-512-96 none), algorithms(:hmac => "hmac-md5-96")[:hmac]
end
def test_constructor_with_multiple_preferred_hmac_should_put_all_preferred_hmac_first
- assert_equal %w(hmac-md5-96 hmac-sha1-96 hmac-sha1 hmac-md5 hmac-sha2-256 hmac-sha2-512 hmac-sha2-256-96 hmac-sha2-512-96 none), algorithms(:hmac => %w(hmac-md5-96 hmac-sha1-96))[:hmac]
+ assert_equal %w(hmac-md5-96 hmac-sha1-96 hmac-sha1 hmac-md5 hmac-ripemd160 hmac-ripemd160@openssh.com hmac-sha2-256 hmac-sha2-512 hmac-sha2-256-96 hmac-sha2-512-96 none), algorithms(:hmac => %w(hmac-md5-96 hmac-sha1-96))[:hmac]
end
def test_constructor_with_unrecognized_hmac_should_raise_exception
@@ -256,7 +273,7 @@ def cipher(type, options={})
def kexinit(options={})
@kexinit ||= P(:byte, KEXINIT,
:long, rand(0xFFFFFFFF), :long, rand(0xFFFFFFFF), :long, rand(0xFFFFFFFF), :long, rand(0xFFFFFFFF),
- :string, options[:kex] || "diffie-hellman-group-exchange-sha1,diffie-hellman-group1-sha1,diffie-hellman-group-exchange-sha256",
+ :string, options[:kex] || "diffie-hellman-group-exchange-sha1,diffie-hellman-group14-sha1,diffie-hellman-group1-sha1,diffie-hellman-group-exchange-sha256",
:string, options[:host_key] || "ssh-rsa,ssh-dss",
:string, options[:encryption_client] || "aes128-cbc,3des-cbc,blowfish-cbc,cast128-cbc,aes192-cbc,aes256-cbc,rijndael-cbc@lysator.liu.se,idea-cbc",
:string, options[:encryption_server] || "aes128-cbc,3des-cbc,blowfish-cbc,cast128-cbc,aes192-cbc,aes256-cbc,rijndael-cbc@lysator.liu.se,idea-cbc",
@@ -272,12 +289,17 @@ def kexinit(options={})
def assert_kexinit(buffer, options={})
assert_equal KEXINIT, buffer.type
assert_equal 16, buffer.read(16).length
- assert_equal options[:kex] || "diffie-hellman-group-exchange-sha1,diffie-hellman-group1-sha1,diffie-hellman-group-exchange-sha256", buffer.read_string
- assert_equal options[:host_key] || "ssh-rsa,ssh-dss", buffer.read_string
- assert_equal options[:encryption_client] || "aes128-cbc,3des-cbc,blowfish-cbc,cast128-cbc,aes192-cbc,aes256-cbc,rijndael-cbc@lysator.liu.se,idea-cbc,none,arcfour128,arcfour256", buffer.read_string
- assert_equal options[:encryption_server] || "aes128-cbc,3des-cbc,blowfish-cbc,cast128-cbc,aes192-cbc,aes256-cbc,rijndael-cbc@lysator.liu.se,idea-cbc,none,arcfour128,arcfour256", buffer.read_string
- assert_equal options[:hmac_client] || "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", buffer.read_string
- assert_equal options[:hmac_server] || "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", buffer.read_string
+ if defined?(OpenSSL::PKey::EC)
+ assert_equal options[:kex] || "diffie-hellman-group-exchange-sha1,diffie-hellman-group1-sha1,diffie-hellman-group14-sha1,diffie-hellman-group-exchange-sha256,ecdh-sha2-nistp256,ecdh-sha2-nistp384,ecdh-sha2-nistp521", buffer.read_string
+ assert_equal options[:host_key] || "ssh-rsa,ssh-dss,ecdsa-sha2-nistp256,ecdsa-sha2-nistp384,ecdsa-sha2-nistp521", buffer.read_string
+ else
+ assert_equal options[:kex] || "diffie-hellman-group-exchange-sha1,diffie-hellman-group1-sha1,diffie-hellman-group14-sha1,diffie-hellman-group-exchange-sha256", buffer.read_string
+ assert_equal options[:host_key] || "ssh-rsa,ssh-dss", buffer.read_string
+ end
+ assert_equal options[:encryption_client] || "aes128-cbc,3des-cbc,blowfish-cbc,cast128-cbc,aes192-cbc,aes256-cbc,rijndael-cbc@lysator.liu.se,idea-cbc,none,arcfour128,arcfour256,arcfour,aes128-ctr,aes192-ctr,aes256-ctr,camellia128-cbc,camellia192-cbc,camellia256-cbc,camellia128-cbc@openssh.org,camellia192-cbc@openssh.org,camellia256-cbc@openssh.org,camellia128-ctr,camellia192-ctr,camellia256-ctr,camellia128-ctr@openssh.org,camellia192-ctr@openssh.org,camellia256-ctr@openssh.org,cast128-ctr,blowfish-ctr,3des-ctr", buffer.read_string
+ assert_equal options[:encryption_server] || "aes128-cbc,3des-cbc,blowfish-cbc,cast128-cbc,aes192-cbc,aes256-cbc,rijndael-cbc@lysator.liu.se,idea-cbc,none,arcfour128,arcfour256,arcfour,aes128-ctr,aes192-ctr,aes256-ctr,camellia128-cbc,camellia192-cbc,camellia256-cbc,camellia128-cbc@openssh.org,camellia192-cbc@openssh.org,camellia256-cbc@openssh.org,camellia128-ctr,camellia192-ctr,camellia256-ctr,camellia128-ctr@openssh.org,camellia192-ctr@openssh.org,camellia256-ctr@openssh.org,cast128-ctr,blowfish-ctr,3des-ctr", buffer.read_string
+ assert_equal options[:hmac_client] || "hmac-sha1,hmac-md5,hmac-sha1-96,hmac-md5-96,hmac-ripemd160,hmac-ripemd160@openssh.com,hmac-sha2-256,hmac-sha2-512,hmac-sha2-256-96,hmac-sha2-512-96,none", buffer.read_string
+ assert_equal options[:hmac_server] || "hmac-sha1,hmac-md5,hmac-sha1-96,hmac-md5-96,hmac-ripemd160,hmac-ripemd160@openssh.com,hmac-sha2-256,hmac-sha2-512,hmac-sha2-256-96,hmac-sha2-512-96,none", buffer.read_string
assert_equal options[:compression_client] || "none,zlib@openssh.com,zlib", buffer.read_string
assert_equal options[:compression_server] || "none,zlib@openssh.com,zlib", buffer.read_string
assert_equal options[:language_client] || "", buffer.read_string
View
282 test/transport/test_cipher_factory.rb
@@ -35,18 +35,22 @@ def test_lengths_for_3des_cbc
assert_equal [24,8], factory.get_lengths("3des-cbc")
end
- def test_lengths_for_aes192_cbc
- assert_equal [24,16], factory.get_lengths("aes192-cbc")
- end
-
def test_lengths_for_aes128_cbc
assert_equal [16,16], factory.get_lengths("aes128-cbc")
end
+ def test_lengths_for_aes192_cbc
+ assert_equal [24,16], factory.get_lengths("aes192-cbc")
+ end
+
def test_lengths_for_aes256_cbc
assert_equal [32,16], factory.get_lengths("aes256-cbc")
end
+ def test_lengths_for_arcfour
+ assert_equal [16,8], factory.get_lengths("arcfour")
+ end
+
def test_lengths_for_arcfour128
assert_equal [16,8], factory.get_lengths("arcfour128")
end
@@ -58,26 +62,86 @@ def test_lengths_for_arcfour256
def test_lengths_for_arcfour512
assert_equal [64,8], factory.get_lengths("arcfour512")
end
-
- BLOWFISH = "\210\021\200\315\240_\026$\352\204g\233\244\242x\332e\370\001\327\224Nv@9_\323\037\252kb\037\036\237\375]\343/y\037\237\312Q\f7]\347Y\005\275%\377\0010$G\272\250B\265Nd\375\342\372\025r6}+Y\213y\n\237\267\\\374^\346BdJ$\353\220Ik\023<\236&H\277=\225"
+
+ if_supported?("camellia128-cbc@openssh.org") do
+ def test_lengths_for_camellia128_cbc_openssh_org
+ assert_equal [16,16], factory.get_lengths("camellia128-cbc@openssh.org")
+ end
+ end
+
+ if_supported?("camellia192-cbc@openssh.org") do
+ def test_lengths_for_camellia192_cbc_openssh_org
+ assert_equal [24,16], factory.get_lengths("camellia192-cbc@openssh.org")
+ end
+ end
+
+ if_supported?("camellia256-cbc@openssh.org") do
+ def test_lengths_for_camellia256_cbc_openssh_org
+ assert_equal [32,16], factory.get_lengths("camellia256-cbc@openssh.org")
+ end
+ end
+
+ def test_lengths_for_3des_ctr
+ assert_equal [24,8], factory.get_lengths("3des-ctr")
+ end
+
+ def test_lengths_for_aes128_ctr
+ assert_equal [16,16], factory.get_lengths("aes128-ctr")
+ end
+
+ def test_lengths_for_aes192_ctr
+ assert_equal [24,16], factory.get_lengths("aes192-ctr")
+ end
+
+ def test_lengths_for_aes256_ctr
+ assert_equal [32,16], factory.get_lengths("aes256-ctr")
+ end
+
+ def test_lengths_for_blowfish_ctr
+ assert_equal [16,8], factory.get_lengths("blowfish-ctr")
+ end
+
+ def test_lengths_for_cast128_ctr
+ assert_equal [16,8], factory.get_lengths("cast128-ctr")
+ end
+
+ if_supported?("camellia128-ctr@openssh.org") do
+ def test_lengths_for_camellia128_ctr_openssh_org
+ assert_equal [16,16], factory.get_lengths("camellia128-ctr@openssh.org")
+ end
+ end
+
+ if_supported?("camellia192-ctr@openssh.org") do
+ def test_lengths_for_camellia192_ctr_openssh_org
+ assert_equal [24,16], factory.get_lengths("camellia192-ctr@openssh.org")
+ end
+ end
+
+ if_supported?("camellia256-ctr@openssh.org") do
+ def test_lengths_for_camellia256_ctr_openssh_org
+ assert_equal [32,16], factory.get_lengths("camellia256-ctr@openssh.org")
+ end
+ end
+
+ BLOWFISH_CBC = "\210\021\200\315\240_\026$\352\204g\233\244\242x\332e\370\001\327\224Nv@9_\323\037\252kb\037\036\237\375]\343/y\037\237\312Q\f7]\347Y\005\275%\377\0010$G\272\250B\265Nd\375\342\372\025r6}+Y\213y\n\237\267\\\374^\346BdJ$\353\220Ik\023<\236&H\277=\225"
def test_blowfish_cbc_for_encryption
- assert_equal BLOWFISH, encrypt("blowfish-cbc")
+ assert_equal BLOWFISH_CBC, encrypt("blowfish-cbc")
end
def test_blowfish_cbc_for_decryption
- assert_equal TEXT, decrypt("blowfish-cbc", BLOWFISH)
+ assert_equal TEXT, decrypt("blowfish-cbc", BLOWFISH_CBC)
end
if_supported?("idea-cbc") do
- IDEA = "W\234\017G\231\b\357\370H\b\256U]\343M\031k\233]~\023C\363\263\177\262-\261\341$\022\376mv\217\322\b\2763\270H\306\035\343z\313\312\3531\351\t\201\302U\022\360\300\354ul7$z\320O]\360g\024\305\005`V\005\335A\351\312\270c\320D\232\eQH1\340\265\2118\031g*\303v"
+ IDEA_CBC = "W\234\017G\231\b\357\370H\b\256U]\343M\031k\233]~\023C\363\263\177\262-\261\341$\022\376mv\217\322\b\2763\270H\306\035\343z\313\312\3531\351\t\201\302U\022\360\300\354ul7$z\320O]\360g\024\305\005`V\005\335A\351\312\270c\320D\232\eQH1\340\265\2118\031g*\303v"
def test_idea_cbc_for_encryption
- assert_equal IDEA, encrypt("idea-cbc")
+ assert_equal IDEA_CBC, encrypt("idea-cbc")
end
def test_idea_cbc_for_decryption
- assert_equal TEXT, decrypt("idea-cbc", IDEA)
+ assert_equal TEXT, decrypt("idea-cbc", IDEA_CBC)
end
end
@@ -91,54 +155,64 @@ def test_rijndael_cbc_for_decryption
assert_equal TEXT, decrypt("rijndael-cbc@lysator.liu.se", RIJNDAEL)
end
- CAST128 = "qW\302\331\333P\223t[9 ~(sg\322\271\227\272\022I\223\373p\255>k\326\314\260\2003\236C_W\211\227\373\205>\351\334\322\227\223\e\236\202Ii\032!P\214\035:\017\360h7D\371v\210\264\317\236a\262w1\2772\023\036\331\227\240:\f/X\351\324I\t[x\350\323E\2301\016m"
+ CAST128_CBC = "qW\302\331\333P\223t[9 ~(sg\322\271\227\272\022I\223\373p\255>k\326\314\260\2003\236C_W\211\227\373\205>\351\334\322\227\223\e\236\202Ii\032!P\214\035:\017\360h7D\371v\210\264\317\236a\262w1\2772\023\036\331\227\240:\f/X\351\324I\t[x\350\323E\2301\016m"
def test_cast128_cbc_for_encryption
- assert_equal CAST128, encrypt("cast128-cbc")
+ assert_equal CAST128_CBC, encrypt("cast128-cbc")
end
def test_cast128_cbc_for_decryption
- assert_equal TEXT, decrypt("cast128-cbc", CAST128)
+ assert_equal TEXT, decrypt("cast128-cbc", CAST128_CBC)
end
- TRIPLE_DES = "\322\252\216D\303Q\375gg\367A{\177\313\3436\272\353%\223K?\257\206|\r&\353/%\340\336 \203E8rY\206\234\004\274\267\031\233T/{\"\227/B!i?[qGaw\306T\206\223\213n \212\032\244%]@\355\250\334\312\265E\251\017\361\270\357\230\274KP&^\031r+r%\370"
+ TRIPLE_DES_CBC = "\322\252\216D\303Q\375gg\367A{\177\313\3436\272\353%\223K?\257\206|\r&\353/%\340\336 \203E8rY\206\234\004\274\267\031\233T/{\"\227/B!i?[qGaw\306T\206\223\213n \212\032\244%]@\355\250\334\312\265E\251\017\361\270\357\230\274KP&^\031r+r%\370"
def test_3des_cbc_for_encryption
- assert_equal TRIPLE_DES, encrypt("3des-cbc")
+ assert_equal TRIPLE_DES_CBC, encrypt("3des-cbc")
end
def test_3des_cbc_for_decryption
- assert_equal TEXT, decrypt("3des-cbc", TRIPLE_DES)
+ assert_equal TEXT, decrypt("3des-cbc", TRIPLE_DES_CBC)
end
- AES128 = "k\026\350B\366-k\224\313\3277}B\035\004\200\035\r\233\024$\205\261\231Q\2214r\245\250\360\315\237\266hg\262C&+\321\346Pf\267v\376I\215P\327\345-\232&HK\375\326_\030<\a\276\212\303g\342C\242O\233\260\006\001a&V\345`\\T\e\236.\207\223l\233ri^\v\252\363\245"
+ AES128_CBC = "k\026\350B\366-k\224\313\3277}B\035\004\200\035\r\233\024$\205\261\231Q\2214r\245\250\360\315\237\266hg\262C&+\321\346Pf\267v\376I\215P\327\345-\232&HK\375\326_\030<\a\276\212\303g\342C\242O\233\260\006\001a&V\345`\\T\e\236.\207\223l\233ri^\v\252\363\245"
def test_aes128_cbc_for_encryption
- assert_equal AES128, encrypt("aes128-cbc")
+ assert_equal AES128_CBC, encrypt("aes128-cbc")
end
def test_aes128_cbc_for_decryption
- assert_equal TEXT, decrypt("aes128-cbc", AES128)
+ assert_equal TEXT, decrypt("aes128-cbc", AES128_CBC)
end
- AES192 = "\256\017)x\270\213\336\303L\003f\235'jQ\3231k9\225\267\242\364C4\370\224\201\302~\217I\202\374\2167='\272\037\225\223\177Y\r\212\376(\275\n\3553\377\177\252C\254\236\016MA\274Z@H\331<\rL\317\205\323[\305X8\376\237=\374\352bH9\244\0231\353\204\352p\226\326~J\242"
+ AES192_CBC = "\256\017)x\270\213\336\303L\003f\235'jQ\3231k9\225\267\242\364C4\370\224\201\302~\217I\202\374\2167='\272\037\225\223\177Y\r\212\376(\275\n\3553\377\177\252C\254\236\016MA\274Z@H\331<\rL\317\205\323[\305X8\376\237=\374\352bH9\244\0231\353\204\352p\226\326~J\242"
def test_aes192_cbc_for_encryption
- assert_equal AES192, encrypt("aes192-cbc")
+ assert_equal AES192_CBC, encrypt("aes192-cbc")
end
def test_aes192_cbc_for_decryption
- assert_equal TEXT, decrypt("aes192-cbc", AES192)
+ assert_equal TEXT, decrypt("aes192-cbc", AES192_CBC)
end
- AES256 = "$\253\271\255\005Z\354\336&\312\324\221\233\307Mj\315\360\310Fk\241EfN\037\231\213\361{'\310\204\347I\343\271\005\240`\325;\034\346uM>#\241\231C`\374\261\vo\226;Z\302:\b\250\366T\330\\#V\330\340\226\363\374!\bm\266\232\207!\232\347\340\t\307\370\356z\236\343=v\210\206y"
+ AES256_CBC = "$\253\271\255\005Z\354\336&\312\324\221\233\307Mj\315\360\310Fk\241EfN\037\231\213\361{'\310\204\347I\343\271\005\240`\325;\034\346uM>#\241\231C`\374\261\vo\226;Z\302:\b\250\366T\330\\#V\330\340\226\363\374!\bm\266\232\207!\232\347\340\t\307\370\356z\236\343=v\210\206y"
def test_aes256_cbc_for_encryption
- assert_equal AES256, encrypt("aes256-cbc")
+ assert_equal AES256_CBC, encrypt("aes256-cbc")
end
def test_aes256_cbc_for_decryption
- assert_equal TEXT, decrypt("aes256-cbc", AES256)
+ assert_equal TEXT, decrypt("aes256-cbc", AES256_CBC)
+ end
+
+ ARCFOUR = "\xC1.\x1AdH\xD0+%\xF1CrG\x1C\xCC\xF6\xACho\xB0\x95\\\xBC\x02P\xF9\xAF\n\xBB<\x13\xF3\xCF\xEB\n\b(iO\xFB'\t^?\xA6\xE5a\xE2\x17\f\x97\xCAs\x9E\xFC\xF2\x88\xC93\v\x84\xCA\x82\x0E\x1D\x11\xEA\xE1\x82\x8E\xB3*\xC5\xFB\x8Cmgs\xB0\xFA\xF5\x9C\\\xE2\xB0\x95\x1F>LT"
+
+ def test_arcfour_for_encryption
+ assert_equal ARCFOUR, encrypt("arcfour")
+ end
+
+ def test_arcfour_for_decryption
+ assert_equal TEXT, decrypt("arcfour", ARCFOUR)
end
ARCFOUR128 = "\n\x90\xED*\xD4\xBE\xCBg5\xA5\a\xEC]\x97\xB7L\x06)6\x12FL\x90@\xF4Sqxqh\r\x11\x1Aq \xC8\xE6v\xC6\x12\xD9<A\xDAZ\xFE\x7F\x88\x19f.\x06\xA7\xFE:\xFF\x93\x9B\x8D\xA0\\\x9E\xCA\x03\x15\xE1\xE2\f\xC0\b\xA2C\xE1\xBD\xB6\x13D\xD1\xB4'g\x89\xDC\xEB\f\x19Z)U"
@@ -170,7 +244,161 @@ def test_arcfour512_for_encryption
def test_arcfour512_for_decryption
assert_equal TEXT, decrypt("arcfour512", ARCFOUR512)
end
-
+
+ if_supported?("camellia128-cbc@openssh.org") do
+ CAMELLIA128_CBC = "\a\b\x83+\xF1\xC5m\a\xE1\xD3\x06\xD2NA\xC3l@\\*M\xFD\x96\xAE\xA8\xB4\xA9\xACm\"8\x8E\xEE<\xC3O[\rK\xFAgu}\xCD\xAC\xF4\x04o\xDB\x94-\xB8\"\xDC\xE7{y\xA9 \x8F=y\x85\x82v\xC8\xCA\x8A\xE9\xE3:\xC4,u=a/\xC0\x05\xDA\xDAk8g\xCB\xD9\xA8\xE6\xFE\xCE_\x8E\x97\xF0\xAC\xB6\xCE"
+ def test_camellia128_cbc_for_encryption
+ assert_equal CAMELLIA128_CBC, encrypt("camellia128-cbc@openssh.org")
+ end
+ def test_camellia128_cbc_for_decryption
+ assert_equal TEXT, decrypt("camellia128-cbc@openssh.org", CAMELLIA128_CBC)
+ end
+ end
+
+ if_supported?("camellia192-cbc@openssh.org") do
+ CAMELLIA192_CBC = "\x82\xB2\x03\x90\xFA\f2\xA0\xE3\xFA\xF2B\xAB\xDBX\xD5\x04z\xD4G\x19\xB8\xAB\v\x85\x84\xCD:.\xBA\x9Dd\xD5(\xEB.\n\xAA]\xCB\xF3\x0F4\x8Bd\xF8m\xC9!\xE2\xA1=\xEBY\xA6\x83\x86\n\x13\e6\v\x06\xBBNJg\xF2-\x14',[\xC1\xB1.\x85\xF3\xC6\xBF\x1Ff\xCE\x87'\x9C\xB2\xC8!\xF3|\xE2\xD2\x9E\x96\xA1"
+ def test_camellia192_cbc_for_encryption
+ assert_equal CAMELLIA192_CBC, encrypt("camellia192-cbc@openssh.org")
+ end
+ def test_camellia192_cbc_for_decryption
+ assert_equal TEXT, decrypt("camellia192-cbc@openssh.org", CAMELLIA192_CBC)
+ end
+ end
+
+ if_supported?("camellia256-cbc@openssh.org") do
+ CAMELLIA256_CBC = ",\x80J/\xF5\x8F\xFE4\xF0@\n[2\xFF4\xB6\xA4\xD0\xF8\xF5*\x17I\xF3\xA2\x1F$L\xC6\xA1\x06\xDC\x84f\x1C\x10&\x1C\xC4/R\x859|i\x85ZP\xC8\x94\xED\xE8-\n@ w\x92\xF7\xD4\xAB\xF0\x85c\xC1\x0F\x1E#\xEB\xE5W\x87N!\xC7'/\xE3E8$\x1D\x9B:\xC9\xAF_\x05\xAC%\xD7\x945\xBBDK"
+ def test_camellia256_cbc_for_encryption
+ assert_equal CAMELLIA256_CBC, encrypt("camellia256-cbc@openssh.org")
+ end
+ def test_camellia256_cbc_for_decryption
+ assert_equal TEXT, decrypt("camellia256-cbc@openssh.org", CAMELLIA256_CBC)
+ end
+ end
+
+ BLOWFISH_CTR = "\xF5\xA6\x1E{\x8F(\x85G\xFAh\xDB\x19\xDC\xDF\xA2\x9A\x99\xDD5\xFF\xEE\x8BE\xE6\xB5\x92\x82\xE80\x91\x11`\xEF\x10\xED\xE9\xD3\vG\x0E\xAF\xB2K\t\xA4\xA6\x05\xD1\x17\x0Fl\r@E\x8DJ\e\xE63\x04\xB5\x05\x99Y\xCC\xFBb\x8FK+\x8C1v\xE4N\b?B\x06Rz\xA6\xB6N/b\xCE}\x83\x8DY\xD7\x92qU\x0F"
+
+ def test_blowfish_ctr_for_encryption
+ assert_equal BLOWFISH_CTR, encrypt("blowfish-ctr")
+ end
+
+ def test_blowfish_ctr_for_decryption
+ assert_equal TEXT, decrypt("blowfish-ctr", BLOWFISH_CTR)
+ end
+
+ CAST128_CTR = "\xB5\xBB\xC3h\x80\x90`{\xD7I\x03\xE9\x80\xC4\xC4U\xE3@\xF1\xE9\xEFX\xDB6\xEE,\x8E\xC2\xE8\x89\x17\xBArf\x81\r\x96\xDC\xB1_'\x83hs\t7\xB8@\x17\xAA\xD9;\xE8\x8E\x94\xBD\xFF\xA4K\xA4\xFA\x8F-\xCD\bO\xD9I`\xE5\xC9H\x99\x14\xC5K\xC8\xEF\xEA#\x1D\xE5\x13O\xE1^P\xDC\x1C^qm\v|c@"
+
+ def test_cast128_ctr_for_encryption
+ assert_equal CAST128_CTR, encrypt("cast128-ctr")
+ end
+
+ def test_cast128_ctr_for_decryption
+ assert_equal TEXT, decrypt("cast128-ctr", CAST128_CTR)
+ end
+
+ TRIPLE_DES_CTR = "\x90\xCD\b\xD2\xF1\x15:\x98\xF4sJ\xF0\xC9\xAA\xC5\xE3\xB4\xCFq\x93\xBAB\xF9v\xE1\xE7\x8B<\xBC\x97R\xDF?kK~Nw\xF3\x92`\x90]\xD9\xEF\x16\xC85V\x03C\xE9\x14\xF0\x86\xEB\x19\x85\x82\xF6\x16gz\x9B`\xB1\xCE\x80&?\xC8\xBD\xBC+\x91/)\xA5x\xBB\xCF\x06\x15#\e\xB3\xBD\x9B\x1F\xA7\xE2\xC7\xA3\xFC\x06\xC8"
+
+ def test_3des_ctr_for_encryption
+ if defined?(JRUBY_VERSION)
+ # on JRuby, this test fails due to JRUBY-6558