From: Remi Gacogne Date: Tue, 13 Dec 2022 14:59:28 +0000 (+0100) Subject: dnsdist: Fix loading PKCS12-encrypted (RC2 CBC) certs with OpenSSL 3.x X-Git-Tag: dnsdist-1.8.0-rc1~146^2 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=refs%2Fpull%2F12320%2Fhead;p=thirdparty%2Fpdns.git dnsdist: Fix loading PKCS12-encrypted (RC2 CBC) certs with OpenSSL 3.x --- diff --git a/pdns/libssl.cc b/pdns/libssl.cc index 4e22a4ead6..9bb0aaee3e 100644 --- a/pdns/libssl.cc +++ b/pdns/libssl.cc @@ -20,6 +20,9 @@ #include #endif /* DISABLE_OCSP_STAPLING */ #include +#if defined(OPENSSL_VERSION_MAJOR) && OPENSSL_VERSION_MAJOR >= 3 +#include +#endif /* defined(OPENSSL_VERSION_MAJOR) && OPENSSL_VERSION_MAJOR >= 3 */ #include #include #include @@ -828,10 +831,30 @@ std::unique_ptr libssl_init_server_context(const TLS EVP_PKEY *keyptr = nullptr; X509 *certptr = nullptr; STACK_OF(X509) *captr = nullptr; - if (!PKCS12_parse(p12.get(), (pair.d_password ? pair.d_password->c_str() : nullptr), &keyptr, &certptr, &captr)) - { - ERR_print_errors_fp(stderr); - throw std::runtime_error("An error occured while parsing PKCS12 file " + pair.d_cert); + if (!PKCS12_parse(p12.get(), (pair.d_password ? pair.d_password->c_str() : nullptr), &keyptr, &certptr, &captr)) { +#if defined(OPENSSL_VERSION_MAJOR) && OPENSSL_VERSION_MAJOR >= 3 + bool failed = true; + /* we might be opening a PKCS12 file that uses RC2 CBC or 3DES CBC which, since OpenSSL 3.0.0, requires loading the legacy provider */ + auto libCtx = OSSL_LIB_CTX_get0_global_default(); + /* check whether the legacy provider is already loaded */ + if (!OSSL_PROVIDER_available(libCtx, "legacy")) { + /* it's not */ + auto provider = OSSL_PROVIDER_load(libCtx, "legacy"); + if (provider != nullptr) { + if (PKCS12_parse(p12.get(), (pair.d_password ? pair.d_password->c_str() : nullptr), &keyptr, &certptr, &captr)) { + failed = false; + } + /* we do not want to keep that provider around after that */ + OSSL_PROVIDER_unload(provider); + } + } + if (failed) { +#endif /* defined(OPENSSL_VERSION_MAJOR) && OPENSSL_VERSION_MAJOR >= 3 */ + ERR_print_errors_fp(stderr); + throw std::runtime_error("An error occured while parsing PKCS12 file " + pair.d_cert); +#if defined(OPENSSL_VERSION_MAJOR) && OPENSSL_VERSION_MAJOR >= 3 + } +#endif /* defined(OPENSSL_VERSION_MAJOR) && OPENSSL_VERSION_MAJOR >= 3 */ } auto key = std::unique_ptr(keyptr, EVP_PKEY_free); auto cert = std::unique_ptr(certptr, X509_free);