Certificate gp12-file generated with Opnsense can't be imported in Zyxel GS1920

Started by Schnuffel2008, May 18, 2023, 08:19:54 AM

Previous topic - Next topic
Hi,
I had a problem with importing a self-signed certificate that I've generated with OPNsense couldn't be imported in a zyxel switch. I solved the problem with downloading the crt-file and the key-file separately and generate the P12-File with an Windows OpenSSL-Installation.
The two files differ in size. The p12-file that was downloaded directly in opnsense is ca. 20% bigger than the file that was generated with OpenSSL.
I am not so familiar with self signed certificates and don't know if the problem belongs to Zyxel or opensense.
But for other Zyxel-users this could be a working solution.

I'd say that could be due to differences in OpenSSL versions.

Was your Windows OpenSSL install v3+ by any chance?

No,

the version that I've used is Win64OpenSSL-1_1_1t. I think that is the same version that Opnsense uses when I look it up under installed packages.

Quote from: Schnuffel2008 on May 18, 2023, 03:59:10 PM
...the version that I've used is Win64OpenSSL-1_1_1t...
It is indeed the same version as presently used in OPNsense.

I'm curious what command you used - and whether the same command from an OPNsense shell would produce a working PKCS #12 archive too. Perhaps some additional parameters are required...

Hi,
I did what you suggested and the result is really interesting.
1.) Download cert- and key-file and generate the P12-File with WinOpenSSL 1.1.1t. The File can be imported to the Zyxel-GS1920-24v2 switch and the switch can afterwards be reached via https. Filesize 3,08kb
2.) Download the p12 directly from Opnsense. The File can't be imported to switch. Filesize 4,75kb
3.) Copy the cert- and key-file that was used with WinOpenSSL to Opnsense, log in with putty and generate P12-File with Opnsense-Openssl. P12 can be imported and https is functional. Filesize 3,08kb
Command for generating the p12-File: openssl pkcs12 -export -out certificate.p12 -inkey certificate.key -in certificate.crt
It looks like the problem belongs to the automated generation of the P12-File in the WebGui.

That is indeed interesting.

Quote from: Schnuffel2008 on May 18, 2023, 08:19:54 AM
The two files differ in size. The p12-file that was downloaded directly in opnsense is ca. 20% bigger than the file that was generated with OpenSSL.

For the file you manually generated, and also for the file exported in OPNsense, what do the differences in output of the command openssl pkcs12 -info -nodes -in certificate.p12 reveal?

OPNsense makes use of the builtin PHP openssl_pkcs12_export() function, which includes the capacity to include a certificate chain. I suspect the PKCS#12 archive generated in OPNsense is including a CA certificate. Given that you are using a self-signed certificate, it is likely including itself as an extra. Maybe that is a problem for Zyxel kit. Maybe for others too.

Looking at the source, there doesn't appear to be any screening of self-signed certificates to prevent them from including extras.

Hi,

I first made a mistake in testing the different files. After comparing the correct files with the command that you've said I can see that the WebGui-generated file consist of 2 certificates and 1 private key and the openssl-generated only of 1 certficate and 1 private key. So I think that it is as you had supposed.
With a little bit more investigation I found that there is another small difference between the files, under the attribute "Bag Attributes" there is the attribute "friendlyName:" that is missing in the openssl-file. Even though I think that this is the problem I want to tell you about it.

Quote from: Schnuffel2008 on May 23, 2023, 07:58:12 PM
...under the attribute "Bag Attributes" there is the attribute "friendlyName:" that is missing in the openssl-file.
Are you sure the friendlyName was missing in the manually generated file? I would expect it to be missing in the OPNsense generated file instead.

This is because the OPNsense code does not add a friendly_name key & value pair in the options parameter to the openssl_pkcs12_export() function (represented by the $args variable in OPNsense). Only the extracerts key is implemented, with the value being the first CA certificate found.

It is exactly as I said.
The WebGui-generated File has the two different certificates and the private-key and the attribute friendlyName: and the OpenSSL-generated file has one certificate and one key and is missing friendlyName: I proofed it now with the OpenSSl-installation from OPNsense via telnet.

Quote from: Schnuffel2008 on May 25, 2023, 09:02:42 PM
It is exactly as I said...
Right, thanks for confirming that.

