From: Jakub Zelenka Date: Sun, 20 Nov 2016 20:06:39 +0000 (+0000) Subject: Fix bug #73478 (openssl_pkey_new() generates wrong pub/priv keys with Diffie Hellman) X-Git-Tag: php-7.1.1RC1~222 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=ce4869f0388e500abf39094ab48ae6769a2ed71f;p=php Fix bug #73478 (openssl_pkey_new() generates wrong pub/priv keys with Diffie Hellman) --- diff --git a/NEWS b/NEWS index ec2ef165f8..4f2bd9518d 100644 --- a/NEWS +++ b/NEWS @@ -22,6 +22,10 @@ PHP NEWS - Opcache: . Fixed bug #69090 (check cached files permissions) +- OpenSSL: + . Fixed bug #73478 (openssl_pkey_new() generates wrong pub/priv keys with + Diffie Hellman). (Jakub Zelenka) + - PCRE: . Fixed bug #73483 (Segmentation fault on pcre_replace_callback). (Laruence) diff --git a/ext/openssl/openssl.c b/ext/openssl/openssl.c index 528d8235a5..7e8d649659 100644 --- a/ext/openssl/openssl.c +++ b/ext/openssl/openssl.c @@ -4091,6 +4091,47 @@ zend_bool php_openssl_pkey_init_dsa(DSA *dsa, zval *data) } /* }}} */ +/* {{{ php_openssl_dh_pub_from_priv */ +static BIGNUM *php_openssl_dh_pub_from_priv(DH *dh, BIGNUM *priv_key, BIGNUM *g, BIGNUM *p) +{ + BIGNUM *pub_key, *priv_key_const_time; + BN_CTX *ctx; + + pub_key = BN_new(); + if (pub_key == NULL) { + php_openssl_store_errors(); + return NULL; + } + + priv_key_const_time = BN_new(); + if (priv_key_const_time == NULL) { + BN_free(pub_key); + php_openssl_store_errors(); + return NULL; + } + ctx = BN_CTX_new(); + if (priv_key_const_time == NULL) { + BN_free(pub_key); + BN_free(priv_key_const_time); + php_openssl_store_errors(); + return NULL; + } + + BN_with_flags(priv_key_const_time, priv_key, BN_FLG_CONSTTIME); + + if (!BN_mod_exp_mont(pub_key, g, priv_key_const_time, p, ctx, NULL)) { + BN_free(pub_key); + php_openssl_store_errors(); + pub_key = NULL; + } + + BN_free(priv_key_const_time); + BN_CTX_free(ctx); + + return pub_key; +} +/* }}} */ + /* {{{ php_openssl_pkey_init_dh */ zend_bool php_openssl_pkey_init_dh(DH *dh, zval *data) { @@ -4108,6 +4149,13 @@ zend_bool php_openssl_pkey_init_dh(DH *dh, zval *data) if (pub_key) { return DH_set0_key(dh, pub_key, priv_key); } + if (priv_key) { + pub_key = php_openssl_dh_pub_from_priv(dh, priv_key, g, p); + if (pub_key == NULL) { + return 0; + } + return DH_set0_key(dh, pub_key, priv_key); + } /* generate key */ PHP_OPENSSL_RAND_ADD_TIME(); diff --git a/ext/openssl/tests/bug73478.phpt b/ext/openssl/tests/bug73478.phpt new file mode 100644 index 0000000000..1dfc584164 --- /dev/null +++ b/ext/openssl/tests/bug73478.phpt @@ -0,0 +1,25 @@ +--TEST-- +Bug #73478: openssl_pkey_new() generates wrong pub/priv keys with Diffie Hellman +--SKIPIF-- + +--FILE-- + base64_decode('3Pk6C4g5cuwOGZiaxaLOMQ4dN3F+jZVxu3Yjcxhm5h73Wi4niYsFf5iRwuJ6Y5w/KbYIFFgc07LKOYbSaDcFV31FwuflLcgcehcYduXOp0sUSL/frxiCjv0lGfFOReOCZjSvGUnltTXMgppIO4p2Ij5dSQolfwW9/xby+yLFg6s='), + 'g' => base64_decode('Ag=='), + 'priv_key' => base64_decode('jUdcV++P/m7oUodWiqKqKXZVenHRuj92Ig6Fmzs7QlqVdUc5mNBxmEWjug+ObffanPpOeab/LyXwjNMzevtBz3tW4oROau++9EIMJVVQr8fW9zdYBJcYieC5l4t8nRj5/Uu/Z0G2rWVLBleSi28mqqNEvnUs7uxYxrar69lwQYs=') +]; + +$opensslKeyResource = openssl_pkey_new(['dh' => $details]); +$data = openssl_pkey_get_details($opensslKeyResource); + +printf("Private key:\n%s\n", base64_encode($data['dh']['priv_key'])); +printf("Public key:\n%s\n", base64_encode($data['dh']['pub_key'])); +?> +--EXPECT-- +Private key: +jUdcV++P/m7oUodWiqKqKXZVenHRuj92Ig6Fmzs7QlqVdUc5mNBxmEWjug+ObffanPpOeab/LyXwjNMzevtBz3tW4oROau++9EIMJVVQr8fW9zdYBJcYieC5l4t8nRj5/Uu/Z0G2rWVLBleSi28mqqNEvnUs7uxYxrar69lwQYs= +Public key: +0DmJUe9dr02pAtVoGyLHdC+rfBU3mDCelKGPXRDFHofx6mFfN2gcZCmp/ab4ezDXfpIBOatpVdbn2fTNUGo64DtKE2WGTsZCl90RgrGUv8XW/4WDPXeE7g5u7KWHBG/LCE5+XsilE5P5/GIyqr9gsiudTmk+H/hiYZl9Smar9k0=