module PuTTY::Key::OpenSSL::ClassMethods
The {ClassMethods} module is used to extend OpenSSL::PKey
when using the PuTTY::Key
refinement or calling {PuTTY::Key.global_install}. This adds a from_ppk
class method to OpenSSL::PKey
.
Public Instance Methods
from_ppk(ppk)
click to toggle source
Creates a new OpenSSL::PKey
from a PuTTY
private key (instance of {PPK}).
This method is called using OpenSSL::PKey.from_ppk(ppk)
.
PuTTY
keys using the algorithms ssh-dss
, ssh-rsa
, ecdsa-sha2-nistp256
, ecdsa-sha2-nistp384
and ecdsa-sha2-nistp521
are supported.
@return [Object] An instance of either OpenSSL::PKey::DSA
, OpenSSL::PKey::RSA
or OpenSSL::PKey::EC
depending on the algorithm of ppk
.
@raise [ArgumentError] If ppk
is nil
. @raise [ArgumentError] If the algorithm of ppk
is not supported.
# File lib/putty/key/openssl.rb, line 48 def from_ppk(ppk) raise ArgumentError, 'ppk must not be nil' unless ppk case ppk.algorithm when 'ssh-dss' ::OpenSSL::PKey::DSA.new.tap do |pkey| _, p, q, g, pub_key = Util.ssh_unpack(ppk.public_blob, :string, :mpint, :mpint, :mpint, :mpint) priv_key = Util.ssh_unpack(ppk.private_blob, :mpint).first if pkey.respond_to?(:set_key) # :nocov_no_openssl_pkey_dsa_set_key: pkey.set_key(pub_key, priv_key) pkey.set_pqg(p, q, g) # :nocov_no_openssl_pkey_dsa_set_key: else # :nocov_openssl_pkey_dsa_set_key: pkey.p, pkey.q, pkey.g, pkey.pub_key, pkey.priv_key = p, q, g, pub_key, priv_key # :nocov_openssl_pkey_dsa_set_key: end end when 'ssh-rsa' ::OpenSSL::PKey::RSA.new.tap do |pkey| _, e, n = Util.ssh_unpack(ppk.public_blob, :string, :mpint, :mpint) d, p, q, iqmp = Util.ssh_unpack(ppk.private_blob, :mpint, :mpint, :mpint, :mpint) dmp1 = d % (p - 1) dmq1 = d % (q - 1) if pkey.respond_to?(:set_factors) # :nocov_no_openssl_pkey_rsa_set_factors: pkey.set_factors(p, q) pkey.set_key(n, e, d) pkey.set_crt_params(dmp1, dmq1, iqmp) # :nocov_no_openssl_pkey_rsa_set_factors: else # :nocov_openssl_pkey_rsa_set_factors: pkey.e, pkey.n, pkey.d, pkey.p, pkey.q, pkey.iqmp, pkey.dmp1, pkey.dmq1 = e, n, d, p, q, iqmp, dmp1, dmq1 # :nocov_openssl_pkey_rsa_set_factors: end end when /\Aecdsa-sha2-(nistp(?:256|384|521))\z/ curve = OPENSSL_CURVES[$1] # Old versions of jruby-openssl don't include an EC class (version 0.9.16). ec_class = (::OpenSSL::PKey::EC rescue raise ArgumentError, "Unsupported algorithm: #{ppk.algorithm}") ec_class.new(curve).tap do |pkey| _, _, point = Util.ssh_unpack(ppk.public_blob, :string, :string, :mpint) group = pkey.group || ::OpenSSL::PKey::EC::Group.new(curve) pkey.public_key = ::OpenSSL::PKey::EC::Point.new(group, point) pkey.private_key = Util.ssh_unpack(ppk.private_blob, :mpint).first end else raise ArgumentError, "Unsupported algorithm: #{ppk.algorithm}" end end