1
0
mirror of https://github.com/php/php-src.git synced 2026-03-24 00:02:20 +01:00

Integrate OpenSSL libctx to pwhash (#19236)

This allows using OpenSSL Argon2 password hashing on ZTS.

Closes GH-19236
This commit is contained in:
Jakub Zelenka
2025-07-29 14:06:34 +01:00
committed by GitHub
parent f72105be81
commit ce6e7a2786
5 changed files with 56 additions and 8 deletions

View File

@@ -49,9 +49,6 @@ if test "$PHP_OPENSSL" != "no"; then
the default provider.])])
AS_VAR_IF([PHP_OPENSSL_ARGON2], [no],, [
AS_VAR_IF([PHP_THREAD_SAFETY], [yes],
[AC_MSG_ERROR([Not supported in ZTS mode for now])])
PHP_CHECK_LIBRARY([crypto], [OSSL_set_max_threads],
[AC_DEFINE([HAVE_OPENSSL_ARGON2], [1],
[Define to 1 to enable OpenSSL argon2 password hashing.])],

View File

@@ -355,7 +355,15 @@ static PHP_INI_MH(OnUpdateLibCtx)
{
#if PHP_OPENSSL_API_VERSION >= 0x30000
if (zend_string_equals_literal(new_value, "default")) {
#if defined(ZTS) && defined(HAVE_OPENSSL_ARGON2)
if (stage != ZEND_INI_STAGE_DEACTIVATE) {
int err_type = stage == ZEND_INI_STAGE_RUNTIME ? E_WARNING : E_ERROR;
php_error_docref(NULL, err_type, "OpenSSL libctx \"default\" cannot be used in this configuration");
}
return FAILURE;
#else
OPENSSL_G(ctx).libctx = OPENSSL_G(ctx).default_libctx;
#endif
} else if (zend_string_equals_literal(new_value, "custom")) {
OPENSSL_G(ctx).libctx = OPENSSL_G(ctx).custom_libctx;
} else {

View File

@@ -22,7 +22,7 @@
#include "ext/standard/php_password.h"
#include "php_openssl.h"
#if defined(HAVE_OPENSSL_ARGON2)
#ifdef HAVE_OPENSSL_ARGON2
#include "Zend/zend_attributes.h"
#include "openssl_pwhash_arginfo.h"
#include <ext/standard/base64.h>
@@ -46,6 +46,8 @@
#define PHP_OPENSSL_HASH_SIZE 32
#define PHP_OPENSSL_DIGEST_SIZE 128
ZEND_EXTERN_MODULE_GLOBALS(openssl)
static inline zend_result get_options(zend_array *options, uint32_t *memlimit, uint32_t *iterlimit, uint32_t *threads)
{
zval *opt;
@@ -98,8 +100,8 @@ static bool php_openssl_argon2_compute_hash(
uint32_t oldthreads;
bool ret = false;
oldthreads = OSSL_get_max_threads(NULL);
if (OSSL_set_max_threads(NULL, threads) != 1) {
oldthreads = OSSL_get_max_threads(PHP_OPENSSL_LIBCTX);
if (OSSL_set_max_threads(PHP_OPENSSL_LIBCTX, threads) != 1) {
goto fail;
}
p = params;
@@ -111,7 +113,7 @@ static bool php_openssl_argon2_compute_hash(
*p++ = OSSL_PARAM_construct_octet_string(OSSL_KDF_PARAM_PASSWORD, (void *)pass, pass_len);
*p++ = OSSL_PARAM_construct_end();
if ((kdf = EVP_KDF_fetch(NULL, algo, NULL)) == NULL) {
if ((kdf = EVP_KDF_fetch(PHP_OPENSSL_LIBCTX, algo, PHP_OPENSSL_PROPQ)) == NULL) {
goto fail;
}
if ((kctx = EVP_KDF_CTX_new(kdf)) == NULL) {
@@ -127,7 +129,7 @@ static bool php_openssl_argon2_compute_hash(
fail:
EVP_KDF_free(kdf);
EVP_KDF_CTX_free(kctx);
OSSL_set_max_threads(NULL, oldthreads);
OSSL_set_max_threads(PHP_OPENSSL_LIBCTX, oldthreads);
return ret;
}
@@ -385,4 +387,5 @@ PHP_MINIT_FUNCTION(openssl_pwhash)
return SUCCESS;
}
#endif /* HAVE_OPENSSL_ARGON2 */

View File

@@ -0,0 +1,22 @@
--TEST--
openssl.libctx INI setting when Argon2 enabled and ZTS used
--EXTENSIONS--
openssl
--INI--
openssl.libctx = default
--SKIPIF--
<?php
if (!ZEND_THREAD_SAFE) {
die("skip - Non ZTS test");
}
if (!function_exists('openssl_password_hash')) {
die("skip - OpenSSL Argon2 not enabled");
}
?>
--FILE--
<?php
var_dump(ini_get('openssl.libctx'));
?>
--EXPECT--
Fatal error: PHP Startup: OpenSSL libctx "default" cannot be used in this configuration in Unknown on line 0
string(6) "custom"

View File

@@ -0,0 +1,18 @@
--TEST--
openssl.libctx INI setting when Argon2 disable or ZTS not used
--EXTENSIONS--
openssl
--INI--
openssl.libctx = default
--SKIPIF--
<?php
if (ZEND_THREAD_SAFE && function_exists('openssl_password_hash')) {
die("skip - ZTS test with Argon2 enabled");
}
?>
--FILE--
<?php
var_dump(ini_get('openssl.libctx'));
?>
--EXPECT--
string(7) "default"