class RHC::Vendor::SSHKey

Constants

SSH_CONVERSION
SSH_TYPES

Attributes

comment[R]
key_object[R]
passphrase[RW]
type[R]

Public Class Methods

fingerprint(key) click to toggle source
Alias for: md5_fingerprint
generate(options = {}) click to toggle source

Generate a new keypair and return an SSHKey object

The default behavior when providing no options will generate a 2048-bit RSA keypair.

Parameters

  • options<~Hash>:

    • :type<~String> - "rsa" or "dsa", "rsa" by default

    • :bits<~Integer> - Bit length

    • :comment<~String> - Comment to use for the public key, defaults to ""

    • :passphrase<~String> - Encrypt the key with this passphrase

# File lib/rhc/vendor/sshkey.rb, line 52
def generate(options = {})
  type   = options[:type] || "rsa"

  # JRuby modulus size must range from 512 to 1024
  default_bits = type == "rsa" ? 2048 : 1024

  bits   = options[:bits] || default_bits
  cipher = OpenSSL::Cipher::Cipher.new("AES-128-CBC") if options[:passphrase]

  case type.downcase
  when "rsa" then new(OpenSSL::PKey::RSA.generate(bits).to_pem(cipher, options[:passphrase]), options)
  when "dsa" then new(OpenSSL::PKey::DSA.generate(bits).to_pem(cipher, options[:passphrase]), options)
  else
    raise "Unknown key type: #{type}"
  end
end
md5_fingerprint(key) click to toggle source

Fingerprints

Accepts either a public or private key

MD5 fingerprint for the given SSH key

# File lib/rhc/vendor/sshkey.rb, line 107
def md5_fingerprint(key)
  if key.match(%rPRIVATE/)
    new(key).md5_fingerprint
  else
    Digest::MD5.hexdigest(decoded_key(key)).gsub(fingerprint_regex, '\1:\2')
  end
end
Also aliased as: fingerprint
new(private_key, options = {}) click to toggle source

Create a new SSHKey object

Parameters

  • #private_key - Existing RSA or DSA private key

  • options<~Hash>

    • :comment<~String> - Comment to use for the public key, defaults to ""

    • :passphrase<~String> - If the key is encrypted, supply the passphrase

# File lib/rhc/vendor/sshkey.rb, line 153
def initialize(private_key, options = {})
  @passphrase = options[:passphrase]
  @comment    = options[:comment] || ""
  begin
    @key_object = OpenSSL::PKey::RSA.new(private_key, passphrase)
    @type = "rsa"
  rescue
    @key_object = OpenSSL::PKey::DSA.new(private_key, passphrase)
    @type = "dsa"
  end
end
sha1_fingerprint(key) click to toggle source

SHA1 fingerprint for the given SSH key

# File lib/rhc/vendor/sshkey.rb, line 117
def sha1_fingerprint(key)
  if key.match(%rPRIVATE/)
    new(key).sha1_fingerprint
  else
    Digest::SHA1.hexdigest(decoded_key(key)).gsub(fingerprint_regex, '\1:\2')
  end
end
valid_ssh_public_key?(ssh_public_key) click to toggle source

Validate an existing SSH public key

Returns true or false depending on the validity of the public key provided

Parameters

# File lib/rhc/vendor/sshkey.rb, line 76
def valid_ssh_public_key?(ssh_public_key)
  ssh_type, encoded_key = ssh_public_key.split(" ")
  type = SSH_TYPES.invert[ssh_type]
  prefix = [0,0,0,7].pack("C*")
  decoded = Base64.decode64(encoded_key)

  # Base64 decoding is too permissive, so we should validate if encoding is correct
  return false unless Base64.encode64(decoded).gsub("\n", "") == encoded_key
  return false unless decoded.sub!(%r^#{prefix}#{ssh_type}/, "")

  unpacked = decoded.unpack("C*")
  data = []
  index = 0
  until unpacked[index].nil?
    datum_size = from_byte_array unpacked[index..index+4-1], 4
    index = index + 4
    datum = from_byte_array unpacked[index..index+datum_size-1], datum_size
    data << datum
    index = index + datum_size
  end

  SSH_CONVERSION[type].size == data.size
rescue
  false
end

Public Instance Methods

dsa_private_key() click to toggle source
Alias for: private_key
dsa_public_key() click to toggle source
Alias for: public_key
encrypted_private_key() click to toggle source

Fetch the encrypted RSA/DSA private key using the passphrase provided

If no passphrase is set, returns the unencrypted private key

# File lib/rhc/vendor/sshkey.rb, line 177
def encrypted_private_key
  return private_key unless passphrase
  key_object.to_pem(OpenSSL::Cipher::Cipher.new("AES-128-CBC"), passphrase)
end
fingerprint() click to toggle source
Alias for: md5_fingerprint
md5_fingerprint() click to toggle source

Fingerprints

MD5 fingerprint for the given SSH public key

# File lib/rhc/vendor/sshkey.rb, line 199
def md5_fingerprint
  Digest::MD5.hexdigest(ssh_public_key_conversion).gsub(%r(.{2})(?=.)/, '\1:\2')
end
Also aliased as: fingerprint
private_key() click to toggle source

Fetch the RSA/DSA private key

#rsa_private_key and #dsa_private_key are aliased for backward compatibility

# File lib/rhc/vendor/sshkey.rb, line 168
def private_key
  key_object.to_pem
end
Also aliased as: rsa_private_key, dsa_private_key
public_key() click to toggle source

Fetch the RSA/DSA public key

#rsa_public_key and #dsa_public_key are aliased for backward compatibility

# File lib/rhc/vendor/sshkey.rb, line 185
def public_key
  key_object.public_key.to_pem
end
Also aliased as: rsa_public_key, dsa_public_key
rsa_private_key() click to toggle source
Alias for: private_key
rsa_public_key() click to toggle source
Alias for: public_key
sha1_fingerprint() click to toggle source

SHA1 fingerprint for the given SSH public key

# File lib/rhc/vendor/sshkey.rb, line 205
def sha1_fingerprint
  Digest::SHA1.hexdigest(ssh_public_key_conversion).gsub(%r(.{2})(?=.)/, '\1:\2')
end
ssh_public_key() click to toggle source

SSH public key

# File lib/rhc/vendor/sshkey.rb, line 192
def ssh_public_key
  [SSH_TYPES[type], Base64.encode64(ssh_public_key_conversion).gsub("\n", ""), comment].join(" ").strip
end