class Inspec::Resources::X509CertificateResource

Public Class Methods

new(opts) click to toggle source

@see tools.ietf.org/html/rfc5280#page-23

# File lib/inspec/resources/x509_certificate.rb, line 37
def initialize(opts)
  @opts = options(opts)
  @issuer = nil
  @parsed_subject = nil
  @parsed_issuer = nil
  @extensions = nil
  @content = @opts[:content]
  @content ||= read_file_content(@opts[:filepath])
  @cert = OpenSSL::X509::Certificate.new @content
end

Public Instance Methods

certificate?() click to toggle source
# File lib/inspec/resources/x509_certificate.rb, line 55
def certificate?
  !@cert.nil?
end
extensions() click to toggle source
# File lib/inspec/resources/x509_certificate.rb, line 116
def extensions
  # Return cached Mash if we already parsed the certificate extensions
  return @extensions if @extensions
  # Return the exception class if we failed to instantiate a Cert from file
  return @cert unless @cert.respond_to? :extensions

  # Use a Mash to make it easier to access hash elements in "its('entensions') {should ...}"
  @extensions = Hashie::Mash.new({})
  # Make sure standard extensions exist so we don't get nil for nil:NilClass
  # when the user tests for extensions which aren't present
  %w{
    keyUsage extendedKeyUsage basicConstraints subjectKeyIdentifier
    authorityKeyIdentifier subjectAltName issuerAltName authorityInfoAccess
    crlDistributionPoints issuingDistributionPoint certificatePolicies
    policyConstraints nameConstraints noCheck tlsfeature nsComment
  }.each { |extension| @extensions[extension] ||= [] }
  # Now parse the extensions into the Mash
  extension_array = @cert.extensions.map(&:to_s)
  extension_array.each do |extension|
    kv = extension.split(/ *= */, 2)
    @extensions[kv.first] = kv.last.split(/ *, */)
  end
  @extensions
end
fingerprint() click to toggle source
# File lib/inspec/resources/x509_certificate.rb, line 59
def fingerprint
  return if @cert.nil?

  OpenSSL::Digest.new("SHA1", @cert.to_der).to_s
end
issuer() click to toggle source
# File lib/inspec/resources/x509_certificate.rb, line 92
def issuer
  return if @cert.nil?
  # Return cached subject if we have already parsed it
  return @parsed_issuer if @parsed_issuer

  # Use a Mash to make it easier to access hash elements in "its('issuer') {should ...}"
  @parsed_issuer = Hashie::Mash.new(Hash[@cert.issuer.to_a.map { |k, v, _| [k, v] }])
end
issuer_dn() click to toggle source
# File lib/inspec/resources/x509_certificate.rb, line 86
def issuer_dn
  return if @cert.nil?

  @cert.issuer.to_s
end
key_length() click to toggle source
# File lib/inspec/resources/x509_certificate.rb, line 101
def key_length
  return if @cert.nil?

  @cert.public_key.n.num_bytes * 8
end
serial() click to toggle source
# File lib/inspec/resources/x509_certificate.rb, line 65
def serial
  return if @cert.nil?

  @cert.serial.to_i
end
subject() click to toggle source
# File lib/inspec/resources/x509_certificate.rb, line 77
def subject
  return if @cert.nil?
  # Return cached subject if we have already parsed it
  return @parsed_subject if @parsed_subject

  # Use a Mash to make it easier to access hash elements in "its('subject') {should ...}"
  @parsed_subject = Hashie::Mash.new(Hash[@cert.subject.to_a.map { |k, v, _| [k, v] }])
end
subject_dn() click to toggle source
# File lib/inspec/resources/x509_certificate.rb, line 71
def subject_dn
  return if @cert.nil?

  @cert.subject.to_s
end
to_s() click to toggle source
# File lib/inspec/resources/x509_certificate.rb, line 141
def to_s
  cert = @opts[:filepath]
  cert ||= subject.CN
  "x509_certificate #{cert}"
end
valid?() click to toggle source
# File lib/inspec/resources/x509_certificate.rb, line 111
def valid?
  now = Time.now
  certificate? && (now >= not_before && now <= not_after)
end
validity_in_days() click to toggle source
# File lib/inspec/resources/x509_certificate.rb, line 107
def validity_in_days
  (not_after - Time.now.utc) / 86400
end

Private Instance Methods

options(opts) click to toggle source
# File lib/inspec/resources/x509_certificate.rb, line 149
def options(opts)
  if opts.is_a?(String)
    { filepath: opts }
  else
    opts
  end
end