@@ -4535,14 +4535,41 @@ PHP_FUNCTION(openssl_pkey_get_details)
4535
4535
}
4536
4536
/* }}} */
4537
4537
4538
+ static zend_string * php_openssl_pkey_derive (EVP_PKEY * key , EVP_PKEY * peer_key , size_t key_size ) {
4539
+ EVP_PKEY_CTX * ctx = EVP_PKEY_CTX_new (key , NULL );
4540
+ if (!ctx ) {
4541
+ return NULL ;
4542
+ }
4543
+
4544
+ if (EVP_PKEY_derive_init (ctx ) <= 0 ||
4545
+ EVP_PKEY_derive_set_peer (ctx , peer_key ) <= 0 ||
4546
+ (key_size == 0 && EVP_PKEY_derive (ctx , NULL , & key_size ) <= 0 )) {
4547
+ php_openssl_store_errors ();
4548
+ EVP_PKEY_CTX_free (ctx );
4549
+ return NULL ;
4550
+ }
4551
+
4552
+ zend_string * result = zend_string_alloc (key_size , 0 );
4553
+ if (EVP_PKEY_derive (ctx , (unsigned char * )ZSTR_VAL (result ), & key_size ) <= 0 ) {
4554
+ php_openssl_store_errors ();
4555
+ zend_string_release_ex (result , 0 );
4556
+ EVP_PKEY_CTX_free (ctx );
4557
+ return NULL ;
4558
+ }
4559
+
4560
+ ZSTR_LEN (result ) = key_size ;
4561
+ ZSTR_VAL (result )[key_size ] = 0 ;
4562
+ EVP_PKEY_CTX_free (ctx );
4563
+ return result ;
4564
+ }
4565
+
4538
4566
/* {{{ Computes shared secret for public value of remote DH key and local DH key */
4539
4567
PHP_FUNCTION (openssl_dh_compute_key )
4540
4568
{
4541
4569
zval * key ;
4542
4570
char * pub_str ;
4543
4571
size_t pub_len ;
4544
4572
DH * dh ;
4545
- EVP_PKEY * pkey ;
4546
4573
BIGNUM * pub ;
4547
4574
zend_string * data ;
4548
4575
int len ;
@@ -4553,11 +4580,12 @@ PHP_FUNCTION(openssl_dh_compute_key)
4553
4580
4554
4581
PHP_OPENSSL_CHECK_SIZE_T_TO_INT (pub_len , pub_key , 1 );
4555
4582
4556
- pkey = Z_OPENSSL_PKEY_P (key )-> pkey ;
4583
+ EVP_PKEY * pkey = Z_OPENSSL_PKEY_P (key )-> pkey ;
4557
4584
4558
4585
if (EVP_PKEY_base_id (pkey ) != EVP_PKEY_DH ) {
4559
4586
RETURN_FALSE ;
4560
4587
}
4588
+
4561
4589
dh = EVP_PKEY_get0_DH (pkey );
4562
4590
if (dh == NULL ) {
4563
4591
RETURN_FALSE ;
@@ -4587,59 +4615,36 @@ PHP_FUNCTION(openssl_pkey_derive)
4587
4615
{
4588
4616
zval * priv_key ;
4589
4617
zval * peer_pub_key ;
4590
- EVP_PKEY * pkey = NULL ;
4591
- EVP_PKEY * peer_key = NULL ;
4592
- EVP_PKEY_CTX * ctx = NULL ;
4593
- size_t key_size ;
4594
4618
zend_long key_len = 0 ;
4595
- zend_string * result ;
4596
4619
4597
4620
if (zend_parse_parameters (ZEND_NUM_ARGS (), "zz|l" , & peer_pub_key , & priv_key , & key_len ) == FAILURE ) {
4598
4621
RETURN_THROWS ();
4599
4622
}
4600
4623
4601
- RETVAL_FALSE ;
4602
4624
if (key_len < 0 ) {
4603
4625
zend_argument_value_error (3 , "must be greater than or equal to 0" );
4604
4626
RETURN_THROWS ();
4605
4627
}
4606
4628
4607
- key_size = key_len ;
4608
- pkey = php_openssl_pkey_from_zval (priv_key , 0 , "" , 0 );
4629
+ EVP_PKEY * pkey = php_openssl_pkey_from_zval (priv_key , 0 , "" , 0 );
4609
4630
if (!pkey ) {
4610
- goto cleanup ;
4631
+ RETURN_FALSE ;
4611
4632
}
4612
4633
4613
- peer_key = php_openssl_pkey_from_zval (peer_pub_key , 1 , NULL , 0 );
4634
+ EVP_PKEY * peer_key = php_openssl_pkey_from_zval (peer_pub_key , 1 , NULL , 0 );
4614
4635
if (!peer_key ) {
4615
- goto cleanup ;
4616
- }
4617
-
4618
- ctx = EVP_PKEY_CTX_new (pkey , NULL );
4619
- if (!ctx ) {
4620
- goto cleanup ;
4621
- }
4622
-
4623
- if (EVP_PKEY_derive_init (ctx ) > 0
4624
- && EVP_PKEY_derive_set_peer (ctx , peer_key ) > 0
4625
- && (key_size > 0 || EVP_PKEY_derive (ctx , NULL , & key_size ) > 0 )
4626
- && (result = zend_string_alloc (key_size , 0 )) != NULL ) {
4627
- if (EVP_PKEY_derive (ctx , (unsigned char * )ZSTR_VAL (result ), & key_size ) > 0 ) {
4628
- ZSTR_LEN (result ) = key_size ;
4629
- ZSTR_VAL (result )[key_size ] = 0 ;
4630
- RETVAL_NEW_STR (result );
4631
- } else {
4632
- php_openssl_store_errors ();
4633
- zend_string_release_ex (result , 0 );
4634
- RETVAL_FALSE ;
4635
- }
4636
+ EVP_PKEY_free (pkey );
4637
+ RETURN_FALSE ;
4636
4638
}
4637
4639
4638
- cleanup :
4640
+ zend_string * result = php_openssl_pkey_derive ( pkey , peer_key , key_len );
4639
4641
EVP_PKEY_free (pkey );
4640
4642
EVP_PKEY_free (peer_key );
4641
- if (ctx ) {
4642
- EVP_PKEY_CTX_free (ctx );
4643
+
4644
+ if (result ) {
4645
+ RETURN_NEW_STR (result );
4646
+ } else {
4647
+ RETURN_FALSE ;
4643
4648
}
4644
4649
}
4645
4650
/* }}} */
0 commit comments