Class: OpenSSL::PKey::SSH

Inherits:
Object
  • Object
show all
Defined in:
lib/openssl/ssh.rb

Constant Summary collapse

RSA_COMPONENTS =
['ssh-rsa', :e, :n].freeze
DSA_COMPONENTS =
['ssh-dss', :p, :q, :g, :pub_key].freeze

Class Method Summary collapse

Class Method Details

.decode_mpi(mpi_str) ⇒ Object



72
73
74
# File 'lib/openssl/ssh.rb', line 72

def self.decode_mpi(mpi_str)
  mpi_str.unpack('C*').inject(0) { |a, e| (a << 8) | e }
end

.decode_pubkey(string) ⇒ Object



32
33
34
35
36
37
38
# File 'lib/openssl/ssh.rb', line 32

def self.decode_pubkey(string)
  components = unpack_pubkey_components Base64.decode64(string)
  raise "Unsupported key type #{components.first}" unless components.first.match?(/#{RSA_COMPONENTS.first}|#{DSA_COMPONENTS.first}/)

  ops, key = process_components(components)
  process_ops(key, ops)
end

.forward_private_key(key, password) ⇒ Object



15
16
17
18
19
20
21
22
# File 'lib/openssl/ssh.rb', line 15

def self.forward_private_key(key, password)
  case key
  when /BEGIN RSA PRIVATE KEY/
    OpenSSL::PKey::RSA.new(key, password)
  when /BEGIN DSA PRIVATE KEY/
    OpenSSL::PKey::DSA.new(key, password)
  end
end

.key_type_components(components) ⇒ Object



40
41
42
# File 'lib/openssl/ssh.rb', line 40

def self.key_type_components(components)
  (components.first.match?(RSA_COMPONENTS.first) ? RSA_COMPONENTS : DSA_COMPONENTS).zip(components)
end

.key_type_object(components) ⇒ Object



44
45
46
# File 'lib/openssl/ssh.rb', line 44

def self.key_type_object(components)
  components.first.match?(RSA_COMPONENTS.first) ? OpenSSL::PKey::RSA.new : OpenSSL::PKey::DSA.new
end

.new(key, password = nil) ⇒ Object



11
12
13
# File 'lib/openssl/ssh.rb', line 11

def self.new(key, password = nil)
  forward_private_key(key, password) || parse_public_ssh_key(key)
end

.parse_public_ssh_key(key) ⇒ Object



24
25
26
27
28
29
30
# File 'lib/openssl/ssh.rb', line 24

def self.parse_public_ssh_key(key)
  if key && key.is_a?(String) && key.match?(/^ssh-/)
    key = key.split[1]
    key = decode_pubkey(key)
  end
  key
end

.process_components(components) ⇒ Object



48
49
50
# File 'lib/openssl/ssh.rb', line 48

def self.process_components(components)
  [key_type_components(components), key_type_object(components)]
end

.process_ops(key, ops) ⇒ Object



52
53
54
55
56
57
58
59
# File 'lib/openssl/ssh.rb', line 52

def self.process_ops(key, ops)
  ops.each do |o|
    next unless o.first.is_a? Symbol

    key.send "#{o.first}=", decode_mpi(o.last)
  end
  key
end

.unpack_pubkey_components(str) ⇒ Object



61
62
63
64
65
66
67
68
69
70
# File 'lib/openssl/ssh.rb', line 61

def self.unpack_pubkey_components(str)
  cs = []
  i = 0
  while i < str.length
    len = str[i, 4].unpack1('N')
    cs << str[i + 4, len]
    i += 4 + len
  end
  cs
end