class Net::SSH::KeyFactory
A factory class for returning new Key classes. It is used for obtaining OpenSSL
key instances via their SSH
names, and for loading both public and private keys. It used used primarily by Net::SSH
itself, internally, and will rarely (if ever) be directly used by consumers of the library.
klass = Net::SSH::KeyFactory.get("rsa") assert klass.is_a?(OpenSSL::PKey::RSA) key = Net::SSH::KeyFactory.load_public_key("~/.ssh/id_dsa.pub")
Constants
Public Class Methods
Loads a private key. It will correctly determine whether the file describes an RSA or DSA key, and will load it appropriately. The new key is returned. If the key itself is encrypted (requiring a passphrase to use), the user will be prompted to enter their password unless passphrase works.
# File lib/net/ssh/key_factory.rb, line 49 def load_data_private_key(data, passphrase = nil, ask_passphrase = true, filename = "", prompt = Prompt.default) key_type = classify_key(data, filename) encrypted_key = nil tries = 0 prompter = nil result = begin key_type.read(data, passphrase || 'invalid') rescue *key_type.error_classes => e encrypted_key = !!key_type.encrypted_key?(data, e) if encrypted_key.nil? if encrypted_key && ask_passphrase tries += 1 if tries <= 3 prompter ||= prompt.start(type: 'private_key', filename: filename, sha: Digest::SHA256.digest(data)) passphrase = prompter.ask("Enter passphrase for #{filename}:", false) retry else raise end else raise end end prompter.success if prompter result end
Loads a public key. It will correctly determine whether the file describes an RSA or DSA key, and will load it appropriately. The new public key is returned.
# File lib/net/ssh/key_factory.rb, line 89 def load_data_public_key(data, filename = "") fields = data.split(/ /) blob = nil begin blob = fields.shift end while !blob.nil? && !/^(ssh-(rsa|dss|ed25519)|ecdsa-sha2-nistp\d+)(-cert-v01@openssh\.com)?$/.match(blob) blob = fields.shift raise Net::SSH::Exception, "public key at #{filename} is not valid" if blob.nil? blob = blob.unpack("m*").first reader = Net::SSH::Buffer.new(blob) reader.read_key or raise OpenSSL::PKey::PKeyError, "not a public key #{filename.inspect}" end
Loads a private key from a file. It will correctly determine whether the file describes an RSA or DSA key, and will load it appropriately. The new key is returned. If the key itself is encrypted (requiring a passphrase to use), the user will be prompted to enter their password unless passphrase works.
# File lib/net/ssh/key_factory.rb, line 39 def load_private_key(filename, passphrase = nil, ask_passphrase = true, prompt = Prompt.default) data = File.read(File.expand_path(filename)) load_data_private_key(data, passphrase, ask_passphrase, filename, prompt) end
Loads a public key from a file. It will correctly determine whether the file describes an RSA or DSA key, and will load it appropriately. The new public key is returned.
# File lib/net/ssh/key_factory.rb, line 81 def load_public_key(filename) data = File.read(File.expand_path(filename)) load_data_public_key(data, filename) end
Private Class Methods
Determine whether the file describes an RSA or DSA key, and return how load it appropriately.
# File lib/net/ssh/key_factory.rb, line 197 def classify_key(data, filename) if data.match(/-----BEGIN OPENSSH PRIVATE KEY-----/) Net::SSH::Authentication::ED25519Loader.raiseUnlessLoaded("OpenSSH keys only supported if ED25519 is available") return OpenSSHPrivateKeyType elsif OpenSSL::PKey.respond_to?(:read) return OpenSSLPKeyType elsif data.match(/-----BEGIN DSA PRIVATE KEY-----/) return OpenSSLDSAKeyType elsif data.match(/-----BEGIN RSA PRIVATE KEY-----/) return OpenSSLRSAKeyType elsif data.match(/-----BEGIN EC PRIVATE KEY-----/) return OpenSSLECKeyType elsif data.match(/-----BEGIN (.+) PRIVATE KEY-----/) raise OpenSSL::PKey::PKeyError, "not a supported key type '#{$1}'" else raise OpenSSL::PKey::PKeyError, "not a private key (#{filename})" end end