#5420·poco

Support OpenSSL 4.0

Author: matejkCreated Jul 25, 2026Updated Aug 25, 2026
Labelsenhancementthird-party

OpenSSL 4.0.0 has been released. Poco should build cleanly and behave correctly against it. This issue tracks the required work for 2.0.

Reported downstream by Debian: https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=1138410 ("poco: FTBFS with openssl 4.0", package version 1.14.2-6)

Status of the reported build failure

The Debian FTBFS is the const-correctness change in X509_alias_get0():

Crypto/src/PKCS12Container.cpp:132: error: reinterpret_cast from type
'const unsigned char*' to type 'char*' casts away qualifiers

This is already fixed by #5239, which constified the X509* usage and switched to the ASN1_STRING accessors -- commit 413d2b9b5 on main, and ee292b113 on the 1.15.x branch. No action needed for 1.16.

Remaining work for OpenSSL 4.0

  1. libcrypto no longer runs OPENSSL_cleanup() from an atexit() handler. OpenSSLInitializer::uninitialize() (Crypto/src/OpenSSLInitializer.cpp) deliberately leaves the OSSL_PROVIDER handles to that handler. Under 4.0 the providers are never released, so the shutdown path has to be revisited (explicit cleanup at process exit, or an own OSSL_LIB_CTX).

  2. FIPS API -- partly done. #5460 converted OpenSSLInitializer::isFIPSEnabled() and SSLManager::isFIPSEnabled() to EVP_default_properties_is_fips_enabled(), and made FIPS usable in Context::initDH() (RFC 7919 ffdhe groups) and Context::initECDH().

    What remains: OpenSSLInitializer::enableFIPSMode() and the openSSL.fips configuration wiring in SSLManager::initDefaultContext() are still behind #ifdef OPENSSL_FIPS, which has not been defined since 1.0.2. So Poco can now detect FIPS but cannot enable it. Either wire EVP_default_properties_enable_fips() up unconditionally, or drop the setter and document that FIPS is enabled through OpenSSL configuration.

  3. Context::createSSLContext() FIPS branch. Now that isFIPSEnabled() is live (#5460), the branch at NetSSL_OpenSSL/src/Context.cpp:524 is reachable for the first time since OpenSSL 1.0.2. It uses TLS_method() for both client and server and leaves minTLSVersion at 0, so SSL_CTX_set_min_proto_version() is skipped entirely: a peer with fips=yes in its default properties silently loses the minimum-TLS-version floor. Either set minTLSVersion as the else path does, or remove the branch, since FIPS selection no longer needs a different method function.

  4. CI coverage. Add an OpenSSL 4.0 build job so regressions are caught before the next release.

Related

  • #5433 -- contributor PR addressing items 1 and 4.
  • #5460 -- FIPS fixes, merged; covers most of item 2 and creates item 3.
  • #5464 -- restores a #else that #5460 mis-nested, and adds an OpenSSL 1.1.1 CI job covering the pre-3.0 preprocessor branches.
  • #5415 / #5416 -- building against no-deprecated, merged.

Checked, no action required

  • ENGINE API removal: Poco does not use ENGINE_*.
  • Fixed SSL/TLS version method removal (SSLv3_method() etc.): not used; Poco selects protocols via SSL_CTX_set_min/max_proto_version.
  • ASN1_STRING made opaque: already accessed through ASN1_STRING_get0_data() / ASN1_STRING_length() / ASN1_STRING_type().
  • ERR_get_state() / ERR_remove_state() / ERR_remove_thread_state() removal: not used.
  • BIO_f_reliable() removal: not used.
  • Deprecated low-level key APIs (RSA_*, EC_KEY_*, DH_*, PEM_*_bio_RSA*, SSL_CTX_set_tmp_dh()): every remaining use in RSAKeyImpl.cpp, ECKeyImpl.cpp, RSACipherImpl.cpp, EVPPKey.cpp and Context::initDH() is inside a #else // !POCO_OPENSSL_VERSION_PREREQ(3, 0, 0) branch, so none of it is compiled against 3.0+ or 4.0. The 3.0+ path already uses EVP_PKEY. The one EC_KEY accessor left on the 3.0+ path (ECKeyImpl.cpp:224-251) is guarded by #ifndef OPENSSL_NO_DEPRECATED_3_0. These functions are also still present in the 4.0 headers as OSSL_DEPRECATEDIN_3_0, not removed.