Module: ChefCookbook::TLS::CLI::Helpers

Defined in:
lib/tls/cli/helpers.rb

Class Method Summary collapse

Class Method Details

.find_valid_item(path) ⇒ Object



87
88
89
90
91
# File 'lib/tls/cli/helpers.rb', line 87

def self.find_valid_item(path)
  get_possible_items(path).max_by do |x|
    ::Date.parse(x)
  end
end

.get_certificates(path) ⇒ Object



98
99
100
101
102
103
104
105
106
107
108
109
# File 'lib/tls/cli/helpers.rb', line 98

def self.get_certificates(path)
  certificates = []
  ::IO.readlines(path).each do |ln|
    if ln == "-----BEGIN CERTIFICATE-----\n"
      certificates << ln
    else
      certificates[-1] += ln
    end
  end

  certificates.map { |x| x.strip }
end

.get_domain_list(pwd, entry_name, item_name) ⇒ Object



116
117
118
119
120
121
122
123
124
125
126
127
128
# File 'lib/tls/cli/helpers.rb', line 116

def self.get_domain_list(pwd, entry_name, item_name)
  cert_file = ::File.join(pwd, entry_name, item_name, 'server.crt')
  cert = ::OpenSSL::X509::Certificate.new(::IO.read(cert_file))
  domains = []

  cert.extensions.each do |x|
    if x.oid == 'subjectAltName'
      domains += x.value.split(',').map { |x| x.split(':')[1] }
    end
  end

  domains
end

.get_fullchain(pwd, entry_name, item_name) ⇒ Object



111
112
113
114
# File 'lib/tls/cli/helpers.rb', line 111

def self.get_fullchain(pwd, entry_name, item_name)
  fullchain_file = ::File.join(pwd, entry_name, item_name, 'server.fullchain.crt')
  get_certificates(fullchain_file)
end

.get_hpkp_pin(key_file) ⇒ Object



130
131
132
133
134
135
136
137
138
139
140
141
# File 'lib/tls/cli/helpers.rb', line 130

def self.get_hpkp_pin(key_file)
  key = ::OpenSSL::PKey.read(::IO.read(key_file))
  public_key = nil
  if key.class == ::OpenSSL::PKey::RSA
    public_key = key.public_key
  elsif key.class == ::OpenSSL::PKey::EC
    public_key = ::OpenSSL::PKey::EC.new(key.group.curve_name)
    public_key.public_key = key.public_key
  end

  ::Digest::SHA256.base64digest(public_key.to_der)
end

.get_hpkp_pin_list(pwd, entry_name, item_name) ⇒ Object



143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
# File 'lib/tls/cli/helpers.rb', line 143

def self.get_hpkp_pin_list(pwd, entry_name, item_name)
  pin_list = []
  main_key_file = ::File.join(pwd, entry_name, item_name, 'server.key')
  pin_list << get_hpkp_pin(main_key_file)

  emergency_key_file = nil
  key = ::OpenSSL::PKey.read(::IO.read(main_key_file))
  if key.class == ::OpenSSL::PKey::RSA
    emergency_key_file = ::File.join(pwd, '.emergency', 'rsa', 'server.key')
  elsif key.class == ::OpenSSL::PKey::EC
    emergency_key_file = ::File.join(pwd, '.emergency', 'ec', 'server.key')
  end
  if !emergency_key_file.nil? && ::File.file?(emergency_key_file)
    pin_list.unshift(get_hpkp_pin(emergency_key_file))
  end

  next_key_file = ::File.join(pwd, entry_name, 'next', 'server.key')
  pin_list << get_hpkp_pin(next_key_file)

  pin_list
end

.get_possible_items(path) ⇒ Object



78
79
80
81
82
83
84
85
# File 'lib/tls/cli/helpers.rb', line 78

def self.get_possible_items(path)
  dir = ::Dir.new(path)
  certificate_dir_regexp = /^\d{4}-\d{2}-\d{2}$/
  dir.select do |x|
    subdir_path = ::File.join(path, x)
    ::File.directory?(subdir_path) && !certificate_dir_regexp.match(x).nil? && valid_certificate_directory?(subdir_path)
  end
end

.get_private_key(pwd, entry_name, item_name) ⇒ Object



93
94
95
96
# File 'lib/tls/cli/helpers.rb', line 93

def self.get_private_key(pwd, entry_name, item_name)
  path = ::File.join(pwd, entry_name, item_name, 'server.key')
  return ::IO.read(path).strip
