diff options
author | Jim Zubov <jz@vesvault.com> | 2018-03-26 18:23:58 -0400 |
---|---|---|
committer | Jakub Zelenka <bukka@php.net> | 2018-05-09 19:37:01 +0100 |
commit | 897133fbdadc037b5d452c11b139d5f9def01129 (patch) | |
tree | 52007d79b8bdb1c5aa516202fd46ee1cae884ab0 /ext/openssl | |
parent | a886ca920f20c3b711715808614fc8699a9ad69f (diff) | |
download | php-git-897133fbdadc037b5d452c11b139d5f9def01129.tar.gz |
Add openssl_pkey_derive
Diffstat (limited to 'ext/openssl')
-rw-r--r-- | ext/openssl/openssl.c | 52 | ||||
-rw-r--r-- | ext/openssl/tests/ecc.phpt | 2 | ||||
-rw-r--r-- | ext/openssl/tests/openssl_pkey_derive-dh.phpt | 44 | ||||
-rw-r--r-- | ext/openssl/tests/openssl_pkey_derive-ecdh.phpt | 29 |
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 |