Pages

Sunday, 13 November 2016

SSL Certificate Revocation List (CRL) with CloudFlare's PKI toolkit and nginx

This post will quickly go over the gotchas I have encountered when making the CRL returned by the cfssl tool work with nginx. This post makes the assumption that you already know a bit about nginx, SSL and cfssl. It also assumes that you have already have nginx serving content over https and nginx is asking for a client-side certificate. This post also assumes that you can create the client-side certificate with cfssl. Each of these steps are well documented else where so will not be repeated here.

After we have client-side certificates, we should make nginx reject any that we revoke. Nginx supports this via a CRL list supplied in the ssl_crl parameter, while cfssl supplies a tool to generate a CRL file: cfssl gencrl.

cfssl gencrl \
  list-of-serial-numbers-to-revoke.txt \
  my-certificate.pem 
  my-certificate-private-key.pem \
  > my-certificate.crl

Alas the created document can not be used directly with nginxes ssl_crl. We have to do the following two steps first:
  1. The created document must be wrapped in
    -----BEGIN X509 CRL-----
    and
    -----END X509 CRL-----.
  2. The CRL file used by nginx has to include the complete certificate chain of CRLs. If you are using your own CA then create the CRL in the same way as before and concatenate them together.
Finally the last gotcha is that the list-of-serial-numbers-to-revoke.txt used by cfssl is a list of number in decimal not hex. Most tools end up outputting the serial number in hex, I recommend using this online converter.

If you want to test a CRL without firing up nginx then you can use Open SSL:

openssl crl -in ~/Projects/starling/client-auth-proxy/conf/ca.crl -text


Once you have done this the CRL should work. If you get nginx crashing on startup with:

2016/11/13 08:59:53 [emerg] 1#1: X509_LOOKUP_load_file("/etc/ssl/ca/private/ca.crl") failed (SSL: error:0906D066:PEM routines:PEM_read_bio:bad end line error:0B084009:x509 certificate routines:X509_load_cert_crl_file:PEM lib)

nginx: [emerg] X509_LOOKUP_load_file("/etc/ssl/ca/private/ca.crl") failed (SSL: error:0906D066:PEM routines:PEM_read_bio:bad end line error:0B084009:x509 certificate routines:X509_load_cert_crl_file:PEM lib)

Then you have missed out step one, and the CRL file does not have each CRL wrapped in the BEGIN/END.

If nginx starts then, but when you hit a page you get and error message like:

2016/11/13 09:01:14 [info] 17#17: *5 client SSL certificate verify error: (3:unable to get certificate CRL) while reading client request headers, client: 192.168.99.1, server: , request: "GET / HTTP/1.1", host: "192.168.99.100"

192.168.99.1 - - [13/Nov/2016:09:01:14 +0000] "GET / HTTP/1.1" 400 633 "-" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_0) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/54.0.2840.71 Safari/537.36"

Then you missed out step two and don't have the CRLs for each of the certificates in the chain.

No comments:

Post a Comment