From dc9b84a779c13aa0b39352ab314908962f474a59 Mon Sep 17 00:00:00 2001 From: Nickolay Olshevsky Date: Mon, 15 Jan 2024 14:13:37 +0200 Subject: [PATCH] Check whether OpenSSL legacy provider is available during the build. --- cmake/Modules/FindOpenSSLFeatures.cmake | 4 ++-- cmake/Modules/findopensslfeatures.c | 29 ++++++++++++++++++++++++- src/lib/CMakeLists.txt | 23 +++++++++++++------- src/lib/config.h.in | 3 ++- src/lib/crypto/backend_version.cpp | 3 +++ 5 files changed, 50 insertions(+), 12 deletions(-) diff --git a/cmake/Modules/FindOpenSSLFeatures.cmake b/cmake/Modules/FindOpenSSLFeatures.cmake index 69677649d0..d5d9d2e5f4 100644 --- a/cmake/Modules/FindOpenSSLFeatures.cmake +++ b/cmake/Modules/FindOpenSSLFeatures.cmake @@ -139,7 +139,7 @@ else(WIN32 AND NOT MINGW) set(FOF "build/findopensslfeatures") endif(WIN32 AND NOT MINGW) -foreach(feature "hashes" "ciphers" "curves" "publickey") +foreach(feature "hashes" "ciphers" "curves" "publickey" "providers") execute_process( COMMAND "${FOF}" "${feature}" WORKING_DIRECTORY "${_fossl_work_dir}" @@ -160,7 +160,7 @@ foreach(feature "hashes" "ciphers" "curves" "publickey") list(APPEND OPENSSL_SUPPORTED_FEATURES ${OPENSSL_SUPPORTED_${feature_up}}) endforeach() -message(STATUS "Fetched OpenSSL features: ${hashes_len} hashes, ${ciphers_len} ciphers, ${curves_len} curves, ${publickey_len} publickey.") +message(STATUS "Fetched OpenSSL features: ${hashes_len} hashes, ${ciphers_len} ciphers, ${curves_len} curves, ${publickey_len} publickey, ${providers_len} providers.") function(OpenSSLHasFeature FEATURE VARIABLE) string(TOUPPER ${FEATURE} _feature_up) diff --git a/cmake/Modules/findopensslfeatures.c b/cmake/Modules/findopensslfeatures.c index 1f2b14eac6..ed7eb8eca1 100644 --- a/cmake/Modules/findopensslfeatures.c +++ b/cmake/Modules/findopensslfeatures.c @@ -4,6 +4,9 @@ #include #include #include +#if OPENSSL_VERSION_NUMBER >= 0x30000000L +#include +#endif int list_curves() @@ -99,11 +102,32 @@ list_publickey() return 0; } +int +list_providers() +{ + printf("default\n"); +#if OPENSSL_VERSION_NUMBER >= 0x30000000L + const char *known_names[] = {"legacy", "fips"}; + for (size_t i = 0; i < sizeof(known_names) / sizeof(known_names[0]); i++) { + OSSL_PROVIDER *prov = OSSL_PROVIDER_load(NULL, known_names[i]); + if (prov) { + printf("%s\n", known_names[i]); + OSSL_PROVIDER_unload(prov); + } + } +#else + /* OpenSSL < 3.0 includes all legacy algorithms in the default provider */ + printf("legacy\n"); +#endif + return 0; +} + int main(int argc, char *argv[]) { if (argc != 2) { - fprintf(stderr, "Usage: opensslfeatures [curves|hashes|ciphers|publickey]\n"); + fprintf(stderr, + "Usage: opensslfeatures [curves|hashes|ciphers|publickey|providers]\n"); return 1; } if (!strcmp(argv[1], "hashes")) { @@ -118,6 +142,9 @@ main(int argc, char *argv[]) if (!strcmp(argv[1], "publickey")) { return list_publickey(); } + if (!strcmp(argv[1], "providers")) { + return list_providers(); + } fprintf(stderr, "Unknown command: %s\n", argv[1]); return 1; } diff --git a/src/lib/CMakeLists.txt b/src/lib/CMakeLists.txt index 8f3ac7c896..6b3189fc52 100755 --- a/src/lib/CMakeLists.txt +++ b/src/lib/CMakeLists.txt @@ -98,7 +98,7 @@ function(backend_has_feature FEATURE RESULT_VARNAME) if (CRYPTO_BACKEND_LOWERCASE STREQUAL "botan") check_cxx_symbol_exists("BOTAN_HAS_${FEATURE}" botan/build.h ${RESULT_VARNAME}) else() - message(STATUS "Looking for OpenSSL feature ${FEATURE}") + message(STATUS "Looking for OpenSSL feature ${FEATURE}") OpenSSLHasFeature(${FEATURE} ${RESULT_VARNAME}) if (${RESULT_VARNAME}) message(STATUS "Looking for OpenSSL feature ${FEATURE} - found") @@ -213,19 +213,26 @@ if(CRYPTO_BACKEND_OPENSSL) RSAENCRYPTION DSAENCRYPTION DHKEYAGREEMENT ID-ECPUBLICKEY X25519 ED25519 ) foreach(feature ${_openssl_required_features}) - message(STATUS "Looking for OpenSSL feature ${feature}") - OpenSSLHasFeature("${feature}" _openssl_has_${feature}) + backend_has_feature("${feature}" _openssl_has_${feature}) if (NOT _openssl_has_${feature}) message(FATAL_ERROR "A required OpenSSL feature is missing: ${feature}") endif() - message(STATUS "Looking for OpenSSL feature ${feature} - found") endforeach() + if (CRYPTO_BACKEND_OPENSSL3) + backend_has_feature("LEGACY" CRYPTO_BACKEND_OPENSSL3_LEGACY) + endif() + resolve_feature_state(ENABLE_BRAINPOOL "BRAINPOOLP256R1;BRAINPOOLP384R1;BRAINPOOLP512R1") - resolve_feature_state(ENABLE_IDEA "IDEA-ECB;IDEA-CBC") - resolve_feature_state(ENABLE_BLOWFISH "BF-ECB") - resolve_feature_state(ENABLE_CAST5 "CAST5-ECB") - resolve_feature_state(ENABLE_RIPEMD160 "RIPEMD160") + # Not all of the OpenSSL installations have legacy crypto provider + resolve_feature_state(ENABLE_IDEA "IDEA-ECB;IDEA-CBC;LEGACY") + resolve_feature_state(ENABLE_BLOWFISH "BF-ECB;LEGACY") + resolve_feature_state(ENABLE_CAST5 "CAST5-ECB;LEGACY") + if("${OPENSSL_VERSION}" VERSION_GREATER_EQUAL "3.0.7") + resolve_feature_state(ENABLE_RIPEMD160 "RIPEMD160") + else() + resolve_feature_state(ENABLE_RIPEMD160 "RIPEMD160;LEGACY") + endif() resolve_feature_state(ENABLE_AEAD "AES-128-OCB;AES-192-OCB;AES-256-OCB") openssl_nope(ENABLE_SM2 "it's on our roadmap, see https://github.com/rnpgp/rnp/issues/1877") #resolve_feature_state(ENABLE_SM2 "SM2;SM3;SM4-ECB") diff --git a/src/lib/config.h.in b/src/lib/config.h.in index 33fe41530e..e51f2cf89f 100644 --- a/src/lib/config.h.in +++ b/src/lib/config.h.in @@ -54,6 +54,7 @@ #cmakedefine CRYPTO_BACKEND_BOTAN3 #cmakedefine CRYPTO_BACKEND_OPENSSL #cmakedefine CRYPTO_BACKEND_OPENSSL3 +#cmakedefine CRYPTO_BACKEND_OPENSSL3_LEGACY #cmakedefine ENABLE_SM2 #cmakedefine ENABLE_AEAD @@ -70,7 +71,7 @@ * we assume to be bundled with a sane implementation of std::regex. */ #if !defined(__GNUC__) || defined(_GLIBCXX_USE_CXX11_ABI) || \ (defined(WIN32) && !defined(MSYS)) || \ - ((defined(__clang__) && (__clang_major__ >= 4)) ) + ((defined(__clang__) && (__clang_major__ >= 4))) #define RNP_USE_STD_REGEX 1 #endif diff --git a/src/lib/crypto/backend_version.cpp b/src/lib/crypto/backend_version.cpp index 43d8d4f516..a70e55e367 100644 --- a/src/lib/crypto/backend_version.cpp +++ b/src/lib/crypto/backend_version.cpp @@ -110,6 +110,9 @@ backend_version() #if defined(ENABLE_IDEA) || defined(ENABLE_CAST5) || defined(ENABLE_BLOWFISH) || \ (defined(ENABLE_RIPEMD160) && OPENSSL_VERSION_NUMBER < 0x30000070L) +#if !defined(CRYPTO_BACKEND_OPENSSL3_LEGACY) +#error "OpenSSL doesn't have legacy provider, however one of the features enables it's load." +#endif #define OPENSSL_LOAD_LEGACY #endif