@@ -3631,132 +3631,130 @@ static EVP_PKEY *php_openssl_pkey_from_zval(zval *val, int public_key, char *pas
36313631 return key ;
36323632}
36333633
3634+ static int php_openssl_get_evp_pkey_type (int key_type ) {
3635+ switch (key_type ) {
3636+ case OPENSSL_KEYTYPE_RSA :
3637+ return EVP_PKEY_RSA ;
3638+ #if !defined(NO_DSA )
3639+ case OPENSSL_KEYTYPE_DSA :
3640+ return EVP_PKEY_DSA ;
3641+ #endif
3642+ #if !defined(NO_DH )
3643+ case OPENSSL_KEYTYPE_DH :
3644+ return EVP_PKEY_DH ;
3645+ #endif
3646+ #ifdef HAVE_EVP_PKEY_EC
3647+ case OPENSSL_KEYTYPE_EC :
3648+ return EVP_PKEY_EC ;
3649+ #endif
3650+ default :
3651+ return -1 ;
3652+ }
3653+ }
3654+
36343655/* {{{ php_openssl_generate_private_key */
36353656static EVP_PKEY * php_openssl_generate_private_key (struct php_x509_request * req )
36363657{
3637- char * randfile = NULL ;
3638- int egdsocket , seeded ;
3639- EVP_PKEY * return_val = NULL ;
3640-
36413658 if (req -> priv_key_bits < MIN_KEY_LENGTH ) {
36423659 php_error_docref (NULL , E_WARNING , "Private key length must be at least %d bits, configured to %d" ,
36433660 MIN_KEY_LENGTH , req -> priv_key_bits );
36443661 return NULL ;
36453662 }
36463663
3647- randfile = php_openssl_conf_get_string (req -> req_config , req -> section_name , "RANDFILE" );
3664+ int type = php_openssl_get_evp_pkey_type (req -> priv_key_type );
3665+ if (type < 0 ) {
3666+ php_error_docref (NULL , E_WARNING , "Unsupported private key type" );
3667+ return NULL ;
3668+ }
3669+
3670+ int egdsocket , seeded ;
3671+ char * randfile = php_openssl_conf_get_string (req -> req_config , req -> section_name , "RANDFILE" );
36483672 php_openssl_load_rand_file (randfile , & egdsocket , & seeded );
3673+ PHP_OPENSSL_RAND_ADD_TIME ();
36493674
3650- if ((req -> priv_key = EVP_PKEY_new ()) != NULL ) {
3651- switch (req -> priv_key_type ) {
3652- case OPENSSL_KEYTYPE_RSA :
3653- {
3654- RSA * rsaparam ;
3655- BIGNUM * bne = (BIGNUM * )BN_new ();
3656- if (BN_set_word (bne , RSA_F4 ) != 1 ) {
3657- BN_free (bne );
3658- php_error_docref (NULL , E_WARNING , "Failed setting exponent" );
3659- return NULL ;
3660- }
3661- rsaparam = RSA_new ();
3662- PHP_OPENSSL_RAND_ADD_TIME ();
3663- if (rsaparam == NULL || !RSA_generate_key_ex (rsaparam , req -> priv_key_bits , bne , NULL )) {
3664- php_openssl_store_errors ();
3665- RSA_free (rsaparam );
3666- rsaparam = NULL ;
3667- }
3668- BN_free (bne );
3669- if (rsaparam && EVP_PKEY_assign_RSA (req -> priv_key , rsaparam )) {
3670- return_val = req -> priv_key ;
3671- } else {
3672- php_openssl_store_errors ();
3673- }
3674- }
3675- break ;
3675+ EVP_PKEY * key = NULL ;
3676+ EVP_PKEY * params = NULL ;
3677+ EVP_PKEY_CTX * ctx = EVP_PKEY_CTX_new_id (type , NULL );
3678+ if (!ctx ) {
3679+ php_openssl_store_errors ();
3680+ goto cleanup ;
3681+ }
3682+
3683+ if (type != EVP_PKEY_RSA ) {
3684+ if (EVP_PKEY_paramgen_init (ctx ) <= 0 ) {
3685+ php_openssl_store_errors ();
3686+ goto cleanup ;
3687+ }
3688+
3689+ switch (type ) {
36763690#if !defined(NO_DSA )
3677- case OPENSSL_KEYTYPE_DSA :
3678- PHP_OPENSSL_RAND_ADD_TIME ();
3679- {
3680- DSA * dsaparam = DSA_new ();
3681- if (dsaparam && DSA_generate_parameters_ex (dsaparam , req -> priv_key_bits , NULL , 0 , NULL , NULL , NULL )) {
3682- DSA_set_method (dsaparam , DSA_get_default_method ());
3683- if (DSA_generate_key (dsaparam )) {
3684- if (EVP_PKEY_assign_DSA (req -> priv_key , dsaparam )) {
3685- return_val = req -> priv_key ;
3686- } else {
3687- php_openssl_store_errors ();
3688- }
3689- } else {
3690- php_openssl_store_errors ();
3691- DSA_free (dsaparam );
3692- }
3693- } else {
3694- php_openssl_store_errors ();
3695- }
3696- }
3697- break ;
3691+ case EVP_PKEY_DSA :
3692+ if (EVP_PKEY_CTX_set_dsa_paramgen_bits (ctx , req -> priv_key_bits ) <= 0 ) {
3693+ php_openssl_store_errors ();
3694+ goto cleanup ;
3695+ }
3696+ break ;
36983697#endif
36993698#if !defined(NO_DH )
3700- case OPENSSL_KEYTYPE_DH :
3701- PHP_OPENSSL_RAND_ADD_TIME ();
3702- {
3703- int codes = 0 ;
3704- DH * dhparam = DH_new ();
3705- if (dhparam && DH_generate_parameters_ex (dhparam , req -> priv_key_bits , 2 , NULL )) {
3706- DH_set_method (dhparam , DH_get_default_method ());
3707- if (DH_check (dhparam , & codes ) && codes == 0 && DH_generate_key (dhparam )) {
3708- if (EVP_PKEY_assign_DH (req -> priv_key , dhparam )) {
3709- return_val = req -> priv_key ;
3710- } else {
3711- php_openssl_store_errors ();
3712- }
3713- } else {
3714- php_openssl_store_errors ();
3715- DH_free (dhparam );
3716- }
3717- } else {
3718- php_openssl_store_errors ();
3719- }
3720- }
3721- break ;
3699+ case EVP_PKEY_DH :
3700+ if (EVP_PKEY_CTX_set_dh_paramgen_prime_len (ctx , req -> priv_key_bits ) <= 0 ) {
3701+ php_openssl_store_errors ();
3702+ goto cleanup ;
3703+ }
3704+ break ;
37223705#endif
37233706#ifdef HAVE_EVP_PKEY_EC
3724- case OPENSSL_KEYTYPE_EC :
3725- {
3726- EC_KEY * eckey ;
3727- if (req -> curve_name == NID_undef ) {
3728- php_error_docref (NULL , E_WARNING , "Missing configuration value: \"curve_name\" not set" );
3729- return NULL ;
3730- }
3731- eckey = EC_KEY_new_by_curve_name (req -> curve_name );
3732- if (eckey ) {
3733- EC_KEY_set_asn1_flag (eckey , OPENSSL_EC_NAMED_CURVE );
3734- if (EC_KEY_generate_key (eckey ) &&
3735- EVP_PKEY_assign_EC_KEY (req -> priv_key , eckey )) {
3736- return_val = req -> priv_key ;
3737- } else {
3738- EC_KEY_free (eckey );
3739- }
3740- }
3741- }
3742- break ;
3707+ case EVP_PKEY_EC :
3708+ if (req -> curve_name == NID_undef ) {
3709+ php_error_docref (NULL , E_WARNING , "Missing configuration value: \"curve_name\" not set" );
3710+ goto cleanup ;
3711+ }
3712+
3713+ if (EVP_PKEY_CTX_set_ec_paramgen_curve_nid (ctx , req -> curve_name ) <= 0 ||
3714+ EVP_PKEY_CTX_set_ec_param_enc (ctx , OPENSSL_EC_NAMED_CURVE ) <= 0 ) {
3715+ php_openssl_store_errors ();
3716+ goto cleanup ;
3717+ }
3718+ break ;
37433719#endif
3744- default :
3745- php_error_docref (NULL , E_WARNING , "Unsupported private key type" );
3720+ EMPTY_SWITCH_DEFAULT_CASE ()
37463721 }
3747- } else {
3722+
3723+ if (EVP_PKEY_paramgen (ctx , & params ) <= 0 ) {
3724+ php_openssl_store_errors ();
3725+ goto cleanup ;
3726+ }
3727+
3728+ EVP_PKEY_CTX_free (ctx );
3729+ ctx = EVP_PKEY_CTX_new (params , NULL );
3730+ if (!ctx ) {
3731+ php_openssl_store_errors ();
3732+ goto cleanup ;
3733+ }
3734+ }
3735+
3736+ if (EVP_PKEY_keygen_init (ctx ) <= 0 ) {
37483737 php_openssl_store_errors ();
3738+ goto cleanup ;
37493739 }
37503740
3751- php_openssl_write_rand_file (randfile , egdsocket , seeded );
3741+ if (type == EVP_PKEY_RSA && EVP_PKEY_CTX_set_rsa_keygen_bits (ctx , req -> priv_key_bits ) <= 0 ) {
3742+ php_openssl_store_errors ();
3743+ goto cleanup ;
3744+ }
37523745
3753- if (return_val == NULL ) {
3754- EVP_PKEY_free (req -> priv_key );
3755- req -> priv_key = NULL ;
3756- return NULL ;
3746+ if (EVP_PKEY_keygen (ctx , & key ) <= 0 ) {
3747+ php_openssl_store_errors ();
3748+ goto cleanup ;
37573749 }
37583750
3759- return return_val ;
3751+ req -> priv_key = key ;
3752+
3753+ cleanup :
3754+ php_openssl_write_rand_file (randfile , egdsocket , seeded );
3755+ EVP_PKEY_free (params );
3756+ EVP_PKEY_CTX_free (ctx );
3757+ return key ;
37603758}
37613759/* }}} */
37623760
0 commit comments