diff --git a/src/ringdht/ringaccount.cpp b/src/ringdht/ringaccount.cpp index 894c03453571cdb8b3332d707505b7d05d436b67..abd4bea70b876138ac1ff7fbe4f7fd530bb1b274 100644 --- a/src/ringdht/ringaccount.cpp +++ b/src/ringdht/ringaccount.cpp @@ -792,19 +792,19 @@ RingAccount::makeReceipt(const dht::crypto::Identity& id) } bool -RingAccount::hasSignedReceipt() +RingAccount::useIdentity(const dht::crypto::Identity& identity) { if (receipt_.empty() or receiptSignature_.empty()) return false; - if (not identity_.first or not identity_.second) { - RING_ERR("[Account %s] no identity loaded", getAccountID().c_str()); + if (not identity.first or not identity.second) { + RING_ERR("[Account %s] no identity provided", getAccountID().c_str()); return false; } - auto accountCertificate = identity_.second->issuer; + auto accountCertificate = identity.second->issuer; if (not accountCertificate) { - RING_ERR("Device certificate must be signed by the account certificate"); + RING_ERR("Device certificate must be issued by the account certificate"); return false; } @@ -821,7 +821,7 @@ RingAccount::hasSignedReceipt() return false; auto dev_id = root["dev"].asString(); - if (dev_id != identity_.second->getId().toString()) { + if (dev_id != identity.second->getId().toString()) { RING_ERR("[Account %s] device ID mismatch between receipt and certificate", getAccountID().c_str()); return false; } @@ -852,8 +852,10 @@ RingAccount::hasSignedReceipt() return false; } + // success, make use of this identity (certificate chain and private key) + identity_ = identity; ringAccountId_ = id; - ringDeviceId_ = identity_.first->getPublicKey().getId().toString(); + ringDeviceId_ = identity.first->getPublicKey().getId().toString(); username_ = RING_URI_PREFIX + id; announce_ = std::make_shared<dht::Value>(std::move(announce_val)); ethAccount_ = root["eth"].asString(); @@ -863,20 +865,13 @@ RingAccount::hasSignedReceipt() } dht::crypto::Identity -RingAccount::loadIdentity() +RingAccount::loadIdentity(const std::string& crt_path, const std::string& key_path, const std::string& key_pwd) { - RING_DBG("[Account %s] loading identity: %s %s", getAccountID().c_str(), tlsCertificateFile_.c_str(), tlsPrivateKeyFile_.c_str()); - dht::crypto::Certificate dht_cert; - dht::crypto::PrivateKey dht_key; + RING_DBG("Loading identity: %s %s", crt_path.c_str(), key_path.c_str()); + dht::crypto::Identity id; try { -#if TARGET_OS_IPHONE - const auto path = fileutils::get_data_dir() + DIR_SEPARATOR_STR + getAccountID() + DIR_SEPARATOR_STR; - dht_cert = dht::crypto::Certificate(fileutils::loadFile(path + tlsCertificateFile_)); - dht_key = dht::crypto::PrivateKey(fileutils::loadFile(path + tlsPrivateKeyFile_), tlsPassword_); -#else - dht_cert = dht::crypto::Certificate(fileutils::loadFile(tlsCertificateFile_)); - dht_key = dht::crypto::PrivateKey(fileutils::loadFile(tlsPrivateKeyFile_), tlsPassword_); -#endif + dht::crypto::Certificate dht_cert(fileutils::loadFile(crt_path)); + dht::crypto::PrivateKey dht_key(fileutils::loadFile(key_path), key_pwd); auto crt_id = dht_cert.getId(); if (crt_id != dht_key.getPublicKey().getId()) return {}; @@ -888,7 +883,7 @@ RingAccount::loadIdentity() // load revocation lists for device authority (account certificate). tls::CertificateStore::instance().loadRevocations(*dht_cert.issuer); - identity_ = { + id = { std::make_shared<dht::crypto::PrivateKey>(std::move(dht_key)), std::make_shared<dht::crypto::Certificate>(std::move(dht_cert)) }; @@ -897,7 +892,7 @@ RingAccount::loadIdentity() RING_ERR("Error loading identity: %s", e.what()); } - return identity_; + return id; } RingAccount::ArchiveContent @@ -1318,11 +1313,11 @@ RingAccount::createAccount(const std::string& archive_password) } bool -RingAccount::needsMigration() const +RingAccount::needsMigration(const dht::crypto::Identity& id) { - if (not identity_.second) + if (not id.second) return true; - auto cert = identity_.second->issuer; + auto cert = id.second->issuer; while (cert) { if (not cert->isCA() or cert->getExpiration() < std::chrono::system_clock::now()) return true; @@ -1392,20 +1387,28 @@ RingAccount::loadAccount(const std::string& archive_password, const std::string& RING_DBG("[Account %s] loading Ring account", getAccountID().c_str()); try { - loadIdentity(); - loadKnownDevices(); - loadContacts(); - loadTrustRequests(); - +#if TARGET_OS_IPHONE + const auto certPath = idPath_ + DIR_SEPARATOR_STR + tlsCertificateFile_; + const auto keyPath = idPath_ + DIR_SEPARATOR_STR + tlsPrivateKeyFile_; +#else + const auto& certPath = tlsCertificateFile_; + const auto& keyPath = tlsPrivateKeyFile_; +#endif + auto id = loadIdentity(certPath, keyPath, tlsPassword_); + bool hasValidId = useIdentity(id); + bool needMigration = hasValidId and needsMigration(id); bool hasArchive = not archivePath_.empty() and fileutils::isFile(archivePath_); - bool hasReceipt = hasSignedReceipt(); - bool needMigration = hasReceipt and needsMigration(); - if (not needMigration and hasReceipt) { - if (not hasArchive) - RING_WARN("[Account %s] account archive not found, won't be able to add new devices.", getAccountID().c_str()); - // normal account loading path - return; + if (hasValidId) { + loadKnownDevices(); + loadContacts(); + loadTrustRequests(); + if (not needMigration) { + if (not hasArchive) + RING_WARN("[Account %s] account archive not found, won't be able to add new devices.", getAccountID().c_str()); + // normal account loading path + return; + } } if (hasArchive) { @@ -1440,9 +1443,9 @@ RingAccount::loadAccount(const std::string& archive_password, const std::string& } } } - } catch (const std::exception& e) { RING_WARN("[Account %s] error loading account: %s", getAccountID().c_str(), e.what()); + identity_ = dht::crypto::Identity{}; setRegistrationState(RegistrationState::ERROR_GENERIC); } } diff --git a/src/ringdht/ringaccount.h b/src/ringdht/ringaccount.h index 84fccbd22c53b221df701acd95f560766e3da28e..92bdca7bda5737de88c4cfb7138864ebe545db95 100644 --- a/src/ringdht/ringaccount.h +++ b/src/ringdht/ringaccount.h @@ -483,8 +483,8 @@ class RingAccount : public SIPAccountBase { bool hasCertificate() const; bool hasPrivateKey() const; - bool hasSignedReceipt(); - bool needsMigration() const; + bool useIdentity(const dht::crypto::Identity& id); + static bool needsMigration(const dht::crypto::Identity& id); std::string makeReceipt(const dht::crypto::Identity& id); void createRingDevice(const dht::crypto::Identity& id); @@ -525,7 +525,7 @@ class RingAccount : public SIPAccountBase { * and certPath_ a valid certificate file, load and returns them. * Otherwise, generate a new identity and returns it. */ - dht::crypto::Identity loadIdentity(); + static dht::crypto::Identity loadIdentity(const std::string& crt_path, const std::string& key_path, const std::string& key_pwd); std::vector<dht::NodeExport> loadNodes() const; std::vector<dht::ValuesExport> loadValues() const;