end

.get_scts(pwd, entry_name, item_name) ⇒ Object



165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
# File 'lib/tls/cli/helpers.rb', line 165

def self.get_scts(pwd, entry_name, item_name)
  scts_dir = ::File.join(pwd, entry_name, item_name, 'scts')
  h = {}
  if ::File.directory?(scts_dir)
    ::Dir.new(scts_dir).each do |x|
      path = ::File.join(scts_dir, x)
      if ::File.file?(path) && ::File.extname(path) == '.sct'
        log_name = ::File.basename(path, '.sct')
        h[log_name] = ::Base64.strict_encode64(::IO.read(path))
      end
    end
  end

  h
end

.jsonify_entry(pwd, entry_name) ⇒ Object



181
182
183
184
185
186
187
188
189
190
191
# File 'lib/tls/cli/helpers.rb', line 181

def self.jsonify_entry(pwd, entry_name)
  item_name = find_valid_item(::File.join(pwd, entry_name))
  {
    name: entry_name,
    domains: get_domain_list(pwd, entry_name, item_name),
    chain: get_fullchain(pwd, entry_name, item_name),
    private_key: get_private_key(pwd, entry_name, item_name),
    hpkp_pins: get_hpkp_pin_list(pwd, entry_name, item_name),
    scts: get_scts(pwd, entry_name, item_name)
  }
end

.list_entries(pwd) ⇒ Object



65
66
67
68
69
70
71
72
73
74
75
76
# File 'lib/tls/cli/helpers.rb', line 65

def self.list_entries(pwd)
  dir = ::Dir.new(pwd)
  stop_list = %w(
    .
    ..
    .emergency
  )
  dir.select do |x|
    path = ::File.join(pwd, x)
    !stop_list.include?(x) && ::File.directory?(path) && valid_directory?(path)
  end
end

.valid_certificate_directory?(path) ⇒ Boolean

Returns:

  • (Boolean)


33
34
35
36
37
38
# File 'lib/tls/cli/helpers.rb', line 33

def self.valid_certificate_directory?(path)
  valid_key_file?(::File.join(path, 'server.key')) &&
  valid_certificate_file?(::File.join(path, 'server.crt')) &&
  ::File.exist?(::File.join(path, 'server.chain.crt')) &&
  ::File.exist?(::File.join(path, 'server.fullchain.crt'))
end

.valid_certificate_file?(cert_file) ⇒ Boolean

Returns:

  • (Boolean)


24
25
26
27
28
29
30
31
# File 'lib/tls/cli/helpers.rb', line 24

def self.valid_certificate_file?(cert_file)
  cert = nil
  if ::File.exist?(cert_file)
    cert = ::OpenSSL::X509::Certificate.new(::IO.read(cert_file))
  end

  !cert.nil?
end

.valid_directory?(path) ⇒ Boolean

Returns:

  • (Boolean)


44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
# File 'lib/tls/cli/helpers.rb', line 44

def self.valid_directory?(path)
  certificate_dir_regexp = /^\d{4}-\d{2}-\d{2}$/
  has_next_dir = false
  has_certificate_dir = false
  dir = ::Dir.new(path)
  dir.each do |x|
    subdir_path = ::File.join(path, x)
    if ::File.directory?(subdir_path)
      if x == 'next'
        has_next_dir = valid_next_directory?(subdir_path)
      end

      if !has_certificate_dir && !certificate_dir_regexp.match(x).nil?
        has_certificate_dir = valid_certificate_directory?(subdir_path)
      end
    end
  end

  has_next_dir && has_certificate_dir
end

.valid_key_file?(key_file) ⇒ Boolean

Returns:

  • (Boolean)


11
12
13
14
15
16
17
18
19
20
21
22
# File 'lib/tls/cli/helpers.rb', line 11

def self.valid_key_file?(key_file)
  key = nil
  if ::File.exist?(key_file)
    begin
      key = ::OpenSSL::PKey.read(::IO.read(key_file))
    rescue ::OpenSSL::PKey::PKeyError
      key = nil
    end
  end

  !key.nil?
end

.valid_next_directory?(path) ⇒ Boolean

Returns:

  • (Boolean)


40
41
42
# File 'lib/tls/cli/helpers.rb', line 40

def self.valid_next_directory?(path)
  valid_key_file?(::File.join(path, 'server.key'))
end