[PATCH 0/4] SSL: Add support for loading X.509 certificates from openssl engine
Vesa Jääskeläinen
vesa.jaaskelainen at vaisala.com
Thu Jul 13 07:38:02 UTC 2023
Hi Maxim,
On 13.7.2023 3.48, Maxim Dounin wrote:
> Hello!
>
> On Wed, Jul 12, 2023 at 05:07:03PM +0300, Vesa Jääskeläinen via nginx-devel wrote:
>
>> (I hope this goes properly out as I had major issues with hg email so
>> combined hg export + git send-email)
>>
>> It is convenient to keep X.509 certificates related to key pairs stored in
>> openssl engine within the engine.
>>
>> Implementation uses 'LOAD_CERT_CTRL' extension to fetch certificate from
>> the engine. This extension is not supported by all engines and in those
>> cases it should report with an error.
>>
>> Configuration is similar to what it is for 'ssl_certificate_key'.
>>
>> First certificate must match with ssl_certificate_key's key pair rest of
>> the certificiates are added to the certificate chain.
>>
>> Example configuration with libp11's pkcs11 engine:
>>
>> ssl_certificate "engine:pkcs11:pkcs11:token=mytoken;object=mykey
>> engine:pkcs11:pkcs11:token=mytoken;object=int-ca";
>> ssl_certificate_key "engine:pkcs11:pkcs11:token=mytoken;object=mykey?pin-value=mypin";
>>
>> Tested the loading with two pkcs11 implementations SoftHSMv2 and with
>> OP-TEE's PKCS11 Trusted Application running on Embedded Linux device.
>>
>> First three commits is the main beef and in order to make it more flexible
>> added also last commit allowing intermediate certificates loaded from file
>> system.
>>
>> Separator of space is used as there was already existing use of array for
>> ssl_certificate configuration.
> Just in case, a similar proposal was previously discussed here:
>
> https://mailman.nginx.org/pipermail/nginx-devel/2020-April/013130.html
> https://mailman.nginx.org/pipermail/nginx-devel/2020-May/013142.html
>
> Notably, the review is here:
>
> https://mailman.nginx.org/pipermail/nginx-devel/2020-May/013152.html
>
> I'm additionally sceptical about this given that engine interface
> is deprecated by OpenSSL.
Thanks for the links.
The provider interface in OpenSSL 3 is yet to be matured for PKCS11 usage.
libp11 so far seems to have stayed with "legacy" engine and just adapted
for OpenSSL 3.
Then there is new project that is still in development phase but looks
promising:
https://github.com/latchset/pkcs11-provider
But before that provider implementation matures and is available in
distributions it takes one or more major LTS releases.
While waiting for that it would be nice to have the support.
What is interesting that the CMD extension is already being integrated
to other software like curl, wpa-supplicant/hostapd, stunnel, ppp,
M2Crypto -- so I would say the feature is there to stay for a while.
Even not documented as official openssl "extension" it is there and is
being used.
Now openssl also has "store" API which can be extended with different
schemes too but in example libp11 does not today support that.
https://www.openssl.org/docs/man1.1.1/man7/ossl_store.html
https://www.openssl.org/docs/man1.1.1/man3/OSSL_STORE_LOADER.html
Now the Nginx is already using the "legacy" interface so if it is enable
why not then support the certificate loading when it is available.
I believe these can even coexist.
provider:<provider>:<object id>
provider:pkcs11:<your pkcs11 uri>
and
engine:<engine>:<object id>
engine:pkcs11:<your pkcs11 uri>
or even:
store:<scheme>:<object id>
store:pkcs11:<your pkcs11 uri>
store:file:/path/to/your/pem-file
Now the problem of these all is what certificate to load and what
certificates from the chain to load if any.
"The correct way" is to load all certificates till the root (excluding
the root) but this is not how some people setup the stuff. So you need a
way to be able to specify the chain.
With PEM files this is easy as one can craft them freely.
With other providers you need to either configure (like what M2Crypto
uses) or be simple only use the certificate without chain (a bit ugly
approach).
ssl_certificate "engine:pkcs11:<your pkcs11 uri> engine:pkcs11:<your
pkcs11 uri> engine:pkcs11:<your pkcs11 uri>"
or you could even mix'n'match if you have go good idea:
ssl_certificate "provider:<provider>:<object id>
store:<scheme>:<object id> /my/pem/file/here.pem"
For this I used the white space(s) as a separator in order to be able to
configure the chain.
Alternative for that would have been:
ssl_certificate "engine:pkcs11:<your pkcs11 uri>"
"engine:pkcs11:<your pkcs11 uri>" "engine:pkcs11:<your pkcs11 uri>"
But that would have created array of array of strings as there was
support to configure multiple certificate chains+key pairs and let the
nginx pick which to serve.
Why I believe it is a good idea to support engine/or in future the
provider interface is that to keep the certificates in one place next to
the keys. With this if the key pair gets re-created or new certificates
to be updated if you have the labels there you just need to trigger the
refresh. Then there is no extra data to extract or such as then those
could be out-of-sync and people try to figure out problems with that.
If I am not mistaken the previous discussion comments has been addressed
in this change set.
I am happy to test out the provider with pkcs11-provider too but I would
recommend that we also support today's methods so people can start using
the feature.
Thanks,
Vesa Jääskeläinen
More information about the nginx-devel
mailing list