You can achieve your desired result with a combination of certtool
and openssl
. It is important to note that there are two things invovled here, one is to validate the chain itself and the other is checking if the chain is trusted against locally installed trusted root certificates.
WARNING: check negative cases
Please check negative cases, that is make sure things which your test should pick up as invalid is correctly picked up as invalid. You can do that with https://badssl.com/ or something you make yourself. If you don't know for sure that negative cases will fail whatever you are testing then the test will not help a lot.
To verify the chain is trusted:
openssl s_client -showcerts -connect example.com:443 </dev/null 2>/dev/null \
| sed -ne '/-BEGIN/,/-END/p' \
| certtool --verify
To verify chain's consistency only - but not trust:
openssl s_client -showcerts -connect example.com:443 </dev/null 2>/dev/null \
| sed -ne '/-BEGIN/,/-END/p' \
| certtool --verify-chain
Example of a trusted chain:
$ openssl s_client -showcerts -connect example.com:443 </dev/null 2>/dev/null | sed -ne '/-BEGIN/,/-END/p' | certtool --verify
Loaded system trust (154 CAs available)
Subject: CN=DigiCert SHA2 Secure Server CA,O=DigiCert Inc,C=US
Issuer: CN=DigiCert Global Root CA,OU=www.digicert.com,O=DigiCert Inc,C=US
Signature algorithm: RSA-SHA256
Output: Not verified. The certificate is NOT trusted. The certificate issuer is unknown.
Subject: CN=DigiCert SHA2 Secure Server CA,O=DigiCert Inc,C=US
Issuer: CN=DigiCert Global Root CA,OU=www.digicert.com,O=DigiCert Inc,C=US
Signature algorithm: RSA-SHA256
Output: Not verified. The certificate is NOT trusted. The certificate issuer is unknown.
Subject: CN=DigiCert SHA2 Secure Server CA,O=DigiCert Inc,C=US
Issuer: CN=DigiCert Global Root CA,OU=www.digicert.com,O=DigiCert Inc,C=US
Checked against: CN=DigiCert Global Root CA,OU=www.digicert.com,O=DigiCert Inc,C=US
Signature algorithm: RSA-SHA256
Output: Verified. The certificate is trusted.
Subject: CN=www.example.org,OU=Technology,O=Internet Corporation for Assigned Names and Numbers,L=Los Angeles,ST=California,C=US
Issuer: CN=DigiCert SHA2 Secure Server CA,O=DigiCert Inc,C=US
Checked against: CN=DigiCert SHA2 Secure Server CA,O=DigiCert Inc,C=US
Signature algorithm: RSA-SHA256
Output: Verified. The certificate is trusted.
Chain verification output: Verified. The certificate is trusted.
Example of an untrusted chain:
$ openssl s_client -showcerts -connect untrusted-root.badssl.com:443 </dev/null 2>/dev/null | sed -ne '/-BEGIN/,/-END/p' | certtool --verify
Loaded system trust (154 CAs available)
Subject: CN=*.badssl.com,O=BadSSL,L=San Francisco,ST=California,C=US
Issuer: CN=BadSSL Untrusted Root Certificate Authority,O=BadSSL,L=San Francisco,ST=California,C=US
Signature algorithm: RSA-SHA256
Output: Not verified. The certificate is NOT trusted. The certificate issuer is unknown.
Subject: CN=*.badssl.com,O=BadSSL,L=San Francisco,ST=California,C=US
Issuer: CN=BadSSL Untrusted Root Certificate Authority,O=BadSSL,L=San Francisco,ST=California,C=US
Signature algorithm: RSA-SHA256
Output: Not verified. The certificate is NOT trusted. The certificate issuer is unknown.
Subject: CN=*.badssl.com,O=BadSSL,L=San Francisco,ST=California,C=US
Issuer: CN=BadSSL Untrusted Root Certificate Authority,O=BadSSL,L=San Francisco,ST=California,C=US
Signature algorithm: RSA-SHA256
Output: Not verified. The certificate is NOT trusted. The certificate issuer is unknown.
Chain verification output: Not verified. The certificate is NOT trusted. The certificate issuer is unknown.
Checking if the untrusted chain is valid nonetheless:
$ openssl s_client -showcerts -connect untrusted-root.badssl.com:443 </dev/null 2>/dev/null | sed -ne '/-BEGIN/,/-END/p' | certtool --verify-chain
Subject: CN=*.badssl.com,O=BadSSL,L=San Francisco,ST=California,C=US
Issuer: CN=BadSSL Untrusted Root Certificate Authority,O=BadSSL,L=San Francisco,ST=California,C=US
Checked against: CN=BadSSL Untrusted Root Certificate Authority,O=BadSSL,L=San Francisco,ST=California,C=US
Signature algorithm: RSA-SHA256
Output: Verified. The certificate is trusted.
Chain verification output: Verified. The certificate is trusted.