Friday, August 5, 2011

CRL management with openssl

CRL basics

Consider the scenario. The certificate authority receives a request for signing a certificate request. It gets the payment; does the background check and issues the certificate. Lets say it was later discovered that the organisation was funding terrorist groups and got banned by the government. Now Certificate authority wants to revoke the trust on the faulty company's ssl certificate. Once a certificate is signed and issued it cannot be changed. How would the clients know that faulty company's certificate is not to be trusted even though it is signed by a trusted certificate authority. CRLs are introduced to solve this. Certificate authorities maintain some thing called as Certificate Revocation List, CRL in short and publish them themselves and or through a third party. CRL contains the serial number of all the certificates that are revoked and not to be trusted even if they chain up to a trusted certificate authority.

CRL distribution extension

CRL distribution point is embedded with in the certificate. It is generally a URI. After validating that the certificate is trusted by a CA, the ssl client is supposed to download the CRL and check that the server certificate is not revoked by the authority signing it.

How to create a certificate with CRL distribution point

Add what should go into your x509 v3 extensions in a config file. Refer for the format.
And then while signing, use the extfile option of "openssl ca" command to add the extensions.

openssl ca -policy policy_anything -cert ./demoCA/private/ca.crt -keyfile ./demoCA/private/ca.key -out server/server.crt -extfile v3_ext.conf -infiles server/server.req

To add CRL distributions point extensions to the x509 certificate, my v3_ext.cnf looks like this :

snape@hogwarts:~/ssl$ cat v3_ext.conf

Or add an extensions section in the config file and use extensions option to select which section to be used for x509 v3 extensions.

The section in the openssl config looks like this :

[ my_v3 ]

The command would be :

openssl ca -policy policy_anything -cert ./demoCA/private/ca.crt -keyfile ./demoCA/private/ca.key -out server/server.crt -config /home/hogwarts/ssl/openssl.cnf -extensions my_v3 -infiles server/server.req

Note that infiles should be the last option.

Revoke a certificate

The revoke option of "openssl ca" command can be used to revoke a certificate signed by the ca. We would need the CA's key and certificate files for verification.

snape@hogwarts:~/ssl$ openssl ca -revoke server/server.crt -keyfile demoCA/private/ca.key -cert demoCA/private/ca.crt
Using configuration from /usr/lib/ssl/openssl.cnf
Revoking Certificate 03.
Data Base Updated

Generate CRL of a certificate

Now to publish the Revocation List of the server.

Just create a file named "crlnumber" inside demoCA directory and write 00 in it. This file keeps track of the number of times the crl has been published.

snape@hogwarts:~/ssl$ echo "00" > ./demoCA/crlnumber

openssl ca -gencrl -keyfile ./demoCA/private/ca.key -cert ./demoCA/private/ca.crt > ./demoCA/crl/crl.0

This generates the crl for the server and writes it to the file crl.0 .

To view the crl:

snape@hogwarts:~/ssl$ openssl crl -in demoCA/crl/crl.0 -text
Certificate Revocation List (CRL):
Version 2 (0x1)
Signature Algorithm: sha1WithRSAEncryption
Issuer: /C=IN/ST=DL/O=ABC Corp/OU=SWD Labs/CN=SWD CA/
Last Update: Aug 2 10:04:02 2011 GMT
Next Update: Sep 1 10:04:02 2011 GMT
CRL extensions:
X509v3 CRL Number:
Revoked Certificates:
Serial Number: 03
Revocation Date: Aug 2 09:56:37 2011 GMT
Signature Algorithm: sha1WithRSAEncryption
-----BEGIN X509 CRL-----
-----END X509 CRL-----

Look at the fiel that says Revoked Certificates, followed by the serial number of the certificates that are revoked.

Now we have to take this crl.0 file and make it available from the URI : http://hogwarts:8080/hogwartsca.crl

This is trivial; just copy the file as hogwartsca.crl to the server's root directory. [ Most of the time, it is just your htdocs directory for the port 8080 ]

Testing it in the client:

Lets start the server :

snape@hogwarts:~/ssl$ openssl s_server -accept 5000 -key server/server.key -cert server/server.crt -www
Using default temp DH parameters
Using default temp ECDH parameters

Server is now listening for incoming connections.
For testing purpose, lets create a crt file with CA certificate and CA recent crl.

snape@hogwarts:~/ssl$ cat demoCA/private/ca.crt > combined.crt
snape@hogwarts:~/ssl$ cat demoCA/crl/crl.0 >> combined.crt
snape@hogwarts:~/ssl$ vi combined.crt

Lets start s_client to connect to the server running on local host

snape@hogwarts:~$ openssl s_client -host localhost -port 5000 -CAfile /home/hogwarts/ssl/combined.crt -crl_check -quiet
depth=0 /C=IN/ST=KA/L=BLR/O=Hogwarts/OU=Herbology/CN=hogwarts/emailAddress=snape@hogwarts
verify error:num=23:certificate revoked
verify return:1
depth=1 /C=IN/ST=DL/O=ABC Corp/OU=SWD Labs/CN=SWD CA/
verify return:1
depth=0 /C=IN/ST=KA/L=BLR/O=Hogwarts/OU=Herbology/CN=hogwarts/emailAddress=snape@hogwarts
verify return:1

See that openssl reports that the certificate is revoked though it is chaining up to a trusted certificate authority.

Note the new options. quiet is to quiet out openssl from printing too many debug stuff about the connection. crl_check enables checking for the certificate revocation.

Note that openssl would not download the crl and check. It expects to find the crl already in your trusted store.

CRL caching

Similar to x509 certificates, CRLs also have an expiry date after which the client is supposed to check back with the server and download the crl again. Till that point, crls can be cached locally like the trusted CA certificates in order to speed things while verifying the ssl certificate.

1 comment: