@@ -200,6 +200,7 @@ static void php_openssl_request_free_obj(zend_object *object)
200200
201201typedef struct _php_openssl_pkey_object {
202202 EVP_PKEY * pkey ;
203+ bool is_private ;
203204 zend_object std ;
204205} php_openssl_pkey_object ;
205206
@@ -223,6 +224,13 @@ static zend_object *php_openssl_pkey_create_object(zend_class_entry *class_type)
223224 return & intern -> std ;
224225}
225226
227+ static void php_openssl_pkey_object_init (zval * zv , EVP_PKEY * pkey , bool is_private ) {
228+ object_init_ex (zv , php_openssl_pkey_ce );
229+ php_openssl_pkey_object * obj = Z_OPENSSL_PKEY_P (zv );
230+ obj -> pkey = pkey ;
231+ obj -> is_private = is_private ;
232+ }
233+
226234static zend_function * php_openssl_pkey_get_constructor (zend_object * object ) {
227235 zend_throw_error (NULL , "Cannot directly construct OpenSSLAsymmetricKey, use openssl_pkey_new() instead" );
228236 return NULL ;
@@ -516,7 +524,6 @@ static X509 *php_openssl_x509_from_zval(zval *val, bool *free_cert);
516524static X509_REQ * php_openssl_csr_from_param (zend_object * csr_obj , zend_string * csr_str );
517525static EVP_PKEY * php_openssl_pkey_from_zval (zval * val , int public_key , char * passphrase , size_t passphrase_len );
518526
519- static int php_openssl_is_private_key (EVP_PKEY * pkey );
520527static X509_STORE * php_openssl_setup_verify (zval * calist );
521528static STACK_OF (X509 ) * php_openssl_load_all_certs_from_file (char * certfile );
522529static EVP_PKEY * php_openssl_generate_private_key (struct php_x509_request * req );
@@ -3337,11 +3344,8 @@ PHP_FUNCTION(openssl_csr_new)
33373344 if (we_made_the_key ) {
33383345 /* and an object for the private key */
33393346 zval zkey_object ;
3340- php_openssl_pkey_object * key_object ;
3341- object_init_ex (& zkey_object , php_openssl_pkey_ce );
3342- key_object = Z_OPENSSL_PKEY_P (& zkey_object );
3343- key_object -> pkey = req .priv_key ;
3344-
3347+ php_openssl_pkey_object_init (
3348+ & zkey_object , req .priv_key , /* is_private */ true);
33453349 ZEND_TRY_ASSIGN_REF_TMP (out_pkey , & zkey_object );
33463350 req .priv_key = NULL ; /* make sure the cleanup code doesn't zap it! */
33473351 }
@@ -3399,7 +3403,6 @@ PHP_FUNCTION(openssl_csr_get_public_key)
33993403 zend_string * csr_str ;
34003404 bool use_shortnames = 1 ;
34013405
3402- php_openssl_pkey_object * key_object ;
34033406 EVP_PKEY * tpubkey ;
34043407
34053408 ZEND_PARSE_PARAMETERS_START (1 , 2 )
@@ -3442,9 +3445,7 @@ PHP_FUNCTION(openssl_csr_get_public_key)
34423445 RETURN_FALSE ;
34433446 }
34443447
3445- object_init_ex (return_value , php_openssl_pkey_ce );
3446- key_object = Z_OPENSSL_PKEY_P (return_value );
3447- key_object -> pkey = tpubkey ;
3448+ php_openssl_pkey_object_init (return_value , tpubkey , /* is_private */ false);
34483449}
34493450/* }}} */
34503451
@@ -3520,10 +3521,9 @@ static EVP_PKEY *php_openssl_pkey_from_zval(zval *val, int public_key, char *pas
35203521 }
35213522
35223523 if (Z_TYPE_P (val ) == IS_OBJECT && Z_OBJCE_P (val ) == php_openssl_pkey_ce ) {
3523- int is_priv ;
3524-
3525- key = php_openssl_pkey_from_obj (Z_OBJ_P (val ))-> pkey ;
3526- is_priv = php_openssl_is_private_key (key );
3524+ php_openssl_pkey_object * obj = php_openssl_pkey_from_obj (Z_OBJ_P (val ));
3525+ key = obj -> pkey ;
3526+ bool is_priv = obj -> is_private ;
35273527
35283528 /* check whether it is actually a private key if requested */
35293529 if (!public_key && !is_priv ) {
@@ -3758,85 +3758,6 @@ static EVP_PKEY * php_openssl_generate_private_key(struct php_x509_request * req
37583758}
37593759/* }}} */
37603760
3761- /* {{{ php_openssl_is_private_key
3762- Check whether the supplied key is a private key by checking if the secret prime factors are set */
3763- static int php_openssl_is_private_key (EVP_PKEY * pkey )
3764- {
3765- assert (pkey != NULL );
3766-
3767- switch (EVP_PKEY_id (pkey )) {
3768- case EVP_PKEY_RSA :
3769- case EVP_PKEY_RSA2 :
3770- {
3771- RSA * rsa = EVP_PKEY_get0_RSA (pkey );
3772- if (rsa != NULL ) {
3773- const BIGNUM * p , * q ;
3774-
3775- RSA_get0_factors (rsa , & p , & q );
3776- if (p == NULL || q == NULL ) {
3777- return 0 ;
3778- }
3779- }
3780- }
3781- break ;
3782- case EVP_PKEY_DSA :
3783- case EVP_PKEY_DSA1 :
3784- case EVP_PKEY_DSA2 :
3785- case EVP_PKEY_DSA3 :
3786- case EVP_PKEY_DSA4 :
3787- {
3788- DSA * dsa = EVP_PKEY_get0_DSA (pkey );
3789- if (dsa != NULL ) {
3790- const BIGNUM * p , * q , * g , * pub_key , * priv_key ;
3791-
3792- DSA_get0_pqg (dsa , & p , & q , & g );
3793- if (p == NULL || q == NULL ) {
3794- return 0 ;
3795- }
3796-
3797- DSA_get0_key (dsa , & pub_key , & priv_key );
3798- if (priv_key == NULL ) {
3799- return 0 ;
3800- }
3801- }
3802- }
3803- break ;
3804- case EVP_PKEY_DH :
3805- {
3806- DH * dh = EVP_PKEY_get0_DH (pkey );
3807- if (dh != NULL ) {
3808- const BIGNUM * p , * q , * g , * pub_key , * priv_key ;
3809-
3810- DH_get0_pqg (dh , & p , & q , & g );
3811- if (p == NULL ) {
3812- return 0 ;
3813- }
3814-
3815- DH_get0_key (dh , & pub_key , & priv_key );
3816- if (priv_key == NULL ) {
3817- return 0 ;
3818- }
3819- }
3820- }
3821- break ;
3822- #ifdef HAVE_EVP_PKEY_EC
3823- case EVP_PKEY_EC :
3824- {
3825- EC_KEY * ec = EVP_PKEY_get0_EC_KEY (pkey );
3826- if (ec != NULL && NULL == EC_KEY_get0_private_key (ec )) {
3827- return 0 ;
3828- }
3829- }
3830- break ;
3831- #endif
3832- default :
3833- php_error_docref (NULL , E_WARNING , "Key type not supported in this PHP build!" );
3834- break ;
3835- }
3836- return 1 ;
3837- }
3838- /* }}} */
3839-
38403761#define OPENSSL_GET_BN (_array , _bn , _name ) do { \
38413762 if (_bn != NULL) { \
38423763 int len = BN_num_bytes(_bn); \
@@ -3895,7 +3816,7 @@ static bool php_openssl_pkey_init_and_assign_rsa(EVP_PKEY *pkey, RSA *rsa, zval
38953816}
38963817
38973818/* {{{ php_openssl_pkey_init_dsa */
3898- static bool php_openssl_pkey_init_dsa (DSA * dsa , zval * data )
3819+ static bool php_openssl_pkey_init_dsa (DSA * dsa , zval * data , bool * is_private )
38993820{
39003821 BIGNUM * p , * q , * g , * priv_key , * pub_key ;
39013822 const BIGNUM * priv_key_const , * pub_key_const ;
@@ -3909,6 +3830,7 @@ static bool php_openssl_pkey_init_dsa(DSA *dsa, zval *data)
39093830
39103831 OPENSSL_PKEY_SET_BN (data , pub_key );
39113832 OPENSSL_PKEY_SET_BN (data , priv_key );
3833+ * is_private = priv_key != NULL ;
39123834 if (pub_key ) {
39133835 return DSA_set0_key (dsa , pub_key , priv_key );
39143836 }
@@ -3973,7 +3895,7 @@ static BIGNUM *php_openssl_dh_pub_from_priv(BIGNUM *priv_key, BIGNUM *g, BIGNUM
39733895/* }}} */
39743896
39753897/* {{{ php_openssl_pkey_init_dh */
3976- static bool php_openssl_pkey_init_dh (DH * dh , zval * data )
3898+ static bool php_openssl_pkey_init_dh (DH * dh , zval * data , bool * is_private )
39773899{
39783900 BIGNUM * p , * q , * g , * priv_key , * pub_key ;
39793901
@@ -3986,6 +3908,7 @@ static bool php_openssl_pkey_init_dh(DH *dh, zval *data)
39863908
39873909 OPENSSL_PKEY_SET_BN (data , priv_key );
39883910 OPENSSL_PKEY_SET_BN (data , pub_key );
3911+ * is_private = priv_key != NULL ;
39893912 if (pub_key ) {
39903913 return DH_set0_key (dh , pub_key , priv_key );
39913914 }
@@ -4014,7 +3937,6 @@ PHP_FUNCTION(openssl_pkey_new)
40143937 struct php_x509_request req ;
40153938 zval * args = NULL ;
40163939 zval * data ;
4017- php_openssl_pkey_object * key_object ;
40183940
40193941 if (zend_parse_parameters (ZEND_NUM_ARGS (), "|a!" , & args ) == FAILURE ) {
40203942 RETURN_THROWS ();
@@ -4031,9 +3953,7 @@ PHP_FUNCTION(openssl_pkey_new)
40313953 RSA * rsa = RSA_new ();
40323954 if (rsa ) {
40333955 if (php_openssl_pkey_init_and_assign_rsa (pkey , rsa , data )) {
4034- object_init_ex (return_value , php_openssl_pkey_ce );
4035- key_object = Z_OPENSSL_PKEY_P (return_value );
4036- key_object -> pkey = pkey ;
3956+ php_openssl_pkey_object_init (return_value , pkey , /* is_private */ true);
40373957 return ;
40383958 }
40393959 RSA_free (rsa );
@@ -4051,11 +3971,10 @@ PHP_FUNCTION(openssl_pkey_new)
40513971 if (pkey ) {
40523972 DSA * dsa = DSA_new ();
40533973 if (dsa ) {
4054- if (php_openssl_pkey_init_dsa (dsa , data )) {
3974+ bool is_private ;
3975+ if (php_openssl_pkey_init_dsa (dsa , data , & is_private )) {
40553976 if (EVP_PKEY_assign_DSA (pkey , dsa )) {
4056- object_init_ex (return_value , php_openssl_pkey_ce );
4057- key_object = Z_OPENSSL_PKEY_P (return_value );
4058- key_object -> pkey = pkey ;
3977+ php_openssl_pkey_object_init (return_value , pkey , is_private );
40593978 return ;
40603979 } else {
40613980 php_openssl_store_errors ();
@@ -4076,13 +3995,10 @@ PHP_FUNCTION(openssl_pkey_new)
40763995 if (pkey ) {
40773996 DH * dh = DH_new ();
40783997 if (dh ) {
4079- if (php_openssl_pkey_init_dh (dh , data )) {
3998+ bool is_private ;
3999+ if (php_openssl_pkey_init_dh (dh , data , & is_private )) {
40804000 if (EVP_PKEY_assign_DH (pkey , dh )) {
4081- php_openssl_pkey_object * key_object ;
4082-
4083- object_init_ex (return_value , php_openssl_pkey_ce );
4084- key_object = Z_OPENSSL_PKEY_P (return_value );
4085- key_object -> pkey = pkey ;
4001+ php_openssl_pkey_object_init (return_value , pkey , is_private );
40864002 return ;
40874003 } else {
40884004 php_openssl_store_errors ();
@@ -4108,6 +4024,7 @@ PHP_FUNCTION(openssl_pkey_new)
41084024 if (pkey ) {
41094025 eckey = EC_KEY_new ();
41104026 if (eckey ) {
4027+ bool is_private = false;
41114028 EC_GROUP * group = NULL ;
41124029 zval * bn ;
41134030 zval * x ;
@@ -4139,6 +4056,7 @@ PHP_FUNCTION(openssl_pkey_new)
41394056 // The public key 'pnt' can be calculated from 'd' or is defined by 'x' and 'y'
41404057 if ((bn = zend_hash_str_find (Z_ARRVAL_P (data ), "d" , sizeof ("d" ) - 1 )) != NULL &&
41414058 Z_TYPE_P (bn ) == IS_STRING ) {
4059+ is_private = true;
41424060 d = BN_bin2bn ((unsigned char * ) Z_STRVAL_P (bn ), Z_STRLEN_P (bn ), NULL );
41434061 if (!EC_KEY_set_private_key (eckey , d )) {
41444062 php_openssl_store_errors ();
@@ -4186,10 +4104,7 @@ PHP_FUNCTION(openssl_pkey_new)
41864104 }
41874105 if (EC_KEY_check_key (eckey ) && EVP_PKEY_assign_EC_KEY (pkey , eckey )) {
41884106 EC_GROUP_free (group );
4189-
4190- object_init_ex (return_value , php_openssl_pkey_ce );
4191- key_object = Z_OPENSSL_PKEY_P (return_value );
4192- key_object -> pkey = pkey ;
4107+ php_openssl_pkey_object_init (return_value , pkey , is_private );
41934108 return ;
41944109 } else {
41954110 php_openssl_store_errors ();
@@ -4224,9 +4139,7 @@ PHP_FUNCTION(openssl_pkey_new)
42244139 if (PHP_SSL_REQ_PARSE (& req , args ) == SUCCESS ) {
42254140 if (php_openssl_generate_private_key (& req )) {
42264141 /* pass back a key resource */
4227- object_init_ex (return_value , php_openssl_pkey_ce );
4228- key_object = Z_OPENSSL_PKEY_P (return_value );
4229- key_object -> pkey = req .priv_key ;
4142+ php_openssl_pkey_object_init (return_value , req .priv_key , /* is_private */ true);
42304143 /* make sure the cleanup code doesn't zap it! */
42314144 req .priv_key = NULL ;
42324145 }
@@ -4399,7 +4312,6 @@ PHP_FUNCTION(openssl_pkey_get_public)
43994312{
44004313 zval * cert ;
44014314 EVP_PKEY * pkey ;
4402- php_openssl_pkey_object * key_object ;
44034315
44044316 if (zend_parse_parameters (ZEND_NUM_ARGS (), "z" , & cert ) == FAILURE ) {
44054317 RETURN_THROWS ();
@@ -4409,9 +4321,7 @@ PHP_FUNCTION(openssl_pkey_get_public)
44094321 RETURN_FALSE ;
44104322 }
44114323
4412- object_init_ex (return_value , php_openssl_pkey_ce );
4413- key_object = Z_OPENSSL_PKEY_P (return_value );
4414- key_object -> pkey = pkey ;
4324+ php_openssl_pkey_object_init (return_value , pkey , /* is_private */ false);
44154325}
44164326/* }}} */
44174327
@@ -4433,7 +4343,6 @@ PHP_FUNCTION(openssl_pkey_get_private)
44334343 EVP_PKEY * pkey ;
44344344 char * passphrase = "" ;
44354345 size_t passphrase_len = sizeof ("" )- 1 ;
4436- php_openssl_pkey_object * key_object ;
44374346
44384347 if (zend_parse_parameters (ZEND_NUM_ARGS (), "z|s!" , & cert , & passphrase , & passphrase_len ) == FAILURE ) {
44394348 RETURN_THROWS ();
@@ -4448,9 +4357,7 @@ PHP_FUNCTION(openssl_pkey_get_private)
44484357 RETURN_FALSE ;
44494358 }
44504359
4451- object_init_ex (return_value , php_openssl_pkey_ce );
4452- key_object = Z_OPENSSL_PKEY_P (return_value );
4453- key_object -> pkey = pkey ;
4360+ php_openssl_pkey_object_init (return_value , pkey , /* is_private */ true);
44544361}
44554362
44564363/* }}} */
0 commit comments