From d11c37a0b4eddb75ea4f200a41968f5991e4b5a1 Mon Sep 17 00:00:00 2001 From: Nick Logozzo Date: Thu, 18 Sep 2025 21:58:33 -0400 Subject: [PATCH 1/2] fix: Database encryption --- CHANGELOG.md | 9 +++++++++ CMakeLists.txt | 2 +- Doxyfile | 2 +- include/database/sqlitedatabase.h | 2 +- manual/README.md | 6 +++--- src/database/sqlitedatabase.cpp | 30 +++++++++++++++++++++++++----- 6 files changed, 40 insertions(+), 11 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 244edc0..a509e16 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,14 @@ # Changelog +## 2025.9.3 +### Breaking Changes +None +### New APIs +None +### Fixes +#### Database +- Fixed an issue where the sqlite database did not encrypt and decrypt correctly + ## 2025.9.2 ### Breaking Changes None diff --git a/CMakeLists.txt b/CMakeLists.txt index 387d2b4..5b76f75 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -20,7 +20,7 @@ endif() set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_SOURCE_DIR}/cmake") #libnick Definition -project ("libnick" LANGUAGES C CXX VERSION 2025.9.2 DESCRIPTION "A cross-platform base for native Nickvision applications.") +project ("libnick" LANGUAGES C CXX VERSION 2025.9.3 DESCRIPTION "A cross-platform base for native Nickvision applications.") include(CMakePackageConfigHelpers) include(GNUInstallDirs) include(CTest) diff --git a/Doxyfile b/Doxyfile index c8ed9ba..19089a2 100644 --- a/Doxyfile +++ b/Doxyfile @@ -48,7 +48,7 @@ PROJECT_NAME = "libnick" # could be handy for archiving the generated documentation or if some version # control system is used. -PROJECT_NUMBER = "2025.9.2" +PROJECT_NUMBER = "2025.9.3" # Using the PROJECT_BRIEF tag one can provide an optional one line description # for a project that appears at the top of each page and should give viewer a diff --git a/include/database/sqlitedatabase.h b/include/database/sqlitedatabase.h index 56c436c..d854330 100644 --- a/include/database/sqlitedatabase.h +++ b/include/database/sqlitedatabase.h @@ -141,4 +141,4 @@ namespace Nickvision::Database }; } -#endif //SQLDATABASE_H \ No newline at end of file +#endif //SQLDATABASE_H diff --git a/manual/README.md b/manual/README.md index a359c62..a3eab18 100644 --- a/manual/README.md +++ b/manual/README.md @@ -6,14 +6,14 @@ libnick provides Nickvision apps with a common set of cross-platform APIs for managing system and desktop app functionality such as network management, taskbar icons, translations, app updates, and more. -## 2025.9.2 +## 2025.9.3 ### Breaking Changes None ### New APIs None ### Fixes -#### Helpers -- Fixed a deadlock in `JsonFileBase` +#### Database +- Fixed an issue where the sqlite database did not encrypt and decrypt correctly ## Dependencies The following are a list of dependencies used by libnick. diff --git a/src/database/sqlitedatabase.cpp b/src/database/sqlitedatabase.cpp index e0926a4..ab898ee 100644 --- a/src/database/sqlitedatabase.cpp +++ b/src/database/sqlitedatabase.cpp @@ -14,7 +14,7 @@ namespace Nickvision::Database { throw std::runtime_error("Unable to open sql database."); } - if(sqlite3_exec(m_database, "PRAGMA schema_version", nullptr, nullptr, nullptr) != SQLITE_OK) + if(sqlite3_exec(m_database, "SELECT count(*) FROM sqlite_master;", nullptr, nullptr, nullptr) != SQLITE_OK) { m_isEncrypted = true; m_isUnlocked = false; @@ -82,7 +82,7 @@ namespace Nickvision::Database } else { - m_isUnlocked = sqlite3_exec(m_database, "PRAGMA schema_version", nullptr, nullptr, nullptr) == SQLITE_OK; + m_isUnlocked = sqlite3_exec(m_database, "SELECT count(*) FROM sqlite_master;", nullptr, nullptr, nullptr) == SQLITE_OK; } return m_isUnlocked; } @@ -101,9 +101,29 @@ namespace Nickvision::Database { return true; } + //If empty database, can use sqlite3_key + SqliteStatement statement{ m_database, "SELECT count(*) FROM sqlite_master;" }; + int tableCount{ -1 }; + if(statement.step() == SqliteStepResult::Row) + { + tableCount = statement.getColumn(0); + } + if(tableCount == 0) + { + if(sqlite3_key(m_database, password.c_str(), static_cast(password.size())) != SQLITE_OK) + { + return false; + } + else + { + m_isUnlocked = sqlite3_exec(m_database, "SELECT count(*) FROM sqlite_master;", nullptr, nullptr, nullptr) == SQLITE_OK; + m_isEncrypted = true; + return true; + } + } //Create temp encrypted database std::filesystem::path tempPath{ (m_path.string() + ".encrypt") }; - std::string cmd{ "ATTACH DATABASE '" + tempPath.string() + "' AS encrypted KEY '" + password + "'" }; + std::string cmd{ "ATTACH DATABASE '" + tempPath.string() + "' AS encrypted KEY '" + password + "'" }; sqlite3_exec(m_database, cmd.c_str(), nullptr, nullptr, nullptr); sqlite3_exec(m_database, "SELECT sqlcipher_export('encrypted')", nullptr, nullptr, nullptr); sqlite3_exec(m_database, "DETACH DATABASE encrypted", nullptr, nullptr, nullptr); @@ -120,7 +140,7 @@ namespace Nickvision::Database { throw std::runtime_error("Unable to open sql database with password."); } - m_isUnlocked = sqlite3_exec(m_database, "PRAGMA schema_version", nullptr, nullptr, nullptr) == SQLITE_OK; + m_isUnlocked = sqlite3_exec(m_database, "SELECT count(*) FROM sqlite_master;", nullptr, nullptr, nullptr) == SQLITE_OK; m_isEncrypted = true; return true; } @@ -202,4 +222,4 @@ namespace Nickvision::Database } return *this; } -} \ No newline at end of file +} From f17f095aa8becd4af79c54d0e8d8f9c1a9590224 Mon Sep 17 00:00:00 2001 From: Nick Logozzo Date: Sun, 21 Sep 2025 15:17:09 -0400 Subject: [PATCH 2/2] feat: Update vcpkg --- .github/workflows/linux.yml | 4 ++-- .github/workflows/macos.yml | 4 ++-- .github/workflows/windows.yml | 4 ++-- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/.github/workflows/linux.yml b/.github/workflows/linux.yml index 7d61e47..a0250d0 100644 --- a/.github/workflows/linux.yml +++ b/.github/workflows/linux.yml @@ -51,9 +51,9 @@ jobs: with: pkgs: boost-json cpr gettext-libintl glib gtest libsecret maddy triplet: ${{ matrix.variant.triplet }} - revision: b1b19307e2d2ec1eefbdb7ea069de7d4bcd31f01 + revision: 29ff5b8131d0c6c8fcb8fbaef35992f0d507cd7c token: ${{ github.token }} - cache-key: ${{ matrix.variant.triplet }}-b1b19307e2d2ec1eefbdb7ea069de7d4bcd31f01 + cache-key: ${{ matrix.variant.triplet }}-29ff5b8131d0c6c8fcb8fbaef35992f0d507cd7c - name: "Build" working-directory: ${{github.workspace}}/build run: | diff --git a/.github/workflows/macos.yml b/.github/workflows/macos.yml index b028f54..28d956e 100644 --- a/.github/workflows/macos.yml +++ b/.github/workflows/macos.yml @@ -31,9 +31,9 @@ jobs: with: pkgs: boost-json cpr gettext-libintl glib gtest maddy triplet: arm64-osx - revision: b1b19307e2d2ec1eefbdb7ea069de7d4bcd31f01 + revision: 29ff5b8131d0c6c8fcb8fbaef35992f0d507cd7c token: ${{ github.token }} - cache-key: "arm64-osx-b1b19307e2d2ec1eefbdb7ea069de7d4bcd31f01" + cache-key: "arm64-osx-29ff5b8131d0c6c8fcb8fbaef35992f0d507cd7c" - name: "Build" working-directory: ${{github.workspace}}/build run: | diff --git a/.github/workflows/windows.yml b/.github/workflows/windows.yml index 8caaf21..071e962 100644 --- a/.github/workflows/windows.yml +++ b/.github/workflows/windows.yml @@ -38,9 +38,9 @@ jobs: with: pkgs: boost-json cpr gettext-libintl gtest maddy sqlcipher triplet: ${{ matrix.variant.triplet }} - revision: b1b19307e2d2ec1eefbdb7ea069de7d4bcd31f01 + revision: 29ff5b8131d0c6c8fcb8fbaef35992f0d507cd7c token: ${{ github.token }} - cache-key: ${{ matrix.variant.triplet }}-b1b19307e2d2ec1eefbdb7ea069de7d4bcd31f01 + cache-key: ${{ matrix.variant.triplet }}-29ff5b8131d0c6c8fcb8fbaef35992f0d507cd7c - name: "Build" working-directory: ${{github.workspace}}/build run: |