How to manually expire any certificate OpenSSL

Why to manually expire any certificate?

There are multiple lab use cases where we want to test certain scenarios which requires a certificate to be expired. For example you have configured an alarm to be triggered when any certificate is about to be expired. Now to verify such alarm you would want the certificate to be expired right?

So how do we manually expire any certificate? Actually there is no such command which you can execute to just mark any certificate as expired. But there are a couple of tricks which can be used to achieve this.

Advertisement

In this tutorial I will share different tips and tricks which you can utilise to expire any certificate generated with openssl.

 

Lab Environment

I have already generate RootCA certificate, Private Key and CSR for Server certificate. In this article I will only execute the commands related to generate a signed server certificate.

You may follow these article to generate your own RootCA and server certificate before starting with this tutorial (if you don't already have one):
Create Certificate Authority and sign a certificate with Root CA
OpenSSL create certificate chain with Root & Intermediate CA

 

How OpenSSL verifies expiry of any certificate

You can check the validity of a certificate using following openssl command:

[root@controller certs]# openssl x509 -noout -text -in server.crt | grep -i -A2 validity
        Validity
            Not Before: Aug 27 19:32:58 2021 GMT
            Not After : Aug 25 19:32:58 2031 GMT

To verify the certificate against RootCA certificate, we use following command:

[root@controller certs]# openssl verify -CAfile cacert.pem -verbose server.crt
server.crt: OK

[root@controller certs]# openssl x509 -checkend 86400 -noout -in server.crt
Certificate will not expire

So basically all looks good here.

Advertisement

Now let us modify the date of my Linux server where this certificate is placed. The current date and time is:

[root@controller certs]# date
Sat Aug 28 01:51:28 IST 2021
IMPORTANT NOTE:
It is not a recommended method to change system's date and time runtime to such future date as this would impact many system features. The below command was executed to just give you a demonstration. You should use this only in lab environment when you are aware of the impacts.

I will use a different method to manipulate system's date and time later in this article which would be the recommended way.

As per above validity check we did with openssl command, our server certificate is going to expire on Aug 25 2031 so let me change my date to any day after this date:

[root@controller certs]# date --set "26 Aug 2031 10:10:10"
Tue Aug 26 10:10:10 IST 2031

Now check the validity of the certificate:

[root@controller certs]# openssl x509 -checkend 86400 -noout -in server.crt
Certificate will expire

So basically our certificate is marked as to be expired. Let us verify the certificate against rootCA:

[root@controller certs]# openssl verify -CAfile cacert.pem -verbose server.crt
C = IN, ST = KARNATAKA, L = BENGALORE, O = GoLinuxCloud, OU = Admin, CN = RootCA
error 10 at 1 depth lookup: certificate has expired
C = IN, ST = Karnataka, L = Bengaluru, O = GoLinuxCloud, OU = Admin, CN = example.com
error 10 at 0 depth lookup: certificate has expired
error server.crt: verification failed

So this exercise should explain the answer to the question "how openssl determines if any certificate has expired or not"

Advertisement

Basically openssl uses localhost server's date and time to determine the certificate's expiry date, so you can manipulate your server's date and time to manually expire any certificate.

Let us look into different scenarios and examples to check this further:

 

Scenario-1: Generate an expired certificate

In this scenario we do not have a certificate yet and we are actually planning to generate a new certificate.

 

Method-1: generate expired certificate using faketime with openssl

Now instead of modifying system's date and time we can use faketime tool to trick openssl into providing a different date and time.

For RHEL/CentOS/Fedora you must install epel-repo to install faketime:

[root@controller certs]# yum install epel-release

[root@controller certs]# yum whatprovides */faketime
Last metadata expiration check: 0:01:51 ago on Tue 26 Aug 2031 10:15:29 AM IST.
libfaketime-0.9.8-5.el8.x86_64 : Manipulate system time per process for testing purposes
Repo        : epel
Matched from:
Filename    : /usr/bin/faketime
Filename    : /usr/lib64/faketime

[root@controller certs]# yum install libfaketime -y

Let us see how faketime works:

# faketime '2010-01-01 10:10:10' date
Fri Jan  1 10:10:10 IST 2010

# date
Sat Aug 28 13:13:51 IST 2021

As you can see, I executed date command by providing a dummy past date using faketime and date command returned the same date while the actual system's date was not changed.

So, now we can use faketime to manipulate system's date into an old date and then generate a certificate:

[root@controller certs]# faketime '2010-01-01 10:10:10' openssl x509 -req -days 365 -in server.csr -CA cacert.pem -CAkey ca.key -CAcreateserial -out server.crt
Signature ok
subject=C = IN, ST = Karnataka, L = Bengaluru, O = GoLinuxCloud, OU = Admin, CN = example.com
Getting CA Private Key

We have set the system date to 01 Jan 2010 and then we generated a certificate with an expiry of 1 year and yet the certificate will still be expired because the actual date is 25 Aug 2021

Check the validity of this certificate:

[root@controller certs]# openssl x509 -checkend 86400 -noout -in server.crt
Certificate will expire

[root@controller certs]# openssl x509 -noout -text -in server.crt | grep -i -A2 validity
        Validity
            Not Before: Jan  1 04:40:10 2010 GMT
            Not After : Jan  1 04:40:10 2011 GMT

[root@controller certs]# openssl verify -CAfile cacert.pem -verbose server.crt
C = IN, ST = Karnataka, L = Bengaluru, O = GoLinuxCloud, OU = Admin, CN = example.com
error 10 at 0 depth lookup: certificate has expired
error server.crt: verification failed

So our certificate is already expired and you can continue with your tests.

 

Method-2: Generate expired certificate using past date

We also have an option to generate an expired certificate without using any additional tool. We have an option to specify number of days of expiry for the certificate using -days NUM.

Here we can provide negative values to provide an past date so the generated certificate will already be expired. Let us check this using an example:

[root@controller certs]# openssl x509 -req -days -365 -in server.csr -CA cacert.pem -CAkey ca.key -CAcreateserial -out server.crt
Signature ok
subject=C = IN, ST = Karnataka, L = Bengaluru, O = GoLinuxCloud, OU = Admin, CN = example.com
Getting CA Private Key

Here I have given number of days as -365 so the expiry date will be in past.

Now check the validity of this server.crt file:

[root@controller certs]# openssl x509 -noout -text -in server.crt | grep -i -A2 validity
        Validity
            Not Before: Aug 28 07:53:53 2021 GMT
            Not After : Aug 28 07:53:53 2020 GMT

[root@controller certs]# openssl x509 -checkend 86400 -noout -in server.crt
Certificate will expire

[root@controller certs]# openssl verify -CAfile cacert.pem -verbose server.crt
C = IN, ST = Karnataka, L = Bengaluru, O = GoLinuxCloud, OU = Admin, CN = example.com
error 10 at 0 depth lookup: certificate has expired
error server.crt: verification failed

So we were able to manually expire this certificate without using any additional tools.

 

Scenario-2: How to expiry any existing certificate

Now this can be tricky depending on your use case as we actually cannot expire an existing certificate without manipulating system's date and time where again we would be tricking openssl into thinking that the certificate has expired.

We would again use faketime with openssl command to manipulate the system date and time. But here actually the certificate will not be in expired state.

For example, I have generated a fresh certificate with proper days of expiry:

[root@controller certs]# openssl x509 -req -days 365 -in server.csr -CA cacert.pem -CAkey ca.key -CAcreateserial -out server.crt
Signature ok
subject=C = IN, ST = Karnataka, L = Bengaluru, O = GoLinuxCloud, OU = Admin, CN = example.com
Getting CA Private Key

The certificate verification is success:

[root@controller certs]# openssl verify -CAfile cacert.pem -verbose server.crt
server.crt: OK

Now we can execute the same command with faketime and some past date:

[root@controller certs]#  faketime '2010-01-01 10:10:10' openssl verify -CAfile cacert.pem -verbose server.crt
C = IN, ST = KARNATAKA, L = BENGALORE, O = GoLinuxCloud, OU = Admin, CN = RootCA
error 9 at 1 depth lookup: certificate is not yet valid
error server.crt: verification failed

As you can see, now the same certificate is reporting as expired but in real we know that the certificate is still proper.

 

Summary

In this tutorial we covered different scenarios and methods which can be used to manually expire any certificate using openssl command. These testcases are mostly required for lab use cases and are not relevant in production environment. In dev environment, we have use cases related to expiry, alarm generation etc which expects the certificate to be expired where we can use the steps from this article.

Let me know if you have any questions or feedbacks using the comment section.

 

References

Create self-signed certificate with end-date in the past

Didn't find what you were looking for? Perform a quick search across GoLinuxCloud

If my articles on GoLinuxCloud has helped you, kindly consider buying me a coffee as a token of appreciation.

Buy GoLinuxCloud a Coffee

For any other feedbacks or questions you can either use the comments section or contact me form.

Thank You for your support!!

Leave a Comment