Bug 13737

Summary: IPSec Renew Host Certificate causes openssl error message
Product: IPFire Reporter: Adolf Belka <adolf.belka>
Component: ---Assignee: Adolf Belka <adolf.belka>
Status: MODIFIED --- QA Contact:
Severity: Major Usability    
Priority: - Unknown - CC: michael.tremer
Version: 2   
Hardware: all   
OS: Unspecified   

Description Adolf Belka 2024-08-06 13:33:53 UTC
When trying to help someone having problems with an IPSec certificate I tested out the Renew Host Certificate icon in the WUI on my vm testbed.

The involved Host Certificate was already expired and revoked.

Pressing the Renew Host Certificate icon gave the following Error message:-

Error messages
OpenSSL produced an error:
Using configuration from /etc/ssl/openssl.cnf
Check that the request matches the signature
Signature ok
The Subject's Distinguished Name is as follows
countryName :PRINTABLE:'NL'
organizationName :PRINTABLE:'XXXXX'
commonName :PRINTABLE:'ipfire.XXXX.XXXX.XXXX'
ERROR:Serial number 01 has already been issued,
check the database/serial_file for corruption
The matching entry has the following details
Type :Revoked
Was revoked on:240530141737Z
Expires on :240530141737Z
Serial Number :01
File name :unknown
Subject Name :/C=NL/O=Newton Sand/CN=  ipfire.XXXX.XXXX.XXXX


I then created a new x509 root and host certificate.

I then pressed the Renew Host Certificate icon again and got the same error message, just with the Was revoked on: and Expires on : entries being 

261109130230Z

This renew option was put into IPSec in CU184 but this is the first time I have tried it out.
Comment 1 Adolf Belka 2024-08-06 13:58:23 UTC
Looking through the log on the vm machine I found the following messages.

Aug  6 15:56:32 ipfire ipsec: Regenerating host certificate...
Aug  6 15:56:32 ipfire ipsec: Revoking the old host cert...
Aug  6 15:56:32 ipfire ipsec: Self signing host cert...


This does not show up in the IPSec System Logs as the name ipsec is used rather than charon.

So the Renew Host Certficate goes through the first three parts and falls down at the Self signing host cert step.
Comment 2 Adolf Belka 2024-08-06 14:14:23 UTC
I ran the openssl commands manually and the failure occurs during the "sign the host certificate request" stage.

The "Create a CSR based on the existing certificate" and "Revoke the old certificate" steps all work fine.

I am not sure but it looks to me like the "Sign the host certificate request" step is also trying to revoke the old cert but it has already been revoked.

The message that came up with the "Sign the host certificate request" step was

openssl ca -md sha256 -days 825 -batch -notext -in /var/ipfire/certs/hostreq.pem -out /var/ipfire/certs/hostcert.pem 

Using configuration from /etc/ssl/openssl.cnf
Check that the request matches the signature
Signature ok
The Subject's Distinguished Name is as follows
countryName           :PRINTABLE:'NL'
organizationName      :PRINTABLE:'XXXXX'
commonName            :PRINTABLE:'ipfire.XXXX.XXXX.XXXX'
ERROR:Serial number 01 has already been issued,
      check the database/serial_file for corruption
The matching entry has the following details
Type          :Revoked
Was revoked on:261109140353Z
Expires on    :261109140353Z
Serial Number :01
File name     :unknown
Subject Name  :/C=NL/O=Newton Sand/CN=ipfire.XXXX.XXXX.XXXX

and the Error message is that the serial number 01 has already been issued.

In the "Revoke the old certificate" step the following was reported:-

openssl ca -revoke /var/ipfire/certs/hostcert.pem 

Using configuration from /etc/ssl/openssl.cnf
Adding Entry with serial number 01 to DB for /C=NL/O=Newton Sand/CN=ipfire.saturn.pimb.org
Revoking Certificate 01.
Database updated

Hence why I think the signing is trying to revoke the cert a second time but my conclusion may not be valid.

Hopefully the above helps to figure out what is going wrong.
Comment 3 Adolf Belka 2024-08-06 14:42:21 UTC
Having looked through the code and thought about it for a while I am wondering if the serial number should be incremented when a new cert is being created. That doesn't happen in vpnmain.cgi. The value in the serial file always stays at 01 so when the replacement cert is being signed it finds that the serial entry in the database has already been used.

I just edited the serial file to change 01 to 02 and then ran the

openssl ca -md sha256 -days 825 -batch -notext -in /var/ipfire/certs/hostreq.pem -out /var/ipfire/certs/hostcert.pem 

command again and this time the cert was successfully signed and now the index.txt database has the revoked 01 cert and a valid 02 cert.

So the serial value needs to be incremented somewhere in the vpnmain.cgi code.

I will have a look and see if I can figure out where it should be done.
Comment 4 Adolf Belka 2024-08-06 16:21:33 UTC
After generating the Root/Host certificate set, if I change the value in the serial file from 01 to 02 and then press the Renew Host Certificate icon then the Host cert is renewed and the value in serial is incremented. So the incrementation is working but not at the start, only after serial has been changed to 02.

I also noticed that after creating the root/host certificates that the index.txt has no Valid entry for that cert, so it looks like the initial generation is not updating the index.txt database.

If the serial is changed to 02 after the root/host certs have been generated then a Renew Host Certificate step updates the index.txt to have a revoked 01 cert and a valid 02 cert.
Comment 5 Adolf Belka 2025-03-01 14:42:50 UTC
The change for renewing the vpn certificate was introduced in CU184.

I installed CU184 in my vm system and tested out renewing the certificate and got exactly the same error.
This suggests that this renewal was not working properly when it was first introduced. At least I have not been able to get it to renew successfully.

