diff --git a/ext/openssl/openssl_backend_common.c b/ext/openssl/openssl_backend_common.c index 42b70c72a9cd0..8f9ff54263457 100644 --- a/ext/openssl/openssl_backend_common.c +++ b/ext/openssl/openssl_backend_common.c @@ -1437,17 +1437,16 @@ static const char *php_openssl_get_evp_pkey_name(int key_type) { EVP_PKEY *php_openssl_generate_private_key(struct php_x509_request * req) { - if (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; - } - int type = php_openssl_get_evp_pkey_type(req->priv_key_type); if (type < 0) { php_error_docref(NULL, E_WARNING, "Unsupported private key type"); return NULL; } + if ((type == EVP_PKEY_RSA || type == EVP_PKEY_DSA || type == EVP_PKEY_DH) && 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; + } const char *name = php_openssl_get_evp_pkey_name(req->priv_key_type); int egdsocket, seeded; diff --git a/ext/openssl/tests/openssl_key_type_bits_enforcement.phpt b/ext/openssl/tests/openssl_key_type_bits_enforcement.phpt new file mode 100644 index 0000000000000..66b22b6626286 --- /dev/null +++ b/ext/openssl/tests/openssl_key_type_bits_enforcement.phpt @@ -0,0 +1,59 @@ +--TEST-- +openssl: test key type and bit length enforcement in php_openssl_generate_private_key +--EXTENSIONS-- +openssl +--SKIPIF-- + +--FILE-- += MIN_KEY_LENGTH +foreach ([OPENSSL_KEYTYPE_RSA, OPENSSL_KEYTYPE_DSA, OPENSSL_KEYTYPE_DH] as $type) { + test_key($type, 1024); // valid, but small to keep test fast +} +// Should succeed: EC with curve only + test_key(OPENSSL_KEYTYPE_EC); +// Should succeed: EC with bits too low + test_key(OPENSSL_KEYTYPE_EC, 256); +?> +--EXPECT-- +bool(false) +bool(false) +bool(false) +bool(true) +bool(true) +bool(true) +bool(true) +bool(true) \ No newline at end of file