From 80ea35b036d0c064d4cdd1da3f153da2ac00440e Mon Sep 17 00:00:00 2001 From: Alexandr Kondratev Date: Sun, 14 Apr 2024 17:02:24 +0300 Subject: [PATCH 1/2] feat crypto: support wolfssl library closes #498 This PR provides minimal changes which replaces internal usage of openssl. It does not checked for other libraries used in userver. Some openssl features does not implemented by wolfssl itself. (has found some typos during investigation, see https://github.com/wolfSSL/wolfssl/pull/7423). BTW, wolfssl v5.7.0-stable requires few small patches which also included into the PR. Finally, "short path" to support wolfssl is not available, because of the lib does not implements some of used functions. It also does not provide `ENGINE_*`, but have not been tried with wolfengine lib yet. PR is building with commands: ``` mkdir -p build_debug cd build_debug cmake \ -Wdev \ -DCMAKE_CXX_COMPILER=clang++-17 \ -DUSERVER_FEATURE_WOLFSSL=ON \ -DUSERVER_DOWNLOAD_PACKAGE_WOLFSSL=ON \ -DUSERVER_FEATURE_GRPC=OFF \ -DUSERVER_FEATURE_POSTGRESQL=OFF \ -DUSERVER_FEATURE_MYSQL=OFF \ -DUSERVER_FEATURE_STACKTRACE=OFF \ -DUSERVER_FEATURE_CLICKHOUSE=OFF \ -DUSERVER_USE_LD=lld \ .. ``` Patch might be re-applied with command: ```(test -d build_debug/_deps/wolfssl-src && cd build_debug/_deps/wolfssl-src && git checkout -- .)``` Final error will be attached in comments to this PR. Help needed. --- .gitignore | 1 - CMakeLists.txt | 8 + cmake/SetupWolfSSL.cmake | 45 +++++ cmake/install/userver-universal-config.cmake | 6 +- cmake/patches/wolfssl-0001-build-fixes.patch | 189 ++++++++++++++++++ core/CMakeLists.txt | 21 +- external-deps/WolfSSL.yaml | 39 ++++ universal/CMakeLists.txt | 21 +- .../include/userver/crypto/basic_types.hpp | 9 + universal/src/crypto/certificate.cpp | 13 ++ universal/src/crypto/helpers.cpp | 24 +++ universal/src/crypto/helpers.hpp | 5 + universal/src/crypto/openssl.cpp | 13 ++ universal/src/crypto/private_key.cpp | 15 ++ universal/src/crypto/public_key.cpp | 16 ++ universal/src/crypto/signers.cpp | 9 + universal/src/crypto/verifiers.cpp | 11 + 17 files changed, 437 insertions(+), 8 deletions(-) create mode 100644 cmake/SetupWolfSSL.cmake create mode 100644 cmake/patches/wolfssl-0001-build-fixes.patch create mode 100644 external-deps/WolfSSL.yaml diff --git a/.gitignore b/.gitignore index 15eb9ed9d223..82d90bab2905 100644 --- a/.gitignore +++ b/.gitignore @@ -13,7 +13,6 @@ /cmake-build-*/ /cmake/cmake_generated/ /docs/ -/third_party/ CMakeLists.txt.user compile_commands.json tags diff --git a/CMakeLists.txt b/CMakeLists.txt index 908ef264c5ba..028d86db41e9 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -99,6 +99,7 @@ else() set(JEMALLOC_DEFAULT ON) endif() option(USERVER_FEATURE_JEMALLOC "Enable linkage with jemalloc memory allocator" ${JEMALLOC_DEFAULT}) +option(USERVER_FEATURE_WOLFSSL "Enable usage of WolfSSL library instead of OpenSSL" OFF) option(USERVER_DISABLE_PHDR_CACHE "Disable caching of dl_phdr_info items, which interferes with dlopen" OFF) @@ -172,6 +173,13 @@ option(USERVER_FEATURE_MYSQL "Provide asynchronous driver for MariaDB/MySQL" "${ option(USERVER_FEATURE_UBOOST_CORO "Use vendored boost context instead of a system one" ON) +if (USERVER_FEATURE_WOLFSSL) + include(cmake/SetupWolfSSL.cmake) + add_compile_definitions("OPENSSL_EXTRA=1") + add_compile_definitions("OPENSSL_ALL=1") + add_compile_definitions("USERVER_FEATURE_WOLFSSL=1") +endif() + if (USERVER_FEATURE_GRPC) include(cmake/SetupProtobuf.cmake) endif() diff --git a/cmake/SetupWolfSSL.cmake b/cmake/SetupWolfSSL.cmake new file mode 100644 index 000000000000..447dfc6f27c0 --- /dev/null +++ b/cmake/SetupWolfSSL.cmake @@ -0,0 +1,45 @@ +if (TARGET wolfssl) + return() +endif() + +option( + USERVER_DOWNLOAD_PACKAGE_WOLFSSL + "Download and setup WolfSSL if no WolfSSL of matching version was found" + ${USERVER_DOWNLOAD_PACKAGES} +) + +if (NOT USERVER_FORCE_DOWNLOAD_PACKAGES) + if (USERVER_DOWNLOAD_PACKAGE_WOLFSSL) + find_package(wolfssl QUIET) + else() + find_package(wolfssl REQUIRED) + endif() + + if (wolfssl_FOUND) + return() + endif() +endif() + +include(DownloadUsingCPM) + +find_package(Patch REQUIRED) +message(STATUS "${wolfssl_parent_directory}") +message(STATUS "${CMAKE_CURRENT_LIST_DIR}") +CPMAddPackage( + NAME WolfSSL + VERSION 5.7.0 + GITHUB_REPOSITORY wolfSSL/wolfssl + GIT_TAG v5.7.0-stable + PATCH_COMMAND + "${Patch_EXECUTABLE}" --merge -p1 < "${CMAKE_CURRENT_LIST_DIR}/patches/wolfssl-0001-build-fixes.patch" + OPTIONS + "BUILD_SHARED_LIBS OFF" + "WOLFSSL_BUILD_TESTING OFF" + "CMAKE_C_FLAGS -Wall -Wextra -O2 -DOPENSSL_ALL -DOPENSSL_EXTRA" +) + +#add_library(WolfSSL INTERFACE) +#target_link_libraries(WolfSSL INTERFACE wolfssl) +#get_filename_component(wolfssl_parent_directory "${WolfSSL_SOURCE_DIR}" DIRECTORY) +#target_include_directories(WolfSSL INTERFACE "${wolfssl_parent_directory}/wolfssl") +#target_compile_options(WolfSSL PRIVATE "-O2") diff --git a/cmake/install/userver-universal-config.cmake b/cmake/install/userver-universal-config.cmake index 1126f9d93222..c5dc35fbc908 100644 --- a/cmake/install/userver-universal-config.cmake +++ b/cmake/install/userver-universal-config.cmake @@ -14,7 +14,11 @@ find_package(Boost REQUIRED COMPONENTS stacktrace_backtrace ) find_package(Iconv REQUIRED) -find_package(OpenSSL REQUIRED) +if(USERVER_FEATURE_WOLFSSL) + find_package(WolfSSL REQUIRED) +else() + find_package(OpenSSL REQUIRED) +endif() find_package(fmt "8.1.1" REQUIRED) list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_LIST_DIR}/..") diff --git a/cmake/patches/wolfssl-0001-build-fixes.patch b/cmake/patches/wolfssl-0001-build-fixes.patch new file mode 100644 index 000000000000..932a6beddae4 --- /dev/null +++ b/cmake/patches/wolfssl-0001-build-fixes.patch @@ -0,0 +1,189 @@ +diff --git a/src/bio.c b/src/bio.c +index 2dab43e..d26a03b 100644 +--- a/src/bio.c ++++ b/src/bio.c +@@ -2336,7 +2336,7 @@ int wolfSSL_BIO_flush(WOLFSSL_BIO* bio) + + if (b->ptr != NULL) { + int rc = wolfSSL_shutdown((WOLFSSL*)b->ptr); +- if (rc == SSL_SHUTDOWN_NOT_DONE) { ++ if (rc == WOLFSSL_SHUTDOWN_NOT_DONE) { + /* In this case, call again to give us a chance to read the + * close notify alert from the other end. */ + wolfSSL_shutdown((WOLFSSL*)b->ptr); +diff --git a/src/pk.c b/src/pk.c +index d7d32dd..c91aaa8 100644 +--- a/src/pk.c ++++ b/src/pk.c +@@ -25,7 +25,7 @@ + + #include + +- #include ++#include + #ifndef WC_NO_RNG + #include + #endif +@@ -45,10 +45,12 @@ + #endif + #else + +-#ifndef NO_RSA ++#ifdef OPENSSL_EXTRA + #include + #endif + ++#ifndef NO_RSA ++ + #if defined(OPENSSL_EXTRA) && !defined(NO_BIO) && defined(WOLFSSL_KEY_GEN) && \ + (defined(HAVE_ECC) || (!defined(NO_DSA) && !defined(HAVE_SELFTEST))) + /* Forward declaration for wolfSSL_PEM_write_bio_DSA_PUBKEY. +@@ -57,6 +59,8 @@ + static int pem_write_bio_pubkey(WOLFSSL_BIO* bio, WOLFSSL_EVP_PKEY* key); + #endif + ++#endif ++ + /******************************************************************************* + * COMMON FUNCTIONS + ******************************************************************************/ +@@ -137,7 +141,9 @@ static int pem_mem_to_der(const char* pem, int pemSz, wc_pem_password_cb* cb, + + return ret; + } +-#endif ++#endif /* ++ (!NO_FILESYSTEM && (OPENSSL_EXTRA || OPENSSL_ALL)) || (!NO_BIO && OPENSSL_EXTRA) ++*/ + + #if !defined(NO_RSA) || !defined(WOLFCRYPT_ONLY) + #ifndef NO_BIO +@@ -217,7 +223,7 @@ static int pem_read_file_key(XFILE fp, wc_pem_password_cb* cb, void* pass, + return ret; + } + #endif /* !NO_FILESYSTEM */ +-#endif ++#endif /* !NO_RSA || !WOLFCRYPT_ONLY */ + + #if defined(OPENSSL_EXTRA) && ((!defined(NO_RSA) && defined(WOLFSSL_KEY_GEN)) \ + || !defined(WOLFCRYPT_ONLY)) +@@ -294,7 +300,7 @@ static int der_write_to_bio_as_pem(const unsigned char* der, int derSz, + XFREE(pem, bio->heap, DYNAMIC_TYPE_TMP_BUFFER); + return ret; + } +-#endif ++#endif /* !NO_BIO */ + #endif + + #if (!defined(NO_RSA) && defined(WOLFSSL_KEY_GEN)) || \ +diff --git a/src/ssl.c b/src/ssl.c +index ea66e42..8bede43 100644 +--- a/src/ssl.c ++++ b/src/ssl.c +@@ -27200,7 +27200,7 @@ int wolfSSL_CTX_use_PrivateKey(WOLFSSL_CTX *ctx, WOLFSSL_EVP_PKEY *pkey) + /* ptr for WOLFSSL_EVP_PKEY struct is expected to be DER format */ + return wolfSSL_CTX_use_PrivateKey_buffer(ctx, + (const unsigned char*)pkey->pkey.ptr, +- pkey->pkey_sz, SSL_FILETYPE_ASN1); ++ pkey->pkey_sz, WOLFSSL_FILETYPE_ASN1); + } + + WOLFSSL_MSG("wolfSSL private key not set"); +@@ -27861,7 +27861,7 @@ int wolfSSL_CTX_use_RSAPrivateKey(WOLFSSL_CTX* ctx, WOLFSSL_RSA* rsa) + return WOLFSSL_FAILURE; + } + ret = wolfSSL_CTX_use_PrivateKey_buffer(ctx, (const unsigned char*)maxDerBuf, +- derSize, SSL_FILETYPE_ASN1); ++ derSize, WOLFSSL_FILETYPE_ASN1); + if (ret != WOLFSSL_SUCCESS) { + WOLFSSL_MSG("wolfSSL_CTX_USE_PrivateKey_buffer() failure"); + XFREE(maxDerBuf, NULL, DYNAMIC_TYPE_TMP_BUFFER); +diff --git a/src/x509.c b/src/x509.c +index eefa69c..4d5244c 100644 +--- a/src/x509.c ++++ b/src/x509.c +@@ -37,6 +37,7 @@ + #ifndef NO_CERTS + + #if defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL) ++ #include + #include + #endif + +@@ -11549,7 +11550,7 @@ err: + #ifndef NO_FILESYSTEM + WOLF_STACK_OF(WOLFSSL_X509_INFO)* wolfSSL_PEM_X509_INFO_read( + XFILE fp, WOLF_STACK_OF(WOLFSSL_X509_INFO)* sk, +- pem_password_cb* cb, void* u) ++ wc_pem_password_cb* cb, void* u) + { + WOLFSSL_BIO* fileBio = wolfSSL_BIO_new_fp(fp, BIO_NOCLOSE); + WOLF_STACK_OF(WOLFSSL_X509_INFO)* ret = NULL; +diff --git a/wolfcrypt/src/evp.c b/wolfcrypt/src/evp.c +index a365ff6..44dc74c 100644 +--- a/wolfcrypt/src/evp.c ++++ b/wolfcrypt/src/evp.c +@@ -44,6 +44,7 @@ + + #include + #include ++#include + #include + #include + +@@ -8791,11 +8792,11 @@ WOLFSSL_DSA* wolfSSL_EVP_PKEY_get1_DSA(WOLFSSL_EVP_PKEY* key) + + if (key->type == EVP_PKEY_DSA) { + if (wolfSSL_DSA_LoadDer(local, (const unsigned char*)key->pkey.ptr, +- key->pkey_sz) != SSL_SUCCESS) { ++ key->pkey_sz) != WOLFSSL_SUCCESS) { + /* now try public key */ + if (wolfSSL_DSA_LoadDer_ex(local, + (const unsigned char*)key->pkey.ptr, key->pkey_sz, +- WOLFSSL_DSA_LOAD_PUBLIC) != SSL_SUCCESS) { ++ WOLFSSL_DSA_LOAD_PUBLIC) != WOLFSSL_SUCCESS) { + wolfSSL_DSA_free(local); + local = NULL; + } +@@ -8986,7 +8987,7 @@ WOLFSSL_DH* wolfSSL_EVP_PKEY_get1_DH(WOLFSSL_EVP_PKEY* key) + return NULL; + } + if (wolfSSL_DH_LoadDer(local, (const unsigned char*)key->pkey.ptr, +- key->pkey_sz) != SSL_SUCCESS) { ++ key->pkey_sz) != WOLFSSL_SUCCESS) { + wolfSSL_DH_free(local); + WOLFSSL_MSG("Error wolfSSL_DH_LoadDer"); + local = NULL; +diff --git a/wolfssl/openssl/cms.h b/wolfssl/openssl/cms.h +index 5355c61..9e4585b 100644 +--- a/wolfssl/openssl/cms.h ++++ b/wolfssl/openssl/cms.h +@@ -22,5 +22,4 @@ + #ifndef WOLFSSL_CMS_H_ + #define WOLFSSL_CMS_H_ + +- + #endif /* WOLFSSL_CMS_H_ */ +diff --git a/wolfssl/ssl.h b/wolfssl/ssl.h +index 804ec44..0e28177 100644 +--- a/wolfssl/ssl.h ++++ b/wolfssl/ssl.h +@@ -40,6 +40,9 @@ + + /* For the types */ + #include ++#ifdef OPENSSL_EXTRA ++#include ++#endif + + #ifdef HAVE_WOLF_EVENT + #include +@@ -4481,7 +4484,7 @@ WOLFSSL_API WOLFSSL_X509 *wolfSSL_PEM_read_bio_X509_AUX + #ifndef NO_FILESYSTEM + WOLFSSL_API WOLF_STACK_OF(WOLFSSL_X509_INFO)* wolfSSL_PEM_X509_INFO_read( + XFILE fp, WOLF_STACK_OF(WOLFSSL_X509_INFO)* sk, +- pem_password_cb* cb, void* u); ++ wc_pem_password_cb* cb, void* u); + #endif + WOLFSSL_API WOLF_STACK_OF(WOLFSSL_X509_INFO)* wolfSSL_PEM_X509_INFO_read_bio( + WOLFSSL_BIO* bio, WOLF_STACK_OF(WOLFSSL_X509_INFO)* sk, diff --git a/core/CMakeLists.txt b/core/CMakeLists.txt index 66309fe0d045..f1c7fd6af5d0 100644 --- a/core/CMakeLists.txt +++ b/core/CMakeLists.txt @@ -58,7 +58,11 @@ find_package(Boost REQUIRED COMPONENTS find_package_required(ZLIB "zlib1g-dev") find_package(Iconv REQUIRED) -find_package_required(OpenSSL "libssl-dev") +if (USERVER_FEATURE_WOLFSSL) + find_package_required(WolfSSL "wolfssl-dev") +else() + find_package_required(OpenSSL "libssl-dev") +endif() if (USERVER_CONAN) find_package(c-ares REQUIRED) @@ -108,11 +112,22 @@ target_link_libraries(${PROJECT_NAME} Boost::iostreams Boost::regex Iconv::Iconv - OpenSSL::Crypto - OpenSSL::SSL ZLIB::ZLIB ) +if (USERVER_FEATURE_WOLFSSL) + target_link_libraries(${PROJECT_NAME} + PRIVATE + wolfssl + ) +else() + target_link_libraries(${PROJECT_NAME} + PRIVATE + OpenSSL::Crypto + OpenSSL::SSL + ) +endif() + add_subdirectory(${USERVER_THIRD_PARTY_DIRS}/llhttp llhttp) add_subdirectory(${USERVER_THIRD_PARTY_DIRS}/http-parser http-parser) diff --git a/external-deps/WolfSSL.yaml b/external-deps/WolfSSL.yaml new file mode 100644 index 000000000000..8d3615f40bc5 --- /dev/null +++ b/external-deps/WolfSSL.yaml @@ -0,0 +1,39 @@ +common-name: WolfSSL +partials: + - name: Crypto + package-name: WolfSSL + + debian-names: + - wolfssl-dev + formula-name: wolfssl + rpm-names: + - wolfssl-devel + pacman-names: + - wolfssl + pkg-config-names: + - wolfssl + + libraries: + enabled: false + + includes: + enabled: false + - name: SSL + package-name: WolfSSL + + debian-names: + - wolfssl-dev + formula-name: wolfssl + rpm-names: + - wolfssl-devel + pacman-names: + - wolfssl + pkg-config-names: + - wolfssl + + libraries: + enabled: false + + includes: + enabled: false + diff --git a/universal/CMakeLists.txt b/universal/CMakeLists.txt index bbd250c49cde..024115d46d21 100644 --- a/universal/CMakeLists.txt +++ b/universal/CMakeLists.txt @@ -53,7 +53,11 @@ if (CMAKE_CXX_COMPILER_ID MATCHES "Clang") endif() find_package(Iconv REQUIRED) -find_package_required(OpenSSL "libssl-dev") +if (USERVER_FEATURE_WOLFSSL) + find_package_required(WolfSSL "wolfssl") +else() + find_package_required(OpenSSL "libssl-dev") +endif() if (USERVER_CONAN) find_package(cryptopp REQUIRED) @@ -232,10 +236,21 @@ target_link_libraries(${PROJECT_NAME} Boost::filesystem Boost::program_options Boost::regex - OpenSSL::Crypto - OpenSSL::SSL ) +if (USERVER_FEATURE_WOLFSSL) + target_link_libraries(${PROJECT_NAME} + PRIVATE + wolfssl + ) +else() + target_link_libraries(${PROJECT_NAME} + PRIVATE + OpenSSL::Crypto + OpenSSL::SSL + ) +endif() + if (USERVER_CONAN) target_link_libraries(${PROJECT_NAME} PUBLIC diff --git a/universal/include/userver/crypto/basic_types.hpp b/universal/include/userver/crypto/basic_types.hpp index 17f1fffc01d8..83f37f4a9044 100644 --- a/universal/include/userver/crypto/basic_types.hpp +++ b/universal/include/userver/crypto/basic_types.hpp @@ -7,18 +7,27 @@ #include +#ifdef USERVER_FEATURE_WOLFSSL +#include +#else /// @cond struct evp_pkey_st; struct x509_st; /// @endcond +#endif USERVER_NAMESPACE_BEGIN namespace crypto { /// @cond +#ifdef USERVER_FEATURE_WOLFSSL +using EVP_PKEY = WOLFSSL_EVP_PKEY; +using X509 = WOLFSSL_X509; +#else using EVP_PKEY = struct evp_pkey_st; using X509 = struct x509_st; +#endif /// @endcond /// SHA digest size in bits diff --git a/universal/src/crypto/certificate.cpp b/universal/src/crypto/certificate.cpp index 9461eab2d02b..189428b6e871 100644 --- a/universal/src/crypto/certificate.cpp +++ b/universal/src/crypto/certificate.cpp @@ -1,7 +1,12 @@ #include +#ifdef USERVER_FEATURE_WOLFSSL +#include +#include +#else #include #include +#endif #include // for boost::starts_with @@ -31,6 +36,13 @@ std::optional Certificate::GetPemString() const { std::string result; result.resize(BIO_pending(membio.get())); +#ifdef USERVER_FEATURE_WOLFSSL +#warning "BIO_read_ex does not supported by wolfSSL" + if (1 != BIO_read(membio.get(), result.data(), result.size())) { + throw SerializationError( + FormatSslError("Error transferring PEM to string")); + } +#else size_t readbytes = 0; if (1 != BIO_read_ex(membio.get(), result.data(), result.size(), &readbytes)) { @@ -40,6 +52,7 @@ std::optional Certificate::GetPemString() const { if (readbytes != result.size()) { throw SerializationError("Error transferring PEM to string"); } +#endif return result; } diff --git a/universal/src/crypto/helpers.cpp b/universal/src/crypto/helpers.cpp index c28f94025f7d..bd72fe361db1 100644 --- a/universal/src/crypto/helpers.cpp +++ b/universal/src/crypto/helpers.cpp @@ -3,6 +3,16 @@ #include #include +#ifdef USERVER_FEATURE_WOLFSSL +#include +#include +#include +#include +#include +#include +#include +#include +#else #include #include #include @@ -10,6 +20,7 @@ #include #include #include +#endif #include #include @@ -186,9 +197,22 @@ std::unique_ptr<::BIO, decltype(&::BIO_free_all)> MakeBioMemoryBuffer() { return {::BIO_new(BIO_s_mem()), &::BIO_free_all}; } +#ifndef USERVER_FEATURE_WOLFSSL std::unique_ptr<::BIO, decltype(&::BIO_free_all)> MakeBioSecureMemoryBuffer() { return {::BIO_new(BIO_s_secmem()), &::BIO_free_all}; } +#endif + +#ifdef USERVER_FEATURE_WOLFSSL +#ifndef EVP_PKEY_CTX_set_rsa_pss_saltlen +#warning "EVP_PKEY_CTX_set_rsa_pss_saltlen() is undefined by wolfSSL" +#define EVP_PKEY_CTX_set_rsa_pss_saltlen(...) 0 +#endif +#ifndef EVP_PKEY_CTX_set_rsa_mgf1_md +#warning "EVP_PKEY_CTX_set_rsa_mgf1_md() is undefined by wolfSSL" +#define EVP_PKEY_CTX_set_rsa_mgf1_md(ctx, sha_md) ((sha_md), 0) +#endif +#endif void SetupJwaRsaPssPadding(EVP_PKEY_CTX* pkey_ctx, DigestSize bits) { if (EVP_PKEY_CTX_set_rsa_padding(pkey_ctx, RSA_PKCS1_PSS_PADDING) <= 0) { diff --git a/universal/src/crypto/helpers.hpp b/universal/src/crypto/helpers.hpp index ac4bb9760c81..a37fe27393bd 100644 --- a/universal/src/crypto/helpers.hpp +++ b/universal/src/crypto/helpers.hpp @@ -4,8 +4,13 @@ #include #include +#ifdef USERVER_FEATURE_WOLFSSL +#include +#include +#else #include #include +#endif #include #include diff --git a/universal/src/crypto/openssl.cpp b/universal/src/crypto/openssl.cpp index 1abcc6ef77b9..c1929f668a86 100644 --- a/universal/src/crypto/openssl.cpp +++ b/universal/src/crypto/openssl.cpp @@ -5,6 +5,12 @@ #include #include +#ifdef USERVER_FEATURE_WOLFSSL +#include +#include +#include +#include +#else #if OPENSSL_VERSION_NUMBER < 0x010100000L #include #endif @@ -13,6 +19,7 @@ #include #include #include +#endif USERVER_NAMESPACE_BEGIN @@ -20,6 +27,7 @@ namespace crypto::impl { namespace { // OpenSSL >= 1.1 has builtin threading support +#ifndef USERVER_FEATURE_WOLFSSL #if OPENSSL_VERSION_NUMBER < 0x010100000L void ThreadIdCallback(CRYPTO_THREADID* thread_id) noexcept { // default OpenSSL implementation @@ -49,6 +57,7 @@ void LockingCallback(int mode, int n, const char*, int) noexcept { mutexes[n].unlock(); } #endif +#endif // !USERVER_FEATURE_WOLFSSL void TrySetDefaultEngineRdrand() noexcept { ENGINE_load_rdrand(); @@ -67,6 +76,9 @@ void TrySetDefaultEngineRdrand() noexcept { } // namespace Openssl::Openssl() noexcept { +#ifdef USERVER_FEATURE_WOLFSSL + wolfSSL_Init(); +#else // USERVER_FEATURE_WOLFSSL #if OPENSSL_VERSION_NUMBER >= 0x010100000L OPENSSL_init_ssl(OPENSSL_INIT_LOAD_CONFIG, nullptr); #else @@ -78,6 +90,7 @@ Openssl::Openssl() noexcept { // never used when THREADID is set, but is often checked by libs CRYPTO_set_id_callback(&LegacyIdCallback); #endif +#endif // USERVER_FEATURE_WOLFSSL TrySetDefaultEngineRdrand(); } diff --git a/universal/src/crypto/private_key.cpp b/universal/src/crypto/private_key.cpp index 1ae122c0602f..0d0b1b99a488 100644 --- a/universal/src/crypto/private_key.cpp +++ b/universal/src/crypto/private_key.cpp @@ -1,8 +1,15 @@ #include +#ifdef USERVER_FEATURE_WOLFSSL +#include +#include +#include +#include +#else #include #include #include +#endif #include #include @@ -41,6 +48,13 @@ std::optional GetPemStringImpl(EVP_PKEY* key, std::string result; result.resize(BIO_pending(membio.get())); +#ifdef USERVER_FEATURE_WOLFSSL +#warning "BIO_read_ex does not supported by wolfSSL" + if (1 != BIO_read(membio.get(), result.data(), result.size())) { + throw SerializationError( + FormatSslError("Error transferring PEM to string")); + } +#else size_t readbytes = 0; if (1 != BIO_read_ex(membio.get(), result.data(), result.size(), &readbytes)) { @@ -50,6 +64,7 @@ std::optional GetPemStringImpl(EVP_PKEY* key, if (readbytes != result.size()) { throw SerializationError("Error transferring PEM to string"); } +#endif return result; } diff --git a/universal/src/crypto/public_key.cpp b/universal/src/crypto/public_key.cpp index 11aff9bfd087..d14d372c1de8 100644 --- a/universal/src/crypto/public_key.cpp +++ b/universal/src/crypto/public_key.cpp @@ -4,10 +4,20 @@ #include +#ifdef USERVER_FEATURE_WOLFSSL +#include +// +#include +#include +#include +#include +#include +#else #include #include #include #include +#endif #include // for boost::starts_with #include @@ -81,6 +91,12 @@ int CurveStringToNid(const std::string_view& curve_str) { return it->second; } +#ifdef USERVER_FEATURE_WOLFSSL +#ifndef EC_KEY_set_public_key_affine_coordinates +#warning "EC_KEY_set_public_key_affine_coordinates does not provided by wolfSSL" +#define EC_KEY_set_public_key_affine_coordinates(ec, x, y) (x, y, 1) +#endif +#endif std::unique_ptr LoadEc(int curve_type, Bignum x, Bignum y) { std::unique_ptr ec{ diff --git a/universal/src/crypto/signers.cpp b/universal/src/crypto/signers.cpp index cee1ba5a7a25..bc09f4d152d3 100644 --- a/universal/src/crypto/signers.cpp +++ b/universal/src/crypto/signers.cpp @@ -3,10 +3,19 @@ #include #include +#ifdef USERVER_FEATURE_WOLFSSL +#include +#include +#include +#include +#include +#include +#else #include #include #include #include +#endif #include #include diff --git a/universal/src/crypto/verifiers.cpp b/universal/src/crypto/verifiers.cpp index a587a3869067..b39153f2639e 100644 --- a/universal/src/crypto/verifiers.cpp +++ b/universal/src/crypto/verifiers.cpp @@ -2,6 +2,16 @@ #include +#ifdef USERVER_FEATURE_WOLFSSL +#include +// keep these two headers in this order +#include + +#include +#include +#include +#include +#else #include // keep these two headers in this order #include @@ -9,6 +19,7 @@ #include #include #include +#endif #include #include From 579bf87ddf798533f39a99168a91f79eeed87b61 Mon Sep 17 00:00:00 2001 From: Alexandr Kondratev Date: Sat, 4 May 2024 18:45:03 +0300 Subject: [PATCH 2/2] using BIO_read instead of BIO_read_ex for openssl too --- universal/src/crypto/certificate.cpp | 13 ------------- universal/src/crypto/private_key.cpp | 13 ------------- 2 files changed, 26 deletions(-) diff --git a/universal/src/crypto/certificate.cpp b/universal/src/crypto/certificate.cpp index 189428b6e871..8d45fd4fbbb5 100644 --- a/universal/src/crypto/certificate.cpp +++ b/universal/src/crypto/certificate.cpp @@ -36,23 +36,10 @@ std::optional Certificate::GetPemString() const { std::string result; result.resize(BIO_pending(membio.get())); -#ifdef USERVER_FEATURE_WOLFSSL -#warning "BIO_read_ex does not supported by wolfSSL" if (1 != BIO_read(membio.get(), result.data(), result.size())) { throw SerializationError( FormatSslError("Error transferring PEM to string")); } -#else - size_t readbytes = 0; - if (1 != - BIO_read_ex(membio.get(), result.data(), result.size(), &readbytes)) { - throw SerializationError( - FormatSslError("Error transferring PEM to string")); - } - if (readbytes != result.size()) { - throw SerializationError("Error transferring PEM to string"); - } -#endif return result; } diff --git a/universal/src/crypto/private_key.cpp b/universal/src/crypto/private_key.cpp index 0d0b1b99a488..f3ddf0da27b8 100644 --- a/universal/src/crypto/private_key.cpp +++ b/universal/src/crypto/private_key.cpp @@ -48,23 +48,10 @@ std::optional GetPemStringImpl(EVP_PKEY* key, std::string result; result.resize(BIO_pending(membio.get())); -#ifdef USERVER_FEATURE_WOLFSSL -#warning "BIO_read_ex does not supported by wolfSSL" if (1 != BIO_read(membio.get(), result.data(), result.size())) { throw SerializationError( FormatSslError("Error transferring PEM to string")); } -#else - size_t readbytes = 0; - if (1 != - BIO_read_ex(membio.get(), result.data(), result.size(), &readbytes)) { - throw SerializationError( - FormatSslError("Error transferring PEM to string")); - } - if (readbytes != result.size()) { - throw SerializationError("Error transferring PEM to string"); - } -#endif return result; }