Creating expired X.509 certificates

Expired Certificate

Last week as I was preparing a the material for a workshop about TLS for developers, for one of the exercises, I needed to create an expired certificate.

To do that I thought that when creating my certificate (self signed) all I had to do was to pass a negative number when specifying the numbers of days for the certificate validity.

So there I went and run the following command:

openssl req -x509 -newkey rsa:4096 -keyout server.key -out server.crt -days -5
req: Non-positive number "-5" for -days
req: Use -help for summary.

As you can see, that didn’t work.

After looking around for a bit, all the solutions I initially found, involved changing my system’s date and then generate the certificate. I didn’t like that option. So my next thought was to create the certificate in a Docker container. I would change the container’s date and then run my openssl command. Let’s try that:

docker run -it --rm ubuntu:18.04
root@c09ad5d2689d:/# date +%Y%m%d -s "20200101"
date: cannot set date: Operation not permitted
20200101
root@c09ad5d2689d:/#

As you can see that didn’t work either. Can you change the date from inside the container? You could, but to do that you need to run the container with higher privileges (–privileged). The reason for this is that the container shares the system’s clock, and therefore, changing the date inside the container would also change the host’s date. So back to square number 1.

I went back to look for other options and finally I found this nice tool called faketime. According to its documentation this is just a simple layer on top of libfaketime. This last one is a library that capture some system calls (time and fstats) and allows you using the LD_PRELOAD functionality to set a specific date and time for a particular application.

So going back to my quest, let’s create a certificate only valid for 1 day between the 1st and 2nd of January of 2020:

faketime '2020-01-01' openssl req -x509 -newkey rsa:4096 -keyout server.key -out server.crt -days 1

Let’s verify that our certificate has the validity period we meant to set:

openssl x509 -in server.crt -text -noout

...
    Validity
        Not Before: Jan  1 00:00:05 2020 GMT
        Not After : Jan  2 00:00:05 2020 GMT
...

That worked!

faketime accepts different ways to set the date and time:

faketime 'last Friday 5 pm' /bin/date
faketime '2008-12-24 08:15:42' /bin/date
faketime -f '+2,5y x10,0' /bin/bash -c 'date; while true; do echo $SECONDS ; sleep 1 ; done'
...
...

You can either install faketime in your system or you can use a Docker container. If you take the container option you can do this manually or using doig:

doig -u -i mytools -t faketime

And then run your container:

docker run -it --rm mytools

From there you mess with faketime without having to worry messing up your system’s date.

By the way, if you are looking for “certificates with issues”, https://badssl.com is a great resource to find all kind of certificates with different issues.