Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Upgrade to OpenSSL 3 #6097

Merged
merged 8 commits into from
Dec 12, 2022
Merged
Show file tree
Hide file tree
Changes from 7 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 0 additions & 3 deletions .gitmodules
Original file line number Diff line number Diff line change
@@ -1,6 +1,3 @@
[submodule "external/catch"]
path = external/catch
url = https://github.com/catchorg/Catch2.git
[submodule "tools/vcpkg/ports"]
path = tools/vcpkg/ports
url = https://github.com/microsoft/vcpkg.git
4 changes: 2 additions & 2 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,14 @@

### Enhancements
* <New feature description> (PR [#????](https://github.com/realm/realm-core/pull/????))
* None.
* Upgrade OpenSSL from 1.1.1n to 3.0.7. ([#6097](https://github.com/realm/realm-core/pull/6097))

### Fixed
* <How do the end-user experience this issue? what was the impact?> ([#????](https://github.com/realm/realm-core/issues/????), since v?.?.?)
* None.

### Breaking changes
* None.
* Core no longer provides any vcpkg infrastructure (the ports submodule and overlay triplets), because it handles dependant libraries internally now.

### Compatibility
* Fileformat: Generates files with format v23. Reads and automatically upgrade from fileformat v5.
Expand Down
67 changes: 19 additions & 48 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ include(SpecialtyBuilds)
include(GetVersion)
include(CheckCXXCompilerFlag)
include(CheckCXXSourceRuns)
include(AcquireRealmDependency)

include(CodeCoverage)

Expand Down Expand Up @@ -130,8 +131,6 @@ if(ANDROID)
add_compile_options(-fdata-sections -ffunction-sections -fomit-frame-pointer -fsigned-char -fstrict-aliasing -funwind-tables -no-canonical-prefixes $<$<CONFIG:Release>:-Oz>)
endif()

set(OPENSSL_VERSION ${DEP_OPENSSL_VERSION})

set(CMAKE_DEBUG_POSTFIX "-dbg")
set(CMAKE_MINSIZEDEBUG_POSTFIX "-dbg")

Expand Down Expand Up @@ -228,52 +227,15 @@ elseif(CMAKE_SYSTEM_NAME MATCHES "Linux|Android")
endif()

if(REALM_NEEDS_OPENSSL OR REALM_FORCE_OPENSSL)
set(OPENSSL_USE_STATIC_LIBS ON)
if(VCPKG_TOOLCHAIN)
# If we're building with vcpkg, prefer to find OpenSSL there first
find_package(OpenSSL)
endif()
# We aren't building with vcpkg, or it didn't have OpenSSL
if(NOT OpenSSL_FOUND)
if(ANDROID OR (CMAKE_SYSTEM_NAME STREQUAL "Linux" AND CMAKE_SYSTEM_PROCESSOR STREQUAL "x86_64"))
# We have prebuilt OpenSSL tarballs for Android and Linux x86_64
set(_realm_have_prebuilt_openssl ON)
endif()
if(NOT REALM_USE_SYSTEM_OPENSSL AND _realm_have_prebuilt_openssl)
# Use our own prebuilt OpenSSL
if(NOT OpenSSL_DIR)
if(NOT EXISTS ${CMAKE_CURRENT_BINARY_DIR}/openssl/lib/cmake/OpenSSL/OpenSSLConfig.cmake)
if(ANDROID)
set(OPENSSL_URL "http://static.realm.io/downloads/openssl/${OPENSSL_VERSION}/Android/${CMAKE_ANDROID_ARCH_ABI}/openssl.tar.gz")
else()
set(OPENSSL_URL "http://static.realm.io/downloads/openssl/${OPENSSL_VERSION}/Linux/x86_64/openssl.tar.gz")
endif()

message(STATUS "Getting ${OPENSSL_URL}...")
file(DOWNLOAD "${OPENSSL_URL}" "${CMAKE_CURRENT_BINARY_DIR}/openssl/openssl.tar.gz" STATUS download_status)

list(GET download_status 0 status_code)
if (NOT "${status_code}" STREQUAL "0")
message(FATAL_ERROR "Downloading ${url}... Failed. Status: ${download_status}")
endif()

message(STATUS "Uncompressing OpenSSL...")
execute_process(
COMMAND ${CMAKE_COMMAND} -E tar xfz "openssl.tar.gz"
WORKING_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/openssl"
)
endif()

set(OpenSSL_DIR "${CMAKE_CURRENT_BINARY_DIR}/openssl/lib/cmake/OpenSSL")
endif()
find_package(OpenSSL REQUIRED CONFIG)
target_link_libraries(OpenSSL::SSL INTERFACE OpenSSL::Crypto)
else()
# Use whatever OpenSSL CMake finds on the system
find_package(OpenSSL REQUIRED)
endif()
if(NOT REALM_USE_SYSTEM_OPENSSL AND (ANDROID OR WIN32 OR CMAKE_SYSTEM_NAME STREQUAL "Linux"))
# Use our own prebuilt OpenSSL
realm_acquire_dependency(openssl ${DEP_OPENSSL_VERSION} OPENSSL_CMAKE_INCLUDE_FILE)

include(${OPENSSL_CMAKE_INCLUDE_FILE})
endif()

set(OPENSSL_USE_STATIC_LIBS ON)
find_package(OpenSSL REQUIRED)
set(REALM_HAVE_OPENSSL ON)
string(REGEX MATCH "^([0-9]+)\\.([0-9]+)" OPENSSL_VERSION_MAJOR_MINOR ${OPENSSL_VERSION})
elseif(APPLE)
Expand All @@ -285,7 +247,10 @@ endif()
# so for an iOS build it'll use the path from the Device plaform, which is an error on Simulator.
# Just use -lz and let Xcode figure it out
if(NOT APPLE AND NOT TARGET ZLIB::ZLIB)
if(ANDROID)
if(WIN32)
realm_acquire_dependency(zlib ${DEP_WIN32_ZLIB_VERSION} ZLIB_CMAKE_INCLUDE_FILE)
include(${ZLIB_CMAKE_INCLUDE_FILE})
elseif(ANDROID)
# On Android FindZLIB chooses the static libz over the dynamic one, but this leads to issues
# (see https://github.com/android/ndk/issues/1179)
# We want to link against the stub library instead of statically linking anyway,
Expand Down Expand Up @@ -364,7 +329,8 @@ if(REALM_ENABLE_SYNC)
list(APPEND REALM_EXPORTED_TARGETS Sync)
endif()
export(TARGETS ${REALM_EXPORTED_TARGETS} NAMESPACE Realm:: FILE RealmTargets.cmake)
configure_file(${CMAKE_CURRENT_LIST_DIR}/tools/cmake/RealmConfig.cmake.in ${CMAKE_CURRENT_BINARY_DIR}/RealmConfig.cmake @ONLY)
configure_file(tools/cmake/RealmConfig.cmake.in ${CMAKE_CURRENT_BINARY_DIR}/RealmConfig.cmake @ONLY)
configure_file(tools/cmake/AcquireRealmDependency.cmake ${CMAKE_CURRENT_BINARY_DIR}/AcquireRealmDependency.cmake @ONLY)

# Make the project importable from the install directory
install(EXPORT realm
Expand All @@ -379,6 +345,11 @@ install(FILES ${CMAKE_CURRENT_BINARY_DIR}/RealmConfig.cmake
COMPONENT devel
)

install(FILES tools/cmake/AcquireRealmDependency.cmake
DESTINATION lib/cmake/Realm
COMPONENT devel
)

# CPack
set(CPACK_GENERATOR "TGZ")
set(CPACK_PACKAGE_VERSION ${REALM_VERSION})
Expand Down
6 changes: 0 additions & 6 deletions Jenkinsfile
Original file line number Diff line number Diff line change
Expand Up @@ -547,12 +547,6 @@ def doBuildWindows(String buildType, boolean isUWP, String platform, boolean run
CMAKE_BUILD_TYPE: buildType,
REALM_ENABLE_SYNC: "ON",
CPACK_SYSTEM_NAME: cpackSystemName,
CMAKE_TOOLCHAIN_FILE: '%WORKSPACE%/tools/vcpkg/ports/scripts/buildsystems/vcpkg.cmake',
VCPKG_MANIFEST_DIR: '%WORKSPACE%/tools/vcpkg',
VCPKG_OVERLAY_TRIPLETS: '%WORKSPACE%/tools/vcpkg/triplets',
// set a custom buildtrees path because the default one is too long and msbuild tasks fail
VCPKG_INSTALL_OPTIONS: '--x-buildtrees-root=%WORKSPACE%/vcpkg-buildtrees',
VCPKG_TARGET_TRIPLET: triplet,
REALM_VERSION: gitDescribeVersion,
]

Expand Down
3 changes: 2 additions & 1 deletion dependencies.list
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
PACKAGE_NAME=realm-core
VERSION=13.1.2
OPENSSL_VERSION=1.1.1n
OPENSSL_VERSION=3.0.7
WIN32_ZLIB_VERSION=1.2.13
MDBREALM_TEST_SERVER_TAG=2022-10-21
74 changes: 0 additions & 74 deletions evergreen/build_zlib.sh

This file was deleted.

12 changes: 0 additions & 12 deletions evergreen/config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -59,15 +59,6 @@ functions:
set_cmake_var compiler_vars CMAKE_CXX_COMPILER PATH $(./evergreen/abspath.sh ${cxx_compiler})
fi

if [ -n "${build_zlib|}" ]; then
CC="${c_compiler|}" GENERATOR="${cmake_generator|}" \
./evergreen/build_zlib.sh \
-p zlib_prefix \
-b v1.2.11 \
-e "${extra_flags}" \
-j ${max_jobs|$(grep -c proc /proc/cpuinfo)}
fi

if [ -n "${run_tests_against_baas|}" ]; then
set_cmake_var baas_vars REALM_ENABLE_AUTH_TESTS BOOL On
set_cmake_var baas_vars REALM_MONGODB_ENDPOINT STRING "http://localhost:9090"
Expand Down Expand Up @@ -1017,7 +1008,6 @@ buildvariants:
extra_flags: "-A x64"
max_jobs: $(($(grep -c proc /proc/cpuinfo) / 2))
fetch_missing_dependencies: On
build_zlib: On
python3: "/cygdrive/c/python/python37/python.exe"
tasks:
- name: compile_test_and_package
Expand All @@ -1033,7 +1023,6 @@ buildvariants:
extra_flags: "-A x64"
max_jobs: $(($(grep -c proc /proc/cpuinfo) / 2))
fetch_missing_dependencies: On
build_zlib: On
python3: "/cygdrive/c/python/python37/python.exe"
run_with_encryption: On
tasks:
Expand All @@ -1050,7 +1039,6 @@ buildvariants:
cmake_build_type: "Release"
max_jobs: $(($(grep -c proc /proc/cpuinfo) / 2))
fetch_missing_dependencies: On
build_zlib: On
python3: "/cygdrive/c/python/python37/python.exe"
tasks:
- name: compile_test
20 changes: 19 additions & 1 deletion src/realm/sync/noinst/server/crypto_server_openssl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,12 @@
#include <openssl/bio.h>
#include <openssl/pem.h>
#include <openssl/evp.h>

#if OPENSSL_VERSION_MAJOR >= 3
#include <openssl/decoder.h>
#else
#include <openssl/rsa.h>
#endif

using namespace realm;
using namespace realm::sync;
Expand Down Expand Up @@ -43,6 +48,19 @@ PKey::~PKey() {}

static key_type load_public_from_bio(BIO* bio)
{
#if OPENSSL_VERSION_MAJOR >= 3
EVP_PKEY* pkey = nullptr;
const char* format = "PEM"; /* NULL for any format */
const char* structure = nullptr; /* any structure */
const char* key_type = "RSA"; /* NULL for any key */
auto ctx = as_unique_ptr(OSSL_DECODER_CTX_new_for_pkey(&pkey, format, structure, key_type,
OSSL_KEYMGMT_SELECT_PUBLIC_KEY, nullptr, nullptr),
OSSL_DECODER_CTX_free);
if (!OSSL_DECODER_from_bio(ctx.get(), bio)) {
throw CryptoError{"Error reading RSA key."};
}
return as_unique_ptr(pkey, EVP_PKEY_free);
#else
pem_password_cb* password_cb = nullptr; // OpenSSL will display a prompt if necessary
void* password_cb_userdata = nullptr;

Expand All @@ -56,8 +74,8 @@ static key_type load_public_from_bio(BIO* bio)
if (EVP_PKEY_assign_RSA(key.get(), rsa.get()) == 0)
throw CryptoError{"Error assigning RSA key."};
rsa.release();

return key;
#endif
}

PKey PKey::load_public(const std::string& pemfile)
Expand Down
12 changes: 12 additions & 0 deletions src/realm/util/encrypted_file_mapping.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -451,6 +451,18 @@ void AESCryptor::calc_hmac(const void* src, size_t len, uint8_t* dst, const uint
sha_process(s, opad, 64);
sha_process(s, dst, 28); // 28 == SHA224_DIGEST_LENGTH
sha_done(s, dst);
#elif OPENSSL_VERSION_NUMBER >= 0x10101000L // 1.1.1
std::unique_ptr<EVP_MD_CTX, void (*)(EVP_MD_CTX*)> ctx = {EVP_MD_CTX_new(), EVP_MD_CTX_free};
EVP_DigestInit(ctx.get(), EVP_sha224());
EVP_DigestUpdate(ctx.get(), ipad, 64);
EVP_DigestUpdate(ctx.get(), static_cast<const uint8_t*>(src), len);
EVP_DigestFinal(ctx.get(), dst, nullptr);

ctx = {EVP_MD_CTX_new(), EVP_MD_CTX_free};
EVP_DigestInit(ctx.get(), EVP_sha224());
EVP_DigestUpdate(ctx.get(), opad, 64);
EVP_DigestUpdate(ctx.get(), dst, SHA224_DIGEST_LENGTH);
EVP_DigestFinal(ctx.get(), dst, nullptr);
#else
SHA256_CTX ctx;
SHA224_Init(&ctx);
Expand Down
5 changes: 4 additions & 1 deletion src/realm/util/network_ssl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -835,15 +835,18 @@ int Stream::bio_puts(BIO* bio, const char* c_str) noexcept
long Stream::bio_ctrl(BIO*, int cmd, long, void*) noexcept
{
switch (cmd) {
case BIO_CTRL_EOF:
return 0;
case BIO_CTRL_PUSH:
case BIO_CTRL_POP:
// Ignoring in alignment with `crypto/bio/bss_sock.c` of OpenSSL.
return 0;
case BIO_CTRL_FLUSH:
// Ignoring in alignment with `crypto/bio/bss_sock.c` of OpenSSL.
return 1;
default:
REALM_ASSERT_EX(false, "Got BIO_ctrl with unknown command %d", cmd);
}
REALM_ASSERT(false);
return 0;
}

Expand Down
Loading