checking a site's certificate with openssl
last updated: Mar 04, 2024
I encountered a problem with a site that wasn't presenting the full certificate chain, causing an error Verify return code: 21 (unable to verify the first certificate)
.
On a site that correctly gives its full certificate chain, here's the relevant bits of what you see:
$ openssl s_client -connect billmill.org:443
Connecting to 161.35.57.166
CONNECTED(00000006)
depth=2 C=US, O=Internet Security Research Group, CN=ISRG Root X1
verify return:1
depth=1 C=US, O=Let's Encrypt, CN=R3
verify return:1
depth=0 CN=billmill.org
verify return:1
---
Certificate chain
0 s:CN=billmill.org
i:C=US, O=Let's Encrypt, CN=R3
a:PKEY: id-ecPublicKey, 256 (bit); sigalg: RSA-SHA256
v:NotBefore: Feb 21 00:09:41 2024 GMT; NotAfter: May 21 00:09:40 2024 GMT
1 s:C=US, O=Let's Encrypt, CN=R3
i:C=US, O=Internet Security Research Group, CN=ISRG Root X1
a:PKEY: rsaEncryption, 2048 (bit); sigalg: RSA-SHA256
v:NotBefore: Sep 4 00:00:00 2020 GMT; NotAfter: Sep 15 16:00:00 2025 GMT
---
<snip>
Verify return code: 0 (ok)
<snip>
On a site where the entire chain is not presented, you'll see 20:unable to get local issue certificate
followed by 21:unable to verify the first certificate
:
$ openssl s_client -connect incomplete-chain.badssl.com:443
Connecting to 104.154.89.105
CONNECTED(00000006)
depth=0 C=US, ST=California, L=Walnut Creek, O=Lucas Garron Torres, CN=*.badssl.com
verify error:num=20:unable to get local issuer certificate
verify return:1
depth=0 C=US, ST=California, L=Walnut Creek, O=Lucas Garron Torres, CN=*.badssl.com
verify error:num=21:unable to verify the first certificate
verify return:1
depth=0 C=US, ST=California, L=Walnut Creek, O=Lucas Garron Torres, CN=*.badssl.com
verify error:num=10:certificate has expired
notAfter=May 17 12:00:00 2022 GMT
verify return:1
depth=0 C=US, ST=California, L=Walnut Creek, O=Lucas Garron Torres, CN=*.badssl.com
notAfter=May 17 12:00:00 2022 GMT
verify return:1
---
Certificate chain
0 s:C=US, ST=California, L=Walnut Creek, O=Lucas Garron Torres, CN=*.badssl.com
i:C=US, O=DigiCert Inc, CN=DigiCert SHA2 Secure Server CA
a:PKEY: rsaEncryption, 2048 (bit); sigalg: RSA-SHA256
v:NotBefore: Mar 23 00:00:00 2020 GMT; NotAfter: May 17 12:00:00 2022 GMT
(Sadly, badssl.com appears to be dead and full of expired certificates; at least in this case I can use it to demonstrate the issue)