class R509::Cert
The primary certificate object.
Attributes
Public Class Methods
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
@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
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
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
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
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
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
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
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
@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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
# 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
# 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