From 7c7c1d38c33b1a61c36de3d0b6c55dd958e45dc7 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?S=C3=A9bastien=20Blin?=
 <sebastien.blin@savoirfairelinux.com>
Date: Mon, 26 Jun 2023 11:51:27 -0400
Subject: [PATCH] conversationrepository: pin issuer certificate if needed

GitLab: #868
Change-Id: I2217c9321bc669ba454b54e5b26653399c4939a0
---
 src/jamidht/conversationrepository.cpp | 29 +++++++++++++++++---------
 1 file changed, 19 insertions(+), 10 deletions(-)

diff --git a/src/jamidht/conversationrepository.cpp b/src/jamidht/conversationrepository.cpp
index e265ef3c96..b67b06f702 100644
--- a/src/jamidht/conversationrepository.cpp
+++ b/src/jamidht/conversationrepository.cpp
@@ -194,22 +194,31 @@ public:
         if (!repo or !acc)
             return {};
         std::map<std::string, std::vector<DeviceId>> memberDevices;
-        std::string deviceDir = fmt::format("{}devices/",
-                                            git_repository_workdir(repo.get()));
+        std::string deviceDir = fmt::format("{}devices/", git_repository_workdir(repo.get()));
         for (const auto& file : fileutils::readDirectory(deviceDir)) {
             std::shared_ptr<dht::crypto::Certificate> cert;
             try {
                 cert = std::make_shared<dht::crypto::Certificate>(
                     fileutils::loadFile(deviceDir + file));
+                if (!cert)
+                    continue;
+                if (ignoreExpired && cert->getExpiration() < std::chrono::system_clock::now())
+                    continue;
+                auto issuerUid = cert->getIssuerUID();
+                if (!acc->certStore().getCertificate(issuerUid)) {
+                    // Check that parentCert
+                    auto memberFile = fmt::format("{}members/{}.crt", git_repository_workdir(repo.get()), issuerUid);
+                    auto adminFile = fmt::format("{}admins/{}.crt", git_repository_workdir(repo.get()), issuerUid);
+                    auto parentCert = std::make_shared<dht::crypto::Certificate>(fileutils::loadFile(fileutils::isFile(memberFile) ? memberFile : adminFile));
+                    if (parentCert && (ignoreExpired || parentCert->getExpiration() < std::chrono::system_clock::now()))
+                        acc->certStore().pinCertificate(parentCert, true); // Pin certificate to local store if not already done
+                }
+                if (!acc->certStore().getCertificate(cert->getPublicKey().getLongId().toString())) {
+                    acc->certStore().pinCertificate(cert, true); // Pin certificate to local store if not already done
+                }
+                memberDevices[cert->getIssuerUID()].emplace_back(cert->getPublicKey().getLongId());
+
             } catch (const std::exception&) {}
-            if (!cert)
-                continue;
-            if (ignoreExpired && cert->getExpiration() < std::chrono::system_clock::now())
-                continue;
-            if (!acc->certStore().getCertificate(cert->getPublicKey().getLongId().toString())) {
-                acc->certStore().pinCertificate(cert, true); // Pin certificate to local store if not already done
-            }
-            memberDevices[cert->getIssuerUID()].emplace_back(cert->getPublicKey().getLongId());
         }
         return memberDevices;
     }
-- 
GitLab