Looking at the source for the PHP openssl_pkcs12_export() function, I see the OpenSSL PKCS12_create() function is ultimately what does the heavy lifting. The man page for this function states:
QuoteIf a certificate contains an alias or keyid then this will be used for the corresponding friendlyName or localKeyID in the PKCS12 structure.
So in our case, when no friendly_name is specified, the PHP uses NULL and the OpenSSL function then uses the certificate alias for the friendlyName Bag attribute. Mystery solved..!

Any chance you could recreate the PKCS#12 archive with the following, and then see if it will import into your switch?
openssl pkcs12 -export -in certificate.crt -inkey certificate.key -name "friendlyName" -out certificate.p12
If it does successfully import, then we can eliminate the inclusion of the friendlyName Bag attribute as a cause.

Quote from: Schnuffel2008 on May 25, 2023, 09:02:42 PM
The WebGui-generated File has the two different certificates...
Can you also please confirm the two certificates in the WebGUI-generated archive are indeed different? I expected them to be the same as it is self-signed. It could be argued that including a self-signed certificate as a CA certificate is a bug.

However, if they are not the same, then we would need to understand how they are related to one another in your particular environment, i.e. is one truly the issuer of the other, and if not why is the CA certificate being picked up...?! If there is proper cause for the inclusion of extra certificate(s), then the bug is likely with the switch (which could at least ignore the extra certificates).

Just to be sure, have you updated the switch firmware to the most recent version [4.80(ABMH.0)C0 dated April 27, 2023].

Hi,

I've generated the P12-File with OpenSSL and the new parameter -name and it can be imported as well, so you are right the friendly name seems to be not the problem.
And I have proofed, that the two certificates are different. The first one is the https-certificate and the second one is the certificate for the intermediate CA. The first one has 2136 chars whereas the second one has 2198 chars. The attributes shows that the issuer for the first certificate is my Intermediate CA and for the second one for the "root CA", so they are for sure different.
And to answer your last question, here is the firmware-info for my switch: V4.80(ABMH.0) and the file that I have used to upgrade the switch was GS1920-24v2_4.80(ABMH.0)C0.zip which is the newest version on the Zyxel-Homepage

Quote from: Schnuffel2008 on May 18, 2023, 08:19:54 AM
I had a problem with importing a self-signed certificate...

Quote from: Schnuffel2008 on May 28, 2023, 11:05:33 AM
And I have proofed, that the two certificates are different. The first one is the https-certificate and the second one is the certificate for the intermediate CA. The first one has 2136 chars whereas the second one has 2198 chars. The attributes shows that the issuer for the first certificate is my Intermediate CA and for the second one for the "root CA", so they are for sure different.

These two statements cannot be reconciled. By definition, a self-signed certificate has no chain of trust established by relevant intermediate (issuing) CA and root CA certificates; it is its own CA. What you likely have is a client certificate, and in this case I would hope it is a server certificate (it should be listed with "CA: No, Server: Yes" in the OPNsense GUI at System: Trust: Certificates).

If the above is true, it would appear the extra certificate is problematic for the switch. Looking at the User Manual I see no reason why the switch wouldn't accept the extra certificate, e.g. it doesn't specify that a self-signed certificate is required. That being said, the switch might not be capable of dealing with Intermediate CA certificates and may only give Issuer information.

More typically in IT device management - and despite best practice - the issuer of SSL certificates is a root CA rather than an Intermediate CA. The root CA certificate isn't usually included in the certificate_list of the Server Certificate Message, and so is usually not needed by the server (in this case your switch) when responding to clients. As such, your switch might not be expecting any extra certificates and therefore it might not have code to deal with an Intermediate CA certificate. An alternative possibility is that the switch is expecting the Root CA certificate to be present too, and when it cannot find it in the PKCS#12 archive it baulks...

You might want to try creating the PKCS#12 archive using the -certfile filename parameter (where filename is a file containing the CA certificates) to see if this also causes a failure. You might also try the -chain parameter instead, which will load all the relevant CA certificates from the local store, so perhaps this is more likely to work at the OPNsense terminal.

The extension of this is to specify the -nokeys -cacerts parameters to get a PKCS#12 archive with just the CA certificates to attempt to import.

