From c5576c85c92c464ff3aa53f680ce18d8b51f60ab Mon Sep 17 00:00:00 2001 From: Aqua-sama Date: Fri, 19 Apr 2019 17:27:39 +0300 Subject: Add plugin signature verification policies --- src/browser.cpp | 13 +++++--- src/main.cpp | 3 +- src/meson.build | 7 ++--- src/plugin/pluginloader.cpp | 77 --------------------------------------------- src/plugin/pluginloader.h | 13 -------- 5 files changed, 12 insertions(+), 101 deletions(-) delete mode 100644 src/plugin/pluginloader.cpp delete mode 100644 src/plugin/pluginloader.h (limited to 'src') diff --git a/src/browser.cpp b/src/browser.cpp index db75fa1..e11a1da 100644 --- a/src/browser.cpp +++ b/src/browser.cpp @@ -38,7 +38,7 @@ #include "adblock/adblocklist.h" #include "hostlist/hostlist.h" #include -#include "plugin/pluginloader.h" +#include Browser::Browser(int &argc, char *argv[], bool allowSecondary) : SingleApplication(argc, argv, allowSecondary, SingleApplication::User | SingleApplication::SecondaryNotification | SingleApplication::ExcludeAppVersion) @@ -151,9 +151,14 @@ QPluginLoader *Browser::addPlugin(const QString &path) if(path.isEmpty()) return nullptr; - auto *loader = new PluginLoader(path, this); - spdlog::info("Verifying plugin: {}", loader->verify() ? "passed" : "failed"); - loader->load(); + auto *loader = new PluginLoader(path, PluginLoader::SignatureMatchIfAvailable, this); + const bool loaded = loader->load(); + spdlog::info("Loading plugin [{}]: {}", qUtf8Printable(path), loaded ? "passed" : "failed"); + + if(!loaded) { + delete loader; + return nullptr; + } auto *info = new PluginInfo(loader); m_plugins.append(info); diff --git a/src/main.cpp b/src/main.cpp index 0d6f466..8063b86 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -18,7 +18,7 @@ #include #include #include -#include "plugin/pluginloader.h" +#include #include #include #include @@ -72,7 +72,6 @@ int main(int argc, char **argv) // Load plugins for(const QString &path : Util::files(config->value("plugins.path").value(), {"*.so", "*.dll"})) { auto *loader = new PluginLoader(path); - spdlog::info("Verifying plugin: {}", loader->verify() ? "passed" : "failed"); const bool loaded = loader->load(); spdlog::info("{} plugin {}", loaded ? "Loaded" : "Failed to load", qUtf8Printable(path)); diff --git a/src/meson.build b/src/meson.build index 960cc69..8660534 100644 --- a/src/meson.build +++ b/src/meson.build @@ -1,7 +1,6 @@ # poi poi_moc = mod_qt5.preprocess( moc_headers: ['browser.h', - 'plugin/pluginloader.h', 'mainwindow/mainwindow.h', 'mainwindow/menubar.h', 'mainwindow/widgets/dockwidget.h', 'mainwindow/widgets/menusearch.h', 'mainwindow/widgets/navigationbar.h', 'mainwindow/widgets/searchform.h', 'session/savesessiondialog.h', 'session/sessiondialog.h', 'session/sessionform.h', 'subwindow/subwindow.h', 'subwindow/tabwidget.h', @@ -14,15 +13,13 @@ poi_moc = mod_qt5.preprocess( poi = executable(get_option('poiName'), install: true, cpp_args: ['-DQAPPLICATION_CLASS=QApplication'], - dependencies: [dep_qt5, dep_boost, dep_spdlog, dep_openssl, dep_SingleApplication, dep_genheaders, optional_deps, - dep_about, dep_addressbar, dep_bookmarks, dep_configuration, dep_downloads, dep_urlfilter, dep_webprofile], + dependencies: [dep_qt5, dep_boost, dep_spdlog, dep_SingleApplication, dep_genheaders, optional_deps, + dep_about, dep_addressbar, dep_bookmarks, dep_configuration, dep_downloads, dep_pluginloader, dep_urlfilter, dep_webprofile], include_directories: [include], sources: ['main.cpp', 'builtins.cpp', 'crashhandler.cpp', poi_moc, 'browser.cpp', 'util.cpp', 'util.h', - 'plugin/pluginloader.cpp', - 'mainwindow/mainwindow.cpp', 'mainwindow/menubar.cpp', 'mainwindow/widgets/dockwidget.cpp', diff --git a/src/plugin/pluginloader.cpp b/src/plugin/pluginloader.cpp deleted file mode 100644 index d1626f2..0000000 --- a/src/plugin/pluginloader.cpp +++ /dev/null @@ -1,77 +0,0 @@ -#include "pluginloader.h" -#include -#include -#include -#include "publicKey.h" -#include - -PluginLoader::PluginLoader(const QString &fileName, QObject *parent) - : QPluginLoader(fileName, parent) -{ -} - -bool PluginLoader::verify(const char *hashName) const -{ - const QString sigName = this->fileName() + ".sig"; - if(!QFile::exists(sigName)) { - spdlog::error("Signature does not exist: {}", qUtf8Printable(sigName)); - return false; - } - - auto *bio = BIO_new_mem_buf(publicKey_pem, publicKey_pem_len); - Q_CHECK_PTR(bio); - - auto *key = PEM_read_bio_PUBKEY(bio, NULL, NULL, NULL); - Q_CHECK_PTR(key); - - auto *ctx = EVP_MD_CTX_new(); - Q_CHECK_PTR(ctx); - - const auto *md = EVP_get_digestbyname(hashName); - Q_CHECK_PTR(md); - - int rc = EVP_DigestVerifyInit(ctx, NULL, md, NULL, key); - if(rc != 1) { - spdlog::error("DigestVerifyInit failed: %i", rc); - return false; - } - - // read plugin into DigestVerifyUpdate - QFile plugin(this->fileName()); - plugin.open(QIODevice::ReadOnly); - int len = plugin.size(); - int read = 0; - auto *buf = new unsigned char[1024]; - while(len > 0) { - read = plugin.read((char*) buf, 1024); - len -= read; - - rc = EVP_DigestVerifyUpdate(ctx, buf, read); - if(rc != 1) - spdlog::error("DigestVerifyUpdate failed: %i", rc); - } - delete buf; - plugin.close(); - - // read signature into DigestVerifyFinal - QFile sigFile(sigName); - sigFile.open(QIODevice::ReadOnly); - const int sig_len = sigFile.size(); - const auto* sig = [&sigFile, sig_len]() { - auto* buf = new unsigned char[sig_len]; - sigFile.read((char*) buf, sig_len); - return buf; - }(); - sigFile.close(); - - rc = EVP_DigestVerifyFinal(ctx, sig, sig_len); - delete sig; - - if(rc == 1) - return true; - else { - spdlog::error("DigestVerifyFinal failed: %i", rc); - return false; - } -} - diff --git a/src/plugin/pluginloader.h b/src/plugin/pluginloader.h deleted file mode 100644 index 8d186aa..0000000 --- a/src/plugin/pluginloader.h +++ /dev/null @@ -1,13 +0,0 @@ -#include - -class PluginLoader : public QPluginLoader -{ - Q_OBJECT - -public: - PluginLoader(const QString &fileName, QObject *parent = nullptr); - ~PluginLoader() = default; - - bool verify(const char *hashName = "SHA256") const; -}; - -- cgit v1.2.1