diff --git a/CMakeLists.txt b/CMakeLists.txt index aeaaa9e..567307c 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -2,7 +2,7 @@ cmake_minimum_required(VERSION 3.0.0) option(TESTS "Build all tests" OFF) -project(IntegrityCheck) +project(IntegrityApp) include(CPack) @@ -26,12 +26,10 @@ find_package(Qt5 COMPONENTS Core Gui Widgets REQUIRED) set(SOURCES src/main.cpp src/mainwindow.cpp - src/integretychecker.cpp ) set(HEADERS inc/mainwindow.h - src/integretychecker.cpp ) set(FORMS @@ -45,10 +43,16 @@ add_executable(${PROJECT_NAME} ) target_include_directories(${PROJECT_NAME} PRIVATE ${CMAKE_CURRENT_SOURCE_DIR} - ./cryptopp/ + #./cryptopp/ + ./integritycheck/inc ) target_link_libraries(${PROJECT_NAME} - ${CMAKE_SOURCE_DIR}/cryptopp/libcryptopp.a + # ${CMAKE_SOURCE_DIR}/cryptopp/libcryptopp.a + IntegrityCheck Qt5::Core Qt5::Widgets ) + +set(BUILD_TESTING OFF) +add_subdirectory(libs/IntegrityCheck) +add_subdirectory(libs/cryptopp) \ No newline at end of file diff --git a/inc/mainwindow.h b/inc/mainwindow.h index ee105a9..6f28374 100644 --- a/inc/mainwindow.h +++ b/inc/mainwindow.h @@ -1,6 +1,5 @@ #pragma once -#include "../inc/integretychecker.h" #include #include diff --git a/libs/IntegrityCheck/CMakeLists.txt b/libs/IntegrityCheck/CMakeLists.txt new file mode 100644 index 0000000..c732446 --- /dev/null +++ b/libs/IntegrityCheck/CMakeLists.txt @@ -0,0 +1,22 @@ +cmake_minimum_required(VERSION 3.0.0) + +project(IntegrityCheck) + +set( SOURCES + src/integritycheck.cpp +) + +set( HEADERS + IntegrityCheck/integritycheck.h +) + +add_library(${PROJECT_NAME} STATIC ${SOURCES} ) + +target_include_directories(${PROJECT_NAME} PUBLIC + inc + ${CMAKE_CURRENT_SOURCE_DIR}/../cryptopp +) + +target_link_libraries(${PROJECT_NAME} PUBLIC + cryptopp-static +) \ No newline at end of file diff --git a/inc/integretychecker.h b/libs/IntegrityCheck/inc/IntegrityCheck/integritycheck.h similarity index 79% rename from inc/integretychecker.h rename to libs/IntegrityCheck/inc/IntegrityCheck/integritycheck.h index 8ffd7b0..6d34075 100644 --- a/inc/integretychecker.h +++ b/libs/IntegrityCheck/inc/IntegrityCheck/integritycheck.h @@ -1,12 +1,12 @@ #pragma once -#include "../cryptopp/rsa.h" +#include "rsa.h" #include -class IntegretyCheck { +class IntegrityCheck { public: - IntegretyCheck(); - IntegretyCheck(const std::string &appPath, bool genKeyPair); + IntegrityCheck(); + IntegrityCheck(const std::string &appPath, bool genKeyPair); bool loadKeyFile(const std::string &app); bool saveKeyFile(const std::string &app); @@ -29,7 +29,15 @@ public: static const std::string SIGNATURE_MARKER; static const std::string HASH_FILE_DIVIDER; + enum E_STATE { + STATE_APPDIR_OK = 0x01, + STATE_PUBLIC_KEY = 0x02, + STATE_HASH_LIST = 0x04, + STATE_PRIVATE_KEY = 0x08 + }; + private: + E_STATE m_state; CryptoPP::RSA::PublicKey m_publicKey; CryptoPP::RSA::PrivateKey m_privateKey; bool extractHashAndFile(const std::string &line, std::string &hash, diff --git a/src/integretychecker.cpp b/libs/IntegrityCheck/src/integritycheck.cpp similarity index 81% rename from src/integretychecker.cpp rename to libs/IntegrityCheck/src/integritycheck.cpp index 6799307..7e7ae48 100644 --- a/src/integretychecker.cpp +++ b/libs/IntegrityCheck/src/integritycheck.cpp @@ -1,20 +1,20 @@ -#include "../inc/integretychecker.h" +#include "IntegrityCheck/integritycheck.h" -#include "../cryptopp/base64.h" -#include "../cryptopp/files.h" -#include "../cryptopp/osrng.h" -#include "../cryptopp/rsa.h" +#include "base64.h" +#include "files.h" +#include "osrng.h" +#include "rsa.h" #include #include #include namespace fs = std::filesystem; -const int IntegretyCheck::KEY_SIZE = 2048; -const std::string IntegretyCheck::HASH_FILE = "hashlist.sha256"; -const std::string IntegretyCheck::KEY_FILE = "appKey.pub"; -const std::string IntegretyCheck::SIGNATURE_MARKER = "### signature ###\n"; -const std::string IntegretyCheck::HASH_FILE_DIVIDER = " *"; +const int IntegrityCheck::KEY_SIZE = 2048; +const std::string IntegrityCheck::HASH_FILE = "hashlist.sha256"; +const std::string IntegrityCheck::KEY_FILE = "appKey.pub"; +const std::string IntegrityCheck::SIGNATURE_MARKER = "### signature ###\n"; +const std::string IntegrityCheck::HASH_FILE_DIVIDER = " *"; std::string string_to_hex(const std::string &input) { static const char *const lut = "0123456789ABCDEF"; @@ -30,9 +30,9 @@ std::string string_to_hex(const std::string &input) { return output; } -IntegretyCheck::IntegretyCheck() {} +IntegrityCheck::IntegrityCheck() {} -IntegretyCheck::IntegretyCheck(const std::string &appPath, bool genKeyPair) { +IntegrityCheck::IntegrityCheck(const std::string &appPath, bool genKeyPair) { if (genKeyPair) { generateKeyPair(); } else { @@ -40,7 +40,7 @@ IntegretyCheck::IntegretyCheck(const std::string &appPath, bool genKeyPair) { } } -bool IntegretyCheck::loadKeyFile(const std::string &app) { +bool IntegrityCheck::loadKeyFile(const std::string &app) { fs::path appPath(app); if (fs::exists(appPath / KEY_FILE)) { CryptoPP::FileSource input((appPath / KEY_FILE).c_str(), true); @@ -50,7 +50,7 @@ bool IntegretyCheck::loadKeyFile(const std::string &app) { return false; } -bool IntegretyCheck::saveKeyFile(const std::string &app) { +bool IntegrityCheck::saveKeyFile(const std::string &app) { ///@todo https://github.com/noloader/cryptopp-pem fs::path appPath(app); CryptoPP::FileSink output((appPath / KEY_FILE).c_str()); @@ -58,7 +58,7 @@ bool IntegretyCheck::saveKeyFile(const std::string &app) { return true; } -bool IntegretyCheck::generateKeyPair() { +bool IntegrityCheck::generateKeyPair() { CryptoPP::AutoSeededRandomPool rng; CryptoPP::InvertibleRSAFunction params; @@ -69,7 +69,7 @@ bool IntegretyCheck::generateKeyPair() { return true; } -std::string IntegretyCheck::generateHashList(const std::string &app) { +std::string IntegrityCheck::generateHashList(const std::string &app) { std::stringstream hashlist; fs::path appPath(app); std::string p = appPath.string(); @@ -94,7 +94,7 @@ std::string IntegretyCheck::generateHashList(const std::string &app) { return hashlist.str(); } -std::string IntegretyCheck::generateFileHash(const std::string &filepath) { +std::string IntegrityCheck::generateFileHash(const std::string &filepath) { std::ifstream in(filepath); std::string contents((std::istreambuf_iterator(in)), std::istreambuf_iterator()); @@ -108,7 +108,7 @@ std::string IntegretyCheck::generateFileHash(const std::string &filepath) { std::string((char *)abDigest, CryptoPP::SHA256::DIGESTSIZE)); } -bool IntegretyCheck::extractHashAndFile(const std::string &line, +bool IntegrityCheck::extractHashAndFile(const std::string &line, std::string &hash, std::string &filename) { size_t divider = line.find(HASH_FILE_DIVIDER); @@ -123,7 +123,7 @@ bool IntegretyCheck::extractHashAndFile(const std::string &line, return result; } -bool IntegretyCheck::checkHashList(const std::string &hashList, +bool IntegrityCheck::checkHashList(const std::string &hashList, const std::string &appPath) { std::stringstream ss(hashList); std::string line, hash, filename; @@ -142,12 +142,12 @@ bool IntegretyCheck::checkHashList(const std::string &hashList, return result; } -bool IntegretyCheck::verifyFileHash(const std::string &filePath, +bool IntegrityCheck::verifyFileHash(const std::string &filePath, const std::string &hash) { return (generateFileHash(filePath) == hash); } -void IntegretyCheck::signHashList(std::string &hashList) { +void IntegrityCheck::signHashList(std::string &hashList) { CryptoPP::AutoSeededRandomPool rng; CryptoPP::RSASSA_PKCS1v15_SHA_Signer signer(m_privateKey); @@ -169,7 +169,7 @@ void IntegretyCheck::signHashList(std::string &hashList) { hashList.append(strHexSignature); } -bool IntegretyCheck::verifyHashList(const std::string &signedHashList, +bool IntegrityCheck::verifyHashList(const std::string &signedHashList, std::string &hashList) { size_t startSig = signedHashList.find(SIGNATURE_MARKER); if (startSig == std::string::npos) { @@ -203,7 +203,7 @@ bool IntegretyCheck::verifyHashList(const std::string &signedHashList, return result; } -std::string IntegretyCheck::loadHashList(const std::string &app) { +std::string IntegrityCheck::loadHashList(const std::string &app) { std::stringstream content; fs::path appPath(app); std::ifstream in(appPath / HASH_FILE, std::ios::in | std::ios::binary); @@ -214,7 +214,7 @@ std::string IntegretyCheck::loadHashList(const std::string &app) { return content.str(); } -void IntegretyCheck::saveHashList(const std::string &app, +void IntegrityCheck::saveHashList(const std::string &app, const std::string &hashList) { fs::path appPath(app); std::ofstream out(appPath / HASH_FILE); diff --git a/src/mainwindow.cpp b/src/mainwindow.cpp index 2f6caa1..0c54dbf 100644 --- a/src/mainwindow.cpp +++ b/src/mainwindow.cpp @@ -1,6 +1,7 @@ #include "inc/mainwindow.h" #include "../ui/ui_mainwindow.h" +#include "IntegrityCheck/integritycheck.h" #include #include @@ -39,12 +40,12 @@ void AppWindow::onAppFolderSelect_click() { void AppWindow::onSign_click() { std::string dir = ui->txtFolderPath->text().toStdString(); - IntegretyCheck integretyCheck(dir, true); + IntegrityCheck integretyCheck(dir, true); log("key pair is generated"); integretyCheck.saveKeyFile(dir); log("public key is saved to '" + - QString::fromStdString(IntegretyCheck::KEY_FILE) + "'"); + QString::fromStdString(IntegrityCheck::KEY_FILE) + "'"); std::string hList = integretyCheck.generateHashList(dir); log("generated hash list"); @@ -54,7 +55,7 @@ void AppWindow::onSign_click() { integretyCheck.saveHashList(dir, hList); log("public key is saved to '" + - QString::fromStdString(IntegretyCheck::HASH_FILE) + "'"); + QString::fromStdString(IntegrityCheck::HASH_FILE) + "'"); if (publicKeyAvailable(ui->txtFolderPath->text()) && hashFileAvailable(ui->txtFolderPath->text())) { @@ -66,14 +67,14 @@ void AppWindow::onSign_click() { void AppWindow::onVerify_click() { std::string dir = ui->txtFolderPath->text().toStdString(); - IntegretyCheck integretyCheck(dir, false); + IntegrityCheck integretyCheck(dir, false); ///@todo check for key file and create log msg std::string newHashList, hList; hList = integretyCheck.loadHashList(dir); if (hList.empty()) { log("App modified, unable to load '" + - QString::fromStdString(IntegretyCheck::HASH_FILE) + "'"); + QString::fromStdString(IntegrityCheck::HASH_FILE) + "'"); return; } log("loaded hash file"); @@ -102,12 +103,12 @@ void AppWindow::log(const QString &msg) { bool AppWindow::publicKeyAvailable(const QString &path) { QString pubKeyFile = path + QDir::separator() + - QString::fromStdString(IntegretyCheck::KEY_FILE); + QString::fromStdString(IntegrityCheck::KEY_FILE); return QFileInfo::exists(pubKeyFile); } bool AppWindow::hashFileAvailable(const QString &path) { QString hashFile = path + QDir::separator() + - QString::fromStdString(IntegretyCheck::HASH_FILE); + QString::fromStdString(IntegrityCheck::HASH_FILE); return QFileInfo::exists(hashFile); }