There is some value in testing with the CA certificate file containing both CA certificates, but also with just the Intermediate CA certificate (-chain won't work for the latter, just specify an exported PEM copy instead using -certfile). Before importing, I would recommend checking the contents of each PKCS#12 archive you create using:openssl pkcs12 -info -nodes -in certificate.p12

If the switch does successfully import a PKCS#12 archive with both extra certificates, then we could raise a bug report on OPNsense to include the root CA certificate too (it really should be imho). If instead, one of the PKCS#12 archives of just CA certificate(s) can be successfully imported, or the switch refuses to import any CA certificates, then I would suggest the issue needs to be raised with Zyxel. They should be able to advise what incompatibility might exist, whether it is a lack of capability in their implementation, or an aspect of your archive or even the certificate, etc.

Hi,
I have tested everything the way you said and it seems to be that you are totally right.
First, the certificate is listed with CA: no, Server: yes in the Opnsense Gui.
When I add the Intermediate-CA-certificate with the certfile option in OpenSSL I get a file that is nearly the same size as the OPNsense-Gui generated file and it can't be imported. After coverting the Root_CA and Intermediate_CA certificates to PEM-Files and combine them with cat cert1.pem cert2.pem > cert.pem I've got a P12-File with 4 certificates by using the -certfile-Option. But this can't be imported too. The -chain option didn't work for me. I've always get an error-message. Since I am only a beginner with the certificate-stuff it is not clear to me what I have to do with the -nokeys -cacerts-Option. I haven't used it so maybe that coud be the reason why the import of the p12-File with all certificates won't work. But it seems to be a fact, that the switch has a problem with P12-Files that have more than one certificate.
I've told Zyxel about my problem with the certificates in their forum too, and they have a closer look on my problem at he moment. I've send them a link to this topic here and maybe someone have a look on the things you found out.
But what is not clear to me is what is the benefit of generating the P12-File in the WebGui with including the certificate for the Intermediate-CA. Does any szenario has a benefit of the second certificate? If not, why won't OPNsense change the way they generate the P12-File to only combine the key and the corresponding certificate? 

Quote from: Schnuffel2008 on May 29, 2023, 11:30:43 PM
Since I am only a beginner with the certificate-stuff it is not clear to me what I have to do with the -nokeys -cacerts-Option.
The -nokeys -nocerts parameters would create the PKCS#12 archive without the private key and server certificate. Only the CA certificate(s) would be included depending on whether you use -certfile cert.pem or -certfile cert2.pem (presuming your Intermediate CA cert was cert2.pem and not cert1.pem). You could then attempt to import them into the switch. This was to check if the switch accepts CA certificates without them being an extra certificate(s). We know it accepts server certificates, but what about CA certificates. I note this may not be a valid test anyway, depending on how Zyxel have chosen to process the bag. An alternative would be to export the Intermediate CA certificate in the GUI as a PKCS#12 archive and see if that can be imported. Does that make sense now?

Quote from: Schnuffel2008 on May 29, 2023, 11:30:43 PM
But what is not clear to me is what is the benefit of generating the P12-File in the WebGui with including the certificate for the Intermediate-CA. Does any szenario has a benefit of the second certificate?
According to the relevant RFC, when setting up the HTTPS connection, a server (in this case your switch) is required to include all intermediate CA certificates in the certificate_list of the Server Certificate Message. The exception is the root CA certificate, which MAY be omitted from the chain specified in the certificate_list.

So essentially, the server is required to provide all the certificates in the chain except the root CA certificate, which should be in your certificate store if you trust it. That way, you only need the trust anchor, i.e. the root CA certificate, and the server will provide any other certificates in the chain.

It is noteworthy that normally, when including the extra CA certificates in a PKCS#12 export, the root CA would also be included, i.e. the whole chain would be in the bag. However, in the case of OPNsense only the issuer certificate is included. One reason could be convenience, as some certificate stores will hold multiple copies of the same certificate when it is imported. So if all certificates are imported, then this could result in multiple copies of the same root CA certificate (and issuing CA certificates) being present in the store, which can introduce additional management overhead. There are likely other compatibility or simplicity reasons for this, but I do note that it is possible this could change in the future and the root CA certificate could end up being included.

I only mention this in the event a vendor might wish to accommodate same, whether it be the presence of a root CA certificate in the PKCS#12 archive generally, or whether it be to check for duplicates before importing.