@@ -3765,17 +3765,17 @@ static EVP_PKEY * php_openssl_generate_private_key(struct php_x509_request * req
3765
3765
}
3766
3766
/* }}} */
3767
3767
3768
- #define OPENSSL_GET_BN ( _array , _bn , _name ) do { \
3769
- if (_bn != NULL) { \
3770
- int len = BN_num_bytes(_bn); \
3771
- zend_string *str = zend_string_alloc(len, 0); \
3772
- BN_bn2bin(_bn , (unsigned char*)ZSTR_VAL(str)); \
3773
- ZSTR_VAL(str)[len] = 0; \
3774
- add_assoc_str(&_array, #_name , str); \
3775
- } \
3776
- } while (0);
3768
+ static void php_openssl_add_bn_to_array ( zval * ary , const BIGNUM * bn , const char * name ) {
3769
+ if (bn != NULL ) {
3770
+ int len = BN_num_bytes (bn );
3771
+ zend_string * str = zend_string_alloc (len , 0 );
3772
+ BN_bn2bin (bn , (unsigned char * )ZSTR_VAL (str ));
3773
+ ZSTR_VAL (str )[len ] = 0 ;
3774
+ add_assoc_str (ary , name , str );
3775
+ }
3776
+ }
3777
3777
3778
- #define OPENSSL_PKEY_GET_BN (_type , _name ) OPENSSL_GET_BN( _type, _name, _name)
3778
+ #define OPENSSL_PKEY_GET_BN (_type , _name ) php_openssl_add_bn_to_array(& _type, _name, # _name)
3779
3779
3780
3780
#define OPENSSL_PKEY_SET_BN (_data , _name ) do { \
3781
3781
zval *bn; \
@@ -4616,12 +4616,34 @@ PHP_FUNCTION(openssl_pkey_get_private)
4616
4616
4617
4617
/* }}} */
4618
4618
4619
+ #if PHP_OPENSSL_API_VERSION >= 0x30000
4620
+ static void php_openssl_copy_bn_param (
4621
+ zval * ary , EVP_PKEY * pkey , const char * param , const char * name ) {
4622
+ BIGNUM * bn = NULL ;
4623
+ if (EVP_PKEY_get_bn_param (pkey , param , & bn ) > 0 ) {
4624
+ php_openssl_add_bn_to_array (ary , bn , name );
4625
+ BN_free (bn );
4626
+ }
4627
+ }
4628
+
4629
+ static zend_string * php_openssl_get_utf8_param (
4630
+ EVP_PKEY * pkey , const char * param , const char * name ) {
4631
+ char buf [64 ];
4632
+ size_t len ;
4633
+ if (EVP_PKEY_get_utf8_string_param (pkey , param , buf , sizeof (buf ), & len ) > 0 ) {
4634
+ zend_string * str = zend_string_alloc (len , 0 );
4635
+ memcpy (ZSTR_VAL (str ), buf , len );
4636
+ ZSTR_VAL (str )[len ] = '\0' ;
4637
+ return str ;
4638
+ }
4639
+ return NULL ;
4640
+ }
4641
+ #endif
4642
+
4619
4643
/* {{{ returns an array with the key details (bits, pkey, type)*/
4620
4644
PHP_FUNCTION (openssl_pkey_get_details )
4621
4645
{
4622
4646
zval * key ;
4623
- EVP_PKEY * pkey ;
4624
- BIO * out ;
4625
4647
unsigned int pbio_len ;
4626
4648
char * pbio ;
4627
4649
zend_long ktype ;
@@ -4630,9 +4652,9 @@ PHP_FUNCTION(openssl_pkey_get_details)
4630
4652
RETURN_THROWS ();
4631
4653
}
4632
4654
4633
- pkey = Z_OPENSSL_PKEY_P (key )-> pkey ;
4655
+ EVP_PKEY * pkey = Z_OPENSSL_PKEY_P (key )-> pkey ;
4634
4656
4635
- out = BIO_new (BIO_s_mem ());
4657
+ BIO * out = BIO_new (BIO_s_mem ());
4636
4658
if (!PEM_write_bio_PUBKEY (out , pkey )) {
4637
4659
BIO_free (out );
4638
4660
php_openssl_store_errors ();
@@ -4646,6 +4668,72 @@ PHP_FUNCTION(openssl_pkey_get_details)
4646
4668
/*TODO: Use the real values once the openssl constants are used
4647
4669
* See the enum at the top of this file
4648
4670
*/
4671
+ #if PHP_OPENSSL_API_VERSION >= 0x30000
4672
+ zval ary ;
4673
+ switch (EVP_PKEY_base_id (pkey )) {
4674
+ case EVP_PKEY_RSA :
4675
+ ktype = OPENSSL_KEYTYPE_RSA ;
4676
+ array_init (& ary );
4677
+ add_assoc_zval (return_value , "rsa" , & ary );
4678
+ php_openssl_copy_bn_param (& ary , pkey , OSSL_PKEY_PARAM_RSA_N , "n" );
4679
+ php_openssl_copy_bn_param (& ary , pkey , OSSL_PKEY_PARAM_RSA_E , "e" );
4680
+ php_openssl_copy_bn_param (& ary , pkey , OSSL_PKEY_PARAM_RSA_D , "d" );
4681
+ php_openssl_copy_bn_param (& ary , pkey , OSSL_PKEY_PARAM_RSA_FACTOR1 , "p" );
4682
+ php_openssl_copy_bn_param (& ary , pkey , OSSL_PKEY_PARAM_RSA_FACTOR2 , "q" );
4683
+ php_openssl_copy_bn_param (& ary , pkey , OSSL_PKEY_PARAM_RSA_EXPONENT1 , "dmp1" );
4684
+ php_openssl_copy_bn_param (& ary , pkey , OSSL_PKEY_PARAM_RSA_EXPONENT2 , "dmq1" );
4685
+ php_openssl_copy_bn_param (& ary , pkey , OSSL_PKEY_PARAM_RSA_COEFFICIENT1 , "iqmp" );
4686
+ break ;
4687
+ case EVP_PKEY_DSA :
4688
+ ktype = OPENSSL_KEYTYPE_DSA ;
4689
+ array_init (& ary );
4690
+ add_assoc_zval (return_value , "dsa" , & ary );
4691
+ php_openssl_copy_bn_param (& ary , pkey , OSSL_PKEY_PARAM_FFC_P , "p" );
4692
+ php_openssl_copy_bn_param (& ary , pkey , OSSL_PKEY_PARAM_FFC_Q , "q" );
4693
+ php_openssl_copy_bn_param (& ary , pkey , OSSL_PKEY_PARAM_FFC_G , "g" );
4694
+ php_openssl_copy_bn_param (& ary , pkey , OSSL_PKEY_PARAM_PRIV_KEY , "priv_key" );
4695
+ php_openssl_copy_bn_param (& ary , pkey , OSSL_PKEY_PARAM_PUB_KEY , "pub_key" );
4696
+ break ;
4697
+ case EVP_PKEY_DH :
4698
+ ktype = OPENSSL_KEYTYPE_DH ;
4699
+ array_init (& ary );
4700
+ add_assoc_zval (return_value , "dh" , & ary );
4701
+ php_openssl_copy_bn_param (& ary , pkey , OSSL_PKEY_PARAM_FFC_P , "p" );
4702
+ php_openssl_copy_bn_param (& ary , pkey , OSSL_PKEY_PARAM_FFC_G , "g" );
4703
+ php_openssl_copy_bn_param (& ary , pkey , OSSL_PKEY_PARAM_PRIV_KEY , "priv_key" );
4704
+ php_openssl_copy_bn_param (& ary , pkey , OSSL_PKEY_PARAM_PUB_KEY , "pub_key" );
4705
+ break ;
4706
+ case EVP_PKEY_EC : {
4707
+ ktype = OPENSSL_KEYTYPE_EC ;
4708
+ array_init (& ary );
4709
+ add_assoc_zval (return_value , "ec" , & ary );
4710
+
4711
+ zend_string * curve_name = php_openssl_get_utf8_param (
4712
+ pkey , OSSL_PKEY_PARAM_GROUP_NAME , "curve_name" );
4713
+ if (curve_name ) {
4714
+ add_assoc_str (& ary , "curve_name" , curve_name );
4715
+
4716
+ int nid = OBJ_sn2nid (ZSTR_VAL (curve_name ));
4717
+ if (nid != NID_undef ) {
4718
+ ASN1_OBJECT * obj = OBJ_nid2obj (nid );
4719
+ if (obj ) {
4720
+ // OpenSSL recommends a buffer length of 80.
4721
+ char oir_buf [80 ];
4722
+ int oir_len = OBJ_obj2txt (oir_buf , sizeof (oir_buf ), obj , 1 );
4723
+ add_assoc_stringl (& ary , "curve_oid" , oir_buf , oir_len );
4724
+ ASN1_OBJECT_free (obj );
4725
+ }
4726
+ }
4727
+ }
4728
+
4729
+ php_openssl_copy_bn_param (& ary , pkey , OSSL_PKEY_PARAM_EC_PUB_X , "x" );
4730
+ php_openssl_copy_bn_param (& ary , pkey , OSSL_PKEY_PARAM_EC_PUB_Y , "y" );
4731
+ php_openssl_copy_bn_param (& ary , pkey , OSSL_PKEY_PARAM_PRIV_KEY , "d" );
4732
+ break ;
4733
+ }
4734
+ EMPTY_SWITCH_DEFAULT_CASE ();
4735
+ }
4736
+ #else
4649
4737
switch (EVP_PKEY_base_id (pkey )) {
4650
4738
case EVP_PKEY_RSA :
4651
4739
case EVP_PKEY_RSA2 :
@@ -4762,14 +4850,14 @@ PHP_FUNCTION(openssl_pkey_get_details)
4762
4850
pub = EC_KEY_get0_public_key (ec_key );
4763
4851
4764
4852
if (EC_POINT_get_affine_coordinates_GFp (ec_group , pub , x , y , NULL )) {
4765
- OPENSSL_GET_BN ( ec , x , x );
4766
- OPENSSL_GET_BN ( ec , y , y );
4853
+ php_openssl_add_bn_to_array ( & ec , x , "x" );
4854
+ php_openssl_add_bn_to_array ( & ec , y , "y" );
4767
4855
} else {
4768
4856
php_openssl_store_errors ();
4769
4857
}
4770
4858
4771
4859
if ((d = EC_KEY_get0_private_key (EVP_PKEY_get0_EC_KEY (pkey ))) != NULL ) {
4772
- OPENSSL_GET_BN ( ec , d , d );
4860
+ php_openssl_add_bn_to_array ( & ec , d , "d" );
4773
4861
}
4774
4862
4775
4863
add_assoc_zval (return_value , "ec" , & ec );
@@ -4783,6 +4871,7 @@ PHP_FUNCTION(openssl_pkey_get_details)
4783
4871
ktype = -1 ;
4784
4872
break ;
4785
4873
}
4874
+ #endif
4786
4875
add_assoc_long (return_value , "type" , ktype );
4787
4876
4788
4877
BIO_free (out );
0 commit comments