@@ -3631,132 +3631,130 @@ static EVP_PKEY *php_openssl_pkey_from_zval(zval *val, int public_key, char *pas
3631
3631
return key ;
3632
3632
}
3633
3633
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
+
3634
3655
/* {{{ php_openssl_generate_private_key */
3635
3656
static EVP_PKEY * php_openssl_generate_private_key (struct php_x509_request * req )
3636
3657
{
3637
- char * randfile = NULL ;
3638
- int egdsocket , seeded ;
3639
- EVP_PKEY * return_val = NULL ;
3640
-
3641
3658
if (req -> priv_key_bits < MIN_KEY_LENGTH ) {
3642
3659
php_error_docref (NULL , E_WARNING , "Private key length must be at least %d bits, configured to %d" ,
3643
3660
MIN_KEY_LENGTH , req -> priv_key_bits );
3644
3661
return NULL ;
3645
3662
}
3646
3663
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" );
3648
3672
php_openssl_load_rand_file (randfile , & egdsocket , & seeded );
3673
+ PHP_OPENSSL_RAND_ADD_TIME ();
3649
3674
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 ) {
3676
3690
#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 ;
3698
3697
#endif
3699
3698
#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 ;
3722
3705
#endif
3723
3706
#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 ;
3743
3719
#endif
3744
- default :
3745
- php_error_docref (NULL , E_WARNING , "Unsupported private key type" );
3720
+ EMPTY_SWITCH_DEFAULT_CASE ()
3746
3721
}
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 ) {
3748
3737
php_openssl_store_errors ();
3738
+ goto cleanup ;
3749
3739
}
3750
3740
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
+ }
3752
3745
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 ;
3757
3749
}
3758
3750
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 ;
3760
3758
}
3761
3759
/* }}} */
3762
3760
0 commit comments