Class: R509::Cert

Inherits:
Object
  • Object
show all
Includes:
Helpers
Defined in:
lib/r509/cert.rb,
lib/r509/cert/extensions/base.rb,
lib/r509/cert/extensions/key_usage.rb,
lib/r509/cert/extensions/ocsp_no_check.rb,
lib/r509/cert/extensions/validation_mixin.rb,
lib/r509/cert/extensions/name_constraints.rb,
lib/r509/cert/extensions/basic_constraints.rb,
lib/r509/cert/extensions/policy_constraints.rb,
lib/r509/cert/extensions/inhibit_any_policy.rb,
lib/r509/cert/extensions/extended_key_usage.rb,
lib/r509/cert/extensions/certificate_policies.rb,
lib/r509/cert/extensions/authority_info_access.rb,
lib/r509/cert/extensions/subject_key_identifier.rb,
lib/r509/cert/extensions/crl_distribution_points.rb,
lib/r509/cert/extensions/subject_alternative_name.rb,
lib/r509/cert/extensions/authority_key_identifier.rb

Overview

The primary certificate object.

Defined Under Namespace

Modules: Extensions

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(opts = {}) ⇒ Cert

Returns a new instance of Cert

Parameters:

  • opts (Hash) (defaults to: {})

    a customizable set of options

Options Hash (opts):

  • :cert (String, OpenSSL::X509::Certificate)

    a cert

  • :key (R509::PrivateKey, String)

    optional private key to supply. either an unencrypted PEM/DER string or an R509::PrivateKey object (use the latter if you need password/hardware support)

  • :pkcs12 (String)

    a PKCS12 object containing both key and cert

  • :password (String)

    password for PKCS12 or private key (if supplied)



19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
# File 'lib/r509/cert.rb', line 19

def initialize(opts = {})
  unless opts.is_a?(Hash)
    raise ArgumentError, 'Must provide a hash of options'
  end
  if opts.key?(:pkcs12) && ( opts.key?(:key) || opts.key?(:cert))
    raise ArgumentError, "When providing pkcs12, do not pass cert or key"
  elsif opts.key?(:pkcs12)
    pkcs12 = OpenSSL::PKCS12.new(opts[:pkcs12], opts[:password])
    parse_certificate(pkcs12.certificate)
    parse_private_key(pkcs12.key)
  elsif !opts.key?(:cert)
    raise ArgumentError, 'Must provide :cert or :pkcs12'
  else
    csr_check(opts[:cert])
    parse_certificate(opts[:cert])
  end

  if opts.key?(:key)
    parse_private_key(opts[:key], opts[:password])
  end
end

Instance Attribute Details

#certObject (readonly) Also known as: internal_obj

Returns the value of attribute cert



13
14
15
# File 'lib/r509/cert.rb', line 13

def cert
  @cert
end

#issuerObject (readonly)

Returns the value of attribute issuer



13
14
15
# File 'lib/r509/cert.rb', line 13

def issuer
  @issuer
end

#keyObject (readonly)

Returns the value of attribute key



13
14
15
# File 'lib/r509/cert.rb', line 13

def key
  @key
end

#subjectObject (readonly)

Returns the value of attribute subject



13
14
15
# File 'lib/r509/cert.rb', line 13

def subject
  @subject
end

Class Method Details

.load_from_file(filename) ⇒ R509::Cert

Helper method to quickly load a cert from the filesystem

Parameters:

  • filename (String)

    Path to file you want to load

Returns:



45
46
47
# File 'lib/r509/cert.rb', line 45

def self.load_from_file(filename)
  R509::Cert.new(:cert => IOHelpers.read_data(filename))
end

Instance Method Details

#all_namesArray

Return the CN, as well as all the subject alternative names (SANs).

Returns:

  • (Array)

    the array of names. Returns an empty array if there are no names, at all. Discards SAN types



130
131
132
133
134
135
136
# File 'lib/r509/cert.rb', line 130

def all_names
  ret = []
  ret << @subject.CN unless @subject.CN.nil?
  ret.concat(self.san.names.map { |n| n.value }) unless self.san.nil?

  ret.sort.uniq
