Certificate Manager CRL exception
-
Hello,
I am trying to understand why i get an Fatal error: Uncaught Exception when trying to add one particular certificate to the CRL-list.
I first created a bug: https://redmine.pfsense.org/issues/12528#change-57458 but since Jim was unable to reproduce my error i am asking here for advice instead (and adding more details).
The CA was created in pfsense I then exported the cert+key to generate a number of client certificates (100+) from a C#-code.
Now one of these generated certs is causing an exception in pfsense when i try to revoke it. The certificate in question is used by OpenVPN and it "works" as expected so i am still uncertain if its a pfsense-issue or if i have managed to create an invalid certificate that somehow works when used by OpenVPN.
I have tried a couple of random generated certificates and all (except the one) can be revoked in the CRL without issues. The only "random" element in the code is the serial-number where i am using byte[] serial = Guid.NewGuid().ToByteArray();
This yields a 16-byte long serial which should be ok since the serial can be 20 bytes long for a X509 certificate.The serial causing me issues is: CB9579AB2AC6D64287E5923816E6D660
Other serial numbers that i can revoke ok:
5214329F10411E498B3FDAC2B9E0E675
3B7547E616420A4189EBB4BDC1F0F311
3ECC14A77F691F4FA3D993D2DB849A52Here is the code generating certificates
using RSA rsa = RSA.Create(4096); var certificateRequest = new CertificateRequest(subject, rsa, HashAlgorithmName.SHA256, RSASignaturePadding.Pkcs1); byte[] serial = Guid.NewGuid().ToByteArray(); var caCertWithKey = LoadPemCertificate("cacert.pem", "cakey.pem"); using X509Certificate2 signedCert = certificateRequest.Create(caCertWithKey, caCertWithKey.NotBefore, caCertWithKey.NotAfter, serial); var signedCertWithPrivateKey = signedCert.CopyWithPrivateKey(rsa); var caCertWithoutKey = new X509Certificate2(caCertWithKey.Export(X509ContentType.Cert)); X509Certificate2Collection certificateChain = new X509Certificate2Collection { caCertWithoutKey, signedCertWithPrivateKey };
I think its the serial since its the only value i set differently each time.
I plan to generate new certificates with byte[] serial = BitConverter.GetBytes(id); instead but before i do i want to verify that this is the issue so i dont stumple on the same thing again in the future.
I tried to attach the pfsense crash report here but get "Post content was flagged as spam by Akismet.com". The crash report can be viewer in the redmine issue i created.
-
@ceaxe said in Certificate Manager CRL exception:
https://redmine.pfsense.org/issues/12528#change-57458
For easier reference the PHP errors read:
[18-Nov-2021 09:27:40 Europe/Stockholm] PHP Fatal error: Uncaught Exception: 0xCB9579AB2AC6D64287E5923816E6D660 is not INT in /usr/local/share/openssl_x509_crl/ASN1_INT.php:25 Stack trace: #0 /usr/local/share/openssl_x509_crl/X509_CRL.php(114): Ukrbublik\openssl_x509_crl\ASN1_INT->_construct('0xCB9579AB2AC6D...') #1 /etc/inc/certs.inc(1058): Ukrbublik\openssl_x509_crl\X509_CRL::create(Array, Resource id #13, '0\x82\x04G0\x82\x03/\xA0\x03\x02\x01\x02\x02\x01...') #2 /etc/inc/certs.inc(1088): crl_update(Array) #3 /usr/local/www/system_crlmanager.php(153): cert_revoke(Array, Array, 0) #4 {main} thrown in /usr/local/share/openssl_x509_crl/ASN1_INT.php on line 25
I have no particular insight there though.
-
The serial should be an integer, though it can be a hex string in some cases, it looks like yours are hitting an upper limit on the code processing the number inside the library. The problem number you posted is almost three times as large as the next largest one in your set, so it's possible it's overflowing somewhere.
The serials generated on pfSense are limited by the PHP SSL code to a serial number smaller than
PHP_INT_MAX
which varies by platform (e.g.9223372036854775807
on 64-bit,2147483647
on 32-bit ARM). This is due to limits in how some of the SSL code in PHP restricts things, which is beyond our control. So anything above that is hit and miss. Your code is making absolutely unnecessarily gigantic serial numbers that are much larger than the maximum the libraries can support. -
@jimp
Thanks for the reply and the technical details!I have changed the code now to be an integer that i convert to a byte[] resulting in way smaller numbers. I then re-created new certificates to be used hereafter.
I never considered that the guid i was generating and setting as the serial would have this affect (i only looked for a way to generate unique serials).
Should this perhaps be checked somewhere in the php frontend code of pfsense instead of crashing?
-
It would be nicer to detect that sort of case but it's highly unusual for anything to have serials like that, since to revoke a cert in the GUI the CA has to be internal to pfSense, and it's rare for anything but pfSense to have created certificates for such a CA.
So it's something we could maybe add eventually, but it's not something I'd consider a priority.