I've written quite a few blogs on how to get started with Let's Encrypt and covered both RSA and ECDSA certificates. In this blog I'm going to look at how we revoke them.
Let's Encrypt
If you haven't come across Let's Encrypt yet, they're a CA that you can use to get free certificates to setup HTTPS on your website quickly and easily. I have a blog on Getting Started with Let's Encrypt, a Smart Renew tool to look after renewals for you and how to obtain both RSA and ECDSA certificates. If you're feeling really adventurous you can get your own emoji subdomain too! https://🔒🔒🔒.scotthelme.co.uk
Revocation
The problem we have with certificates is that they can, at the time of writing, be valid for up to 39 months and we need to look after them during that time. If we lose the key associated with our certificate then whoever obtains the key can use our certificate to prove they are us. Imagine that, someone else on the internet being able to prove that they are you, when they are not you! This is the problem that revocation solves. We can make a request to our CA to revoke the certificate and then browsers will know not to trust it.
Revoking a Let's Encrypt certificate
I use a script called acme_tiny to obtain my Let's Encrypt certificates and I will be using another script from the same author to revoke them, revoke_crt.py. Grab a copy of the script to get started.
wget -O - https://raw.githubusercontent.com/diafygi/letsencrypt-nosudo/master/revoke_crt.py > revoke_crt.py
Once you have a copy of the script it's a simple case of using it to revoke the certificate. The script needs the public key from your Let's Encrypt account key so we will extract that first.
openssl rsa -in account.key -pubout > public.key
We can now use the public key in the command to start the revocation request.
python revoke_crt.py -p public.key signed.crt
This will give you some instructions to run another command to sign the revocation request.
Reading pubkey file...
Found public key!
STEP 1: You need to sign a file (replace 'user.key' with your user private key)
openssl dgst -sha256 -sign user.key -out revoke_CuuyfH.sig revoke_1ot9Ul.json
Press Enter when you've run the above command in a new terminal window...
You will need to open a new terminal window to run this command while the current command is paused.
openssl dgst -sha256 -sign account.key -out revoke_CuuyfH.sig revoke_1ot9Ul.json
If that command succeeds there will be no output and you can switch back to the other window and hit Enter to complete the original command.
Requesting revocation...
Certificate revoked!
That's it, your certificate is now revoked! Hopefully you will never need to actually do this but it's always good to know how.
Verify the revocation
Of course, now that the certificate is revoked, it'd be cool to see the proof. To do that, we're going to use OCSP, the Online Certificate Status Protocol. I've talked about OCSP in the past and how to enable a cool feature called OCSP Stapling, but today we're going to do a manual OCSP request and fetch the response. To do that we will need the root and intermediate certificates from our chain.
wget -O - https://censys.io/certificates/0687260331a72403d909f105e69bcf0d32e1bd2493ffc6d9206d11bcd6770739/pem/raw > root.pem
wget -O - https://letsencrypt.org/certs/lets-encrypt-x3-cross-signed.pem > intermediate.pem
This will give you the root and intermediate certificates as PEM files, you then need to build the chain.
cat intermediate.pem root.pem > chain.pem
We now need to know where the Let's Encrypt OCSP responder is and that information is stored inside the certificate itself.
openssl x509 -in signed.crt -noout -text | grep OCSP
That command will search the certificate for any instances of 'OCSP' and output the result.
OCSP - URI:http://ocsp.int-x3.letsencrypt.org
This is the address we will query to fetch the OCSP response. Let's do it!
openssl ocsp -noverify -no_nonce -issuer chain.pem -cert signed.crt -url http://ocsp.int-x3.letsencrypt.org -header "HOST" "ocsp.int-x3.letsencrypt.org"
There are a few components to this command so let's break them out. We're using openssl
and specifically the ocsp
tool. The -noverify
flag tells the tool we don't want it to verify the response and -no_nonce
instructs it not to include an OCSP nonce in the request. After that, the -issuer
flag provides the certificate chain we created earlier, the -cert
flag is the certificate we want to check the status of and the -url
flag is the location of the OCSP responder we want to query. The last flag, -header
, adds the appropriate HOST header to the request so we don't get a 400 Bad Request back from Let's Encrypt. Once you fire that request, you should get an OCSP response back.
signed.crt: revoked
This Update: Jun 20 12:00:00 2017 GMT
Next Update: Jun 27 12:00:00 2017 GMT
Revocation Time: Jun 20 12:35:27 2017 GMT
That's the proof that our certificate has indeed been revoked!