mirror of
https://github.com/php/php-src.git
synced 2025-08-15 21:48:51 +02:00
Introduce OpenSSL INI for selecting libctx (#18768)
Closes GH-18768 Co-authored-by: Gina Peter Banyard <girgias@php.net>
This commit is contained in:
parent
2beb44a80b
commit
d0c0a9abfd
7 changed files with 95 additions and 32 deletions
|
@ -351,12 +351,31 @@ int php_openssl_get_ssl_stream_data_index(void)
|
||||||
return ssl_stream_data_index;
|
return ssl_stream_data_index;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* {{{ INI Settings */
|
static PHP_INI_MH(OnUpdateLibCtx)
|
||||||
|
{
|
||||||
|
#if PHP_OPENSSL_API_VERSION >= 0x30000
|
||||||
|
if (zend_string_equals_literal(new_value, "default")) {
|
||||||
|
OPENSSL_G(ctx).libctx = OPENSSL_G(ctx).default_libctx;
|
||||||
|
} else if (zend_string_equals_literal(new_value, "custom")) {
|
||||||
|
OPENSSL_G(ctx).libctx = OPENSSL_G(ctx).custom_libctx;
|
||||||
|
} else {
|
||||||
|
/* Do not output error when restoring ini options. */
|
||||||
|
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 \"%s\" cannot be found", ZSTR_VAL(new_value));
|
||||||
|
}
|
||||||
|
return FAILURE;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
PHP_INI_BEGIN()
|
PHP_INI_BEGIN()
|
||||||
PHP_INI_ENTRY("openssl.cafile", NULL, PHP_INI_PERDIR, NULL)
|
PHP_INI_ENTRY("openssl.cafile", NULL, PHP_INI_PERDIR, NULL)
|
||||||
PHP_INI_ENTRY("openssl.capath", NULL, PHP_INI_PERDIR, NULL)
|
PHP_INI_ENTRY("openssl.capath", NULL, PHP_INI_PERDIR, NULL)
|
||||||
|
PHP_INI_ENTRY("openssl.libctx", "custom", PHP_INI_PERDIR, OnUpdateLibCtx)
|
||||||
PHP_INI_END()
|
PHP_INI_END()
|
||||||
/* }}} */
|
|
||||||
|
|
||||||
/* {{{ PHP_MINIT_FUNCTION */
|
/* {{{ PHP_MINIT_FUNCTION */
|
||||||
PHP_MINIT_FUNCTION(openssl)
|
PHP_MINIT_FUNCTION(openssl)
|
||||||
|
@ -438,9 +457,7 @@ PHP_GINIT_FUNCTION(openssl)
|
||||||
#endif
|
#endif
|
||||||
openssl_globals->errors = NULL;
|
openssl_globals->errors = NULL;
|
||||||
openssl_globals->errors_mark = NULL;
|
openssl_globals->errors_mark = NULL;
|
||||||
#if PHP_OPENSSL_API_VERSION >= 0x30000
|
php_openssl_backend_init_libctx(&openssl_globals->ctx);
|
||||||
php_openssl_backend_init_libctx(&openssl_globals->libctx, &openssl_globals->propq);
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
/* }}} */
|
/* }}} */
|
||||||
|
|
||||||
|
@ -453,9 +470,7 @@ PHP_GSHUTDOWN_FUNCTION(openssl)
|
||||||
if (openssl_globals->errors_mark) {
|
if (openssl_globals->errors_mark) {
|
||||||
pefree(openssl_globals->errors_mark, 1);
|
pefree(openssl_globals->errors_mark, 1);
|
||||||
}
|
}
|
||||||
#if PHP_OPENSSL_API_VERSION >= 0x30000
|
php_openssl_backend_destroy_libctx(&openssl_globals->ctx);
|
||||||
php_openssl_backend_destroy_libctx(openssl_globals->libctx, openssl_globals->propq);
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
/* }}} */
|
/* }}} */
|
||||||
|
|
||||||
|
|
|
@ -44,6 +44,16 @@ void php_openssl_backend_shutdown(void)
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void php_openssl_backend_init_libctx(struct php_openssl_libctx *ctx)
|
||||||
|
{
|
||||||
|
// Do nothing as there is no libctx
|
||||||
|
}
|
||||||
|
|
||||||
|
void php_openssl_backend_destroy_libctx(struct php_openssl_libctx *ctx)
|
||||||
|
{
|
||||||
|
// Do nothing as there is no libctx
|
||||||
|
}
|
||||||
|
|
||||||
EVP_PKEY_CTX *php_openssl_pkey_new_from_name(const char *name, int id)
|
EVP_PKEY_CTX *php_openssl_pkey_new_from_name(const char *name, int id)
|
||||||
{
|
{
|
||||||
return EVP_PKEY_CTX_new_id(id, NULL);
|
return EVP_PKEY_CTX_new_id(id, NULL);
|
||||||
|
|
|
@ -29,32 +29,47 @@ void php_openssl_backend_shutdown(void)
|
||||||
(void) 0;
|
(void) 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void php_openssl_backend_init_libctx(OSSL_LIB_CTX **plibctx, char **ppropq)
|
#define PHP_OPENSSL_DEFAULT_CONF_MFLAGS \
|
||||||
|
(CONF_MFLAGS_DEFAULT_SECTION | CONF_MFLAGS_IGNORE_MISSING_FILE | CONF_MFLAGS_IGNORE_RETURN_CODES)
|
||||||
|
|
||||||
|
void php_openssl_backend_init_libctx(struct php_openssl_libctx *ctx)
|
||||||
{
|
{
|
||||||
/* The return value is not checked because we cannot reasonable fail in GINIT so using NULL
|
ctx->default_libctx = OSSL_LIB_CTX_get0_global_default();
|
||||||
* (default context) is probably better. */
|
ctx->custom_libctx = OSSL_LIB_CTX_new();
|
||||||
*plibctx = OSSL_LIB_CTX_new();
|
if (ctx->custom_libctx != NULL) {
|
||||||
*ppropq = NULL;
|
/* This is not being checked because there is not much that can be done. */
|
||||||
|
CONF_modules_load_file_ex(ctx->custom_libctx, NULL, NULL,
|
||||||
|
PHP_OPENSSL_DEFAULT_CONF_MFLAGS);
|
||||||
|
#ifdef LOAD_OPENSSL_LEGACY_PROVIDER
|
||||||
|
OSSL_PROVIDER_load(ctx->custom_libctx, "legacy");
|
||||||
|
OSSL_PROVIDER_load(ctx->custom_libctx, "default");
|
||||||
|
#endif
|
||||||
|
ctx->libctx = ctx->custom_libctx;
|
||||||
|
} else {
|
||||||
|
/* If creation fails, just fallback to default */
|
||||||
|
ctx->libctx = ctx->default_libctx;
|
||||||
|
}
|
||||||
|
ctx->propq = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
void php_openssl_backend_destroy_libctx(OSSL_LIB_CTX *libctx, char *propq)
|
void php_openssl_backend_destroy_libctx(struct php_openssl_libctx *ctx)
|
||||||
{
|
{
|
||||||
if (libctx != NULL) {
|
if (ctx->custom_libctx != NULL) {
|
||||||
OSSL_LIB_CTX_free(libctx);
|
OSSL_LIB_CTX_free(ctx->custom_libctx);
|
||||||
}
|
}
|
||||||
if (propq != NULL) {
|
if (ctx->propq != NULL) {
|
||||||
free(propq);
|
free(ctx->propq);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
EVP_PKEY_CTX *php_openssl_pkey_new_from_name(const char *name, int id)
|
EVP_PKEY_CTX *php_openssl_pkey_new_from_name(const char *name, int id)
|
||||||
{
|
{
|
||||||
return EVP_PKEY_CTX_new_from_name(OPENSSL_G(libctx), name, OPENSSL_G(propq));
|
return EVP_PKEY_CTX_new_from_name(PHP_OPENSSL_LIBCTX, name, PHP_OPENSSL_PROPQ);
|
||||||
}
|
}
|
||||||
|
|
||||||
EVP_PKEY_CTX *php_openssl_pkey_new_from_pkey(EVP_PKEY *pkey)
|
EVP_PKEY_CTX *php_openssl_pkey_new_from_pkey(EVP_PKEY *pkey)
|
||||||
{
|
{
|
||||||
return EVP_PKEY_CTX_new_from_pkey(OPENSSL_G(libctx), pkey, OPENSSL_G(propq));
|
return EVP_PKEY_CTX_new_from_pkey(PHP_OPENSSL_LIBCTX, pkey, PHP_OPENSSL_PROPQ);
|
||||||
}
|
}
|
||||||
|
|
||||||
EVP_PKEY *php_openssl_pkey_init_rsa(zval *data)
|
EVP_PKEY *php_openssl_pkey_init_rsa(zval *data)
|
||||||
|
@ -299,7 +314,7 @@ EVP_PKEY *php_openssl_pkey_init_ec(zval *data, bool *is_private) {
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!(group = EC_GROUP_new_by_curve_name_ex(OPENSSL_G(libctx), OPENSSL_G(propq), nid))) {
|
if (!(group = EC_GROUP_new_by_curve_name_ex(PHP_OPENSSL_LIBCTX, PHP_OPENSSL_PROPQ, nid))) {
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -698,7 +713,7 @@ zend_string *php_openssl_dh_compute_key(EVP_PKEY *pkey, char *pub_str, size_t pu
|
||||||
|
|
||||||
const EVP_MD *php_openssl_get_evp_md_by_name(const char *name)
|
const EVP_MD *php_openssl_get_evp_md_by_name(const char *name)
|
||||||
{
|
{
|
||||||
return EVP_MD_fetch(OPENSSL_G(libctx), name, OPENSSL_G(propq));
|
return EVP_MD_fetch(PHP_OPENSSL_LIBCTX, name, PHP_OPENSSL_PROPQ);
|
||||||
}
|
}
|
||||||
|
|
||||||
static const char *php_openssl_digest_names[] = {
|
static const char *php_openssl_digest_names[] = {
|
||||||
|
@ -754,7 +769,7 @@ static const char *php_openssl_cipher_names[] = {
|
||||||
|
|
||||||
const EVP_CIPHER *php_openssl_get_evp_cipher_by_name(const char *name)
|
const EVP_CIPHER *php_openssl_get_evp_cipher_by_name(const char *name)
|
||||||
{
|
{
|
||||||
return EVP_CIPHER_fetch(OPENSSL_G(libctx), name, OPENSSL_G(propq));
|
return EVP_CIPHER_fetch(PHP_OPENSSL_LIBCTX, name, PHP_OPENSSL_PROPQ);
|
||||||
}
|
}
|
||||||
|
|
||||||
const EVP_CIPHER *php_openssl_get_evp_cipher_from_algo(zend_long algo)
|
const EVP_CIPHER *php_openssl_get_evp_cipher_from_algo(zend_long algo)
|
||||||
|
@ -805,7 +820,7 @@ static int php_openssl_compare_func(Bucket *a, Bucket *b)
|
||||||
void php_openssl_get_cipher_methods(zval *return_value, bool aliases)
|
void php_openssl_get_cipher_methods(zval *return_value, bool aliases)
|
||||||
{
|
{
|
||||||
array_init(return_value);
|
array_init(return_value);
|
||||||
EVP_CIPHER_do_all_provided(OPENSSL_G(libctx),
|
EVP_CIPHER_do_all_provided(PHP_OPENSSL_LIBCTX,
|
||||||
aliases ? php_openssl_add_cipher_or_alias : php_openssl_add_cipher,
|
aliases ? php_openssl_add_cipher_or_alias : php_openssl_add_cipher,
|
||||||
return_value);
|
return_value);
|
||||||
zend_hash_sort(Z_ARRVAL_P(return_value), php_openssl_compare_func, 1);
|
zend_hash_sort(Z_ARRVAL_P(return_value), php_openssl_compare_func, 1);
|
||||||
|
|
|
@ -70,15 +70,24 @@ struct php_openssl_errors {
|
||||||
int bottom;
|
int bottom;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct php_openssl_libctx {
|
||||||
|
#if PHP_OPENSSL_API_VERSION >= 0x30000
|
||||||
|
OSSL_LIB_CTX *libctx;
|
||||||
|
OSSL_LIB_CTX *default_libctx;
|
||||||
|
OSSL_LIB_CTX *custom_libctx;
|
||||||
|
#endif
|
||||||
|
char *propq;
|
||||||
|
};
|
||||||
|
|
||||||
ZEND_BEGIN_MODULE_GLOBALS(openssl)
|
ZEND_BEGIN_MODULE_GLOBALS(openssl)
|
||||||
struct php_openssl_errors *errors;
|
struct php_openssl_errors *errors;
|
||||||
struct php_openssl_errors *errors_mark;
|
struct php_openssl_errors *errors_mark;
|
||||||
#if PHP_OPENSSL_API_VERSION >= 0x30000
|
struct php_openssl_libctx ctx;
|
||||||
OSSL_LIB_CTX *libctx;
|
|
||||||
char *propq;
|
|
||||||
#endif
|
|
||||||
ZEND_END_MODULE_GLOBALS(openssl)
|
ZEND_END_MODULE_GLOBALS(openssl)
|
||||||
|
|
||||||
|
#define PHP_OPENSSL_LIBCTX OPENSSL_G(ctx).libctx
|
||||||
|
#define PHP_OPENSSL_PROPQ OPENSSL_G(ctx).propq
|
||||||
|
|
||||||
#define OPENSSL_G(v) ZEND_MODULE_GLOBALS_ACCESSOR(openssl, v)
|
#define OPENSSL_G(v) ZEND_MODULE_GLOBALS_ACCESSOR(openssl, v)
|
||||||
|
|
||||||
#if defined(ZTS) && defined(COMPILE_DL_OPENSSL)
|
#if defined(ZTS) && defined(COMPILE_DL_OPENSSL)
|
||||||
|
|
|
@ -237,10 +237,8 @@ void php_openssl_backend_init_common(void);
|
||||||
void php_openssl_backend_gshutdown(void);
|
void php_openssl_backend_gshutdown(void);
|
||||||
void php_openssl_backend_shutdown(void);
|
void php_openssl_backend_shutdown(void);
|
||||||
|
|
||||||
#if PHP_OPENSSL_API_VERSION >= 0x30000
|
void php_openssl_backend_init_libctx(struct php_openssl_libctx *ctx);
|
||||||
void php_openssl_backend_init_libctx(OSSL_LIB_CTX **plibctx, char **ppropq);
|
void php_openssl_backend_destroy_libctx(struct php_openssl_libctx *ctx);
|
||||||
void php_openssl_backend_destroy_libctx(OSSL_LIB_CTX *libctx, char *propq);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
const char *php_openssl_get_conf_filename(void);
|
const char *php_openssl_get_conf_filename(void);
|
||||||
|
|
||||||
|
|
|
@ -1863,6 +1863,14 @@ ldap.max_links = -1
|
||||||
; SSL stream context option.
|
; SSL stream context option.
|
||||||
;openssl.capath=
|
;openssl.capath=
|
||||||
|
|
||||||
|
; The libctx is an OpenSSL library context. OpenSSL defines a default library
|
||||||
|
; context, but PHP OpenSSL also defines its own library context to avoid
|
||||||
|
; interference with other libraries using OpenSSL and to provide an independent
|
||||||
|
; context for each thread in ZTS. Possible values:
|
||||||
|
; "custom" - use a custom library context (default)
|
||||||
|
; "default" - use the default OpenSSL library context
|
||||||
|
;openssl.libctx=custom
|
||||||
|
|
||||||
[ffi]
|
[ffi]
|
||||||
; FFI API restriction. Possible values:
|
; FFI API restriction. Possible values:
|
||||||
; "preload" - enabled in CLI scripts and preloaded files (default)
|
; "preload" - enabled in CLI scripts and preloaded files (default)
|
||||||
|
|
|
@ -1865,6 +1865,14 @@ ldap.max_links = -1
|
||||||
; SSL stream context option.
|
; SSL stream context option.
|
||||||
;openssl.capath=
|
;openssl.capath=
|
||||||
|
|
||||||
|
; The libctx is an OpenSSL library context. OpenSSL defines a default library
|
||||||
|
; context, but PHP OpenSSL also defines its own library context to avoid
|
||||||
|
; interference with other libraries using OpenSSL and to provide an independent
|
||||||
|
; context for each thread in ZTS. Possible values:
|
||||||
|
; "custom" - use a custom library context (default)
|
||||||
|
; "default" - use the default OpenSSL library context
|
||||||
|
;openssl.libctx=custom
|
||||||
|
|
||||||
[ffi]
|
[ffi]
|
||||||
; FFI API restriction. Possible values:
|
; FFI API restriction. Possible values:
|
||||||
; "preload" - enabled in CLI scripts and preloaded files (default)
|
; "preload" - enabled in CLI scripts and preloaded files (default)
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue