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