From df91825693b0c1a6df5440f99d4ff4cc2faa093c Mon Sep 17 00:00:00 2001
From: Xavier Jouslin de Noray <xavier.jouslindenoray@savoirfairelinux.com>
Date: Mon, 11 Dec 2023 09:11:45 -0500
Subject: [PATCH] Plugin Update: verify public key if the plugin already
 install

Change-Id: Ia3b3ec41994117af228a1ef595208fee165b0d3b
---
 src/plugin/jamipluginmanager.cpp | 26 ++++++++++++++++++++++++++
 src/plugin/jamipluginmanager.h   |  7 +++++++
 2 files changed, 33 insertions(+)

diff --git a/src/plugin/jamipluginmanager.cpp b/src/plugin/jamipluginmanager.cpp
index aca42c11a8..d826ff7274 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 1dda410569..7e7aa35fb5 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
-- 
GitLab