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
_______________________________________________
nginx-devel mailing list
nginx-devel@nginx.org
https://mailman.nginx.org/mailman/listinfo/nginx-devel

Reply via email to