The error messages say that the renewal cannot be done because the serial number of the cert has already been revoked. So this looks like the missing bit is that when the renewal is done, that after the revoke the number in the serial file needs to be incremented.

I will have a look at adding the incremental update in and see if I can get it to work. Doing the incrementing manually worked when I tried it in my testing back in August 2024.
Comment 6 Adolf Belka 2025-03-02 18:52:14 UTC
So I have been able to get the regen working.

I had to increment the serial file number from 01 to 02 after the root/host certificate generation was completed.

After that the regen works and the serial number is automatically incremented.

There may be a better way of doing this but I could not identify it.

I also changed the "ipsec" entry for the log messages to "charon" so that the System Logs for IPSec show all the messages, including those related to generation and regeneration of the certificates.

I will submit a patch set for these changes for review to identify if there is a better alternative that I should have used.
Comment 8 Adolf Belka 2025-03-07 10:05:18 UTC
patch has been merged into next.

https://git.ipfire.org/?p=ipfire-2.x.git;a=commit;h=7d1d7e0bec4c7f991dbbb622ce414e0b91d14d74
Comment 10 Adolf Belka 2025-03-22 17:16:10 UTC
More work needed on the patch.

The patch submitted so far sets the serial number to 02 after the root/host certificate set is created, which works fine for a newly created certificate set.

However it doesn't work for an existing root/host certificate set which already has the serial number set at 01.

The simplest option would be to check in the update.sh script if the ipsec x509 certificate set has been created and then change the serial number to 02.

The only way this might be a problem is if someone has manually edited the serial file to have 02 in which case after any regen this number could already be higher than 02.

I think if I check in the update.sh script if serial contains 01 then it should be changed to 02 but otherwise it should be left as it is.

That way the serial number will only be updated for those ipsec root/host certificate sets that have been created but still have the serial file having the contents of 01.

I have moved the status back to ON_DEV until I have submitted a patch for the update.sh script and it has been merged etc.
Comment 11 Adolf Belka 2025-03-22 17:44:40 UTC
I realised that the backup should also be modified to ensure that a restore did not end up with a serial file with 01 again but then I discovered that the serial filer and the index.txt and the old versions of both of them are not backed up.

The only files backed up from the /var/ipfire/certs/ directory are all .pem files.

However the serial and the index.txt also need to be backed up, otherwise a restore could bring back an old certificate that has already been revoked in the existing index.txt file.

The serial and index.txt files for the /var/ipfire/ovpn/certs/ directory are backed up ( all files in that directory are backed up) and the same should be happening for the ipsec certs.

So my patch submission will also include a change to the include file to capture all in the vpn certs directory.

No change will be needed to the backup.pl file as no existing backups will contain a serial file for ipsec.  When this is started to be backed up then the serial file will already have contents of 02 once the root/host certificate set has been created for the first time and the update will ensure that existing ipsec systems will have a serial file containing at least 02.
Comment 12 Adolf Belka 2025-03-26 15:11:43 UTC
Further information has been identified. With the submitted patch when a new root/host x509 certificate set is created the serial file is set to "02".

However, when a client connection is then created, the act of doing this resets the serial file contents to "01".

It has become clear to me that the patch I submitted dealt with the symptoms of the problem and not the cause itself.

So the patch I submitted has been reverted.

Looking through the code I have identified that the subroutine &clearssldatabase is run after every openssl command for a new client connection cert and the root/host cert set. It is run both for when the command is successful and also if it gets an error.

Basically every cert action will reset the serial file back to "01" which is not what is wanted.

Currently the code also rests the serial entry for both client and root/host certs but there are no revocations of the client connection cert so that does not need to have any command to reset the serial file.

So it looks like I need to remove the &cleanssldatabase commands from the client opensssl cert creation commands and leave them in the root/host openssl cert commands but only for when the command has a failure and the status needs to be put back to the start position.

I now need to test the above out to confirm that it does what I expect and that it has not unexpected side effects.


It has also been identified that the renew process, which was supposed to create a new host cert with identical contents as the expired/revoked one was missing out the SubjectAltName line contents.

It has been identified how to fix that and the fix has been confirmed, so that will be submitted as a patch when the fix for the serial file contents has been identified and confirmed as working.
Comment 13 Adolf Belka 2025-04-01 13:06:29 UTC
(In reply to Adolf Belka from comment #12)

> 
> It has also been identified that the renew process, which was supposed to
> create a new host cert with identical contents as the expired/revoked one
> was missing out the SubjectAltName line contents.
> 
> It has been identified how to fix that and the fix has been confirmed, so
> that will be submitted as a patch when the fix for the serial file contents
> has been identified and confirmed as working.

I identified that the fix I used had already been applied to openssl.cnf in CU184 but the changed file was not shipped.

So the change is only found in new installs of CU184 or later.

Patch has been submitted to ship the changed openssl.cnf file

https://lists.ipfire.org/development/20250401122650.5358-1-adolf.belka@ipfire.org/T/#u

https://patchwork.ipfire.org/project/ipfire/list/?series=4834
Comment 14 Adolf Belka 2025-04-01 18:13:35 UTC
Patch set submitted to the dev mailing list and patchwork.

I have tested this quite carefully both with creating, renewing and deleting the root/host cert set and also with adding and deleting client certs.

Also tested out the backup changes.

Everything I tried worked but it will be good to have it reviewed in the patch review process in case I missed anything.

https://lists.ipfire.org/development/20250401180802.19784-1-adolf.belka@ipfire.org/T/#t

https://patchwork.ipfire.org/project/ipfire/list/?series=4835
Comment 16 Adolf Belka 2025-04-02 20:59:58 UTC
Patch set has been merged into next for CU194.