end

#authority_info_accessR509::Cert::Extensions::AuthorityInfoAccess Also known as: aia

Returns this object's AuthorityInfoAccess extension as an R509 extension

if this cert does not have a AuthorityInfoAccess extension.

Returns:



250
251
252
# File 'lib/r509/cert.rb', line 250

def authority_info_access
  extensions[R509::Cert::Extensions::AuthorityInfoAccess]
end

#authority_key_identifierR509::Cert::Extensions::AuthorityKeyIdentifier

Returns this object's AuthorityKeyIdentifier extension as an R509 extension

if this cert does not have a AuthorityKeyIdentifier extension.

Returns:



232
233
234
# File 'lib/r509/cert.rb', line 232

def authority_key_identifier
  extensions[R509::Cert::Extensions::AuthorityKeyIdentifier]
end

#basic_constraintsR509::Cert::Extensions::BasicConstraints

Returns this object's BasicConstraints extension as an R509 extension

if this cert does not have a BasicConstraints extension.

Returns:



198
199
200
# File 'lib/r509/cert.rb', line 198

def basic_constraints
  extensions[R509::Cert::Extensions::BasicConstraints]
end

#bit_lengthInteger Also known as: bit_strength Originally defined in module Helpers

Returns the bit length of the key

Returns:

  • (Integer)

    the integer bit length.

#certificate_policiesR509::Cert::Extensions::CertificatePolicies

Returns this object's CertificatePolicies extension as an R509 extension

if this cert does not have a CertificatePolicies extension.

Returns:



276
277
278
# File 'lib/r509/cert.rb', line 276

def certificate_policies
  extensions[R509::Cert::Extensions::CertificatePolicies]
end

#crl_distribution_pointsR509::Cert::Extensions::CRLDistributionPoints Also known as: cdp

Returns this object's CRLDistributionPoints extension as an R509 extension

if this cert does not have a CRLDistributionPoints extension.

Returns:



259
260
261
# File 'lib/r509/cert.rb', line 259

def crl_distribution_points
  extensions[R509::Cert::Extensions::CRLDistributionPoints]
end

#curve_nameString Originally defined in module Helpers

Returns the short name of the elliptic curve used to generate the public key if the key is EC. If not, raises an error.

Returns:

  • (String)

    elliptic curve name

#dsa?Boolean Originally defined in module Helpers

Returns whether the public key is DSA

Returns:

  • (Boolean)

    true if the public key is DSA, false otherwise

#ec?Boolean Originally defined in module Helpers

Returns whether the public key is EC

Returns:

  • (Boolean)

    true if the public key is EC, false otherwise

#extended_key_usageR509::Cert::Extensions::ExtendedKeyUsage Also known as: eku

Returns this object's ExtendedKeyUsage extension as an R509 extension

if this cert does not have a ExtendedKeyUsage extension.

Returns:



215
216
217
# File 'lib/r509/cert.rb', line 215

def extended_key_usage
  extensions[R509::Cert::Extensions::ExtendedKeyUsage]
end

#extensionsHash

Returns the certificate extensions as a hash of R509::Cert::Extensions specific objects.

R509::Cert::Extensions module, each specific to the extension. The hash is keyed with the R509 extension class. Extensions without an R509 implementation are ignored (see #get_unknown_extensions).

Returns:

  • (Hash)

    A hash, in which the values are classes from the



174
175
176
177
178
179
180
# File 'lib/r509/cert.rb', line 174

def extensions
  if @r509_extensions.nil?
    @r509_extensions = Extensions.wrap_openssl_extensions(self.cert.extensions)
  end

  @r509_extensions
end

#fingerprint(algorithm = 'sha256') ⇒ String

Returns the certificate fingerprint with the specified algorithm (default sha256)

Parameters:

  • algorithm (String) (defaults to: 'sha256')

    Which algorithm to use for the fingerprint. See R509::MessageDigest for supported algorithm names

Returns:

  • (String)

    hex digest of the certificate



90
91
92
93
94
95
# File 'lib/r509/cert.rb', line 90

def fingerprint(algorithm = 'sha256')
  message_digest = R509::MessageDigest.new(algorithm)
  md = message_digest.digest
  md.update(@cert.to_der)
  md.to_s
end

#has_private_key?Boolean

Returns Boolean of whether the object contains a private key

Returns:

  • (Boolean)

    Boolean of whether the object contains a private key



122
123
124
# File 'lib/r509/cert.rb', line 122

def has_private_key?
  !@key.nil?
end

#hexserialString

Returns the serial number of the certificate in hexadecimal form

Returns:

  • (String)


68
69
70
# File 'lib/r509/cert.rb', line 68

def hexserial
  @cert.serial.to_s(16)
end

#inhibit_any_policyR509::Cert::Extensions::InhibitAnyPolicy

Returns this object's InhibitAnyPolicy extension as an R509 extension

if this cert does not have a InhibitAnyPolicy extension.

Returns:



284
285
286
# File 'lib/r509/cert.rb', line 284

def inhibit_any_policy
  extensions[R509::Cert::Extensions::InhibitAnyPolicy]
end

#is_revoked_by_crl?(r509_crl) ⇒ Boolean

Checks the given CRL for this certificate's serial number. Note that this does NOT check to verify that the CRL you're checking is signed by the same CA as the cert so do that check yourself

Parameters:

Returns:

  • (Boolean)


163
164
165
# File 'lib/r509/cert.rb', line 163

def is_revoked_by_crl?(r509_crl)
  r509_crl.revoked?(self.serial)
end

#key_algorithmString Originally defined in module Helpers

Returns key algorithm (RSA/DSA/EC)

Returns:

  • (String)

    value of the key algorithm.

#key_usageR509::Cert::Extensions::KeyUsage Also known as: ku

Returns this object's KeyUsage extension as an R509 extension

if this cert does not have a KeyUsage extension.

Returns:



206
207
208
# File 'lib/r509/cert.rb', line 206

def key_usage
  extensions[R509::Cert::Extensions::KeyUsage]
end

#name_constraintsR509::Cert::Extensions::NameConstraints

Returns this object's NameConstraints extension as an R509 extension

if this cert does not have a NameConstraints extension.

Returns:



300
301
302
# File 'lib/r509/cert.rb', line 300

def name_constraints
  extensions[R509::Cert::Extensions::NameConstraints]
end

#not_afterTime

Returns ending (notAfter) of certificate validity period

Returns:

  • (Time)

    time object



75
76
77
# File 'lib/r509/cert.rb', line 75

def not_after
  @cert.not_after
end

#not_beforeTime

Returns beginning (notBefore) of certificate validity period

Returns:

  • (Time)

    time object



54
55
56
# File 'lib/r509/cert.rb', line 54

def not_before
  @cert.not_before
end

#ocsp_no_check?Boolean

Returns true if the OCSP No Check extension is present (value is irrelevant to this extension)

Returns:

  • (Boolean)

    presence/absence of the nocheck extension



268
269
270
# File 'lib/r509/cert.rb', line 268

def ocsp_no_check?
  (extensions.key?(R509::Cert::Extensions::OCSPNoCheck))
end

#policy_constraintsR509::Cert::Extensions::PolicyConstraints

Returns this object's PolicyConstraints extension as an R509 extension

if this cert does not have a PolicyConstraints extension.

Returns:



292
293
294
# File 'lib/r509/cert.rb', line 292

def policy_constraints
  extensions[R509::Cert::Extensions::PolicyConstraints]
end

#public_keyOpenSSL::PKey::RSA

Returns the certificate public key

Returns:

  • (OpenSSL::PKey::RSA)

    public key object



82
83
84
# File 'lib/r509/cert.rb', line 82

def public_key
  @cert.public_key
end

#rsa?Boolean Originally defined in module Helpers

Returns whether the public key is RSA

Returns:

  • (Boolean)

    true if the public key is RSA, false otherwise

#serialInteger

Returns the serial number of the certificate in decimal form

Returns:

  • (Integer)


61
62
63
# File 'lib/r509/cert.rb', line 61

def serial
  @cert.serial.to_i
end

#signature_algorithmString

Returns signature algorithm

Returns:

  • (String)

    value of the signature algorithm. E.g. sha1WithRSAEncryption, sha256WithRSAEncryption, md5WithRSAEncryption, et cetera



141
142
143
# File 'lib/r509/cert.rb', line 141

def signature_algorithm
  @cert.signature_algorithm
end

#subject_alternative_nameR509::Cert::Extensions::SubjectAlternativeName Also known as: san, subject_alt_name

Returns this object's SubjectAlternativeName extension as an R509 extension

if this cert does not have a SubjectAlternativeName extension.

Returns:



240
241
242
# File 'lib/r509/cert.rb', line 240

def subject_alternative_name
  extensions[R509::Cert::Extensions::SubjectAlternativeName]
end

#subject_key_identifierR509::Cert::Extensions::SubjectKeyIdentifier

Returns this object's SubjectKeyIdentifier extension as an R509 extension

if this cert does not have a SubjectKeyIdentifier extension.

Returns:



224
225
226
# File 'lib/r509/cert.rb', line 224

def subject_key_identifier
  extensions[R509::Cert::Extensions::SubjectKeyIdentifier]
end

#to_derString Originally defined in module Helpers

Converts the object into DER format

Returns:

  • (String)

    the object converted into DER format.

#to_pemString Originally defined in module Helpers

Converts the object into PEM format

Returns:

  • (String)

    the object converted into PEM format.

#unknown_extensionsArray

Returns an array of OpenSSL::X509::Extension objects representing the extensions that do not have R509 implementations.

Returns:

  • (Array)

    An array of OpenSSL::X509::Extension objects.



186
187
188
# File 'lib/r509/cert.rb', line 186

def unknown_extensions
  Extensions.get_unknown_extensions(self.cert.extensions)
end

#valid?Boolean

Returns whether the current time is between the notBefore and notAfter times in the certificate.

Returns:

  • (Boolean)


101
102
103
# File 'lib/r509/cert.rb', line 101

def valid?
  valid_at?(Time.now)
end

#valid_at?(time) ⇒ Boolean

Returns whether the certificate was between its notBefore and notAfter at the time provided

Parameters:

  • time (Time, Integer)

    Time object or integer timestamp

Returns:

  • (Boolean)


109
110
111
112
113
114
115
116
117
118
119
# File 'lib/r509/cert.rb', line 109

def valid_at?(time)
  if time.is_a?(Integer)
    time = Time.at(time)
  end

  if (self.not_after < time) || (self.not_before > time)
    false
  else
    true
  end
end

#write_der(filename_or_io) ⇒ Object Originally defined in module Helpers

Writes the object into DER format

Parameters:

  • filename_or_io (String, #write)

    Either a string of the path for the file that you'd like to write, or an IO-like object.

#write_pem(filename_or_io) ⇒ Object Originally defined in module Helpers

Writes the object into PEM format

Parameters:

  • filename_or_io (String, #write)

    Either a string of the path for the file that you'd like to write, or an IO-like object.

#write_pkcs12(filename_or_io, password, friendly_name = 'r509 pkcs12') ⇒ Object

Writes cert and key into PKCS12 format using OpenSSL defaults for encryption (des3)

Parameters:

  • filename_or_io (String, #write)

    Either a string of the path for the file that you'd like to write, or an IO-like object.

  • password (String)

    password

  • friendly_name (String) (defaults to: 'r509 pkcs12')

    An optional string to encode in the PKCS12 for friendlyName. defaults to “r509 pkcs12”



150
151
152
153
154
155
156
# File 'lib/r509/cert.rb', line 150

def write_pkcs12(filename_or_io, password, friendly_name = 'r509 pkcs12')
  if @key.nil?
    raise R509::R509Error, "Writing a PKCS12 requires both key and cert"
  end
  pkcs12 = OpenSSL::PKCS12.create(password, friendly_name, @key.key, @cert)
  write_data(filename_or_io, pkcs12.to_der)
end