cryptcheck/lib/cryptcheck/tls/cert.rb

122 lignes
3.6 KiB
Ruby

module CryptCheck
module Tls
class Cert
DEFAULT_CA_DIRECTORIES = [
'/usr/share/ca-certificates/mozilla'
]
SIGNATURE_ALGORITHMS = %i(md2 mdc2 md4 md5 ripemd160 sha sha1 sha2 rsa dss ecc ghost).freeze
SIGNATURE_ALGORITHMS_X509 = {
'dsaWithSHA' => %i(sha1 dss),
'dsaWithSHA1' => %i(sha1 dss),
'dsaWithSHA1_2' => %i(sha1 dss),
'dsa_with_SHA224' => %i(sha2 dss),
'dsa_with_SHA256' => %i(sha2 dss),
'mdc2WithRSA' => %i(mdc2 rsa),
'md2WithRSAEncryption' => %i(md2 rsa),
'md4WithRSAEncryption' => %i(md4, rsa),
'md5WithRSA' => %i(md5 rsa),
'md5WithRSAEncryption' => %i(md5 rsa),
'shaWithRSAEncryption' => %i(sha rsa),
'sha1WithRSA' => %i(sha1 rsa),
'sha1WithRSAEncryption' => %i(sha1 rsa),
'sha224WithRSAEncryption' => %i(sha2 rsa),
'sha256WithRSAEncryption' => %i(sha2 rsa),
'sha384WithRSAEncryption' => %i(sha2 rsa),
'sha512WithRSAEncryption' => %i(sha2 rsa),
'ripemd160WithRSA' => %i(ripemd160 rsa),
'ecdsa-with-SHA1' => %i(sha1 ecc),
'ecdsa-with-SHA224' => %i(sha2 ecc),
'ecdsa-with-SHA256' => %i(sha2 ecc),
'ecdsa-with-SHA384' => %i(sha2 ecc),
'ecdsa-with-SHA512' => %i(sha2 ecc),
'id_GostR3411_94_with_GostR3410_2001' => %i(ghost),
'id_GostR3411_94_with_GostR3410_94' => %i(ghost),
'id_GostR3411_94_with_GostR3410_94_cc' => %i(ghost),
'id_GostR3411_94_with_GostR3410_2001_cc' => %i(ghost)
}.freeze
WEAK_SIGN = {
critical: %i(mdc2 md2 md4 md5 sha sha1)
}.freeze
SIGNATURE_ALGORITHMS.each do |name|
class_eval <<-RUBY_EVAL, __FILE__, __LINE__ + 1
def #{name}?
SIGNATURE_ALGORITHMS_X509[@cert.signature_algorithm].include? :#{name}
end
RUBY_EVAL
end
def initialize(cert, chain=[])
@cert, @chain = case cert
when ::OpenSSL::X509::Certificate
[cert, chain]
when ::OpenSSL::SSL::SSLSocket
[cert.peer_cert, cert.peer_cert_chain]
end
end
def self.trusted?(cert, chain, roots: DEFAULT_CA_DIRECTORIES)
store = ::OpenSSL::X509::Store.new
store.purpose = ::OpenSSL::X509::PURPOSE_SSL_SERVER
store.add_chains roots
chain.each do |cert|
# Never add other self signed certificates than system CA !
next if cert.subject == cert.issuer
store.add_cert cert rescue nil
end if chain
trusted = store.verify cert
return :trusted if trusted
store.error_string
end
def trusted?(roots: DEFAULT_CA_DIRECTORIES)
Cert.trusted? @cert, @chain, roots: roots
end
def valid?(host)
::OpenSSL::SSL.verify_certificate_identity @cert, host
end
def fingerprint
::OpenSSL::Digest::SHA256.hexdigest @cert.to_der
end
def key
@cert.public_key
end
def subject
@cert.subject
end
def serial
@cert.serial
end
def issuer
@cert.issuer
end
include ::CryptCheck::Statused
CHECKS = [:weak_sign, -> (s) do
not (SIGNATURE_ALGORITHMS_X509[s.signature_algorithm] & WEAK_SIGN).empty?
end, :critical].freeze
def children
[self.key]
end
end
end
end