Skip to content

Fix GH-21083: Skip private_key_bits validation for EC/curve-based keys#21387

Open
iliaal wants to merge 1 commit intophp:PHP-8.4from
iliaal:fix/gh-21083-ec-key-private-key-bits
Open

Fix GH-21083: Skip private_key_bits validation for EC/curve-based keys#21387
iliaal wants to merge 1 commit intophp:PHP-8.4from
iliaal:fix/gh-21083-ec-key-private-key-bits

Conversation

@iliaal
Copy link
Contributor

@iliaal iliaal commented Mar 8, 2026

Summary

openssl_pkey_new() checks private_key_bits >= 384 before generating any key. EC and curve-based key types (X25519, ED25519, X448, ED448) don't use private_key_bits at all, their size comes from the curve or is fixed.

This worked by accident because most openssl.cnf files set default_bits = 2048, which passes the check even though EC keys ignore it. OpenSSL 3.6 ships with default_bits commented out, so priv_key_bits defaults to 0 and the check rejects the key.

Fix

Skip the priv_key_bits < MIN_KEY_LENGTH guard for key types where bit length is inherent:

  • OPENSSL_KEYTYPE_EC - size from curve name
  • OPENSSL_KEYTYPE_X25519 / OPENSSL_KEYTYPE_X448 - fixed 256/448 bits
  • OPENSSL_KEYTYPE_ED25519 / OPENSSL_KEYTYPE_ED448 - fixed 256/456 bits

Test

ext/openssl/tests/gh21083.phpt creates a minimal openssl.cnf without default_bits and generates EC, X25519, and ED25519 keys without specifying private_key_bits. Fails before the fix, passes after.

Fixes #21083

@ndossche
Copy link
Member

ndossche commented Mar 8, 2026

This shouldn't target master, but 8.4

…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 phpGH-21083
@iliaal iliaal force-pushed the fix/gh-21083-ec-key-private-key-bits branch from a5d817c to cb819e1 Compare March 8, 2026 21:57
@iliaal iliaal changed the base branch from master to PHP-8.4 March 8, 2026 21:57
@iliaal
Copy link
Contributor Author

iliaal commented Mar 8, 2026

Updated branch, btw how does multi-branch fix workflow go no a days, should there be separate PR for each affected branch or something else?

Comment on lines +3831 to +3835
if (req->priv_key_type != OPENSSL_KEYTYPE_EC &&
req->priv_key_type != OPENSSL_KEYTYPE_X25519 &&
req->priv_key_type != OPENSSL_KEYTYPE_ED25519 &&
req->priv_key_type != OPENSSL_KEYTYPE_X448 &&
req->priv_key_type != OPENSSL_KEYTYPE_ED448 &&
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It would be probably better to make it opt in (it means for RSA, DH, DSA) as it won't likely apply for new key types as well...

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

openssl_pkey_new() fails for EC keys on OpenSSL 3.6 - incorrectly requires private_key_bits

3 participants