Module: Zerg::Support::OpenSSH
- Defined in:
- lib/zerg_support/open_ssh.rb
Overview
Tools for managing openssh cryptographic material
Constant Summary collapse
- RSA_COMPONENTS =
The components in a openssh .pub / known_host RSA public key.
['ssh-rsa', :e, :n]
- DSA_COMPONENTS =
The components in a openssh .pub / known_host DSA public key.
['ssh-dss', :p, :q, :g, :pub_key]
Class Method Summary collapse
-
.decode_mpi(mpi_str) ⇒ Object
Decodes an openssh-mpi-encoded integer.
-
.decode_pubkey(string) ⇒ Object
Decodes an openssh public key from the format of .pub & known_hosts files.
-
.encode_mpi(n) ⇒ Object
Encodes an openssh-mpi-encoded integer.
-
.encode_pubkey(key) ⇒ Object
Encodes a key’s public part in the format found in .pub & known_hosts files.
-
.first_line(string) ⇒ Object
Extracts the first line of a string.
-
.key_from_string(serialized_key) ⇒ Object
Reads a serialized key from a string.
-
.known_hosts_keys(io) ⇒ Object
Extracts the keys from a file of known_hosts format.
-
.load_key(io) ⇒ Object
Loads a serialized key from an IO instance (File, StringIO).
-
.pack_pubkey_components(strings) ⇒ Object
Packs string components into an openssh-encoded pubkey.
-
.unpack_pubkey_components(str) ⇒ Object
Unpacks the string components in an openssh-encoded pubkey.
Class Method Details
.decode_mpi(mpi_str) ⇒ Object
Decodes an openssh-mpi-encoded integer.
93 94 95 |
# File 'lib/zerg_support/open_ssh.rb', line 93 def self.decode_mpi(mpi_str) mpi_str.unpack('C*').inject(0) { |acc, c| (acc << 8) | c } end |
.decode_pubkey(string) ⇒ Object
Decodes an openssh public key from the format of .pub & known_hosts files.
34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 |
# File 'lib/zerg_support/open_ssh.rb', line 34 def self.decode_pubkey(string) components = unpack_pubkey_components Base64.decode64(string) case components.first when RSA_COMPONENTS.first ops = RSA_COMPONENTS.zip components key = OpenSSL::PKey::RSA.new when DSA_COMPONENTS.first ops = DSA_COMPONENTS.zip components key = OpenSSL::PKey::DSA.new else raise "Unsupported key type #{components.first}" end ops.each do |o| next unless o.first.kind_of? Symbol key.send "#{o.first}=", decode_mpi(o.last) end return key end |
.encode_mpi(n) ⇒ Object
Encodes an openssh-mpi-encoded integer.
98 99 100 101 102 103 |
# File 'lib/zerg_support/open_ssh.rb', line 98 def self.encode_mpi(n) chars, n = [], n.to_i chars << (n & 0xff) and n >>= 8 while n != 0 chars << 0 if chars.empty? or chars.last >= 0x80 chars.reverse.pack('C*') end |
.encode_pubkey(key) ⇒ Object
Encodes a key’s public part in the format found in .pub & known_hosts files.
19 20 21 22 23 24 25 26 27 28 29 30 31 |
# File 'lib/zerg_support/open_ssh.rb', line 19 def self.encode_pubkey(key) case key when OpenSSL::PKey::RSA components = RSA_COMPONENTS when OpenSSL::PKey::DSA components = DSA_COMPONENTS else raise "Unsupported key type #{key.class.name}" end components.map! { |c| c.kind_of?(Symbol) ? encode_mpi(key.send(c)) : c } # ruby tries to be helpful and adds new lines every 60 bytes :( [pack_pubkey_components(components)].pack('m').gsub("\n", '') end |
.first_line(string) ⇒ Object
Extracts the first line of a string.
71 72 73 |
# File 'lib/zerg_support/open_ssh.rb', line 71 def self.first_line(string) string[0, string.index(/\r|\n/) || string.len] end |
.key_from_string(serialized_key) ⇒ Object
Reads a serialized key from a string.
59 60 61 62 63 64 65 66 67 68 |
# File 'lib/zerg_support/open_ssh.rb', line 59 def self.key_from_string(serialized_key) header = first_line serialized_key if header.index 'RSA' OpenSSL::PKey::RSA.new serialized_key elsif header.index 'DSA' OpenSSL::PKey::DSA.new serialized_key else raise 'Unknown key type' end end |
.known_hosts_keys(io) ⇒ Object
Extracts the keys from a file of known_hosts format.
7 8 9 10 11 |
# File 'lib/zerg_support/open_ssh.rb', line 7 def self.known_hosts_keys(io) io.each_line do |line| end end |
.load_key(io) ⇒ Object
Loads a serialized key from an IO instance (File, StringIO).
54 55 56 |
# File 'lib/zerg_support/open_ssh.rb', line 54 def self.load_key(io) key_from_string io.read end |
.pack_pubkey_components(strings) ⇒ Object
Packs string components into an openssh-encoded pubkey.
88 89 90 |
# File 'lib/zerg_support/open_ssh.rb', line 88 def self.pack_pubkey_components(strings) (strings.map { |s| [s.length].pack('N') }).zip(strings).flatten.join end |
.unpack_pubkey_components(str) ⇒ Object
Unpacks the string components in an openssh-encoded pubkey.
76 77 78 79 80 81 82 83 84 85 |
# File 'lib/zerg_support/open_ssh.rb', line 76 def self.unpack_pubkey_components(str) cs = [] i = 0 while i < str.length len = str[i, 4].unpack('N').first cs << str[i + 4, len] i += 4 + len end return cs end |