class R509::Cert

The primary certificate object.

Attributes

cert[R]
internal_obj[R]
issuer[R]
key[R]
subject[R]

Public Class Methods

load_from_file(filename) click to toggle source

Helper method to quickly load a cert from the filesystem

@param [String] filename Path to file you want to load @return [R509::Cert] cert object

# File lib/r509/cert.rb, line 45
def self.load_from_file(filename)
  R509::Cert.new(:cert => IOHelpers.read_data(filename))
end
new(opts = {}) click to toggle source

@option opts [String,OpenSSL::X509::Certificate] :cert a cert @option opts [R509::PrivateKey,String] :key 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) @option opts [String] :pkcs12 a PKCS12 object containing both key and cert @option opts [String] :password password for PKCS12 or private key (if supplied)

# 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

Public Instance Methods

aia()
all_names() click to toggle source

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

@return [Array] the array of names. Returns an empty array if

there are no names, at all. Discards SAN types
# 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_access() click to toggle source

Returns this object's AuthorityInfoAccess extension as an R509 extension

@return [R509::Cert::Extensions::AuthorityInfoAccess] The object, or nil if this cert does not have a AuthorityInfoAccess extension.

# File lib/r509/cert.rb, line 250
def authority_info_access
  extensions[R509::Cert::Extensions::AuthorityInfoAccess]
end
Also aliased as: aia
authority_key_identifier() click to toggle source

Returns this object's AuthorityKeyIdentifier extension as an R509 extension

@return [R509::Cert::Extensions::AuthorityKeyIdentifier] The object, or nil if this cert does not have a AuthorityKeyIdentifier extension.

# File lib/r509/cert.rb, line 232
def authority_key_identifier
  extensions[R509::Cert::Extensions::AuthorityKeyIdentifier]
end
basic_constraints() click to toggle source

Returns this object's BasicConstraints extension as an R509 extension

@return [R509::Cert::Extensions::BasicConstraints] The object, or nil if this cert does not have a BasicConstraints extension.

# File lib/r509/cert.rb, line 198
def basic_constraints
  extensions[R509::Cert::Extensions::BasicConstraints]
end
cdp()
certificate_policies() click to toggle source

Returns this object's CertificatePolicies extension as an R509 extension

@return [R509::Cert::Extensions::CertificatePolicies] The object, or nil if this cert does not have a CertificatePolicies extension.

# File lib/r509/cert.rb, line 276
def certificate_policies
  extensions[R509::Cert::Extensions::CertificatePolicies]
end
crl_distribution_points() click to toggle source

Returns this object's CRLDistributionPoints extension as an R509 extension

@return [R509::Cert::Extensions::CRLDistributionPoints] The object, or nil if this cert does not have a CRLDistributionPoints extension.

# File lib/r509/cert.rb, line 259
def crl_distribution_points
  extensions[R509::Cert::Extensions::CRLDistributionPoints]
end
Also aliased as: cdp
eku()
Alias for: extended_key_usage
extended_key_usage() click to toggle source

Returns this object's ExtendedKeyUsage extension as an R509 extension

@return [R509::Cert::Extensions::ExtendedKeyUsage] The object, or nil if this cert does not have a ExtendedKeyUsage extension.

# File lib/r509/cert.rb, line 215
def extended_key_usage
  extensions[R509::Cert::Extensions::ExtendedKeyUsage]
end
Also aliased as: eku
extensions() click to toggle source

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

@return [Hash] A hash, in which the values are classes from the 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).

# 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') click to toggle source

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

@param [String] algorithm Which algorithm to use for the fingerprint. See R509::MessageDigest for supported algorithm names @return [String] hex digest of the certificate

# 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?() click to toggle source

@return [Boolean] Boolean of whether the object contains a private key

# File lib/r509/cert.rb, line 122
def has_private_key?
  !@key.nil?
end
hexserial() click to toggle source

Returns the serial number of the certificate in hexadecimal form

@return [String]

# File lib/r509/cert.rb, line 68
def hexserial
  @cert.serial.to_s(16)
end
inhibit_any_policy() click to toggle source

Returns this object's InhibitAnyPolicy extension as an R509 extension

@return [R509::Cert::Extensions::InhibitAnyPolicy] The object, or nil if this cert does not have a InhibitAnyPolicy extension.

# File lib/r509/cert.rb, line 284
def inhibit_any_policy
  extensions[R509::Cert::Extensions::InhibitAnyPolicy]
end
is_revoked_by_crl?(r509_crl) click to toggle source

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

@param [R509::CRL::SignedList] r509_crl A CRL from the CA that issued this certificate.

# File lib/r509/cert.rb, line 163
def is_revoked_by_crl?(r509_crl)
  r509_crl.revoked?(self.serial)
end
key_usage() click to toggle source

Returns this object's KeyUsage extension as an R509 extension

@return [R509::Cert::Extensions::KeyUsage] The object, or nil if this cert does not have a KeyUsage extension.

# File lib/r509/cert.rb, line 206
def key_usage
  extensions[R509::Cert::Extensions::KeyUsage]
