diff --git a/src/plugin/jamipluginmanager.cpp b/src/plugin/jamipluginmanager.cpp index aca42c11a8ea6776fcd0af45dbd8726db64a6de7..d826ff72746d226fd77e4dab12154d7264eab383 100644 --- a/src/plugin/jamipluginmanager.cpp +++ b/src/plugin/jamipluginmanager.cpp @@ -126,6 +126,30 @@ JamiPluginManager::getInstalledPlugins() return pluginsPaths; } +bool +JamiPluginManager::checkPluginCertificatePublicKey(const std::string& oldJplPath, const std::string& newJplPath) +{ + std::map<std::string, std::string> oldDetails = PluginUtils::parseManifestFile(PluginUtils::manifestPath(oldJplPath), oldJplPath); + if ( + oldDetails.empty() || + !std::filesystem::is_regular_file(oldJplPath + DIR_SEPARATOR_CH + oldDetails["id"] + ".crt") || + !std::filesystem::is_regular_file(newJplPath) + ) + return false; + try { + auto oldCert = PluginUtils::readPluginCertificate(oldJplPath, oldDetails["id"]); + auto newCert = PluginUtils::readPluginCertificateFromArchive(newJplPath); + if (!oldCert || !newCert) { + return false; + } + return oldCert->getPublicKey() == newCert->getPublicKey(); + } catch (const std::exception& e) { + JAMI_ERR() << e.what(); + return false; + } + return true; +} + bool JamiPluginManager::checkPluginCertificateValidity(dht::crypto::Certificate* cert) { @@ -256,6 +280,8 @@ JamiPluginManager::installPlugin(const std::string& jplPath, bool force) } else { std::string installedVersion = alreadyInstalledManifestMap.at("version"); if (version > installedVersion) { + if(!checkPluginCertificatePublicKey(destinationDir, jplPath)) + return CERTIFICATE_VERIFICATION_FAILED; r = uninstallPlugin(destinationDir); if (r == SUCCESS) { archiver::uncompressArchive(jplPath, diff --git a/src/plugin/jamipluginmanager.h b/src/plugin/jamipluginmanager.h index 1dda410569fbd797d9ee9ff7bd89b6ed4455f544..7e7aa35fb545431dc5259053256e101d34fc1327 100644 --- a/src/plugin/jamipluginmanager.h +++ b/src/plugin/jamipluginmanager.h @@ -79,6 +79,13 @@ public: */ bool checkPluginCertificateValidity(dht::crypto::Certificate* cert); + /** + * @brief check if the if the public key of the certificate is the same as the public key in the new plugin + * @param oldJplPath, newJplPath + * return true if valid + */ + bool checkPluginCertificatePublicKey(const std::string& oldJplPath, const std::string& newJplPath); + /** * @brief check if all file are present in the signature file * @param jplPath