Skip to content

Commit c6542b2

Browse files
committed
Extract php_openssl_pkey_derive() function
To allow sharing it with the openssl_dh_compute_key() implementation.
1 parent 7168f71 commit c6542b2

File tree

1 file changed

+41
-36
lines changed

1 file changed

+41
-36
lines changed

ext/openssl/openssl.c

Lines changed: 41 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -4535,14 +4535,41 @@ PHP_FUNCTION(openssl_pkey_get_details)
45354535
}
45364536
/* }}} */
45374537

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+
45384566
/* {{{ Computes shared secret for public value of remote DH key and local DH key */
45394567
PHP_FUNCTION(openssl_dh_compute_key)
45404568
{
45414569
zval *key;
45424570
char *pub_str;
45434571
size_t pub_len;
45444572
DH *dh;
4545-
EVP_PKEY *pkey;
45464573
BIGNUM *pub;
45474574
zend_string *data;
45484575
int len;
@@ -4553,11 +4580,12 @@ PHP_FUNCTION(openssl_dh_compute_key)
45534580

45544581
PHP_OPENSSL_CHECK_SIZE_T_TO_INT(pub_len, pub_key, 1);
45554582

4556-
pkey = Z_OPENSSL_PKEY_P(key)->pkey;
4583+
EVP_PKEY *pkey = Z_OPENSSL_PKEY_P(key)->pkey;
45574584

45584585
if (EVP_PKEY_base_id(pkey) != EVP_PKEY_DH) {
45594586
RETURN_FALSE;
45604587
}
4588+
45614589
dh = EVP_PKEY_get0_DH(pkey);
45624590
if (dh == NULL) {
45634591
RETURN_FALSE;
@@ -4587,59 +4615,36 @@ PHP_FUNCTION(openssl_pkey_derive)
45874615
{
45884616
zval *priv_key;
45894617
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;
45944618
zend_long key_len = 0;
4595-
zend_string *result;
45964619

45974620
if (zend_parse_parameters(ZEND_NUM_ARGS(), "zz|l", &peer_pub_key, &priv_key, &key_len) == FAILURE) {
45984621
RETURN_THROWS();
45994622
}
46004623

4601-
RETVAL_FALSE;
46024624
if (key_len < 0) {
46034625
zend_argument_value_error(3, "must be greater than or equal to 0");
46044626
RETURN_THROWS();
46054627
}
46064628

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);
46094630
if (!pkey) {
4610-
goto cleanup;
4631+
RETURN_FALSE;
46114632
}
46124633

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);
46144635
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;
46364638
}
46374639

4638-
cleanup:
4640+
zend_string *result = php_openssl_pkey_derive(pkey, peer_key, key_len);
46394641
EVP_PKEY_free(pkey);
46404642
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;
46434648
}
46444649
}
46454650
/* }}} */

0 commit comments

Comments
 (0)