From b5580c33d8f0dab11ac7c3697d1b2b326133bf36 Mon Sep 17 00:00:00 2001 From: Jorrit Wronski Date: Tue, 13 Dec 2022 10:04:50 +0100 Subject: [PATCH 1/6] Add a CMake module to find SQLite3MultipleCiphers --- cmake/FindSQLite3MultipleCiphers.cmake | 187 +++++++++++++++++++++++++ 1 file changed, 187 insertions(+) create mode 100644 cmake/FindSQLite3MultipleCiphers.cmake diff --git a/cmake/FindSQLite3MultipleCiphers.cmake b/cmake/FindSQLite3MultipleCiphers.cmake new file mode 100644 index 00000000..76ae5196 --- /dev/null +++ b/cmake/FindSQLite3MultipleCiphers.cmake @@ -0,0 +1,187 @@ +# Based on the FindSQLite3.cmake from the CMake project file to add support for +# SQLite3MultipleCiphers (https://github.com/utelle/SQLite3MultipleCiphers) +# to the SQLiteCpp (https://github.com/SRombauts/SQLiteCpp) project. +# +# Created in 2022 Jorrit Wronski (https://github.com/jowr) +# +# Distributed under the MIT License (MIT) (See accompanying file LICENSE.txt +# or copy at http://opensource.org/licenses/MIT) + +#[=======================================================================[.rst: +FindSQLite3MultipleCiphers +-------------------------- + +Find the SQLite3MultipleCiphers library that implements SQLite3 with encryption. + +IMPORTED targets +^^^^^^^^^^^^^^^^ + +This module defines the following `IMPORTED` targets: + +``SQLite::SQLite3MultipleCiphers`` +``SQLite::SQLite3`` + +Result variables +^^^^^^^^^^^^^^^^ + +This module will set the following variables if found: + +``SQLite3MultipleCiphers_INCLUDE_DIRS`` + where to find sqlite3mc.h, etc. +``SQLite3MultipleCiphers_LIBRARIES`` + the libraries to link against to use SQLite3MultipleCiphers. +``SQLite3MultipleCiphers_VERSION`` + SQLite3 version of the SQLite3MultipleCiphers library found +``SQLite3MultipleCiphers_FOUND`` + TRUE if found + +It also sets alias variables for SQLite3 for campatibility reasons: + +``SQLite3_INCLUDE_DIRS`` + where to find sqlite3.h, etc. +``SQLite3_LIBRARIES`` + the libraries to link against to use SQLite3. +``SQLite3_VERSION`` + version of the SQLite3 library found +``SQLite3_FOUND`` + TRUE if found +``SQLite::SQLite3`` + the ordinary SQLite3 target for linking + +#]=======================================================================] + +find_path(SQLite3MultipleCiphers_INCLUDE_DIR NAMES sqlite3mc.h + HINTS + ${SQLITE3MULTIPLECIPHERS_DIR} + ENV SQLITE3MULTIPLECIPHERS_DIR + PATH_SUFFIXES src +) +mark_as_advanced(SQLite3MultipleCiphers_INCLUDE_DIR) + +#if("amd64" IN_LIST CMAKE_CPU_ARCHITECTURES) # I am targeting 64-bit x86. +if(CMAKE_SIZEOF_VOID_P MATCHES "8") + set(SQLite3MultipleCiphers_LIB_SUFFIX "_x64") +else() + set(SQLite3MultipleCiphers_LIB_SUFFIX "") +endif() + +find_library(SQLite3MultipleCiphers_LIBRARY_RELEASE sqlite3mc${SQLite3MultipleCiphers_LIB_SUFFIX} + HINTS + ${SQLITE3MULTIPLECIPHERS_DIR} + ENV SQLITE3MULTIPLECIPHERS_DIR + PATH_SUFFIXES + bin/vc13/lib/release + bin/vc14/lib/release + bin/vc15/lib/release + bin/vc16/lib/release + bin/vc17/lib/release + bin/gcc/lib/release + bin/clang/lib/release + bin/lib/release + REQUIRED +) +mark_as_advanced(SQLite3MultipleCiphers_LIBRARY_RELEASE) + +find_library(SQLite3MultipleCiphers_LIBRARY_DEBUG sqlite3mc${SQLite3MultipleCiphers_LIB_SUFFIX} + HINTS + ${SQLITE3MULTIPLECIPHERS_DIR} + ENV SQLITE3MULTIPLECIPHERS_DIR + PATH_SUFFIXES + bin/vc13/lib/debug + bin/vc14/lib/debug + bin/vc15/lib/debug + bin/vc16/lib/debug + bin/vc17/lib/debug + bin/gcc/lib/debug + bin/clang/lib/debug + bin/lib/debug +) +mark_as_advanced(SQLite3MultipleCiphers_LIBRARY_DEBUG) + +find_library(SQLite3MultipleCiphers_LIBRARY_MINSIZEREL sqlite3mc${SQLite3MultipleCiphers_LIB_SUFFIX} + HINTS + ${SQLITE3MULTIPLECIPHERS_DIR} + ENV SQLITE3MULTIPLECIPHERS_DIR + PATH_SUFFIXES + bin/vc13/lib/minsizerel + bin/vc14/lib/minsizerel + bin/vc15/lib/minsizerel + bin/vc16/lib/minsizerel + bin/vc17/lib/minsizerel + bin/gcc/lib/minsizerel + bin/clang/lib/minsizerel + bin/lib/minsizerel +) +mark_as_advanced(SQLite3MultipleCiphers_LIBRARY_MINSIZEREL) + +find_library(SQLite3MultipleCiphers_LIBRARY_RELWITHDEBINFO sqlite3mc${SQLite3MultipleCiphers_LIB_SUFFIX} + HINTS + ${SQLITE3MULTIPLECIPHERS_DIR} + ENV SQLITE3MULTIPLECIPHERS_DIR + PATH_SUFFIXES + bin/vc13/lib/relwithdebinfo + bin/vc14/lib/relwithdebinfo + bin/vc15/lib/relwithdebinfo + bin/vc16/lib/relwithdebinfo + bin/vc17/lib/relwithdebinfo + bin/gcc/lib/relwithdebinfo + bin/clang/lib/relwithdebinfo + bin/lib/relwithdebinfo +) +mark_as_advanced(SQLite3MultipleCiphers_LIBRARY_RELWITHDEBINFO) + +# Extract version information from the header file +if(SQLite3MultipleCiphers_INCLUDE_DIR) + file(STRINGS ${SQLite3MultipleCiphers_INCLUDE_DIR}/sqlite3mc_version.h _ver_line + REGEX "^#define SQLITE3MC_VERSION_STRING *\"[0-9]+\\.[0-9]+\\.[0-9]+\"" + LIMIT_COUNT 1) + string(REGEX MATCH "[0-9]+\\.[0-9]+\\.[0-9]+" + SQLite3MultipleCiphers_VERSION "${_ver_line}") + unset(_ver_line) + mark_as_advanced(SQLite3MultipleCiphers_VERSION) +endif() + +#include(${CMAKE_CURRENT_LIST_DIR}/FindPackageHandleStandardArgs.cmake) +include(FindPackageHandleStandardArgs) +find_package_handle_standard_args(SQLite3MultipleCiphers + REQUIRED_VARS SQLite3MultipleCiphers_INCLUDE_DIR SQLite3MultipleCiphers_LIBRARY_RELEASE SQLite3MultipleCiphers_LIBRARY_DEBUG + VERSION_VAR SQLite3MultipleCiphers_VERSION) + +# Create the imported target +if(SQLite3MultipleCiphers_FOUND) + set(SQLite3MultipleCiphers_INCLUDE_DIRS ${SQLite3MultipleCiphers_INCLUDE_DIR}) + set(SQLite3MultipleCiphers_LIBRARIES + debug ${SQLite3MultipleCiphers_LIBRARY_DEBUG} + optimized ${SQLite3MultipleCiphers_LIBRARY_RELEASE}) + if(NOT TARGET SQLite::SQLite3MultipleCiphers) + add_library(SQLite::SQLite3MultipleCiphers UNKNOWN IMPORTED) + set_target_properties(SQLite::SQLite3MultipleCiphers PROPERTIES + IMPORTED_LOCATION_DEBUG "${SQLite3MultipleCiphers_LIBRARY_DEBUG}" + IMPORTED_LOCATION_RELEASE "${SQLite3MultipleCiphers_LIBRARY_RELEASE}" + IMPORTED_LOCATION_MINSIZEREL "${SQLite3MultipleCiphers_LIBRARY_MINSIZEREL}" + IMPORTED_LOCATION_RELWITHDEBINFO "${SQLite3MultipleCiphers_LIBRARY_RELWITHDEBINFO}" + INTERFACE_INCLUDE_DIRECTORIES "${SQLite3MultipleCiphers_INCLUDE_DIR}") + endif() +endif() + +# define the alias variables +if(NOT SQLite3_INCLUDE_DIRS AND NOT SQLite3_LIBRARIES AND NOT SQLite3_VERSION AND NOT SQLite3_FOUND AND NOT TARGET SQLite::SQLite3) + set(SQLite3_INCLUDE_DIRS ${SQLite3MultipleCiphers_INCLUDE_DIRS}) + mark_as_advanced(SQLite3_INCLUDE_DIRS) + set(SQLite3_LIBRARIES ${SQLite3MultipleCiphers_LIBRARIES}) + mark_as_advanced(SQLite3_LIBRARIES) + #set(SQLite3_VERSION ${SQLite3MultipleCiphers_VERSION}) + #mark_as_advanced(SQLite3_VERSION) + file(STRINGS ${SQLite3MultipleCiphers_INCLUDE_DIR}/sqlite3.h _ver_line + REGEX "^#define SQLITE_VERSION *\"[0-9]+\\.[0-9]+\\.[0-9]+\"" + LIMIT_COUNT 1) + string(REGEX MATCH "[0-9]+\\.[0-9]+\\.[0-9]+" + SQLite3_VERSION "${_ver_line}") + unset(_ver_line) + mark_as_advanced(SQLite3_VERSION) + set(SQLite3_FOUND ${SQLite3MultipleCiphers_FOUND}) + mark_as_advanced(SQLite3_FOUND) + add_library(SQLite::SQLite3 ALIAS SQLite::SQLite3MultipleCiphers) +else() + message(FATAL_ERROR "SQLite3 has already been defined, please check you options. The current settings are very likely to produce conflicts.") +endif() From 54fd1a407caf8ee3aed6dae0747fe44f2c1aba10 Mon Sep 17 00:00:00 2001 From: Jorrit Wronski Date: Tue, 13 Dec 2022 10:21:27 +0100 Subject: [PATCH 2/6] Allow selecting the cipher library using CMake definitions, make sure that all imported libraries define the SQLite3_version variable --- CMakeLists.txt | 142 ++++++++++++++++++++++++++--------------- sqlite3/CMakeLists.txt | 9 +++ 2 files changed, 100 insertions(+), 51 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 4c020dae..6afb3011 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -202,7 +202,7 @@ endif (SQLITE_ENABLE_ASSERT_HANDLER) option(SQLITE_HAS_CODEC "Enable database encryption API. Not available in the public release of SQLite." OFF) if (SQLITE_HAS_CODEC) - # Enable database encryption API. Requires implementations of sqlite3_key & sqlite3_key_v2. + # Enable database encryption API. Requires implementations of sqlite3_key & sqlite3_rekey. # Eg. SQLCipher (libsqlcipher-dev) is an SQLite extension that provides 256 bit AES encryption of database files. target_compile_definitions(SQLiteCpp PUBLIC SQLITE_HAS_CODEC) endif (SQLITE_HAS_CODEC) @@ -240,62 +240,102 @@ if (SQLITECPP_USE_GCOV) set_target_properties(SQLiteCpp PROPERTIES COMPILE_FLAGS "-fkeep-inline-functions -fkeep-static-functions") endif () -## Build provided copy of SQLite3 C library ## - -option(SQLITECPP_INTERNAL_SQLITE "Add the internal SQLite3 source to the project." ON) -if (SQLITECPP_INTERNAL_SQLITE) - message(STATUS "Compile sqlite3 from source in subdirectory") - option(SQLITE_ENABLE_JSON1 "Enable JSON1 extension when building internal sqlite3 library." ON) - # build the SQLite3 C library (for ease of use/compatibility) versus Linux sqlite3-dev package - add_subdirectory(sqlite3) +# Try to handle the non-standard SQLite3 implementations first +if (TARGET SQLite::SQLite3) + message(STATUS "SQLite::SQLite3 target has already been defined, using it.") target_link_libraries(SQLiteCpp PUBLIC SQLite::SQLite3) -else (SQLITECPP_INTERNAL_SQLITE) - # When using the SQLite codec, we need to link against the sqlcipher lib & include - # So this gets the lib & header, and links/includes everything - if(SQLITE_HAS_CODEC) - # Make PkgConfig optional since Windows doesn't usually have it installed. - find_package(PkgConfig QUIET) - if(PKG_CONFIG_FOUND) - # IMPORTED_TARGET was added in 3.6.3 - if(CMAKE_VERSION VERSION_LESS 3.6.3) - pkg_check_modules(sqlcipher REQUIRED sqlcipher) - # Only used in Database.cpp so PRIVATE to hide from end-user - # Since we can't use IMPORTED_TARGET on this older Cmake version, manually link libs & includes - target_link_libraries(SQLiteCpp PRIVATE ${sqlcipher_LIBRARIES}) - target_include_directories(SQLiteCpp PRIVATE ${sqlcipher_INCLUDE_DIRS}) - else() - pkg_check_modules(sqlcipher REQUIRED IMPORTED_TARGET sqlcipher) - # Only used in Database.cpp so PRIVATE to hide from end-user - target_link_libraries(SQLiteCpp PRIVATE PkgConfig::sqlcipher) - endif() +endif (TARGET SQLite::SQLite3) + +option(SQLITECPP_USE_SQLCIPHER "Use SQLCipher as SQLite3 library with encyption support." OFF) +if (SQLITECPP_USE_SQLCIPHER AND TARGET SQLite::SQLite3) + message(FATAL_ERROR "SQLite::SQLite3 target has already been defined, cannot use SQLCipher.") +elseif (SQLITECPP_USE_SQLCIPHER) + # Make PkgConfig optional since Windows doesn't usually have it installed. + find_package(PkgConfig QUIET) + if(PKG_CONFIG_FOUND) + # IMPORTED_TARGET was added in 3.6.3 + if(CMAKE_VERSION VERSION_LESS 3.6.3) + pkg_check_modules(SQLCipher REQUIRED sqlcipher) + # Since we can't use IMPORTED_TARGET on this older Cmake version, manually link libs & includes + message(STATUS "Link to SQLCipher library") + add_library(SQLite::SQLite3 ALIAS ${SQLCipher_LIBRARIES}) + target_link_libraries(SQLiteCpp PUBLIC ${SQLCipher_LIBRARIES}) + target_include_directories(SQLiteCpp PUBLIC ${SQLCipher_INCLUDE_DIRS}) else() - # Since we aren't using pkgconf here, find it manually - find_library(sqlcipher_LIBRARY "sqlcipher") - find_path(sqlcipher_INCLUDE_DIR "sqlcipher/sqlite3.h" - PATH_SUFFIXES - "include" - "includes" - ) - # Hides it from the GUI - mark_as_advanced(sqlcipher_LIBRARY sqlcipher_INCLUDE_DIR) - if(NOT sqlcipher_INCLUDE_DIR) - message(FATAL_ERROR "${PROJECT_NAME} requires the \"\" header to use the codec functionality but it wasn't found.") - elseif(NOT sqlcipher_LIBRARY) - message(FATAL_ERROR "${PROJECT_NAME} requires the sqlcipher library to use the codec functionality but it wasn't found.") - endif() - # Only used in Database.cpp so PRIVATE to hide from end-user - target_include_directories(SQLiteCpp PRIVATE "${sqlcipher_INCLUDE_DIR}/sqlcipher") - target_link_libraries(SQLiteCpp PRIVATE ${sqlcipher_LIBRARY}) + pkg_check_modules(SQLCipher REQUIRED IMPORTED_TARGET sqlcipher) + message(STATUS "Link to SQLCipher library") + add_library(SQLite::SQLite3 ALIAS PkgConfig::SQLCipher) + target_link_libraries(SQLiteCpp PUBLIC PkgConfig::SQLCipher) endif() else() - find_package (SQLite3 REQUIRED) - message(STATUS "Link to sqlite3 system library") - target_link_libraries(SQLiteCpp PUBLIC SQLite::SQLite3) - if(SQLite3_VERSION VERSION_LESS "3.19") - set_target_properties(SQLiteCpp PROPERTIES COMPILE_FLAGS "-DSQLITECPP_HAS_MEM_STRUCT") + # Since we aren't using pkgconf here, find it manually + find_library(SQLCipher_LIBRARY "sqlcipher") + find_path(SQLCipher_INCLUDE_DIR "sqlcipher/sqlite3.h" + PATH_SUFFIXES + "include" + "includes" + ) + # Hides it from the GUI + mark_as_advanced(SQLCipher_LIBRARY SQLCipher_INCLUDE_DIR) + if(NOT SQLCipher_INCLUDE_DIR) + message(FATAL_ERROR "${PROJECT_NAME} requires the \"\" header to use the codec functionality but it wasn't found.") + elseif(NOT SQLCipher_LIBRARY) + message(FATAL_ERROR "${PROJECT_NAME} requires the SQLCipher library to use the codec functionality but it wasn't found.") endif() + message(STATUS "Link to SQLCipher library") + add_library(SQLite::SQLite3 ALIAS ${SQLCipher_LIBRARY}) + target_link_libraries(SQLiteCpp PUBLIC ${SQLCipher_LIBRARY}) + target_include_directories(SQLiteCpp PUBLIC "${SQLCipher_INCLUDE_DIR}/sqlcipher") endif() -endif (SQLITECPP_INTERNAL_SQLITE) + # Try to extract the SQLCipher version + file(STRINGS "${SQLCipher_INCLUDE_DIR}/sqlcipher/crypto.h" _ver_line + REGEX "^#define CIPHER_VERSION_NUMBER *\"[0-9]+\\.[0-9]+\\.[0-9]+\"" + LIMIT_COUNT 1) + string(REGEX MATCH "[0-9]+\\.[0-9]+\\.[0-9]+" + SQLCipher_VERSION "${_ver_line}") + unset(_ver_line) + mark_as_advanced(SQLCipher_VERSION) + # Try to extract the SQLite3 version + file(STRINGS "${SQLCipher_INCLUDE_DIR}/sqlcipher/sqlite3.h" _ver_line + REGEX "^#define SQLITE_VERSION *\"[0-9]+\\.[0-9]+\\.[0-9]+\"" + LIMIT_COUNT 1) + string(REGEX MATCH "[0-9]+\\.[0-9]+\\.[0-9]+" + SQLite3_VERSION "${_ver_line}") + unset(_ver_line) + mark_as_advanced(SQLite3_VERSION) + target_compile_definitions(SQLiteCpp PRIVATE SQLITECPP_USE_SQLCIPHER) + target_compile_definitions(SQLiteCpp PUBLIC SQLITE_HAS_CODEC) +endif () + +option(SQLITECPP_USE_SQLITE3MULTIPLECIPHERS "Use SQLite3MultipleCiphers as SQLite3 library with encyption support." OFF) +if (SQLITECPP_USE_SQLITE3MULTIPLECIPHERS AND TARGET SQLite::SQLite3) + message(FATAL_ERROR "SQLite::SQLite3 target has already been defined, cannot use SQLite3MultipleCiphers.") +elseif (SQLITECPP_USE_SQLITE3MULTIPLECIPHERS) + find_package (SQLite3MultipleCiphers REQUIRED) + message(STATUS "Link to SQLite3MultipleCiphers library") + target_link_libraries(SQLiteCpp PUBLIC SQLite::SQLite3MultipleCiphers) + target_compile_definitions(SQLiteCpp PRIVATE SQLITECPP_USE_SQLITE3MULTIPLECIPHERS) + target_compile_definitions(SQLiteCpp PUBLIC SQLITE_HAS_CODEC) +endif () + +option(SQLITECPP_INTERNAL_SQLITE "Add the internal SQLite3 source to the project." ON) +if (SQLITECPP_INTERNAL_SQLITE AND TARGET SQLite::SQLite3) + message(FATAL_ERROR "SQLite::SQLite3 target has already been defined, cannot use internal SQLite3.") +elseif (SQLITECPP_INTERNAL_SQLITE) + # Build the provided copy of the SQLite3 C library + message(STATUS "Compile sqlite3 from source in subdirectory") + option(SQLITE_ENABLE_JSON1 "Enable JSON1 extension when building internal sqlite3 library." ON) + # build the SQLite3 C library (for ease of use/compatibility) versus Linux sqlite3-dev package + add_subdirectory(sqlite3) + target_link_libraries(SQLiteCpp PRIVATE SQLite::SQLite3) + target_compile_definitions(SQLiteCpp PRIVATE SQLITECPP_INTERNAL_SQLITE) + #target_compile_definitions(SQLiteCpp PUBLIC SQLITE_HAS_CODEC) +endif () + +# Check the version of the found SQLite3 implementation +if(SQLite3_VERSION AND SQLite3_VERSION VERSION_LESS "3.19") + set_target_properties(SQLiteCpp PROPERTIES COMPILE_FLAGS "-DSQLITECPP_HAS_MEM_STRUCT") +endif() ## disable the optional support for std::filesystem (C++17) option(SQLITECPP_DISABLE_STD_FILESYSTEM "Disable the use of std::filesystem in SQLiteCpp." OFF) diff --git a/sqlite3/CMakeLists.txt b/sqlite3/CMakeLists.txt index 0efc3eee..bc67eebd 100644 --- a/sqlite3/CMakeLists.txt +++ b/sqlite3/CMakeLists.txt @@ -11,6 +11,15 @@ add_library(sqlite3 sqlite3.h ) +# Try to extract the SQLite3 version +file(STRINGS "sqlite3.h" _ver_line + REGEX "^#define SQLITE_VERSION *\"[0-9]+\\.[0-9]+\\.[0-9]+\"" + LIMIT_COUNT 1) +string(REGEX MATCH "[0-9]+\\.[0-9]+\\.[0-9]+" + SQLite3_VERSION "${_ver_line}") +unset(_ver_line) +mark_as_advanced(SQLite3_VERSION) + add_library(SQLite::SQLite3 ALIAS sqlite3) target_include_directories(sqlite3 From ef4b7ee3ed13fb89c6435253ccbaa5e415e1a33b Mon Sep 17 00:00:00 2001 From: Jorrit Wronski Date: Tue, 13 Dec 2022 10:22:00 +0100 Subject: [PATCH 3/6] Add a method to select the cipher algorithm in the database object --- include/SQLiteCpp/Database.h | 17 +++++++++++++++++ src/Database.cpp | 36 ++++++++++++++++++++++++++++++++++++ 2 files changed, 53 insertions(+) diff --git a/include/SQLiteCpp/Database.h b/include/SQLiteCpp/Database.h index e30ff947..996cfda8 100644 --- a/include/SQLiteCpp/Database.h +++ b/include/SQLiteCpp/Database.h @@ -521,6 +521,23 @@ class Database */ void loadExtension(const char* apExtensionName, const char* apEntryPointName); + /** + * @brief Set the cipher for the current sqlite database instance. + * + * This function is needed because some encryption providers require the user + * to select the cipher that they wish to use. This should happen immediately + * after opening an encrypted database: + * Open encrypted database + * -> call db.cipher("aes256cbc") + * -> call db.key("secret") + * -> database ready + * + * @param[in] aCipher Cipher to decode/encode the database + * + * @throw SQLite::Exception in case of error + */ + void cipher(const std::string& aCipher) const; + /** * @brief Set the key for the current sqlite database instance. * diff --git a/src/Database.cpp b/src/Database.cpp index f6e2f07b..c0d304b9 100644 --- a/src/Database.cpp +++ b/src/Database.cpp @@ -23,6 +23,10 @@ #define SQLITE_DETERMINISTIC 0x800 #endif // SQLITE_DETERMINISTIC +#if defined(SQLITECPP_USE_SQLITE3MULTIPLECIPHERS) +#include "sqlite3mc.h" +#endif + namespace SQLite { @@ -223,6 +227,38 @@ void Database::loadExtension(const char* apExtensionName, const char *apEntryPoi #endif } +// Set the cipher for the current sqlite database instance. +void Database::cipher(const std::string& aCipher) const { + int cipherLen = static_cast(aCipher.length()); +#ifdef SQLITECPP_USE_SQLCIPHER + if (cipherLen > 0) + { + throw SQLite::Exception("SQLiteCpp has been compiled with SQLCipher support, but the functionality has not been implemented, yet."); + } +#else +#ifdef SQLITECPP_USE_SQLITE3MULTIPLECIPHERS + if (cipherLen > 0) + { + int idx = sqlite3mc_cipher_index(aCipher.c_str()); + if (idx < 0) + { + throw SQLite::Exception("Could not find the cipher named \"" + aCipher + "\"."); + } + int res = sqlite3mc_config(getHandle(), "cipher", idx); + if (idx != res) + { + throw SQLite::Exception("Could not set the cipher index to \"" + std::to_string(idx) + "\"."); + } + } +#else // SQLITECPP_USE_SQLITE3MULTIPLECIPHERS + if (cipherLen > 0) + { + throw SQLite::Exception("No cipher selection support, recompile with an encryption library enabled."); + } +#endif // SQLITECPP_USE_SQLITE3MULTIPLECIPHERS +#endif // SQLITECPP_USE_SQLCIPHER +} + // Set the key for the current sqlite database instance. void Database::key(const std::string& aKey) const { From 78c85680293cb2154874572c0d53822ef0ec7f25 Mon Sep 17 00:00:00 2001 From: Jorrit Wronski Date: Tue, 13 Dec 2022 15:39:22 +0100 Subject: [PATCH 4/6] Follow the convention for writing includes --- src/Database.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Database.cpp b/src/Database.cpp index c0d304b9..bbcee6c5 100644 --- a/src/Database.cpp +++ b/src/Database.cpp @@ -24,7 +24,7 @@ #endif // SQLITE_DETERMINISTIC #if defined(SQLITECPP_USE_SQLITE3MULTIPLECIPHERS) -#include "sqlite3mc.h" +#include #endif From 34f2d4dd1c97c3f515c5457defada0d56bdb0eae Mon Sep 17 00:00:00 2001 From: Jorrit Wronski Date: Tue, 13 Dec 2022 15:40:52 +0100 Subject: [PATCH 5/6] Link the local SQLite3 publicly to make the include paths available to the test routines --- CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 6afb3011..256d07da 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -327,7 +327,7 @@ elseif (SQLITECPP_INTERNAL_SQLITE) option(SQLITE_ENABLE_JSON1 "Enable JSON1 extension when building internal sqlite3 library." ON) # build the SQLite3 C library (for ease of use/compatibility) versus Linux sqlite3-dev package add_subdirectory(sqlite3) - target_link_libraries(SQLiteCpp PRIVATE SQLite::SQLite3) + target_link_libraries(SQLiteCpp PUBLIC SQLite::SQLite3) target_compile_definitions(SQLiteCpp PRIVATE SQLITECPP_INTERNAL_SQLITE) #target_compile_definitions(SQLiteCpp PUBLIC SQLITE_HAS_CODEC) endif () From 31d745ffa1eff212cc18086a3ce228f6e2ba4238 Mon Sep 17 00:00:00 2001 From: Jorrit Wronski Date: Wed, 14 Dec 2022 09:57:26 +0100 Subject: [PATCH 6/6] Use the system SQLite3 as fallback --- CMakeLists.txt | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 256d07da..8fe59632 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -241,10 +241,6 @@ if (SQLITECPP_USE_GCOV) endif () # Try to handle the non-standard SQLite3 implementations first -if (TARGET SQLite::SQLite3) - message(STATUS "SQLite::SQLite3 target has already been defined, using it.") - target_link_libraries(SQLiteCpp PUBLIC SQLite::SQLite3) -endif (TARGET SQLite::SQLite3) option(SQLITECPP_USE_SQLCIPHER "Use SQLCipher as SQLite3 library with encyption support." OFF) if (SQLITECPP_USE_SQLCIPHER AND TARGET SQLite::SQLite3) @@ -332,6 +328,16 @@ elseif (SQLITECPP_INTERNAL_SQLITE) #target_compile_definitions(SQLiteCpp PUBLIC SQLITE_HAS_CODEC) endif () +# Use the system library as fallback solution +if (NOT TARGET SQLite::SQLite3) + find_package (SQLite3 REQUIRED) + message(STATUS "Link to sqlite3 system library") + target_link_libraries(SQLiteCpp PUBLIC SQLite::SQLite3) +else (NOT TARGET SQLite::SQLite3) + message(STATUS "SQLite::SQLite3 target has already been defined, using it.") + target_link_libraries(SQLiteCpp PUBLIC SQLite::SQLite3) +endif (NOT TARGET SQLite::SQLite3) + # Check the version of the found SQLite3 implementation if(SQLite3_VERSION AND SQLite3_VERSION VERSION_LESS "3.19") set_target_properties(SQLiteCpp PROPERTIES COMPILE_FLAGS "-DSQLITECPP_HAS_MEM_STRUCT")