Class: Inspec::Resources::X509CertificateResource

Inherits:
Object
  • Object
show all
Defined in:
lib/resources/x509_certificate.rb

Overview

rubocop:disable Metrics/ClassLength

Instance Method Summary collapse

Constructor Details

#initialize(filename) ⇒ X509CertificateResource

Returns a new instance of X509CertificateResource.



36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
# File 'lib/resources/x509_certificate.rb', line 36

def initialize(filename)
  @certpath = filename
  @issuer = nil
  @parsed_subject = nil
  @parsed_issuer = nil
  @extensions = nil

  file = inspec.file(@certpath)
  return skip_resource "Unable to find certificate file #{@certpath}" unless file.exist?

  begin
    @cert = OpenSSL::X509::Certificate.new file.content
  rescue OpenSSL::X509::CertificateError
    @cert = nil
    return skip_resource "Unable to load certificate #{@certpath}"
  end
end

Instance Method Details

#certificate?Boolean

Returns:

  • (Boolean)


61
62
63
# File 'lib/resources/x509_certificate.rb', line 61

def certificate?
  !@cert.nil?
end

#extensionsObject



115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
# File 'lib/resources/x509_certificate.rb', line 115

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

#fingerprintObject



65
66
67
68
# File 'lib/resources/x509_certificate.rb', line 65

def fingerprint
  return if @cert.nil?
  OpenSSL::Digest::SHA1.new(@cert.to_der).to_s
end

#issuerObject



93
94
95
96
97
98
99
# File 'lib/resources/x509_certificate.rb', line 93

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_dnObject



88
89
90
91
# File 'lib/resources/x509_certificate.rb', line 88

def issuer_dn
  return if @cert.nil?
  @cert.issuer.to_s
end

#key_lengthObject



101
102
103
104
# File 'lib/resources/x509_certificate.rb', line 101

def key_length
  return if @cert.nil?
  @cert.public_key.n.num_bytes * 8
end

#serialObject



70
71
72
73
# File 'lib/resources/x509_certificate.rb', line 70

def serial
  return if @cert.nil?
  @cert.serial.to_i
end

#subjectObject



80
81
82
83
84
85
86
# File 'lib/resources/x509_certificate.rb', line 80

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_dnObject



75
76
77
78
# File 'lib/resources/x509_certificate.rb', line 75

def subject_dn
  return if @cert.nil?
  @cert.subject.to_s
end

#to_sObject



139
140
141
# File 'lib/resources/x509_certificate.rb', line 139

def to_s
  "x509_certificate #{@certpath}"
end

#valid?Boolean

Returns:

  • (Boolean)


110
111
112
113
# File 'lib/resources/x509_certificate.rb', line 110

def valid?
  now = Time.now
  certificate? && (now >= not_before && now <= not_after)
end

#validity_in_daysObject



106
107
108
# File 'lib/resources/x509_certificate.rb', line 106

def validity_in_days
  (not_after - Time.now.utc) / 86400
end