Skip to content
Snippets Groups Projects
Commit 8abc792a authored by Sébastien Blin's avatar Sébastien Blin
Browse files

certstore: make getCertificate always construct the complete cert

Because the certstore can contains a certificate chain splitted
in different parts (eg, in a swarm the device cert is in /devices
and the rest in /members), the certstore should be able to return
the whole certificate.
Moreover, at some places we do the assumption that the cert is
complete (AccountManager::foundPeerDevice which uses cert->issuer)
getCertificate() should only return the certificate if complete.

Change-Id: I1ff2006cb4f63694016e38e5b4a72b6a287c2345
GitLab: https://git.jami.net/savoirfairelinux/ring-project/-/issues/1282
parent c5e369ea
No related branches found
No related tags found
No related merge requests found
...@@ -143,15 +143,32 @@ CertificateStore::getPinnedCertificates() const ...@@ -143,15 +143,32 @@ CertificateStore::getPinnedCertificates() const
} }
std::shared_ptr<crypto::Certificate> std::shared_ptr<crypto::Certificate>
CertificateStore::getCertificate(const std::string& k) const CertificateStore::getCertificate(const std::string& k)
{ {
std::unique_lock<std::mutex> l(lock_); auto getCertificate_ = [this](const std::string& k) -> std::shared_ptr<crypto::Certificate> {
auto cit = certs_.find(k); auto cit = certs_.find(k);
if (cit == certs_.cend()) { if (cit == certs_.cend())
return {}; return {};
}
return cit->second; return cit->second;
};
std::unique_lock<std::mutex> l(lock_);
auto crt = getCertificate_(k);
// Check if certificate is complete
// If the certificate has been splitted, reconstruct it
auto top_issuer = crt;
while (top_issuer && top_issuer->getUID() != top_issuer->getIssuerUID()) {
if (top_issuer->issuer) {
top_issuer = top_issuer->issuer;
} else if (auto cert = getCertificate_(top_issuer->getIssuerUID())) {
top_issuer->issuer = cert;
top_issuer = cert;
} else {
// In this case, a certificate was not found
JAMI_WARN("Incomplete certificate detected %s", k.c_str());
break;
}
}
return crt;
} }
std::shared_ptr<crypto::Certificate> std::shared_ptr<crypto::Certificate>
......
...@@ -53,7 +53,10 @@ public: ...@@ -53,7 +53,10 @@ public:
CertificateStore(); CertificateStore();
std::vector<std::string> getPinnedCertificates() const; std::vector<std::string> getPinnedCertificates() const;
std::shared_ptr<crypto::Certificate> getCertificate(const std::string& cert_id) const; /**
* Return certificate (with full chain)
*/
std::shared_ptr<crypto::Certificate> getCertificate(const std::string& cert_id);
std::shared_ptr<crypto::Certificate> findCertificateByName( std::shared_ptr<crypto::Certificate> findCertificateByName(
const std::string& name, crypto::NameType type = crypto::NameType::UNKNOWN) const; const std::string& name, crypto::NameType type = crypto::NameType::UNKNOWN) const;
......
...@@ -36,9 +36,11 @@ public: ...@@ -36,9 +36,11 @@ public:
private: private:
void trustStoreTest(); void trustStoreTest();
void getCertificateWithSplitted();
CPPUNIT_TEST_SUITE(CertStoreTest); CPPUNIT_TEST_SUITE(CertStoreTest);
CPPUNIT_TEST(trustStoreTest); CPPUNIT_TEST(trustStoreTest);
CPPUNIT_TEST(getCertificateWithSplitted);
CPPUNIT_TEST_SUITE_END(); CPPUNIT_TEST_SUITE_END();
}; };
...@@ -157,6 +159,31 @@ CertStoreTest::trustStoreTest() ...@@ -157,6 +159,31 @@ CertStoreTest::trustStoreTest()
== 0); == 0);
} }
void
CertStoreTest::getCertificateWithSplitted()
{
jami::tls::TrustStore trustStore;
auto& certStore = jami::tls::CertificateStore::instance();
auto ca = dht::crypto::generateIdentity("test CA");
auto account = dht::crypto::generateIdentity("test account", ca, 4096, true);
auto device = dht::crypto::generateIdentity("test device", account);
auto caCert = std::make_shared<dht::crypto::Certificate>(ca.second->toString(false));
auto accountCert = std::make_shared<dht::crypto::Certificate>(account.second->toString(false));
auto devicePartialCert = std::make_shared<dht::crypto::Certificate>(
device.second->toString(false));
certStore.pinCertificate(caCert);
certStore.pinCertificate(accountCert);
certStore.pinCertificate(devicePartialCert);
auto fullCert = certStore.getCertificate(device.second->getId().toString());
CPPUNIT_ASSERT(fullCert->issuer && fullCert->issuer->getUID() == accountCert->getUID());
CPPUNIT_ASSERT(fullCert->issuer->issuer
&& fullCert->issuer->issuer->getUID() == caCert->getUID());
}
} // namespace test } // namespace test
} // namespace jami } // namespace jami
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment