fix provider loading take two (#10390) (#10395)

we previously hoisted this into rust, but we used the try_load feature
which supposedly retains fallbacks. Something about that doesn't behave
the way we expect though and the machinery in providers is sufficiently
complex that we are just going to load the default provider explicitly.

this matches our behavior pre-rust.
This commit is contained in:
Paul Kehrer 2024-02-15 19:01:07 -08:00 committed by GitHub
parent 0e0e46f5f7
commit 396bcf64c5
No known key found for this signature in database
GPG key ID: B5690EEEBB952194

View file

@ -24,6 +24,7 @@ mod x509;
#[pyo3::prelude::pyclass(frozen, module = "cryptography.hazmat.bindings._rust")] #[pyo3::prelude::pyclass(frozen, module = "cryptography.hazmat.bindings._rust")]
struct LoadedProviders { struct LoadedProviders {
legacy: Option<provider::Provider>, legacy: Option<provider::Provider>,
_default: provider::Provider,
} }
#[pyo3::prelude::pyfunction] #[pyo3::prelude::pyfunction]
@ -37,7 +38,7 @@ fn is_fips_enabled() -> bool {
} }
#[cfg(CRYPTOGRAPHY_OPENSSL_300_OR_GREATER)] #[cfg(CRYPTOGRAPHY_OPENSSL_300_OR_GREATER)]
fn _initialize_legacy_provider() -> CryptographyResult<LoadedProviders> { fn _initialize_providers() -> CryptographyResult<LoadedProviders> {
// As of OpenSSL 3.0.0 we must register a legacy cipher provider // As of OpenSSL 3.0.0 we must register a legacy cipher provider
// to get RC2 (needed for junk asymmetric private key // to get RC2 (needed for junk asymmetric private key
// serialization), RC4, Blowfish, IDEA, SEED, etc. These things // serialization), RC4, Blowfish, IDEA, SEED, etc. These things
@ -47,13 +48,14 @@ fn _initialize_legacy_provider() -> CryptographyResult<LoadedProviders> {
.map(|v| v.is_empty() || v == "0") .map(|v| v.is_empty() || v == "0")
.unwrap_or(true); .unwrap_or(true);
let legacy = if load_legacy { let legacy = if load_legacy {
let legacy_result = provider::Provider::try_load(None, "legacy", true); let legacy_result = provider::Provider::load(None, "legacy");
_legacy_provider_error(legacy_result.is_ok())?; _legacy_provider_error(legacy_result.is_ok())?;
Some(legacy_result?) Some(legacy_result?)
} else { } else {
None None
}; };
Ok(LoadedProviders { legacy }) let _default = provider::Provider::load(None, "default")?;
Ok(LoadedProviders { legacy, _default })
} }
fn _legacy_provider_error(success: bool) -> pyo3::PyResult<()> { fn _legacy_provider_error(success: bool) -> pyo3::PyResult<()> {
@ -94,13 +96,13 @@ fn _rust(py: pyo3::Python<'_>, m: &pyo3::types::PyModule) -> pyo3::PyResult<()>
let openssl_mod = pyo3::prelude::PyModule::new(py, "openssl")?; let openssl_mod = pyo3::prelude::PyModule::new(py, "openssl")?;
cfg_if::cfg_if! { cfg_if::cfg_if! {
if #[cfg(CRYPTOGRAPHY_OPENSSL_300_OR_GREATER)] { if #[cfg(CRYPTOGRAPHY_OPENSSL_300_OR_GREATER)] {
let providers = _initialize_legacy_provider()?; let providers = _initialize_providers()?;
if providers.legacy.is_some() { if providers.legacy.is_some() {
openssl_mod.add("_legacy_provider_loaded", true)?; openssl_mod.add("_legacy_provider_loaded", true)?;
openssl_mod.add("_providers", providers)?;
} else { } else {
openssl_mod.add("_legacy_provider_loaded", false)?; openssl_mod.add("_legacy_provider_loaded", false)?;
} }
openssl_mod.add("_providers", providers)?;
} else { } else {
// default value for non-openssl 3+ // default value for non-openssl 3+
openssl_mod.add("_legacy_provider_loaded", false)?; openssl_mod.add("_legacy_provider_loaded", false)?;