Class: Net::SSH::Transport::CipherFactory

Inherits:
Object
  • Object
show all
Defined in:
lib/net/ssh/transport/cipher_factory.rb

Overview

Implements a factory of OpenSSL cipher algorithms.

Constant Summary collapse

SSH_TO_OSSL =

Maps the SSH name of a cipher to it’s corresponding OpenSSL name

{
  "3des-cbc"                    => "des-ede3-cbc",
  "blowfish-cbc"                => "bf-cbc",
  "aes256-cbc"                  => "aes-256-cbc",
  "aes192-cbc"                  => "aes-192-cbc",
  "aes128-cbc"                  => "aes-128-cbc",
  "idea-cbc"                    => "idea-cbc",
  "cast128-cbc"                 => "cast-cbc",
  "[email protected]" => "aes-256-cbc",
  "arcfour128"                  => "rc4",
  "arcfour256"                  => "rc4",
  "arcfour512"                  => "rc4",
  "none"                        => "none"
}

Class Method Summary collapse

Class Method Details

.get(name, options = {}) ⇒ Object

Retrieves a new instance of the named algorithm. The new instance will be initialized using an iv and key generated from the given iv, key, shared, hash and digester values. Additionally, the cipher will be put into encryption or decryption mode, based on the value of the encrypt parameter.



37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
# File 'lib/net/ssh/transport/cipher_factory.rb', line 37

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.iv      = make_key(cipher.iv_len, options[:iv], options) if ossl_name != "rc4"
  key_len = cipher.key_len
  cipher.key_len = key_len = 32 if name == "arcfour256"
  cipher.key_len = key_len = 64 if name == "arcfour512"
  cipher.key     = make_key(key_len, options[:key], options)
  cipher.update(" " * 1536) if ossl_name == "rc4"

  return cipher
end

.get_lengths(name) ⇒ Object

Returns a two-element array containing the [ key-length, block-size ] for the named cipher algorithm. If the cipher algorithm is unknown, or is “none”, 0 is returned for both elements of the tuple.



59
60
61
62
63
64
65
66
67
68
# File 'lib/net/ssh/transport/cipher_factory.rb', line 59

def self.get_lengths(name)
  ossl_name = SSH_TO_OSSL[name]
  return [0, 0] if ossl_name.nil? || ossl_name == "none"

  cipher = OpenSSL::Cipher::Cipher.new(ossl_name)
  key_len = cipher.key_len
  key_len = 32 if name == "arcfour256"
  key_len = 64 if name == "arcfour512"
  return [key_len, ossl_name=="rc4" ? 8 : cipher.block_size]
end

.supported?(name) ⇒ Boolean

Returns true if the underlying OpenSSL library supports the given cipher, and false otherwise.

Returns:

  • (Boolean)


26
27
28
29
30
# File 'lib/net/ssh/transport/cipher_factory.rb', line 26

def self.supported?(name)
  ossl_name = SSH_TO_OSSL[name] or raise NotImplementedError, "unimplemented cipher `#{name}'"
  return true if ossl_name == "none"
  return OpenSSL::Cipher.ciphers.include?(ossl_name)
end