From 7861badf0fca7744edb446428e8d3048b9fe6bcf Mon Sep 17 00:00:00 2001 From: Jim Zubov Date: Mon, 26 Mar 2018 18:23:58 -0400 Subject: [PATCH 1/8] ECDH support for openssl_dh_compute_key() string openssl_dh_compute_key(resource ec_pub_key,resource ec_priv_key) [new] string openssl_dh_compute_key(resource dh_pub_key,resource dh_priv_key) [new] string openssl_dh_compute_key(string dh_pub,resource dh_priv_key) [original] --- ext/openssl/openssl.c | 102 ++++++++++++++++++++++++++++++------------ 1 file changed, 74 insertions(+), 28 deletions(-) diff --git a/ext/openssl/openssl.c b/ext/openssl/openssl.c index 024d3cf51b8e..8804f43a2c04 100644 --- a/ext/openssl/openssl.c +++ b/ext/openssl/openssl.c @@ -4886,55 +4886,101 @@ PHP_FUNCTION(openssl_pkey_get_details) } /* }}} */ -/* {{{ proto string openssl_dh_compute_key(string pub_key, resource dh_key) +/* {{{ proto string openssl_dh_compute_key(string|resource pub_key, resource dh_key) Computes shared secret for public value of remote DH key and local DH key */ PHP_FUNCTION(openssl_dh_compute_key) { zval *key; - char *pub_str; - size_t pub_len; - DH *dh; + zval *peer_key; EVP_PKEY *pkey; - BIGNUM *pub; zend_string *data; int len; - if (zend_parse_parameters(ZEND_NUM_ARGS(), "sr", &pub_str, &pub_len, &key) == FAILURE) { + if (zend_parse_parameters(ZEND_NUM_ARGS(), "zr", &peer_key, &key) == FAILURE) { return; } if ((pkey = (EVP_PKEY *)zend_fetch_resource(Z_RES_P(key), "OpenSSL key", le_key)) == NULL) { RETURN_FALSE; } - if (EVP_PKEY_base_id(pkey) != EVP_PKEY_DH) { - RETURN_FALSE; - } - dh = EVP_PKEY_get0_DH(pkey); - if (dh == NULL) { - RETURN_FALSE; - } - - PHP_OPENSSL_CHECK_SIZE_T_TO_INT(pub_len, pub_key); - pub = BN_bin2bn((unsigned char*)pub_str, (int)pub_len, NULL); - - data = zend_string_alloc(DH_size(dh), 0); - len = DH_compute_key((unsigned char*)ZSTR_VAL(data), pub, dh); - if (len >= 0) { - ZSTR_LEN(data) = len; - ZSTR_VAL(data)[len] = 0; - RETVAL_STR(data); - } else { - php_openssl_store_errors(); - zend_string_release(data); + switch (EVP_PKEY_base_id(pkey)) { + case EVP_PKEY_DH: { + DH *dh = EVP_PKEY_get0_DH(pkey); + if (dh != NULL) { + BIGNUM *dh_pub; + char dh_free; + switch (Z_TYPE_P(peer_key)) { + case IS_STRING: { + unsigned char *pub_str = Z_STRVAL_P(peer_key); + size_t pub_len = Z_STRLEN_P(peer_key); + PHP_OPENSSL_CHECK_SIZE_T_TO_INT(pub_len, pub_key); + dh_pub = BN_bin2bn((unsigned char*) pub_str, (int)pub_len, NULL); + dh_free = 1; + break; + } + case IS_RESOURCE: { + EVP_PKEY *pub; + if ((pub = (EVP_PKEY *)zend_fetch_resource(Z_RES_P(peer_key), "OpenSSL key", le_key)) == NULL || EVP_PKEY_base_id(pub) != EVP_PKEY_DH) { + RETURN_FALSE; + } + dh_pub = EVP_PKEY_get0_DH(pub)->pub_key; + dh_free = 0; + break; + } + default: RETURN_FALSE; + } + data = zend_string_alloc(DH_size(dh), 0); + len = DH_compute_key((unsigned char*)ZSTR_VAL(data), dh_pub, dh); + if (len >= 0) { + ZSTR_LEN(data) = len; + ZSTR_VAL(data)[len] = 0; + RETVAL_STR(data); + } else { + php_openssl_store_errors(); + zend_string_release(data); + RETVAL_FALSE; + } + if (dh_free) BN_free(dh_pub); + } else { + RETVAL_FALSE; + } + break; + } + case EVP_PKEY_EC: { + if (Z_TYPE_P(peer_key) != IS_RESOURCE) RETURN_FALSE; + EVP_PKEY *pub; + if ((pub = (EVP_PKEY *)zend_fetch_resource(Z_RES_P(peer_key), "OpenSSL key", le_key)) == NULL || EVP_PKEY_base_id(pub) != EVP_PKEY_EC) { + RETURN_FALSE; + } + EC_KEY *ec = EVP_PKEY_get0_EC_KEY(pkey); + EC_KEY *ec_pub = EVP_PKEY_get0_EC_KEY(pub); + if (ec != NULL && ec_pub != NULL && EVP_PKEY_bits(pkey) == EVP_PKEY_bits(pub)) { + size_t maxlen = (EVP_PKEY_bits(pkey) + 7) >> 3; + data = zend_string_alloc(maxlen + 1, 0); + len = ECDH_compute_key((unsigned char*)ZSTR_VAL(data), maxlen, EC_KEY_get0_public_key(ec_pub), ec, NULL); + if (len >= 0) { + ZSTR_LEN(data) = len; + ZSTR_VAL(data)[len] = 0; + RETVAL_STR(data); + } else { + php_openssl_store_errors(); + zend_string_release(data); + RETVAL_FALSE; + } + } else { + RETVAL_FALSE; + } + break; + } + default: RETVAL_FALSE; } - - BN_free(pub); } /* }}} */ /* }}} */ + /* {{{ proto string openssl_pbkdf2(string password, string salt, int key_length, int iterations [, string digest_method = "sha1"]) Generates a PKCS5 v2 PBKDF2 string, defaults to sha1 */ PHP_FUNCTION(openssl_pbkdf2) From e925b4352061d22ef75430f1d788959b40be8bdd Mon Sep 17 00:00:00 2001 From: Jim Zubov Date: Tue, 27 Mar 2018 10:31:19 -0400 Subject: [PATCH 2/8] windows fix --- ext/openssl/openssl.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/ext/openssl/openssl.c b/ext/openssl/openssl.c index 8804f43a2c04..32214c002c3d 100644 --- a/ext/openssl/openssl.c +++ b/ext/openssl/openssl.c @@ -4920,10 +4920,11 @@ PHP_FUNCTION(openssl_dh_compute_key) } case IS_RESOURCE: { EVP_PKEY *pub; + BIGNUM *dh_priv; if ((pub = (EVP_PKEY *)zend_fetch_resource(Z_RES_P(peer_key), "OpenSSL key", le_key)) == NULL || EVP_PKEY_base_id(pub) != EVP_PKEY_DH) { RETURN_FALSE; } - dh_pub = EVP_PKEY_get0_DH(pub)->pub_key; + DH_get0_key(EVP_PKEY_get0_DH(pub), &dh_pub, &dh_priv); dh_free = 0; break; } @@ -4946,6 +4947,7 @@ PHP_FUNCTION(openssl_dh_compute_key) } break; } +#ifdef HAVE_EVP_PKEY_EC case EVP_PKEY_EC: { if (Z_TYPE_P(peer_key) != IS_RESOURCE) RETURN_FALSE; EVP_PKEY *pub; @@ -4972,6 +4974,7 @@ PHP_FUNCTION(openssl_dh_compute_key) } break; } +#endif default: RETVAL_FALSE; } @@ -4980,7 +4983,6 @@ PHP_FUNCTION(openssl_dh_compute_key) /* }}} */ - /* {{{ proto string openssl_pbkdf2(string password, string salt, int key_length, int iterations [, string digest_method = "sha1"]) Generates a PKCS5 v2 PBKDF2 string, defaults to sha1 */ PHP_FUNCTION(openssl_pbkdf2) From f2cfd3d3f0752c3a418419b94562c6803ec72057 Mon Sep 17 00:00:00 2001 From: Jim Zubov Date: Sat, 31 Mar 2018 11:55:38 -0400 Subject: [PATCH 3/8] openssl_derive(resource peer_pub_key, resource priv_key, int keylen=NULL) --- ext/openssl/openssl.c | 46 +++++++++++++++++++++ ext/openssl/tests/openssl_derive-dh.phpt | 47 ++++++++++++++++++++++ ext/openssl/tests/openssl_derive-ecdh.phpt | 32 +++++++++++++++ 3 files changed, 125 insertions(+) create mode 100644 ext/openssl/tests/openssl_derive-dh.phpt create mode 100644 ext/openssl/tests/openssl_derive-ecdh.phpt diff --git a/ext/openssl/openssl.c b/ext/openssl/openssl.c index 024d3cf51b8e..9da6a8244a5a 100644 --- a/ext/openssl/openssl.c +++ b/ext/openssl/openssl.c @@ -128,6 +128,7 @@ PHP_FUNCTION(openssl_decrypt); PHP_FUNCTION(openssl_cipher_iv_length); PHP_FUNCTION(openssl_dh_compute_key); +PHP_FUNCTION(openssl_derive); PHP_FUNCTION(openssl_random_pseudo_bytes); /* {{{ arginfo */ @@ -430,6 +431,12 @@ ZEND_BEGIN_ARG_INFO(arginfo_openssl_dh_compute_key, 0) ZEND_ARG_INFO(0, dh_key) ZEND_END_ARG_INFO() +ZEND_BEGIN_ARG_INFO(arginfo_openssl_derive, 0) + ZEND_ARG_INFO(0, peer_pub_key) + ZEND_ARG_INFO(0, priv_key) + ZEND_ARG_INFO(0, keylen) +ZEND_END_ARG_INFO() + ZEND_BEGIN_ARG_INFO_EX(arginfo_openssl_random_pseudo_bytes, 0, 0, 1) ZEND_ARG_INFO(0, length) ZEND_ARG_INFO(1, result_is_strong) @@ -534,6 +541,7 @@ static const zend_function_entry openssl_functions[] = { #endif PHP_FE(openssl_dh_compute_key, arginfo_openssl_dh_compute_key) + PHP_FE(openssl_derive, arginfo_openssl_derive) PHP_FE(openssl_random_pseudo_bytes, arginfo_openssl_random_pseudo_bytes) PHP_FE(openssl_error_string, arginfo_openssl_error_string) @@ -4933,6 +4941,44 @@ PHP_FUNCTION(openssl_dh_compute_key) } /* }}} */ +/* {{{ proto string openssl_derive(resource peer_pub_key, resource priv_key,int keylen=NULL) + Computes shared secret for public value of remote and local DH or ECDH key */ +PHP_FUNCTION(openssl_derive) +{ + zval *priv_key; + zval *peer_pub_key; + EVP_PKEY *pkey; + EVP_PKEY *peer_key; + zend_long keylen = 0; + zend_string *result; + + if (zend_parse_parameters(ZEND_NUM_ARGS(), "rr|l", &peer_pub_key, &priv_key, &keylen) == FAILURE) { + return; + } + if ((pkey = (EVP_PKEY *)zend_fetch_resource(Z_RES_P(priv_key), "OpenSSL key", le_key)) == NULL + || (peer_key = (EVP_PKEY *)zend_fetch_resource(Z_RES_P(peer_pub_key), "OpenSSL key", le_key)) == NULL) { + RETURN_FALSE; + } + EVP_PKEY_CTX *ctx = EVP_PKEY_CTX_new(pkey, NULL); + if (!ctx) RETURN_FALSE; + if (EVP_PKEY_derive_init(ctx) > 0 + && EVP_PKEY_derive_set_peer(ctx, peer_key) > 0 + && (keylen > 0 || EVP_PKEY_derive(ctx, NULL, &keylen) > 0) + && (result = zend_string_alloc(keylen, 0)) != NULL) { + if (EVP_PKEY_derive(ctx, (unsigned char*)ZSTR_VAL(result), &keylen) > 0) { + ZSTR_LEN(result) = keylen; + ZSTR_VAL(result)[keylen] = 0; + RETVAL_STR(result); + } else { + php_openssl_store_errors(); + zend_string_release(result); + RETVAL_FALSE; + } + } else { + RETVAL_FALSE; + } + EVP_PKEY_CTX_free(ctx); +} /* }}} */ /* {{{ proto string openssl_pbkdf2(string password, string salt, int key_length, int iterations [, string digest_method = "sha1"]) diff --git a/ext/openssl/tests/openssl_derive-dh.phpt b/ext/openssl/tests/openssl_derive-dh.phpt new file mode 100644 index 000000000000..e356ed31656e --- /dev/null +++ b/ext/openssl/tests/openssl_derive-dh.phpt @@ -0,0 +1,47 @@ +--TEST-- +openssl_derive() DH +--SKIPIF-- + +--FILE-- + +--EXPECTF-- +10aed66ad96a65f50543aa9adbc18ea169bf98521c682c49fb8b7daeb9e8fbe6b9a800199ffe1123cc36fc358829cbbc5d21bf1eb8ce3cf644538b357f478361a284c27fbe31fc94d431562786dd7314613cd70e6d76ca1ab3c1f31556ed07162f243dcc1a43ea98c454fb6e891eaec7a14158d54cd33d3fbbbc75f1ea8ff5deaab25d5deb657c7c43004252df301b195207d01614e7cb833e0e8d785ba2ecfe16ad7a9634784fdb8db8afe049476b58743575725ee99c761a59a7d7b9e709fff84c8d427e2bc07953a7c2408eb3f8f7e0ebc2f901c6889955874ae79a3de19921757d69424145a35dbe5af778b080dada55bdfce8fb0319f2de39110f58e05d +6640f467ea55d08f912206d87588370588ef411a6a4f59075c17f4c230b6366956932eebc4f2b6850540f99cb00cc6fa30f94e1af072879bd4ea869cd85ec14a3ce51aa0cc1c9f5d7fd43ef1cdeaa4afca804f9caa492abb738198485a56f103d6126d19578b9e92eab132107d529a6f2bb98c433888398cea8b60b73725cbc69c944982efc7c4a33a3d3e102e974477611be305ec54efc95eb05b6c88bd77f51735e222f5b2a56637b9091b1a58bd39bc41f8987df560c2d2c15aa36c381d1b51ed55b49e4638ab490b95ecf7272f8c6477ddc01bba873bf2395a918049f326e089558304f1e374c978912935c1fd04aa0a14f080263d590523d28de52cedfe diff --git a/ext/openssl/tests/openssl_derive-ecdh.phpt b/ext/openssl/tests/openssl_derive-ecdh.phpt new file mode 100644 index 000000000000..cb79096625a1 --- /dev/null +++ b/ext/openssl/tests/openssl_derive-ecdh.phpt @@ -0,0 +1,32 @@ +--TEST-- +openssl_derive() ECDH +--SKIPIF-- + +--FILE-- + +--EXPECTF-- +01171967cc0ddc553b46c6a821502aaea44aa04e6933d897ea11222efa0556f2d5d972816676c9ccf4e2430a26e07193ad39373050f6e54e4059f17720d7dd667635 +0129ed9749701a48f01a70757c8d967007cb7abeff2ec46ce18b51f1e7daeae81aaef146a0a585db5ee3c5469c0c4bd3a2395f79d36b4a800ac08e866fc96548fad8 From 3feba65c4986727158a73917e69b7c4aed7d47a3 Mon Sep 17 00:00:00 2001 From: Jim Zubov Date: Sat, 31 Mar 2018 15:45:52 -0400 Subject: [PATCH 4/8] openssl_dh_compute_key reverted to the original --- ext/openssl/openssl.c | 104 ++++++++++++------------------------------ 1 file changed, 28 insertions(+), 76 deletions(-) diff --git a/ext/openssl/openssl.c b/ext/openssl/openssl.c index b892ac0a55f2..9da6a8244a5a 100644 --- a/ext/openssl/openssl.c +++ b/ext/openssl/openssl.c @@ -4894,98 +4894,50 @@ PHP_FUNCTION(openssl_pkey_get_details) } /* }}} */ -/* {{{ proto string openssl_dh_compute_key(string|resource pub_key, resource dh_key) +/* {{{ proto string openssl_dh_compute_key(string pub_key, resource dh_key) Computes shared secret for public value of remote DH key and local DH key */ PHP_FUNCTION(openssl_dh_compute_key) { zval *key; - zval *peer_key; + char *pub_str; + size_t pub_len; + DH *dh; EVP_PKEY *pkey; + BIGNUM *pub; zend_string *data; int len; - if (zend_parse_parameters(ZEND_NUM_ARGS(), "zr", &peer_key, &key) == FAILURE) { + if (zend_parse_parameters(ZEND_NUM_ARGS(), "sr", &pub_str, &pub_len, &key) == FAILURE) { return; } if ((pkey = (EVP_PKEY *)zend_fetch_resource(Z_RES_P(key), "OpenSSL key", le_key)) == NULL) { RETURN_FALSE; } + if (EVP_PKEY_base_id(pkey) != EVP_PKEY_DH) { + RETURN_FALSE; + } + dh = EVP_PKEY_get0_DH(pkey); + if (dh == NULL) { + RETURN_FALSE; + } - switch (EVP_PKEY_base_id(pkey)) { - case EVP_PKEY_DH: { - DH *dh = EVP_PKEY_get0_DH(pkey); - if (dh != NULL) { - BIGNUM *dh_pub; - char dh_free; - switch (Z_TYPE_P(peer_key)) { - case IS_STRING: { - unsigned char *pub_str = Z_STRVAL_P(peer_key); - size_t pub_len = Z_STRLEN_P(peer_key); - PHP_OPENSSL_CHECK_SIZE_T_TO_INT(pub_len, pub_key); - dh_pub = BN_bin2bn((unsigned char*) pub_str, (int)pub_len, NULL); - dh_free = 1; - break; - } - case IS_RESOURCE: { - EVP_PKEY *pub; - BIGNUM *dh_priv; - if ((pub = (EVP_PKEY *)zend_fetch_resource(Z_RES_P(peer_key), "OpenSSL key", le_key)) == NULL || EVP_PKEY_base_id(pub) != EVP_PKEY_DH) { - RETURN_FALSE; - } - DH_get0_key(EVP_PKEY_get0_DH(pub), &dh_pub, &dh_priv); - dh_free = 0; - break; - } - default: RETURN_FALSE; - } - data = zend_string_alloc(DH_size(dh), 0); - len = DH_compute_key((unsigned char*)ZSTR_VAL(data), dh_pub, dh); - if (len >= 0) { - ZSTR_LEN(data) = len; - ZSTR_VAL(data)[len] = 0; - RETVAL_STR(data); - } else { - php_openssl_store_errors(); - zend_string_release(data); - RETVAL_FALSE; - } - if (dh_free) BN_free(dh_pub); - } else { - RETVAL_FALSE; - } - break; - } -#ifdef HAVE_EVP_PKEY_EC - case EVP_PKEY_EC: { - if (Z_TYPE_P(peer_key) != IS_RESOURCE) RETURN_FALSE; - EVP_PKEY *pub; - if ((pub = (EVP_PKEY *)zend_fetch_resource(Z_RES_P(peer_key), "OpenSSL key", le_key)) == NULL || EVP_PKEY_base_id(pub) != EVP_PKEY_EC) { - RETURN_FALSE; - } - EC_KEY *ec = EVP_PKEY_get0_EC_KEY(pkey); - EC_KEY *ec_pub = EVP_PKEY_get0_EC_KEY(pub); - if (ec != NULL && ec_pub != NULL && EVP_PKEY_bits(pkey) == EVP_PKEY_bits(pub)) { - size_t maxlen = (EVP_PKEY_bits(pkey) + 7) >> 3; - data = zend_string_alloc(maxlen + 1, 0); - len = ECDH_compute_key((unsigned char*)ZSTR_VAL(data), maxlen, EC_KEY_get0_public_key(ec_pub), ec, NULL); - if (len >= 0) { - ZSTR_LEN(data) = len; - ZSTR_VAL(data)[len] = 0; - RETVAL_STR(data); - } else { - php_openssl_store_errors(); - zend_string_release(data); - RETVAL_FALSE; - } - } else { - RETVAL_FALSE; - } - break; - } -#endif - default: + PHP_OPENSSL_CHECK_SIZE_T_TO_INT(pub_len, pub_key); + pub = BN_bin2bn((unsigned char*)pub_str, (int)pub_len, NULL); + + data = zend_string_alloc(DH_size(dh), 0); + len = DH_compute_key((unsigned char*)ZSTR_VAL(data), pub, dh); + + if (len >= 0) { + ZSTR_LEN(data) = len; + ZSTR_VAL(data)[len] = 0; + RETVAL_STR(data); + } else { + php_openssl_store_errors(); + zend_string_release(data); RETVAL_FALSE; } + + BN_free(pub); } /* }}} */ From bea922de03f96731815084c75d14ac3056d23ced Mon Sep 17 00:00:00 2001 From: Jim Zubov Date: Sat, 31 Mar 2018 16:18:18 -0400 Subject: [PATCH 5/8] fixed a wrong skip condition in ecc.phpt, was copied into the ecdh test as well --- ext/openssl/tests/ecc.phpt | 2 +- ext/openssl/tests/openssl_derive-ecdh.phpt | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/ext/openssl/tests/ecc.phpt b/ext/openssl/tests/ecc.phpt index e4c1d20805f5..fda45f9edb8b 100644 --- a/ext/openssl/tests/ecc.phpt +++ b/ext/openssl/tests/ecc.phpt @@ -1,7 +1,7 @@ --TEST-- openssl_*() with OPENSSL_KEYTYPE_EC --SKIPIF-- - + --FILE-- + --FILE-- Date: Sat, 31 Mar 2018 19:00:08 -0400 Subject: [PATCH 6/8] an empty commit to restart appveyor, seems like it failed for no good reason - From e011b83873c97bb50452f50b9d835bac714dedb7 Mon Sep 17 00:00:00 2001 From: Jim Zubov Date: Tue, 3 Apr 2018 15:02:06 -0400 Subject: [PATCH 7/8] renamed to openssl_pkey_derive() - --- ext/openssl/openssl.c | 32 +++++++++++-------- ...ve-dh.phpt => openssl_pkey_derive-dh.phpt} | 7 ++-- ...cdh.phpt => openssl_pkey_derive-ecdh.phpt} | 7 ++-- 3 files changed, 23 insertions(+), 23 deletions(-) rename ext/openssl/tests/{openssl_derive-dh.phpt => openssl_pkey_derive-dh.phpt} (78%) rename ext/openssl/tests/{openssl_derive-ecdh.phpt => openssl_pkey_derive-ecdh.phpt} (79%) diff --git a/ext/openssl/openssl.c b/ext/openssl/openssl.c index 9da6a8244a5a..35ba20786bd5 100644 --- a/ext/openssl/openssl.c +++ b/ext/openssl/openssl.c @@ -128,7 +128,7 @@ PHP_FUNCTION(openssl_decrypt); PHP_FUNCTION(openssl_cipher_iv_length); PHP_FUNCTION(openssl_dh_compute_key); -PHP_FUNCTION(openssl_derive); +PHP_FUNCTION(openssl_pkey_derive); PHP_FUNCTION(openssl_random_pseudo_bytes); /* {{{ arginfo */ @@ -431,7 +431,7 @@ ZEND_BEGIN_ARG_INFO(arginfo_openssl_dh_compute_key, 0) ZEND_ARG_INFO(0, dh_key) ZEND_END_ARG_INFO() -ZEND_BEGIN_ARG_INFO(arginfo_openssl_derive, 0) +ZEND_BEGIN_ARG_INFO(arginfo_openssl_pkey_derive, 0) ZEND_ARG_INFO(0, peer_pub_key) ZEND_ARG_INFO(0, priv_key) ZEND_ARG_INFO(0, keylen) @@ -541,7 +541,7 @@ static const zend_function_entry openssl_functions[] = { #endif PHP_FE(openssl_dh_compute_key, arginfo_openssl_dh_compute_key) - PHP_FE(openssl_derive, arginfo_openssl_derive) + PHP_FE(openssl_pkey_derive, arginfo_openssl_pkey_derive) PHP_FE(openssl_random_pseudo_bytes, arginfo_openssl_random_pseudo_bytes) PHP_FE(openssl_error_string, arginfo_openssl_error_string) @@ -4941,9 +4941,9 @@ PHP_FUNCTION(openssl_dh_compute_key) } /* }}} */ -/* {{{ proto string openssl_derive(resource peer_pub_key, resource priv_key,int keylen=NULL) +/* {{{ proto string openssl_pkey_derive(peer_pub_key, priv_key, int keylen=NULL) Computes shared secret for public value of remote and local DH or ECDH key */ -PHP_FUNCTION(openssl_derive) +PHP_FUNCTION(openssl_pkey_derive) { zval *priv_key; zval *peer_pub_key; @@ -4952,19 +4952,24 @@ PHP_FUNCTION(openssl_derive) zend_long keylen = 0; zend_string *result; - if (zend_parse_parameters(ZEND_NUM_ARGS(), "rr|l", &peer_pub_key, &priv_key, &keylen) == FAILURE) { - return; + if (zend_parse_parameters(ZEND_NUM_ARGS(), "zz|l", &peer_pub_key, &priv_key, &keylen) == FAILURE) { + RETURN_FALSE; + } + if (keylen < 0) { + php_error_docref(NULL, E_WARNING, "keylen < 0, assuming NULL"); } - if ((pkey = (EVP_PKEY *)zend_fetch_resource(Z_RES_P(priv_key), "OpenSSL key", le_key)) == NULL - || (peer_key = (EVP_PKEY *)zend_fetch_resource(Z_RES_P(peer_pub_key), "OpenSSL key", le_key)) == NULL) { + if ((pkey = php_openssl_evp_from_zval(priv_key,0,"",0,0,NULL)) == NULL + || (peer_key = php_openssl_evp_from_zval(peer_pub_key,1,NULL,0,0,NULL)) == NULL) { RETURN_FALSE; } EVP_PKEY_CTX *ctx = EVP_PKEY_CTX_new(pkey, NULL); - if (!ctx) RETURN_FALSE; + if (!ctx) { + RETURN_FALSE; + } if (EVP_PKEY_derive_init(ctx) > 0 - && EVP_PKEY_derive_set_peer(ctx, peer_key) > 0 - && (keylen > 0 || EVP_PKEY_derive(ctx, NULL, &keylen) > 0) - && (result = zend_string_alloc(keylen, 0)) != NULL) { + && EVP_PKEY_derive_set_peer(ctx, peer_key) > 0 + && (keylen > 0 || EVP_PKEY_derive(ctx, NULL, &keylen) > 0) + && (result = zend_string_alloc(keylen, 0)) != NULL) { if (EVP_PKEY_derive(ctx, (unsigned char*)ZSTR_VAL(result), &keylen) > 0) { ZSTR_LEN(result) = keylen; ZSTR_VAL(result)[keylen] = 0; @@ -4981,6 +4986,7 @@ PHP_FUNCTION(openssl_derive) } /* }}} */ + /* {{{ proto string openssl_pbkdf2(string password, string salt, int key_length, int iterations [, string digest_method = "sha1"]) Generates a PKCS5 v2 PBKDF2 string, defaults to sha1 */ PHP_FUNCTION(openssl_pbkdf2) diff --git a/ext/openssl/tests/openssl_derive-dh.phpt b/ext/openssl/tests/openssl_pkey_derive-dh.phpt similarity index 78% rename from ext/openssl/tests/openssl_derive-dh.phpt rename to ext/openssl/tests/openssl_pkey_derive-dh.phpt index e356ed31656e..5d65afbed430 100644 --- a/ext/openssl/tests/openssl_derive-dh.phpt +++ b/ext/openssl/tests/openssl_pkey_derive-dh.phpt @@ -1,5 +1,5 @@ --TEST-- -openssl_derive() DH +openssl_pkey_derive() DH --SKIPIF-- --FILE-- @@ -37,11 +37,8 @@ dtlkbGbtoDOnxeNnN93gwQZngGYZYciu -----END PUBLIC KEY----- "); -echo bin2hex(openssl_derive($pub,$priv)); -echo "\n"; -echo bin2hex(openssl_derive($priv,$priv)); +echo bin2hex(openssl_pkey_derive($pub,$priv)); echo "\n"; ?> --EXPECTF-- 10aed66ad96a65f50543aa9adbc18ea169bf98521c682c49fb8b7daeb9e8fbe6b9a800199ffe1123cc36fc358829cbbc5d21bf1eb8ce3cf644538b357f478361a284c27fbe31fc94d431562786dd7314613cd70e6d76ca1ab3c1f31556ed07162f243dcc1a43ea98c454fb6e891eaec7a14158d54cd33d3fbbbc75f1ea8ff5deaab25d5deb657c7c43004252df301b195207d01614e7cb833e0e8d785ba2ecfe16ad7a9634784fdb8db8afe049476b58743575725ee99c761a59a7d7b9e709fff84c8d427e2bc07953a7c2408eb3f8f7e0ebc2f901c6889955874ae79a3de19921757d69424145a35dbe5af778b080dada55bdfce8fb0319f2de39110f58e05d -6640f467ea55d08f912206d87588370588ef411a6a4f59075c17f4c230b6366956932eebc4f2b6850540f99cb00cc6fa30f94e1af072879bd4ea869cd85ec14a3ce51aa0cc1c9f5d7fd43ef1cdeaa4afca804f9caa492abb738198485a56f103d6126d19578b9e92eab132107d529a6f2bb98c433888398cea8b60b73725cbc69c944982efc7c4a33a3d3e102e974477611be305ec54efc95eb05b6c88bd77f51735e222f5b2a56637b9091b1a58bd39bc41f8987df560c2d2c15aa36c381d1b51ed55b49e4638ab490b95ecf7272f8c6477ddc01bba873bf2395a918049f326e089558304f1e374c978912935c1fd04aa0a14f080263d590523d28de52cedfe diff --git a/ext/openssl/tests/openssl_derive-ecdh.phpt b/ext/openssl/tests/openssl_pkey_derive-ecdh.phpt similarity index 79% rename from ext/openssl/tests/openssl_derive-ecdh.phpt rename to ext/openssl/tests/openssl_pkey_derive-ecdh.phpt index 836712121c5d..d26e479ee840 100644 --- a/ext/openssl/tests/openssl_derive-ecdh.phpt +++ b/ext/openssl/tests/openssl_pkey_derive-ecdh.phpt @@ -1,5 +1,5 @@ --TEST-- -openssl_derive() ECDH +openssl_pkey_derive() ECDH --SKIPIF-- --FILE-- @@ -22,11 +22,8 @@ N2IRPU2MF6S0S6i44MU= -----END PUBLIC KEY----- "); -echo bin2hex(openssl_derive($pub,$priv)); -echo "\n"; -echo bin2hex(openssl_derive($priv,$priv)); +echo bin2hex(openssl_pkey_derive($pub,$priv)); echo "\n"; ?> --EXPECTF-- 01171967cc0ddc553b46c6a821502aaea44aa04e6933d897ea11222efa0556f2d5d972816676c9ccf4e2430a26e07193ad39373050f6e54e4059f17720d7dd667635 -0129ed9749701a48f01a70757c8d967007cb7abeff2ec46ce18b51f1e7daeae81aaef146a0a585db5ee3c5469c0c4bd3a2395f79d36b4a800ac08e866fc96548fad8 From cd853e6a1b1feed48bf226d4bdb1a5022cd0ce72 Mon Sep 17 00:00:00 2001 From: Jim Zubov Date: Wed, 4 Apr 2018 16:48:37 -0400 Subject: [PATCH 8/8] NIT CS --- ext/openssl/openssl.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ext/openssl/openssl.c b/ext/openssl/openssl.c index 35ba20786bd5..f6c8b8156aa3 100644 --- a/ext/openssl/openssl.c +++ b/ext/openssl/openssl.c @@ -4958,8 +4958,8 @@ PHP_FUNCTION(openssl_pkey_derive) if (keylen < 0) { php_error_docref(NULL, E_WARNING, "keylen < 0, assuming NULL"); } - if ((pkey = php_openssl_evp_from_zval(priv_key,0,"",0,0,NULL)) == NULL - || (peer_key = php_openssl_evp_from_zval(peer_pub_key,1,NULL,0,0,NULL)) == NULL) { + if ((pkey = php_openssl_evp_from_zval(priv_key, 0, "", 0, 0, NULL)) == NULL + || (peer_key = php_openssl_evp_from_zval(peer_pub_key, 1, NULL, 0, 0, NULL)) == NULL) { RETURN_FALSE; } EVP_PKEY_CTX *ctx = EVP_PKEY_CTX_new(pkey, NULL);