summaryrefslogtreecommitdiff
path: root/ext/openssl
diff options
context:
space:
mode:
authorJim Zubov <jz@vesvault.com>2018-03-26 18:23:58 -0400
committerJakub Zelenka <bukka@php.net>2018-05-09 19:37:01 +0100
commit897133fbdadc037b5d452c11b139d5f9def01129 (patch)
tree52007d79b8bdb1c5aa516202fd46ee1cae884ab0 /ext/openssl
parenta886ca920f20c3b711715808614fc8699a9ad69f (diff)
downloadphp-git-897133fbdadc037b5d452c11b139d5f9def01129.tar.gz
Add openssl_pkey_derive
Diffstat (limited to 'ext/openssl')
-rw-r--r--ext/openssl/openssl.c52
-rw-r--r--ext/openssl/tests/ecc.phpt2
-rw-r--r--ext/openssl/tests/openssl_pkey_derive-dh.phpt44
-rw-r--r--ext/openssl/tests/openssl_pkey_derive-ecdh.phpt29
4 files changed, 126 insertions, 1 deletions
diff --git a/ext/openssl/openssl.c b/ext/openssl/openssl.c
index 024d3cf51b..f6c8b8156a 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_pkey_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_pkey_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_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)
@@ -4933,8 +4941,52 @@ PHP_FUNCTION(openssl_dh_compute_key)
}
/* }}} */
+/* {{{ 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_pkey_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(), "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 = 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 (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"])
Generates a PKCS5 v2 PBKDF2 string, defaults to sha1 */
PHP_FUNCTION(openssl_pbkdf2)
diff --git a/ext/openssl/tests/ecc.phpt b/ext/openssl/tests/ecc.phpt
index e4c1d20805..fda45f9edb 100644
--- a/ext/openssl/tests/ecc.phpt
+++ b/ext/openssl/tests/ecc.phpt
@@ -1,7 +1,7 @@
--TEST--
openssl_*() with OPENSSL_KEYTYPE_EC
--SKIPIF--
-<?php if (!extension_loaded("openssl") && !defined("OPENSSL_KEYTYPE_EC")) print "skip"; ?>
+<?php if (!extension_loaded("openssl") || !defined("OPENSSL_KEYTYPE_EC")) print "skip"; ?>
--FILE--
<?php
$args = array(
diff --git a/ext/openssl/tests/openssl_pkey_derive-dh.phpt b/ext/openssl/tests/openssl_pkey_derive-dh.phpt
new file mode 100644
index 0000000000..5d65afbed4
--- /dev/null
+++ b/ext/openssl/tests/openssl_pkey_derive-dh.phpt
@@ -0,0 +1,44 @@
+--TEST--
+openssl_pkey_derive() DH
+--SKIPIF--
+<?php if (!extension_loaded("openssl")) print "skip"; ?>
+--FILE--
+<?php
+
+$priv = openssl_pkey_get_private("-----BEGIN PRIVATE KEY-----
+MIICJgIBADCCARcGCSqGSIb3DQEDATCCAQgCggEBAJLxRCaZ933uW+AXmabHFDDy
+upojBIRlbmQLJZfigDaSA1f9YOTsIv+WwVFTX/J1mtCyx9uBcz0Nt2kmVwxWuc2f
+VtCEMPsmLsVXX7xRUFLpyX1Y1IYGBVXQOoOvLWYQjpZgnx47Pkh1Ok1+smffztfC
+0DCNt4KorWrbsPcmqBejXHN79KvWFjZmXOksRiNu/Bn76RiqvofC4z8Ri3kHXQG2
+197JGZzzFXHadGC3xbkg8UxsNbYhVMKbm0iANfafUH7/hoS9UjAVQYtvwe7YNiW/
+HnyfVCrKwcc7sadd8Iphh+3lf5P1AhaQEAMytanrzq9RDXKBxuvpSJifRYasZYsC
+AQIEggEEAoIBAGwAYC2E81Y1U2Aox0U7u1+vBcbht/OO87tutMvc4NTLf6NLPHsW
+cPqBixs+3rSn4fADzAIvdLBmogjtiIZoB6qyHrllF/2xwTVGEeYaZIupQH3bMK2b
+6eUvnpuu4Ytksiz6VpXBBRMrIsj3frM+zUtnq8vKUr+TbjV2qyKR8l3eNDwzqz30
+dlbKh9kIhZafclHfRVfyp+fVSKPfgrRAcLUgAbsVjOjPeJ90xQ4DTMZ6vjiv6tHM
+hkSjJIcGhRtSBzVF/cT38GyCeTmiIA/dRz2d70lWrqDQCdp9ArijgnpjNKAAulSY
+CirnMsGZTDGmLOHg4xOZ5FEAzZI2sFNLlcw=
+-----END PRIVATE KEY-----
+");
+
+$pub = openssl_pkey_get_public("-----BEGIN PUBLIC KEY-----
+MIICJDCCARcGCSqGSIb3DQEDATCCAQgCggEBAJLxRCaZ933uW+AXmabHFDDyupoj
+BIRlbmQLJZfigDaSA1f9YOTsIv+WwVFTX/J1mtCyx9uBcz0Nt2kmVwxWuc2fVtCE
+MPsmLsVXX7xRUFLpyX1Y1IYGBVXQOoOvLWYQjpZgnx47Pkh1Ok1+smffztfC0DCN
+t4KorWrbsPcmqBejXHN79KvWFjZmXOksRiNu/Bn76RiqvofC4z8Ri3kHXQG2197J
+GZzzFXHadGC3xbkg8UxsNbYhVMKbm0iANfafUH7/hoS9UjAVQYtvwe7YNiW/Hnyf
+VCrKwcc7sadd8Iphh+3lf5P1AhaQEAMytanrzq9RDXKBxuvpSJifRYasZYsCAQID
+ggEFAAKCAQAiCSBpxvGgsTorxAWtcAlSmzAJnJxFgSPef0g7OjhESytnc8G2QYmx
+ovMt5KVergcitztWh08hZQUdAYm4rI+zMlAFDdN8LWwBT/mGKSzRkWeprd8E7mvy
+ucqC1YXCMqmIwPySvLQUB/Dl8kgau7BLAnIJm8VP+MVrn8g9gghD0qRCgPgtEaDV
+vocfgnOU43rhKnIgO0cHOKtw2qybSFB8QuZrYugq4j8Bwkrzh6rdMMeyMl/ej5Aj
+c0wamOzuBDtXt0T9+Fx3khHaowjCc7xJZRgZCxg43SbqMWJ9lUg94I7+LTX61Gyv
+dtlkbGbtoDOnxeNnN93gwQZngGYZYciu
+-----END PUBLIC KEY-----
+");
+
+echo bin2hex(openssl_pkey_derive($pub,$priv));
+echo "\n";
+?>
+--EXPECTF--
+10aed66ad96a65f50543aa9adbc18ea169bf98521c682c49fb8b7daeb9e8fbe6b9a800199ffe1123cc36fc358829cbbc5d21bf1eb8ce3cf644538b357f478361a284c27fbe31fc94d431562786dd7314613cd70e6d76ca1ab3c1f31556ed07162f243dcc1a43ea98c454fb6e891eaec7a14158d54cd33d3fbbbc75f1ea8ff5deaab25d5deb657c7c43004252df301b195207d01614e7cb833e0e8d785ba2ecfe16ad7a9634784fdb8db8afe049476b58743575725ee99c761a59a7d7b9e709fff84c8d427e2bc07953a7c2408eb3f8f7e0ebc2f901c6889955874ae79a3de19921757d69424145a35dbe5af778b080dada55bdfce8fb0319f2de39110f58e05d
diff --git a/ext/openssl/tests/openssl_pkey_derive-ecdh.phpt b/ext/openssl/tests/openssl_pkey_derive-ecdh.phpt
new file mode 100644
index 0000000000..d26e479ee8
--- /dev/null
+++ b/ext/openssl/tests/openssl_pkey_derive-ecdh.phpt
@@ -0,0 +1,29 @@
+--TEST--
+openssl_pkey_derive() ECDH
+--SKIPIF--
+<?php if (!extension_loaded("openssl") || !defined("OPENSSL_KEYTYPE_EC")) print "skip"; ?>
+--FILE--
+<?php
+
+$priv = openssl_pkey_get_private("-----BEGIN EC PRIVATE KEY-----
+MIHbAgEBBEEHI4mYyIOu8zQYAThKCgDIj4JAMekWFcrJSSa4K+C80xtrT07tz1Yj
+mZdn+7/sAuZ4HBg56EzFBhLGxwGDakot1qAHBgUrgQQAI6GBiQOBhgAEARnoOOKF
+c+1CNtrq2Jq0GvcBjIi1kJpQLfFF1RFgP/jVDeimSJi8elAtl6NqdikDVSIg6ZwT
+6XOz6IdPRZsCMsWyAYeWz2jTRoT93nGLm9G96jwOm0VhLHjp3WtTY4kDp9dVHdhH
+x3Nz35sz8u0CE6befv+Fxo5ORq373v9eDzp62Z8g
+-----END EC PRIVATE KEY-----
+");
+
+$pub = openssl_pkey_get_public("-----BEGIN PUBLIC KEY-----
+MIGbMBAGByqGSM49AgEGBSuBBAAjA4GGAAQBGs5c8VCdd3VcOAUhuCzEB6uMUDob
+lG5vtncWqvHfcnsR4uHEuufl24rbraVFyVeGr/BV0AfUnnhKGnaEtSDG9h4BMw5A
+vHiBzBCZUlA1TUMSmNpedutkZul4h6gYNrzFtfjmbqSnC0732YgUIrr4yueOSL2E
+N2IRPU2MF6S0S6i44MU=
+-----END PUBLIC KEY-----
+");
+
+echo bin2hex(openssl_pkey_derive($pub,$priv));
+echo "\n";
+?>
+--EXPECTF--
+01171967cc0ddc553b46c6a821502aaea44aa04e6933d897ea11222efa0556f2d5d972816676c9ccf4e2430a26e07193ad39373050f6e54e4059f17720d7dd667635