From 12714e31b450eb82f35077cbcbe539bbcc3255c7 Mon Sep 17 00:00:00 2001 From: cailianchun Date: Fri, 16 May 2025 02:12:49 +0000 Subject: [PATCH] rgw, common: OpenSSL provider support Removed `openssl_engine_opts` configuration option. OpenSSL engine configurations in string format are no longer supported. Added `openssl_conf` configuration option for loading specified providers as default providers. Signed-off-by: cailianchun --- PendingReleaseNotes | 7 +++ src/common/openssl_opts_handler.cc | 93 ++++++++---------------------- src/common/openssl_opts_handler.h | 4 +- src/common/options/global.yaml.in | 7 +-- src/rgw/rgw_appmain.cc | 3 - src/rgw/rgw_common.cc | 4 ++ 6 files changed, 39 insertions(+), 79 deletions(-) diff --git a/PendingReleaseNotes b/PendingReleaseNotes index b337a2dcbeb5b..68d7ae2d99ca6 100644 --- a/PendingReleaseNotes +++ b/PendingReleaseNotes @@ -1,3 +1,10 @@ +* RGW: OpenSSL engine support deprecated in favor of provider support. + - Removed `openssl_engine_opts` configuration option. OpenSSL engine configurations in string format are no longer supported. + - Added `openssl_conf` configuration option for loading specified providers as default providers. + Configuration file syntax follows the OpenSSL standard (see https://github.com/openssl/openssl/blob/master/doc/man5/config.pod). + If the default provider is still required when using custom providers, + it must be explicitly loaded in the configuration file or code (see https://github.com/openssl/openssl/blob/master/README-PROVIDERS.md). + >=20.0.0 * RADOS: lead Monitor and stretch mode status are now included in the `ceph status` output. diff --git a/src/common/openssl_opts_handler.cc b/src/common/openssl_opts_handler.cc index 6b16d521ae9ef..c3fdfd54b862f 100644 --- a/src/common/openssl_opts_handler.cc +++ b/src/common/openssl_opts_handler.cc @@ -3,7 +3,7 @@ /* * Ceph - scalable distributed file system * - * Copyright (c) 2020 Huawei Technologies Co., Ltd. + * Copyright (c) 2025 Huawei Technologies Co., Ltd. * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -16,12 +16,6 @@ #include #include -#ifndef OPENSSL_NO_ENGINE -#include -#endif -#include -#include -#include #include "common/debug.h" #include "global/global_context.h" @@ -29,8 +23,8 @@ #include "include/scope_guard.h" using std::string; +using std::string_view; using std::ostream; -using std::vector; // ----------------------------------------------------------------------------- #define dout_context g_ceph_context @@ -43,44 +37,14 @@ static ostream &_prefix(std::ostream *_dout) return *_dout << "OpenSSLOptsHandler: "; } -#ifndef OPENSSL_NO_ENGINE - // ----------------------------------------------------------------------------- -string construct_engine_conf(const string &opts) -{ - const string conf_header = "openssl_conf=openssl_def\n[openssl_def]\n"; - const string engine_header = "engines=engine_section\n[engine_section]\n"; - - string engine_id, engine_statement, engine_detail; - const string id_prefix = "engine"; - const string suffix = "_section"; - const char delimiter = '\n'; - - int index = 1; - vector confs = get_str_vec(opts, ":"); - for (auto conf : confs) { - // Construct engine section statement like "engine1=engine1_section" - engine_id = id_prefix + std::to_string(index++); - engine_statement += engine_id + "=" + engine_id + suffix + delimiter; - - // Adapt to OpenSSL parser - // Replace ',' with '\n' and add section in front - std::replace(conf.begin(), conf.end(), ',', delimiter); - engine_detail += "[" + engine_id + suffix + "]" + delimiter; - engine_detail += conf + delimiter; - } - - return conf_header + engine_header + engine_statement + engine_detail; -} - -string get_openssl_error() +static string get_openssl_error() { BIO *bio = BIO_new(BIO_s_mem()); if (bio == nullptr) { return "failed to create BIO for more error printing"; } - ERR_print_errors(bio); char* buf; size_t len = BIO_get_mem_data(bio, &buf); string ret(buf, len); @@ -88,44 +52,38 @@ string get_openssl_error() return ret; } -void log_error(const string &err) +static void log_error(const string_view &err) { - derr << "Intended OpenSSL engine acceleration failed.\n" - << "set by openssl_engine_opts = " - << g_ceph_context->_conf->openssl_engine_opts + derr << "Intended OpenSSL acceleration failed.\n" + << "set by openssl_conf = " + << g_ceph_context->_conf.get_val("openssl_conf") << "\ndetail error information:\n" << err << dendl; } -void load_module(const string &engine_conf) +static void load_openssl_modules(const string &openssl_conf) { - BIO *mem = BIO_new_mem_buf(engine_conf.c_str(), engine_conf.size()); - if (mem == nullptr) { - log_error("failed to new BIO memory"); + BIO *bio = BIO_new_file(openssl_conf.c_str(), "r"); + if (bio == nullptr) { + log_error("failed to open openssl conf"); return; } - auto sg_mem = make_scope_guard([&mem] { BIO_free(mem); }); + + auto sg_bio = make_scope_guard([bio] { BIO_free(bio); }); CONF *conf = NCONF_new(nullptr); if (conf == nullptr) { log_error("failed to new OpenSSL CONF"); return; } - auto sg_conf = make_scope_guard([&conf] { NCONF_free(conf); }); - if (NCONF_load_bio(conf, mem, nullptr) <= 0) { + auto sg_conf = make_scope_guard([conf] { NCONF_free(conf); }); + + if (NCONF_load_bio(conf, bio, nullptr) <= 0) { log_error("failed to load CONF from BIO:\n" + get_openssl_error()); return; } OPENSSL_load_builtin_modules(); -#pragma GCC diagnostic push -#pragma GCC diagnostic ignored "-Wdeprecated-declarations" - -#pragma clang diagnostic push -#pragma clang diagnostic ignored "-Wdeprecated-declarations" - ENGINE_load_builtin_engines(); -#pragma clang diagnostic pop -#pragma GCC diagnostic pop if (CONF_modules_load( conf, nullptr, @@ -133,24 +91,19 @@ void load_module(const string &engine_conf) log_error("failed to load modules from CONF:\n" + get_openssl_error()); } } -#endif // !OPENSSL_NO_ENGINE -void init_engine() +static void init_openssl() { - string opts = g_ceph_context->_conf->openssl_engine_opts; - if (opts.empty()) { + string openssl_conf = g_ceph_context->_conf.get_val("openssl_conf"); + if (openssl_conf.empty()) { return; } -#ifdef OPENSSL_NO_ENGINE - derr << "OpenSSL is compiled with no engine, but openssl_engine_opts is set" << dendl; -#else - string engine_conf = construct_engine_conf(opts); - load_module(engine_conf); -#endif + + load_openssl_modules(openssl_conf); } -void ceph::crypto::init_openssl_engine_once() +void ceph::crypto::init_openssl_once() { static std::once_flag flag; - std::call_once(flag, init_engine); + std::call_once(flag, init_openssl); } diff --git a/src/common/openssl_opts_handler.h b/src/common/openssl_opts_handler.h index cad9060c9fa70..cab942ea9da08 100644 --- a/src/common/openssl_opts_handler.h +++ b/src/common/openssl_opts_handler.h @@ -3,7 +3,7 @@ /* * Ceph - scalable distributed file system * - * Copyright (c) 2020 Huawei Technologies Co., Ltd. + * Copyright (c) 2025 Huawei Technologies Co., Ltd. * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -17,7 +17,7 @@ namespace ceph { namespace crypto { - void init_openssl_engine_once(); + void init_openssl_once(); } } diff --git a/src/common/options/global.yaml.in b/src/common/options/global.yaml.in index 8b95145badef8..fabe14b00004e 100644 --- a/src/common/options/global.yaml.in +++ b/src/common/options/global.yaml.in @@ -822,14 +822,13 @@ options: desc: Crypto accelerator library to use default: crypto_isal with_legacy: true -- name: openssl_engine_opts +- name: openssl_conf type: str level: advanced - desc: Use engine for specific openssl algorithm - long_desc: 'Pass opts in this way: engine_id=engine1,dynamic_path=/some/path/engine1.so,default_algorithms=DIGESTS:engine_id=engine2,dynamic_path=/some/path/engine2.so,default_algorithms=CIPHERS,other_ctrl=other_value' + desc: Use openssl_conf for specific openssl algorithm + long_desc: 'Pass opts in this way: openssl_conf=/path/to/openssl.conf' flags: - startup - with_legacy: true - name: mempool_debug type: bool level: dev diff --git a/src/rgw/rgw_appmain.cc b/src/rgw/rgw_appmain.cc index d3f616d252422..049352878433a 100644 --- a/src/rgw/rgw_appmain.cc +++ b/src/rgw/rgw_appmain.cc @@ -20,7 +20,6 @@ #include "common/errno.h" #include "common/Timer.h" #include "common/TracepointProvider.h" -#include "common/openssl_opts_handler.h" #include "common/numa.h" #include "include/compat.h" #include "include/str_list.h" @@ -168,8 +167,6 @@ void rgw::AppMain::init_frontends1(bool nfs) if (!g_conf()->rgw_region.empty() && g_conf()->rgw_zonegroup.empty()) { g_conf().set_val_or_die("rgw_zonegroup", g_conf()->rgw_region.c_str()); } - - ceph::crypto::init_openssl_engine_once(); } /* init_frontends1 */ void rgw::AppMain::init_numa() diff --git a/src/rgw/rgw_common.cc b/src/rgw/rgw_common.cc index d5b8db3f134f0..6303e6e3e9326 100644 --- a/src/rgw/rgw_common.cc +++ b/src/rgw/rgw_common.cc @@ -22,6 +22,7 @@ #include "global/global_init.h" #include "common/ceph_crypto.h" +#include "common/openssl_opts_handler.h" #include "common/armor.h" #include "common/errno.h" #include "common/Clock.h" @@ -3250,6 +3251,9 @@ rgw_global_init(const std::map *defaults, // Load the config from the files, but not the mon global_pre_init(defaults, args, module_type, code_env, flags); + // Init and load specific openssl algorithm + ceph::crypto::init_openssl_once(); + // Get the store backend const auto& config_store = g_conf().get_val("rgw_backend_store"); -- 2.39.5