end
Also aliased as: ku
ku()
Alias for: key_usage
name_constraints() click to toggle source

Returns this object's NameConstraints extension as an R509 extension

@return [R509::Cert::Extensions::NameConstraints] The object, or nil if this cert does not have a NameConstraints extension.

# File lib/r509/cert.rb, line 300
def name_constraints
  extensions[R509::Cert::Extensions::NameConstraints]
end
not_after() click to toggle source

Returns ending (notAfter) of certificate validity period

@return [Time] time object

# File lib/r509/cert.rb, line 75
def not_after
  @cert.not_after
end
not_before() click to toggle source

Returns beginning (notBefore) of certificate validity period

@return [Time] time object

# File lib/r509/cert.rb, line 54
def not_before
  @cert.not_before
end
ocsp_no_check?() click to toggle source

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

@return [Boolean] presence/absence of the nocheck extension

# File lib/r509/cert.rb, line 268
def ocsp_no_check?
  (extensions.key?(R509::Cert::Extensions::OCSPNoCheck))
end
policy_constraints() click to toggle source

Returns this object's PolicyConstraints extension as an R509 extension

@return [R509::Cert::Extensions::PolicyConstraints] The object, or nil if this cert does not have a PolicyConstraints extension.

# File lib/r509/cert.rb, line 292
def policy_constraints
  extensions[R509::Cert::Extensions::PolicyConstraints]
end
public_key() click to toggle source

Returns the certificate public key

@return [OpenSSL::PKey::RSA] public key object

# File lib/r509/cert.rb, line 82
def public_key
  @cert.public_key
end
san()
serial() click to toggle source

Returns the serial number of the certificate in decimal form

@return [Integer]

# File lib/r509/cert.rb, line 61
def serial
  @cert.serial.to_i
end
signature_algorithm() click to toggle source

Returns signature algorithm

@return [String] value of the signature algorithm. E.g. sha1WithRSAEncryption, sha256WithRSAEncryption, md5WithRSAEncryption, et cetera

# File lib/r509/cert.rb, line 141
def signature_algorithm
  @cert.signature_algorithm
end
subject_alt_name()
subject_alternative_name() click to toggle source

Returns this object's SubjectAlternativeName extension as an R509 extension

@return [R509::Cert::Extensions::SubjectAlternativeName] The object, or nil if this cert does not have a SubjectAlternativeName extension.

# File lib/r509/cert.rb, line 240
def subject_alternative_name
  extensions[R509::Cert::Extensions::SubjectAlternativeName]
end
Also aliased as: san, subject_alt_name
subject_key_identifier() click to toggle source

Returns this object's SubjectKeyIdentifier extension as an R509 extension

@return [R509::Cert::Extensions::SubjectKeyIdentifier] The object, or nil if this cert does not have a SubjectKeyIdentifier extension.

# File lib/r509/cert.rb, line 224
def subject_key_identifier
  extensions[R509::Cert::Extensions::SubjectKeyIdentifier]
end
unknown_extensions() click to toggle source

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

@return [Array] An array of OpenSSL::X509::Extension objects.

# File lib/r509/cert.rb, line 186
def unknown_extensions
  Extensions.get_unknown_extensions(self.cert.extensions)
end
valid?() click to toggle source

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

@return [Boolean]

# File lib/r509/cert.rb, line 101
def valid?
  valid_at?(Time.now)
end
valid_at?(time) click to toggle source

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

@param [Time,Integer] time Time object or integer timestamp @return [Boolean]

# 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_pkcs12(filename_or_io, password, friendly_name = 'r509 pkcs12') click to toggle source

Writes cert and key into PKCS12 format using OpenSSL defaults for encryption (des3) @param [String, write] filename_or_io Either a string of the path for

the file that you'd like to write, or an IO-like object.

@param [String] password password @param [String] friendly_name An optional string to encode in the PKCS12 for friendlyName. defaults to “r509 pkcs12”

# 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

Private Instance Methods

csr_check(cert) click to toggle source

This method exists only to provide a friendlier error msg if you attempt to parse a CSR as a certificate. All for Sean

# File lib/r509/cert.rb, line 308
def csr_check(cert)
  begin
    OpenSSL::X509::Request.new cert
    raise ArgumentError, 'Cert provided is actually a certificate signing request.'
  rescue OpenSSL::X509::RequestError
    # do nothing, it shouldn't be a CSR anyway!
  end
end
parse_certificate(cert) click to toggle source
# File lib/r509/cert.rb, line 317
def parse_certificate(cert)
  @cert = OpenSSL::X509::Certificate.new cert
  @subject = R509::Subject.new(@cert.subject)
  @issuer = R509::Subject.new(@cert.issuer)
end
parse_private_key(key, password = nil) click to toggle source
# File lib/r509/cert.rb, line 323
def parse_private_key(key, password = nil)
  unless key.is_a?(R509::PrivateKey)
    key = R509::PrivateKey.new(:key => key, :password => password)
  end
  unless @cert.public_key.to_der == key.public_key.to_der
    raise R509Error, 'Key does not match cert.'
  end
  @key = key
end