Skip to content

openssl libctx implementation needs broader scoping #21239

@brett-moser-eschat

Description

@brett-moser-eschat

Description

Attempting to upgrade from php 8.4.18 to 8.5.3, without changing anything else, has caused issues with the use of the OpenSSL extension.

  1. using mysqli/mysqlnd we were unable to open a TLS 1.3 connection to a MySQL database. The SSL_CTX_new() was returning an error, indicating no available Ciphers. Changing to the use of SSL_CTX_new_ex(), and passing in the libctx global, fixed this issue.

  2. attempts to use openssl_random_pseudo_bytes() generated [Exception] Error reading from source device that was traced back to RAND_bytes() which required a similar uplift to RAND_bytes_ex()

There is uncertainty whether additional OpenSSL functions still need to be modified to use LIBCTX, these are the only examples encountered thus far.

Environment:

Running in a containerized environment based on redhat UBI 9.6 with FIPS cryptography enabled using OpenSSL 3.5.1 and the OpenSSL 3.0.7 FIPS provider.

patches that got things working (NOTE: these are quick hacks clearly not the correct way to implement given the multiple backends (v1 vs v3) support:

diff --git a/ext/openssl/openssl_backend_common.c b/ext/openssl/openssl_backend_common.c
index 33ffa55e489..09a1f1f4f57 100644
--- a/ext/openssl/openssl_backend_common.c
+++ b/ext/openssl/openssl_backend_common.c
@@ -30,6 +30,7 @@
 #define timezone _timezone     /* timezone is called _timezone in LibC */
 #endif
 
+ZEND_EXTERN_MODULE_GLOBALS(openssl)
 
 /* openssl -> PHP "bridging" */
 /* true global; readonly after module startup */
@@ -2053,7 +2054,7 @@ PHP_OPENSSL_API zend_string* php_openssl_random_pseudo_bytes(zend_long buffer_le
        buffer = zend_string_alloc(buffer_length, 0);
 
        PHP_OPENSSL_CHECK_LONG_TO_INT_NULL_RETURN(buffer_length, length);
-       if (RAND_bytes((unsigned char*)ZSTR_VAL(buffer), (int)buffer_length) <= 0) {
+       if (RAND_bytes_ex(PHP_OPENSSL_LIBCTX, (unsigned char*)ZSTR_VAL(buffer), (int)buffer_length, 256) <= 0) {
                php_openssl_store_errors();
                zend_string_release_ex(buffer, 0);
                zend_throw_exception(zend_ce_exception, "Error reading from source device", 0);
diff --git a/ext/openssl/xp_ssl.c b/ext/openssl/xp_ssl.c
index db71a3c325a..beebd58f32d 100644
--- a/ext/openssl/xp_ssl.c
+++ b/ext/openssl/xp_ssl.c
@@ -150,6 +150,8 @@
 #define HAVE_IPV6_SAN 1
 #endif
 
+ZEND_EXTERN_MODULE_GLOBALS(openssl)
+
 extern php_stream* php_openssl_get_stream_from_ssl_handle(const SSL *ssl);
 extern zend_string* php_openssl_x509_fingerprint(X509 *peer, const char *method, bool raw);
 extern int php_openssl_get_ssl_stream_data_index(void);
@@ -1302,7 +1304,7 @@ static SSL_CTX *php_openssl_create_sni_server_ctx(char *cert_path, char *key_pat
 {
        /* The hello method is not inherited by SSL structs when assigning a new context
         * inside the SNI callback, so the just use SSLv23 */
-       SSL_CTX *ctx = SSL_CTX_new(SSLv23_server_method());
+       SSL_CTX *ctx = SSL_CTX_new_ex(PHP_OPENSSL_LIBCTX, PHP_OPENSSL_PROPQ, SSLv23_server_method());
 
        if (SSL_CTX_use_certificate_chain_file(ctx, cert_path) != 1) {
                php_error_docref(NULL, E_WARNING,
@@ -1576,10 +1578,32 @@ static zend_result php_openssl_setup_crypto(php_stream *stream,
        method_flags = cparam->inputs.method & ~STREAM_CRYPTO_IS_CLIENT;
 
        method = sslsock->is_client ? SSLv23_client_method() : SSLv23_server_method();
-       sslsock->ctx = SSL_CTX_new(method);
+       sslsock->ctx = SSL_CTX_new_ex(PHP_OPENSSL_LIBCTX, PHP_OPENSSL_PROPQ, method);

PHP Version

PHP 8.5.3 (cli) (built: Feb 16 2026 22:11:01) (NTS DEBUG)
Copyright (c) The PHP Group
Zend Engine v4.5.3, Copyright (c) Zend Technologies
    with Zend OPcache v8.5.3, Copyright (c), by Zend Technologies

Operating System

Redhat UBI 9.6 w/ FIPS provider

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions