Skip to content

Configurable loading of OpenSSL providers #12369

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
fdelapena opened this issue Oct 6, 2023 · 11 comments
Open

Configurable loading of OpenSSL providers #12369

fdelapena opened this issue Oct 6, 2023 · 11 comments

Comments

@fdelapena
Copy link

Description

Since OpenSSL 3, some ciphers are not available unless users configure some openssl.cnf file. This is not always possible on certain hosting configurations, so allowing this would unbreak applications depending on this feature.

Today, Windows .p12 files are still being generated using legacy ciphers, so PHP applications relying on this feature are not working out of the box. Distros are dropping OpenSSL 1.x.x since upstream support ended, current apps are struggling with this.

An example of legacy support added to a libssl-dependent app for guidance:
mtrojnar/osslsigncode#194

If legacy provider is not planned to be enabled by default, please consider allowing to enable this programmatically at least. Thank you.

@schweini
Copy link

schweini commented Oct 6, 2023

I second this. I just had a major headache after updating to Debian 12 Bookworm because of this. OpenSSL and the PHP libraries that were trying to use it just refused to open the .p12 file until I enabled legacy providers in OpenSSL config.

@bukka
Copy link
Member

bukka commented Oct 6, 2023

I don't think we would want to enable legacy provider by default as it contains insecure algorithms but maybe something that would allow easier loading of providers could be added.

@alphaolomi
Copy link

User Contributed Notes report the openssl-pkcs12-read doesn't work anymore

https://www.php.net/manual/en/function.openssl-pkcs12-read.php

@fdelapena
Copy link
Author

fdelapena commented Oct 10, 2023

Maybe it could be applied just for the openssl_pkcs12_read() and other pkcs12_* functions when it fails when the .p12 file uses the quite common RC2-40-CBC cipher suite and let the rest of PHP without legacy provider. Note there are different ciphers for certificate bag and key bag and usually both are legacy, this is usually the first that makes read fail).

For affected users, the current workaround is awful as it requires to add or uncomment certain openssl.cnf lines from specific sections to look like this:

openssl_conf = openssl_init

[openssl_init]
providers = provider_sect

[provider_sect]
default = default_sect
legacy = legacy_sect

[default_sect]
activate = 1

[legacy_sect]
activate = 1

Configuration placement differs depending on the platform or there could be multipe configuration files, the openssl.cnf that uses the openssl command corresponds to the OPENSSLDIR value that returns the openssl version -d comand and affected users usually need to modify the openssl.cnf that is inside that directory.

Modifying the whole OpenSSL configuration is worse than having fine grained legacy provider loading when required by affected PHP funtions, so this is good to have as an opt-in configuration at least.

@bukka
Copy link
Member

bukka commented Oct 20, 2023

So I have been looking into this and investigated the whole providers loading.

As correctly noted the only way how to load providers is through the config. Specifically it needs to load the config and call CONF_modules_load which happens only during openssl extension MINIT (module initialisation) when PHP starts. This should not be confused with config passed to functions like openssl_pkey_new which only loads the config (using NCONF_load) but does not load modules. It means you cannot put openssl_pkey_new with config loading providers as that is not going to work. I just tested it to be sure and can confirm that's how it works which is expected because we don't want to probably allow loading modules during each request as this is not a good pattern - it should always happen during MINIT.

There is actually a way how you can change OpenSSL config so it does not need to depend on OPENSSLDIR. This can be done by setting OPENSSL_CONF environment variable. So in my case (using my test script) I can do something like:

OPENSSL_CONF=/home/jakub/prog/php/tests/openssl/pkcs12-rc2/openssl.conf php parse.php

Please note that it needs to be set before MINIT so if you run it in FPM, then it needs to be exported when starting FPM. Adding that to FPM config is not going to work because that would be just for children that run after MINIT.

I realise that it is not an optimal solution and we should allow configurable way of loading and activating providers. This will be however a feature so it can only target master branch which currently means PHP 8.4.

I have been also checking how we could enabled specific providers only for specific PHP part (e.g. enabling it legacy just pcks12 functions). There is a library context (libctx param) that is exactly for this purpose and the used providers can be also customised using properties (usually used for fetching) - meaning it is possible to select providers that the operation will be dispatched to. However this is not available for all functions by the look of it. It doesn't seem possible to use custom library context or properties for PKCS12_parse so this might not be an option. It can basically work just for some parts (e.g. ciphers, pkey, md, rand and potentially something else).

@bukka bukka changed the title Enable legacy OpenSSL provider by default Configurable loading of OpenSSL providers Oct 20, 2023
@parallels999
Copy link

@fdelapena hi, on windows, i'm already tried

openssl_conf = openssl_init

[openssl_init]
providers = provider_sect

[provider_sect]
default = default_sect
legacy = legacy_sect

[default_sect]
activate = 1

[legacy_sect]
activate = 1

But Still openssl_pkcs12_read doesn't work, PHP 8.2.11

@fdelapena
Copy link
Author

@parallels999 not tested on Windows here, but it could be #9890.

@parallels999
Copy link

Yes, that was it, I added OPENSSL_MODULES and legacy.dll, then restarted Windows, thank you

@jlungo
Copy link

jlungo commented Jun 26, 2024

Thanks, I updated the openssl.cnf

@jlungo
Copy link

jlungo commented Jun 26, 2024

Thanks, I updated the openssl.cnf

and it works. Thanks

@jlungo
Copy link

jlungo commented Jun 26, 2024

@fdelapena hi, on windows, i'm already tried

openssl_conf = openssl_init

[openssl_init]
providers = provider_sect

[provider_sect]
default = default_sect
legacy = legacy_sect

[default_sect]
activate = 1

[legacy_sect]
activate = 1

But Still openssl_pkcs12_read doesn't work, PHP 8.2.11

This is a perfect solution

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

6 participants