class SSLTool::Certificate

Constants

RX_DOMAIN_NAME

Public Class Methods

new(s) click to toggle source
Calls superclass method
# File lib/ssltool/certificate.rb, line 16
def self.new(s)
  cert = super(s)
  k = cert.fingerprint
  @@certificate_cache.delete(k) if v = @@certificate_cache[k] and v.respond_to?(:weakref_alive?) && !v.weakref_alive?
  (@@certificate_cache[k] ||= WeakRef.new(cert)).__getobj__
end
scan(s) click to toggle source

returns an array of Certificate objects created from cert strings found in s

# File lib/ssltool/certificate.rb, line 24
def self.scan(s)
  PEMScanner.certs_from(s).uniq
end

Public Instance Methods

acceptable?() click to toggle source
# File lib/ssltool/certificate.rb, line 122
def acceptable?
  valid? && (!key_size || key_size_secure?)
end
authority_key_identifier() click to toggle source
# File lib/ssltool/certificate.rb, line 97
def authority_key_identifier
  map_extension_value('authorityKeyIdentifier') { |s| s.sub(/^keyid:/, '').chomp }
end
certificate_authority?() click to toggle source
# File lib/ssltool/certificate.rb, line 85
def certificate_authority?
  map_extension_value('basicConstraints') { |s| s.split(", ").include?('CA:TRUE') }
end
certificate_sign?() click to toggle source
# File lib/ssltool/certificate.rb, line 89
def certificate_sign?
  map_extension_value('keyUsage') { |s| s.split(", ").include?('Certificate Sign') }
end
chain_from(certs) click to toggle source

chain

# File lib/ssltool/certificate.rb, line 147
def chain_from(certs)
  chain  = [self]
  parent = (certs - chain).find { |cert| cert.parent?(self) }
  chain.concat(parent.chain_from(certs - chain)) if parent
  chain
end
common_names() click to toggle source
# File lib/ssltool/certificate.rb, line 63
def common_names
  subject.to_a.select { |k, _, _| k == "CN" }.map { |_, v, _| v }
end
domain_names() click to toggle source
# File lib/ssltool/certificate.rb, line 75
def domain_names
  [ domain_names_from_common_names,
    domain_names_from_subject_alt_names,
  ].flatten.compact.sort.uniq
end
domain_names_from_common_names() click to toggle source
# File lib/ssltool/certificate.rb, line 67
def domain_names_from_common_names
  common_names.select { |cn| cn =~ RX_DOMAIN_NAME }
end
domain_names_from_subject_alt_names() click to toggle source
# File lib/ssltool/certificate.rb, line 71
def domain_names_from_subject_alt_names
  map_extension_value('subjectAltName') { |s| s.scan(/\bDNS:([^\s,]+)/) }
end
extensions() click to toggle source
Calls superclass method
# File lib/ssltool/certificate.rb, line 135
def extensions
  super.tap { |a| class << a; include Extensions; end }
end
fingerprint() click to toggle source

properties

# File lib/ssltool/certificate.rb, line 59
def fingerprint
  @fingerprint ||= Digest::SHA1.hexdigest(to_der)
end
for_domain_name?() click to toggle source
# File lib/ssltool/certificate.rb, line 81
def for_domain_name?
  !domain_names.empty?
end
key_size() click to toggle source
# File lib/ssltool/certificate.rb, line 101
def key_size
  case public_key
  when OpenSSL::PKey::RSA ; public_key.n.num_bits
  when OpenSSL::PKey::EC  ; public_key.group.order.num_bits
  else                    ; nil
  end
end
key_size_secure?() click to toggle source
# File lib/ssltool/certificate.rb, line 109
def key_size_secure?
  case public_key
  when OpenSSL::PKey::RSA ; key_size >= 2048
  when OpenSSL::PKey::EC  ; key_size >= 224
  else                    ; nil
  end
end
map_extension_value(extension_name, default = nil) { |value| ... } click to toggle source
# File lib/ssltool/certificate.rb, line 139
def map_extension_value(extension_name, default = nil)
  e = extensions[extension_name]
  return default if e.nil?
  block_given? ? yield(e.value) : e.value
end
parent?(other_cert) click to toggle source
# File lib/ssltool/certificate.rb, line 51
def parent?(other_cert)
  signs?(other_cert) \
  && subject == other_cert.issuer \
  && subject_key_identifier == other_cert.authority_key_identifier
end
self_issued?() click to toggle source
# File lib/ssltool/certificate.rb, line 47
def self_issued?
  subject.eql?(issuer)
end
self_signed?() click to toggle source
# File lib/ssltool/certificate.rb, line 43
def self_signed?
  signs?(self)
end
signed_by?(other_cert) click to toggle source

signing

# File lib/ssltool/certificate.rb, line 30
def signed_by?(other_cert)
  verify(other_cert.public_key)
rescue OpenSSL::X509::CertificateError => e
  OpenSSL.errors  # clear error queue to prevent pg errors
  return false if e.message == "wrong public key type"                                              # self.signature_algorithm is incompatible with type of other_cert.public_key; verify is definitely false
  return nil   if e.message == "unknown message digest algorithm" && signature_algorithm =~ /^md2/  # md2 is not present in later versions of openssl; can't tell signature verifies, so returning nil
  raise e
end
signs?(other_cert) click to toggle source
# File lib/ssltool/certificate.rb, line 39
def signs?(other_cert)
  other_cert.signed_by?(self)
end
subject_key_identifier() click to toggle source
# File lib/ssltool/certificate.rb, line 93
def subject_key_identifier
  map_extension_value('subjectKeyIdentifier') { |s| s.chomp }
end
valid?() click to toggle source
# File lib/ssltool/certificate.rb, line 117
def valid?
  now = Time.now.utc
  now <= not_after && now >= not_before
end