@@ -3819,8 +3819,8 @@ static bool php_openssl_pkey_init_and_assign_rsa(EVP_PKEY *pkey, RSA *rsa, zval
3819
3819
return 1 ;
3820
3820
}
3821
3821
3822
- /* {{{ php_openssl_pkey_init_dsa */
3823
- static bool php_openssl_pkey_init_dsa (DSA * dsa , zval * data , bool * is_private )
3822
+ #if PHP_OPENSSL_API_VERSION < 0x30000
3823
+ static bool php_openssl_pkey_init_legacy_dsa (DSA * dsa , zval * data , bool * is_private )
3824
3824
{
3825
3825
BIGNUM * p , * q , * g , * priv_key , * pub_key ;
3826
3826
const BIGNUM * priv_key_const , * pub_key_const ;
@@ -3853,9 +3853,102 @@ static bool php_openssl_pkey_init_dsa(DSA *dsa, zval *data, bool *is_private)
3853
3853
return 0 ;
3854
3854
}
3855
3855
/* all good */
3856
+ * is_private = true;
3856
3857
return 1 ;
3857
3858
}
3858
- /* }}} */
3859
+ #endif
3860
+
3861
+ static EVP_PKEY * php_openssl_pkey_init_dsa (zval * data , bool * is_private )
3862
+ {
3863
+ #if PHP_OPENSSL_API_VERSION >= 0x30000
3864
+ BIGNUM * p = NULL , * q = NULL , * g = NULL , * priv_key = NULL , * pub_key = NULL ;
3865
+ EVP_PKEY * param_key = NULL , * pkey = NULL ;
3866
+ EVP_PKEY_CTX * ctx = EVP_PKEY_CTX_new_id (EVP_PKEY_DSA , NULL );
3867
+ OSSL_PARAM * params = NULL ;
3868
+ OSSL_PARAM_BLD * bld = OSSL_PARAM_BLD_new ();
3869
+
3870
+ OPENSSL_PKEY_SET_BN (data , p );
3871
+ OPENSSL_PKEY_SET_BN (data , q );
3872
+ OPENSSL_PKEY_SET_BN (data , g );
3873
+ OPENSSL_PKEY_SET_BN (data , priv_key );
3874
+ OPENSSL_PKEY_SET_BN (data , pub_key );
3875
+
3876
+ if (!ctx || !bld || !p || !q || !g ) {
3877
+ goto cleanup ;
3878
+ }
3879
+
3880
+ OSSL_PARAM_BLD_push_BN (bld , OSSL_PKEY_PARAM_FFC_P , p );
3881
+ OSSL_PARAM_BLD_push_BN (bld , OSSL_PKEY_PARAM_FFC_Q , q );
3882
+ OSSL_PARAM_BLD_push_BN (bld , OSSL_PKEY_PARAM_FFC_G , g );
3883
+ // TODO: We silently ignore priv_key if pub_key is not given, unlike in the DH case.
3884
+ if (pub_key ) {
3885
+ OSSL_PARAM_BLD_push_BN (bld , OSSL_PKEY_PARAM_PUB_KEY , pub_key );
3886
+ if (priv_key ) {
3887
+ OSSL_PARAM_BLD_push_BN (bld , OSSL_PKEY_PARAM_PRIV_KEY , priv_key );
3888
+ }
3889
+ }
3890
+
3891
+ params = OSSL_PARAM_BLD_to_param (bld );
3892
+ if (!params ) {
3893
+ goto cleanup ;
3894
+ }
3895
+
3896
+ if (EVP_PKEY_fromdata_init (ctx ) <= 0 ||
3897
+ EVP_PKEY_fromdata (ctx , & param_key , EVP_PKEY_KEYPAIR , params ) <= 0 ) {
3898
+ goto cleanup ;
3899
+ }
3900
+
3901
+ if (pub_key ) {
3902
+ * is_private = priv_key != NULL ;
3903
+ EVP_PKEY_up_ref (param_key );
3904
+ pkey = param_key ;
3905
+ } else {
3906
+ * is_private = true;
3907
+ PHP_OPENSSL_RAND_ADD_TIME ();
3908
+ EVP_PKEY_CTX_free (ctx );
3909
+ ctx = EVP_PKEY_CTX_new (param_key , NULL );
3910
+ if (EVP_PKEY_keygen_init (ctx ) <= 0 || EVP_PKEY_keygen (ctx , & pkey ) <= 0 ) {
3911
+ goto cleanup ;
3912
+ }
3913
+ }
3914
+
3915
+ cleanup :
3916
+ php_openssl_store_errors ();
3917
+ EVP_PKEY_free (param_key );
3918
+ EVP_PKEY_CTX_free (ctx );
3919
+ OSSL_PARAM_free (params );
3920
+ OSSL_PARAM_BLD_free (bld );
3921
+ BN_free (p );
3922
+ BN_free (q );
3923
+ BN_free (g );
3924
+ BN_free (priv_key );
3925
+ BN_free (pub_key );
3926
+ return pkey ;
3927
+ #else
3928
+ EVP_PKEY * pkey = EVP_PKEY_new ();
3929
+ if (!pkey ) {
3930
+ php_openssl_store_errors ();
3931
+ return NULL ;
3932
+ }
3933
+
3934
+ DSA * dsa = DSA_new ();
3935
+ if (!dsa ) {
3936
+ php_openssl_store_errors ();
3937
+ EVP_PKEY_free (pkey );
3938
+ return NULL ;
3939
+ }
3940
+
3941
+ if (!php_openssl_pkey_init_legacy_dsa (dsa , data , is_private )
3942
+ || !EVP_PKEY_assign_DSA (pkey , dsa )) {
3943
+ php_openssl_store_errors ();
3944
+ EVP_PKEY_free (pkey );
3945
+ DSA_free (dsa );
3946
+ return NULL ;
3947
+ }
3948
+
3949
+ return pkey ;
3950
+ #endif
3951
+ }
3859
3952
3860
3953
/* {{{ php_openssl_dh_pub_from_priv */
3861
3954
static BIGNUM * php_openssl_dh_pub_from_priv (BIGNUM * priv_key , BIGNUM * g , BIGNUM * p )
@@ -4070,28 +4163,13 @@ PHP_FUNCTION(openssl_pkey_new)
4070
4163
RETURN_FALSE ;
4071
4164
} else if ((data = zend_hash_str_find (Z_ARRVAL_P (args ), "dsa" , sizeof ("dsa" ) - 1 )) != NULL &&
4072
4165
Z_TYPE_P (data ) == IS_ARRAY ) {
4073
- pkey = EVP_PKEY_new ();
4074
- if (pkey ) {
4075
- DSA * dsa = DSA_new ();
4076
- if (dsa ) {
4077
- bool is_private ;
4078
- if (php_openssl_pkey_init_dsa (dsa , data , & is_private )) {
4079
- if (EVP_PKEY_assign_DSA (pkey , dsa )) {
4080
- php_openssl_pkey_object_init (return_value , pkey , is_private );
4081
- return ;
4082
- } else {
4083
- php_openssl_store_errors ();
4084
- }
4085
- }
4086
- DSA_free (dsa );
4087
- } else {
4088
- php_openssl_store_errors ();
4089
- }
4090
- EVP_PKEY_free (pkey );
4091
- } else {
4092
- php_openssl_store_errors ();
4166
+ bool is_private ;
4167
+ pkey = php_openssl_pkey_init_dsa (data , & is_private );
4168
+ if (!pkey ) {
4169
+ RETURN_FALSE ;
4093
4170
}
4094
- RETURN_FALSE ;
4171
+ php_openssl_pkey_object_init (return_value , pkey , is_private );
4172
+ return ;
4095
4173
} else if ((data = zend_hash_str_find (Z_ARRVAL_P (args ), "dh" , sizeof ("dh" ) - 1 )) != NULL &&
4096
4174
Z_TYPE_P (data ) == IS_ARRAY ) {
4097
4175
bool is_private ;
0 commit comments