mirror of
https://git.jami.net/savoirfairelinux/jami-daemon.git
synced 2025-08-12 22:09:25 +08:00
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
This commit is contained in:
@ -143,15 +143,32 @@ CertificateStore::getPinnedCertificates() const
|
||||
}
|
||||
|
||||
std::shared_ptr<crypto::Certificate>
|
||||
CertificateStore::getCertificate(const std::string& k) const
|
||||
CertificateStore::getCertificate(const std::string& k)
|
||||
{
|
||||
auto getCertificate_ = [this](const std::string& k) -> std::shared_ptr<crypto::Certificate> {
|
||||
auto cit = certs_.find(k);
|
||||
if (cit == certs_.cend())
|
||||
return {};
|
||||
return cit->second;
|
||||
};
|
||||
std::unique_lock<std::mutex> l(lock_);
|
||||
|
||||
auto cit = certs_.find(k);
|
||||
if (cit == certs_.cend()) {
|
||||
return {};
|
||||
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 cit->second;
|
||||
return crt;
|
||||
}
|
||||
|
||||
std::shared_ptr<crypto::Certificate>
|
||||
|
@ -53,7 +53,10 @@ public:
|
||||
CertificateStore();
|
||||
|
||||
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(
|
||||
const std::string& name, crypto::NameType type = crypto::NameType::UNKNOWN) const;
|
||||
|
@ -36,9 +36,11 @@ public:
|
||||
|
||||
private:
|
||||
void trustStoreTest();
|
||||
void getCertificateWithSplitted();
|
||||
|
||||
CPPUNIT_TEST_SUITE(CertStoreTest);
|
||||
CPPUNIT_TEST(trustStoreTest);
|
||||
CPPUNIT_TEST(getCertificateWithSplitted);
|
||||
CPPUNIT_TEST_SUITE_END();
|
||||
};
|
||||
|
||||
@ -157,6 +159,31 @@ CertStoreTest::trustStoreTest()
|
||||
== 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 jami
|
||||
|
||||
|
Reference in New Issue
Block a user