mirror of
https://github.com/php/php-src.git
synced 2025-08-15 13:38:49 +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;
|
||||
}
|
||||
|
||||
/* {{{ 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_ENTRY("openssl.cafile", 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_MINIT_FUNCTION */
|
||||
PHP_MINIT_FUNCTION(openssl)
|
||||
|
@ -438,9 +457,7 @@ PHP_GINIT_FUNCTION(openssl)
|
|||
#endif
|
||||
openssl_globals->errors = NULL;
|
||||
openssl_globals->errors_mark = NULL;
|
||||
#if PHP_OPENSSL_API_VERSION >= 0x30000
|
||||
php_openssl_backend_init_libctx(&openssl_globals->libctx, &openssl_globals->propq);
|
||||
#endif
|
||||
php_openssl_backend_init_libctx(&openssl_globals->ctx);
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
|
@ -453,9 +470,7 @@ PHP_GSHUTDOWN_FUNCTION(openssl)
|
|||
if (openssl_globals->errors_mark) {
|
||||
pefree(openssl_globals->errors_mark, 1);
|
||||
}
|
||||
#if PHP_OPENSSL_API_VERSION >= 0x30000
|
||||
php_openssl_backend_destroy_libctx(openssl_globals->libctx, openssl_globals->propq);
|
||||
#endif
|
||||
php_openssl_backend_destroy_libctx(&openssl_globals->ctx);
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
|
|
|
@ -44,6 +44,16 @@ void php_openssl_backend_shutdown(void)
|
|||
#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)
|
||||
{
|
||||
return EVP_PKEY_CTX_new_id(id, NULL);
|
||||
|
|
|
@ -29,32 +29,47 @@ void php_openssl_backend_shutdown(void)
|
|||
(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
|
||||
* (default context) is probably better. */
|
||||
*plibctx = OSSL_LIB_CTX_new();
|
||||
*ppropq = NULL;
|
||||
ctx->default_libctx = OSSL_LIB_CTX_get0_global_default();
|
||||
ctx->custom_libctx = OSSL_LIB_CTX_new();
|
||||
if (ctx->custom_libctx != 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) {
|
||||
OSSL_LIB_CTX_free(libctx);
|
||||
if (ctx->custom_libctx != NULL) {
|
||||
OSSL_LIB_CTX_free(ctx->custom_libctx);
|
||||
}
|
||||
if (propq != NULL) {
|
||||
free(propq);
|
||||
if (ctx->propq != NULL) {
|
||||
free(ctx->propq);
|
||||
}
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
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)
|
||||
|
@ -299,7 +314,7 @@ EVP_PKEY *php_openssl_pkey_init_ec(zval *data, bool *is_private) {
|
|||
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;
|
||||
}
|
||||
|
||||
|
@ -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)
|
||||
{
|
||||
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[] = {
|
||||
|
@ -754,7 +769,7 @@ static const char *php_openssl_cipher_names[] = {
|
|||
|
||||
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)
|
||||
|
@ -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)
|
||||
{
|
||||
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,
|
||||
return_value);
|
||||
zend_hash_sort(Z_ARRVAL_P(return_value), php_openssl_compare_func, 1);
|
||||
|
|
|
@ -70,15 +70,24 @@ struct php_openssl_errors {
|
|||
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)
|
||||
struct php_openssl_errors *errors;
|
||||
struct php_openssl_errors *errors_mark;
|
||||
#if PHP_OPENSSL_API_VERSION >= 0x30000
|
||||
OSSL_LIB_CTX *libctx;
|
||||
char *propq;
|
||||
#endif
|
||||
struct php_openssl_libctx ctx;
|
||||
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)
|
||||
|
||||
#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_shutdown(void);
|
||||
|
||||
#if PHP_OPENSSL_API_VERSION >= 0x30000
|
||||
void php_openssl_backend_init_libctx(OSSL_LIB_CTX **plibctx, char **ppropq);
|
||||
void php_openssl_backend_destroy_libctx(OSSL_LIB_CTX *libctx, char *propq);
|
||||
#endif
|
||||
void php_openssl_backend_init_libctx(struct php_openssl_libctx *ctx);
|
||||
void php_openssl_backend_destroy_libctx(struct php_openssl_libctx *ctx);
|
||||
|
||||
const char *php_openssl_get_conf_filename(void);
|
||||
|
||||
|
|
|
@ -1863,6 +1863,14 @@ ldap.max_links = -1
|
|||
; SSL stream context option.
|
||||
;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 API restriction. Possible values:
|
||||
; "preload" - enabled in CLI scripts and preloaded files (default)
|
||||
|
|
|
@ -1865,6 +1865,14 @@ ldap.max_links = -1
|
|||
; SSL stream context option.
|
||||
;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 API restriction. Possible values:
|
||||
; "preload" - enabled in CLI scripts and preloaded files (default)
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue