Skip to content

Commit

Permalink
Upgrade to OpenSSL 3 (#6097)
Browse files Browse the repository at this point in the history
* Upgrade to OpenSSL 3

* don’t build zlib on evergreen anymore

* changelog

* fix deprecated SHA224 APIs

* fix deprecated RSA PEM decoding APIs
  • Loading branch information
fealebenpae authored Dec 12, 2022
1 parent 5643848 commit b4d45f3
Show file tree
Hide file tree
Showing 18 changed files with 130 additions and 245 deletions.
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,16 +2,16 @@

### 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
* Core no longer provides any vcpkg infrastructure (the ports submodule and overlay triplets), because it handles dependant libraries internally now.
* Allow Realm instances to have a complete view of their schema, if mode is additive. ([PR #5784](https://github.com/realm/realm-core/pull/5784)).


### 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

0 comments on commit b4d45f3

Please sign in to comment.