From 7950482562f3f53fb06d9933474b981358689faf Mon Sep 17 00:00:00 2001 From: Ilia Alshanetsky Date: Sun, 8 Mar 2026 17:56:29 -0400 Subject: [PATCH 1/3] Fix GH-21083: Skip private_key_bits validation for EC/curve-based keys openssl_pkey_new() checks private_key_bits >= 384 before generating any key. For EC, X25519, ED25519, X448, and ED448 the size is inherent to the curve or algorithm, so this check doesn't apply and causes failures when default_bits is missing from openssl.cnf (which is the case in OpenSSL 3.6's default config). Skip the minimum-bits check for key types that don't use private_key_bits. Closes GH-21387. --- NEWS | 4 +++ ext/openssl/openssl.c | 5 ++- ext/openssl/tests/gh21083.phpt | 61 ++++++++++++++++++++++++++++++++++ 3 files changed, 69 insertions(+), 1 deletion(-) create mode 100644 ext/openssl/tests/gh21083.phpt diff --git a/NEWS b/NEWS index 088a2768da3c7..76cca47611f6a 100644 --- a/NEWS +++ b/NEWS @@ -5,6 +5,10 @@ PHP NEWS - Bz2: . Fix truncation of total output size causing erroneous errors. (ndossche) +- OpenSSL: + . Fixed bug GH-21083 (Skip private_key_bits validation for EC/curve-based + keys). (iliaal) + - PCRE: . Fixed re-entrancy issue on php_pcre_match_impl, php_pcre_replace_impl, php_pcre_split_impl, and php_pcre_grep_impl. (David Carlier) diff --git a/ext/openssl/openssl.c b/ext/openssl/openssl.c index 2f2aae1e7335b..7e2b95683256e 100644 --- a/ext/openssl/openssl.c +++ b/ext/openssl/openssl.c @@ -3828,7 +3828,10 @@ static int php_openssl_get_evp_pkey_type(int key_type) { /* {{{ php_openssl_generate_private_key */ static EVP_PKEY * php_openssl_generate_private_key(struct php_x509_request * req) { - if (req->priv_key_bits < MIN_KEY_LENGTH) { + if ((req->priv_key_type == OPENSSL_KEYTYPE_RSA || + req->priv_key_type == OPENSSL_KEYTYPE_DH || + req->priv_key_type == OPENSSL_KEYTYPE_DSA) && + req->priv_key_bits < MIN_KEY_LENGTH) { php_error_docref(NULL, E_WARNING, "Private key length must be at least %d bits, configured to %d", MIN_KEY_LENGTH, req->priv_key_bits); return NULL; diff --git a/ext/openssl/tests/gh21083.phpt b/ext/openssl/tests/gh21083.phpt new file mode 100644 index 0000000000000..31afb7ca084d1 --- /dev/null +++ b/ext/openssl/tests/gh21083.phpt @@ -0,0 +1,61 @@ +--TEST-- +GH-21083 (openssl_pkey_new() fails for EC keys when private_key_bits is not set) +--EXTENSIONS-- +openssl +--SKIPIF-- + +--ENV-- +OPENSSL_CONF= +--FILE-- + $conf, + 'private_key_type' => OPENSSL_KEYTYPE_EC, + 'curve_name' => 'prime256v1', +]); +var_dump($key !== false); +$details = openssl_pkey_get_details($key); +var_dump($details['bits']); +var_dump($details['type'] === OPENSSL_KEYTYPE_EC); +echo "EC OK\n"; + +// X25519 - fixed size key, private_key_bits should not be required +if (defined('OPENSSL_KEYTYPE_X25519')) { + $key = openssl_pkey_new([ + 'config' => $conf, + 'private_key_type' => OPENSSL_KEYTYPE_X25519, + ]); + var_dump($key !== false); + echo "X25519 OK\n"; +} else { + echo "bool(true)\nX25519 OK\n"; +} + +// Ed25519 - fixed size key, private_key_bits should not be required +if (defined('OPENSSL_KEYTYPE_ED25519')) { + $key = openssl_pkey_new([ + 'config' => $conf, + 'private_key_type' => OPENSSL_KEYTYPE_ED25519, + ]); + var_dump($key !== false); + echo "Ed25519 OK\n"; +} else { + echo "bool(true)\nEd25519 OK\n"; +} + +unlink($conf); +?> +--EXPECT-- +bool(true) +int(256) +bool(true) +EC OK +bool(true) +X25519 OK +bool(true) +Ed25519 OK From 9150226166ffc3bda3ca341a8b4f37dae09061fa Mon Sep 17 00:00:00 2001 From: ndossche <7771979+ndossche@users.noreply.github.com> Date: Thu, 12 Mar 2026 22:04:08 +0100 Subject: [PATCH 2/3] [ci skip] NEWS for GH-20838 --- NEWS | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/NEWS b/NEWS index 76cca47611f6a..ed07306765672 100644 --- a/NEWS +++ b/NEWS @@ -5,6 +5,10 @@ PHP NEWS - Bz2: . Fix truncation of total output size causing erroneous errors. (ndossche) +- Opcache: + . Fixed bug GH-20838 (JIT compiler produces wrong arithmetic results). + (Dmitry, iliaal) + - OpenSSL: . Fixed bug GH-21083 (Skip private_key_bits validation for EC/curve-based keys). (iliaal) From 5ccaccda97df3f445f7c4d12a5ad646c887d80ae Mon Sep 17 00:00:00 2001 From: Arshid Date: Fri, 13 Mar 2026 05:44:03 +0530 Subject: [PATCH 3/3] ext/reflection: Use smart_str_append instead of smart_str_appendl (#21413) --- ext/reflection/php_reflection.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ext/reflection/php_reflection.c b/ext/reflection/php_reflection.c index e44a746ff0846..5a349b28905f3 100644 --- a/ext/reflection/php_reflection.c +++ b/ext/reflection/php_reflection.c @@ -875,7 +875,7 @@ static void _function_string(smart_str *str, zend_function *fptr, zend_class_ent smart_str_append_printf(str, "%s%s\n", indent, ZSTR_VAL(fptr->internal_function.doc_comment)); } - smart_str_appendl(str, indent, strlen(indent)); + smart_str_appends(str, indent); smart_str_appends(str, fptr->common.fn_flags & ZEND_ACC_CLOSURE ? "Closure [ " : (fptr->common.scope ? "Method [ " : "Function [ ")); smart_str_appends(str, (fptr->type == ZEND_USER_FUNCTION) ? "common.fn_flags & ZEND_ACC_DEPRECATED) {