Certificate trust chain check
parent
3d12eaacea
commit
e28b857213
|
@ -38,6 +38,7 @@ module CryptCheck
|
|||
autoload :Method, 'cryptcheck/tls/method'
|
||||
autoload :Cipher, 'cryptcheck/tls/cipher'
|
||||
autoload :Curve, 'cryptcheck/tls/curve'
|
||||
autoload :Cert, 'cryptcheck/tls/cert'
|
||||
autoload :Server, 'cryptcheck/tls/server'
|
||||
autoload :TcpServer, 'cryptcheck/tls/server'
|
||||
autoload :UdpServer, 'cryptcheck/tls/server'
|
||||
|
|
|
@ -1,6 +1,10 @@
|
|||
module CryptCheck
|
||||
module Tls
|
||||
class Cert
|
||||
DEFAULT_CA_DIRECTORIES = [
|
||||
'/usr/share/ca-certificates/mozilla'
|
||||
]
|
||||
|
||||
SIGNATURE_ALGORITHMS = {
|
||||
'dsaWithSHA' => %i(sha1 dss),
|
||||
'dsaWithSHA1' => %i(sha1 dss),
|
||||
|
@ -48,6 +52,21 @@ module CryptCheck
|
|||
end
|
||||
RUBY_EVAL
|
||||
end
|
||||
|
||||
def self.trusted?(cert, chain, roots: DEFAULT_CA_DIRECTORIES)
|
||||
store = ::OpenSSL::X509::Store.new
|
||||
store.purpose = OpenSSL::X509::PURPOSE_SSL_CLIENT
|
||||
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
|
||||
|
||||
trusted = store.verify cert
|
||||
return :trusted if trusted
|
||||
store.error_string
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -154,3 +154,24 @@ class ::OpenSSL::PKey::DH
|
|||
end
|
||||
end
|
||||
end
|
||||
|
||||
class ::OpenSSL::X509::Store
|
||||
def add_chains(chains)
|
||||
chains = [chains] unless chains.is_a? Enumerable
|
||||
chains.each do |chain|
|
||||
case chain
|
||||
when ::OpenSSL::X509::Certificate
|
||||
self.add_cert chain
|
||||
else
|
||||
if File.directory?(chain)
|
||||
Dir.entries(chain)
|
||||
.collect { |e| File.join chain, e }
|
||||
.select { |e| File.file? e }
|
||||
.each { |f| self.add_file f }
|
||||
else
|
||||
self.add_file chain
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -0,0 +1,32 @@
|
|||
describe CryptCheck::Tls::Cert do
|
||||
def load_chain(chain)
|
||||
chain.collect { |f| ::OpenSSL::X509::Certificate.new File.read File.join 'spec/resources', "#{f}.crt" }
|
||||
end
|
||||
|
||||
describe '::trusted?' do
|
||||
it 'must accept valid certificat' do
|
||||
cert, *chain, ca = load_chain %w(custom intermediate ca)
|
||||
trust = ::CryptCheck::Tls::Cert.trusted? cert, chain, roots: ca
|
||||
expect(trust).to eq :trusted
|
||||
end
|
||||
|
||||
it 'must reject self signed certificate' do
|
||||
cert, ca = load_chain %w(self-signed ca)
|
||||
trust = ::CryptCheck::Tls::Cert.trusted? cert, [], roots: ca
|
||||
expect(trust).to eq 'self signed certificate'
|
||||
end
|
||||
|
||||
it 'must reject unknown CA' do
|
||||
cert, *chain = load_chain %w(custom intermediate ca)
|
||||
trust = ::CryptCheck::Tls::Cert.trusted? cert, chain, roots: []
|
||||
expect(trust).to eq 'unable to get issuer certificate'
|
||||
end
|
||||
|
||||
it 'must reject missing intermediate chain' do
|
||||
cert, ca = load_chain %w(custom ca)
|
||||
chain = []
|
||||
trust = ::CryptCheck::Tls::Cert.trusted? cert, chain, roots: ca
|
||||
expect(trust).to eq 'unable to get local issuer certificate'
|
||||
end
|
||||
end
|
||||
end
|
|
@ -0,0 +1,13 @@
|
|||
-----BEGIN CERTIFICATE-----
|
||||
MIIB7zCCAXWgAwIBAgIJAKFu2k3vOIffMAoGCCqGSM49BAMEMBIxEDAOBgNVBAMM
|
||||
B3Rlc3QtY2EwHhcNMTcwMTIyMTg1NTUxWhcNMTgwMTIyMTg1NTUxWjASMRAwDgYD
|
||||
VQQDDAd0ZXN0LWNhMHYwEAYHKoZIzj0CAQYFK4EEACIDYgAEhVE2pSx4GG922yqA
|
||||
z0W0usG8dFdY4qtTD5mwwBzRhu9NegzQmaE5oHNzQrQE8v0/ShrSHNdID6Phty9K
|
||||
lPYoenUmpH0sdJDqQ5cVUDkmw0+f+XpROtCiBcN8kTmiVXQ5o4GWMIGTMA8GA1Ud
|
||||
EwEB/wQFMAMBAf8wCwYDVR0PBAQDAgL0MB0GA1UdJQQWMBQGCCsGAQUFBwMBBggr
|
||||
BgEFBQcDAjAdBgNVHQ4EFgQU2saIfk29nr+adaNemnS2AaNjXJEwHwYDVR0jBBgw
|
||||
FoAU2saIfk29nr+adaNemnS2AaNjXJEwFAYDVR0RBA0wC4IJbG9jYWxob3N0MAoG
|
||||
CCqGSM49BAMEA2gAMGUCMQCzxeexb5HauoM8OQPBK7MWxzganLfVoi1GCsbvjUQy
|
||||
AB8AAVijIPwT/MGcigge4z8CMFimJXl934AtL8iM+Jd9ykvNXXxzSn9YRm9aLD3K
|
||||
w6vam+k+gA4sdijDbRC/Tc/3NQ==
|
||||
-----END CERTIFICATE-----
|
|
@ -0,0 +1,13 @@
|
|||
-----BEGIN CERTIFICATE-----
|
||||
MIIB6jCCAXCgAwIBAgIJAKyx4KGEOyVdMAoGCCqGSM49BAMEMBwxGjAYBgNVBAMM
|
||||
EXRlc3QtaW50ZXJtZWRpYXRlMB4XDTE3MDEyMjE4NTU1MVoXDTE4MDEyMjE4NTU1
|
||||
MVowFDESMBAGA1UEAwwJdGVzdC1sZWFmMHYwEAYHKoZIzj0CAQYFK4EEACIDYgAE
|
||||
kZFi7jp4Z+3m1lR/aIHuNalLQtjaCErIgrWhFL7oUjzWMN1dR3nAmmosKlCSRc7A
|
||||
Xazs+CC0QB1LgsZCFFPhPqUd5456iwCHaSVQ3maESrZtzJo78v/fE9HRuuh5fFiL
|
||||
o4GFMIGCMAsGA1UdDwQEAwIE8DAdBgNVHSUEFjAUBggrBgEFBQcDAQYIKwYBBQUH
|
||||
AwIwHQYDVR0OBBYEFB54cEd+wLKHpMKYkYCxmSgWERrQMB8GA1UdIwQYMBaAFMgN
|
||||
6Mqlnk3ZRmp4RrAXXKeC3yVHMBQGA1UdEQQNMAuCCWxvY2FsaG9zdDAKBggqhkjO
|
||||
PQQDBANoADBlAjEAwbhbwXjekyl3esK9ywh+jKCVhf7BzaF4H7LAxUE1PmXTORrZ
|
||||
tqz2MXK3/zYfe1bXAjAuan+xZ4d5zCgBvnFO2/LMEX07SFQJT3l1hKAZjpbdNm/K
|
||||
MY23IR6iLWkPlG1u+Wo=
|
||||
-----END CERTIFICATE-----
|
|
@ -0,0 +1,13 @@
|
|||
-----BEGIN CERTIFICATE-----
|
||||
MIIB+TCCAX+gAwIBAgIJAOko1FM8hOfNMAoGCCqGSM49BAMEMBIxEDAOBgNVBAMM
|
||||
B3Rlc3QtY2EwHhcNMTcwMTIyMTg1NTUxWhcNMTgwMTIyMTg1NTUxWjAcMRowGAYD
|
||||
VQQDDBF0ZXN0LWludGVybWVkaWF0ZTB2MBAGByqGSM49AgEGBSuBBAAiA2IABNjg
|
||||
qyABIHj96OvYN1YCe+z3mILDlm1qNXm1bpoMcx7AVANk+AFUjbK/mhSyx5ONbBw/
|
||||
4kMBNtVW7OpkiZwLr57SbqDv0n4ExirUvvBm7OcqqSY+73lXM/cezMTRA/3ZqqOB
|
||||
ljCBkzAPBgNVHRMBAf8EBTADAQH/MAsGA1UdDwQEAwIC9DAdBgNVHSUEFjAUBggr
|
||||
BgEFBQcDAQYIKwYBBQUHAwIwHQYDVR0OBBYEFMgN6Mqlnk3ZRmp4RrAXXKeC3yVH
|
||||
MB8GA1UdIwQYMBaAFNrGiH5NvZ6/mnWjXpp0tgGjY1yRMBQGA1UdEQQNMAuCCWxv
|
||||
Y2FsaG9zdDAKBggqhkjOPQQDBANoADBlAjAUAte4U3OtzmeQLA/Cq1JTtsrE7sy9
|
||||
kZzxGHxACZ53sTGA2c4K86lR2RGoXYvW62wCMQCNSLH+qukadu52ip7HTkihrtae
|
||||
hBVOBO+el6rCcby91xUuWU24AJy9Ce9TxcQC384=
|
||||
-----END CERTIFICATE-----
|
|
@ -0,0 +1,13 @@
|
|||
-----BEGIN CERTIFICATE-----
|
||||
MIICBjCCAYugAwIBAgIJAPnnJnLp7H/XMAoGCCqGSM49BAMEMBQxEjAQBgNVBAMM
|
||||
CWxvY2FsaG9zdDAeFw0xNzAxMjIxNjM1NDdaFw0xODAxMjIxNjM1NDdaMBQxEjAQ
|
||||
BgNVBAMMCWxvY2FsaG9zdDB2MBAGByqGSM49AgEGBSuBBAAiA2IABJvRcgAMkjzZ
|
||||
p0YD/mXa2Td8sy7fBr7F5Sj8toSmLAxkxxPCnm9DDdLQXy7IZXA1HJkiRUIJ8BTk
|
||||
gSxmKQBwl3my2quHGx7GSZshpER4tRtqWI21dTUkuu9bGR66bbLa8aOBqDCBpTAP
|
||||
BgNVHRMBAf8EBTADAQH/MAsGA1UdDwQEAwIC9DAdBgNVHSUEFjAUBggrBgEFBQcD
|
||||
AQYIKwYBBQUHAwIwHQYDVR0OBBYEFCEkGXQc44mMopATg1jr+stKnF4LMB8GA1Ud
|
||||
IwQYMBaAFCEkGXQc44mMopATg1jr+stKnF4LMBQGA1UdEQQNMAuCCWxvY2FsaG9z
|
||||
dDAQBggrBgEFBQcBGAEB/wQBMDAKBggqhkjOPQQDBANpADBmAjEAkPKxToKRloWT
|
||||
eH4lGaUrqBGpRof92rWmJiBLs5WnaYM73S/GdKNK1j0jKRCKXKpzAjEAgpjvaUhd
|
||||
qXkR3g8iWedrFjkVHHVrUGV9JW7elHP7bD6XryqsGRNK2X8yq0J616gP
|
||||
-----END CERTIFICATE-----
|
Loading…
Reference in New Issue