Class: Cheffish::KeyFormatter

Inherits:
Object
  • Object
show all
Defined in:
lib/cheffish/key_formatter.rb

Class Method Summary collapse

Class Method Details

.decode(str, pass_phrase = nil, filename = "") ⇒ Object

Returns nil or key, format



11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
# File 'lib/cheffish/key_formatter.rb', line 11

def self.decode(str, pass_phrase = nil, filename = "")
  key_format = {}
  key_format[:format] = format_of(str)

  case key_format[:format]
  when :openssh
    key = decode_openssh_key(str, filename)
  else
    begin
      key = OpenSSL::PKey.read(str) { pass_phrase }
    rescue
      return nil
    end
  end

  key_format[:type] = type_of(key) if type_of(key)
  key_format[:size] = size_of(key) if size_of(key)
  key_format[:pass_phrase] = pass_phrase if pass_phrase
  # TODO cipher, exponent

  [key, key_format]
end

.decode_openssh_key(str, filename = "") ⇒ Object



71
72
73
# File 'lib/cheffish/key_formatter.rb', line 71

def self.decode_openssh_key(str, filename = "")
  Net::SSH::KeyFactory.load_data_public_key(str, filename)
end

.encode(key, key_format) ⇒ Object



34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
# File 'lib/cheffish/key_formatter.rb', line 34

def self.encode(key, key_format)
  format = key_format[:format] || :pem
  case format
  when :openssh
    encode_openssh_key(key)
  when :pem
    if key_format[:pass_phrase]
      cipher = key_format[:cipher] || "DES-EDE3-CBC"
      key.to_pem(OpenSSL::Cipher.new(cipher), key_format[:pass_phrase])
    else
      key.to_pem
    end
  when :der
    key.to_der
  when :fingerprint, :pkcs1md5fingerprint
    hexes = Digest::MD5.hexdigest(key.to_der)
    # Put : between every pair of hexes
    hexes.scan(/../).join(":")
  when :rfc4716md5fingerprint
    _type, base64_data, _etc = encode_openssh_key(key).split
    data = Base64.decode64(base64_data)
    hexes = Digest::MD5.hexdigest(data)
    hexes.scan(/../).join(":")
  when :pkcs8sha1fingerprint
    raise "PKCS8 SHA1 not supported by Ruby 2.0 and later"
  else
    raise "Unrecognized key format #{format}"
  end
end

.encode_openssh_key(key) ⇒ Object



64
65
66
67
68
69
# File 'lib/cheffish/key_formatter.rb', line 64

def self.encode_openssh_key(key)
  # TODO there really isn't a method somewhere in net/ssh or openssl that does this??
  type = key.ssh_type
  data = [ key.to_blob ].pack("m0")
  "#{type} #{data} #{Etc.getlogin}@#{Socket.gethostname}"
end

.format_of(key_contents) ⇒ Object



75
76
77
78
79
80
81
82
83
# File 'lib/cheffish/key_formatter.rb', line 75

def self.format_of(key_contents)
  if key_contents.start_with?("-----BEGIN ")
    :pem
  elsif key_contents.start_with?("ssh-rsa ", "ssh-dss ")
    :openssh
  else
    :der
  end
end

.size_of(key) ⇒ Object



96
97
98
99
100
101
102
103
# File 'lib/cheffish/key_formatter.rb', line 96

def self.size_of(key)
  case key.class
    when OpenSSL::PKey::RSA
      key.n.num_bytes * 8
    else
      nil
  end
end

.type_of(key) ⇒ Object



85
86
87
88
89
90
91
92
93
94
# File 'lib/cheffish/key_formatter.rb', line 85

def self.type_of(key)
  case key.class
    when OpenSSL::PKey::RSA
      :rsa
    when OpenSSL::PKey::DSA
      :dsa
    else
      nil
  end
end