Module: OpenSSL::PKey
- Defined in:
- lib/openssl/ssh_pkey.rb
Overview
Enhancements to the core asymmetric key handling.
Constant Summary collapse
- SSH_CURVE_NAME_MAP =
A mapping of the “SSH” names for various curves, to their OpenSSL equivalents.
{ "nistp256" => "prime256v1", "nistp384" => "secp384r1", "nistp521" => "secp521r1", }
Class Method Summary collapse
-
.from_putty_key(s) { ... } ⇒ OpenSSL::PKey::PKey
Create a new ‘OpenSSL::PKey` from a PuTTY private key.
-
.from_ssh_key(s) { ... } ⇒ OpenSSL::PKey::PKey
Create a new ‘OpenSSL::PKey` from an SSH public or private key.
Class Method Details
.from_putty_key(s) { ... } ⇒ OpenSSL::PKey::PKey
Create a new ‘OpenSSL::PKey` from a PuTTY private key.
Given a PuTTY version 2 key file (“PPK”), an equivalent instance of an ‘OpenSSL::PKey::PKey` subclass will be derived representing the same key parameters.
63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 |
# File 'lib/openssl/ssh_pkey.rb', line 63 def self.from_putty_key(s, &blk) lines = s.gsub("\r\n", "\n").gsub("\r", "\n").split("\n") unless lines.shift =~ /\APuTTY-User-Key-File-2: ([a-z0-9-]+)\z/ raise OpenSSL::PKey::PKeyError, "No PuTTY key file header found" end keytype = $1 key = case keytype when 'ssh-rsa' OpenSSL::PKey::RSA.new when 'ssh-dss' OpenSSL::PKey::DSA.new when /ecdsa-sha2-/ OpenSSL::PKey::EC.new else raise OpenSSL::PKey::PKeyError, "Unknown key type #{keytype}" end unless lines.shift =~ /\AEncryption: (none|aes256-cbc)\z/ raise OpenSSL::PKey::PKeyError, "Missing or invalid PuTTY Encryption line" end cipher = $1 if cipher != "none" yield if block_given? raise OpenSSL::PKey::PKeyError, "Encrypted PuTTY keys are not (yet) supported" end unless lines.shift =~ /\AComment: / raise OpenSSL::PKey::PKeyError, "Missing or invalid PuTTY Comment line" end unless lines.shift =~ /\APublic-Lines: (\d+)\z/ raise OpenSSL::PKey::PKeyError, "Missing or invalid PuTTY Public-Lines line" end line_count = $1.to_i if lines.length < line_count raise OpenSSL::PKey::PKeyError, "Invalid Public-Lines value, only #{lines.length} lines remaining in file" end pubkey = lines[0, line_count].join.unpack("m").first lines = lines[line_count..-1] unless lines.shift =~ /Private-Lines: (\d+)\z/ raise OpenSSL::PKey::PKeyError, "Missing or invalid PuTTY Private-Lines line" end line_count = $1.to_i if lines.length < line_count raise OpenSSL::PKey::PKeyError, "Invalid Private-Lines value, only #{lines.length} lines remaining in file" end privkey = lines[0, line_count].join.unpack("m").first case key when OpenSSL::PKey::RSA _kt, e, n = ssh_key_lv_decode(pubkey, 3).map { |c| ssh_key_mpi_decode(c) } d, p, q, iqmp, _ = ssh_key_lv_decode(privkey, 4).map { |c| ssh_key_mpi_decode(c) } key.set_key(n, e, d) key.set_factors(p, q) key.set_crt_params(d % (p - 1), d % (q - 1), iqmp) when OpenSSL::PKey::DSA _kt, p, q, g, y = ssh_key_lv_decode(pubkey, 5).map { |c| ssh_key_mpi_decode(c) } x, _ = ssh_key_lv_decode(privkey, 1).map { |c| ssh_key_mpi_decode(c) } key.set_key(y, x) key.set_pqg(p, q, g) when OpenSSL::PKey::EC _kt, curve, w = ssh_key_lv_decode(pubkey, 3) p, _ = ssh_key_lv_decode(privkey, 1).map { |c| ssh_key_mpi_decode(c) } begin key = OpenSSL::PKey::EC.new(SSH_CURVE_NAME_MAP[curve]) rescue TypeError raise OpenSSL::PKey::PKeyError, "Unknown curve identifier #{curve}" end key.public_key = OpenSSL::PKey::EC::Point.new(key.group, w) key.private_key = p end key end |
.from_ssh_key(s) { ... } ⇒ OpenSSL::PKey::PKey
Create a new ‘OpenSSL::PKey` from an SSH public or private key.
Given an OpenSSH 2 public key (with or without the ‘ssh-rsa` / `ecdsa-etc` prefix), or an encrypted or unencrypted OpenSSH private key, create an equivalent instance of an `OpenSSL::PKey::PKey` subclass which represents the same key parameters.
39 40 41 42 43 44 45 |
# File 'lib/openssl/ssh_pkey.rb', line 39 def self.from_ssh_key(s, &blk) if s =~ /\A-----BEGIN OPENSSH PRIVATE KEY-----/ decode_private_ssh_key(s, &blk) else decode_public_ssh_key(s) end end |