Add support for fallback keys
This commit is contained in:
parent
7f2ae13c43
commit
0a65019242
@ -400,7 +400,7 @@ if(USE_BUNDLED_MTXCLIENT)
|
|||||||
FetchContent_Declare(
|
FetchContent_Declare(
|
||||||
MatrixClient
|
MatrixClient
|
||||||
GIT_REPOSITORY https://github.com/Nheko-Reborn/mtxclient.git
|
GIT_REPOSITORY https://github.com/Nheko-Reborn/mtxclient.git
|
||||||
GIT_TAG 288f585725ecdf2e5e04c5985fdbf658a7fe8a1b
|
GIT_TAG 2122209f04681ac8d61ddd0fa4fcbc8368eb5b5b
|
||||||
)
|
)
|
||||||
set(BUILD_LIB_EXAMPLES OFF CACHE INTERNAL "")
|
set(BUILD_LIB_EXAMPLES OFF CACHE INTERNAL "")
|
||||||
set(BUILD_LIB_TESTS OFF CACHE INTERNAL "")
|
set(BUILD_LIB_TESTS OFF CACHE INTERNAL "")
|
||||||
@ -418,7 +418,7 @@ if(USE_BUNDLED_OLM)
|
|||||||
set(OLM_TESTS OFF CACHE INTERNAL "")
|
set(OLM_TESTS OFF CACHE INTERNAL "")
|
||||||
FetchContent_MakeAvailable(Olm)
|
FetchContent_MakeAvailable(Olm)
|
||||||
else()
|
else()
|
||||||
find_package(Olm 3 REQUIRED)
|
find_package(Olm 3.2.7 REQUIRED)
|
||||||
set_package_properties(Olm PROPERTIES
|
set_package_properties(Olm PROPERTIES
|
||||||
DESCRIPTION "An implementation of the Double Ratchet cryptographic ratchet"
|
DESCRIPTION "An implementation of the Double Ratchet cryptographic ratchet"
|
||||||
URL "https://git.matrix.org/git/olm/about/"
|
URL "https://git.matrix.org/git/olm/about/"
|
||||||
|
@ -203,7 +203,7 @@ modules:
|
|||||||
buildsystem: cmake-ninja
|
buildsystem: cmake-ninja
|
||||||
name: mtxclient
|
name: mtxclient
|
||||||
sources:
|
sources:
|
||||||
- commit: 288f585725ecdf2e5e04c5985fdbf658a7fe8a1b
|
- commit: 2122209f04681ac8d61ddd0fa4fcbc8368eb5b5b
|
||||||
#tag: v0.7.0
|
#tag: v0.7.0
|
||||||
type: git
|
type: git
|
||||||
url: https://github.com/Nheko-Reborn/mtxclient.git
|
url: https://github.com/Nheko-Reborn/mtxclient.git
|
||||||
|
@ -236,6 +236,15 @@ ChatPage::ChatPage(QSharedPointer<UserSettings> userSettings, QObject *parent)
|
|||||||
|
|
||||||
connect(this, &ChatPage::dropToLoginPageCb, this, &ChatPage::dropToLoginPage);
|
connect(this, &ChatPage::dropToLoginPageCb, this, &ChatPage::dropToLoginPage);
|
||||||
|
|
||||||
|
connect(
|
||||||
|
this,
|
||||||
|
&ChatPage::startRemoveFallbackKeyTimer,
|
||||||
|
this,
|
||||||
|
[this]() {
|
||||||
|
QTimer::singleShot(std::chrono::minutes(5), this, &ChatPage::removeOldFallbackKey);
|
||||||
|
},
|
||||||
|
Qt::QueuedConnection);
|
||||||
|
|
||||||
connectCallMessage<mtx::events::msg::CallInvite>();
|
connectCallMessage<mtx::events::msg::CallInvite>();
|
||||||
connectCallMessage<mtx::events::msg::CallCandidates>();
|
connectCallMessage<mtx::events::msg::CallCandidates>();
|
||||||
connectCallMessage<mtx::events::msg::CallAnswer>();
|
connectCallMessage<mtx::events::msg::CallAnswer>();
|
||||||
@ -432,6 +441,7 @@ ChatPage::loadStateFromCache()
|
|||||||
emit contentLoaded();
|
emit contentLoaded();
|
||||||
|
|
||||||
// Start receiving events.
|
// Start receiving events.
|
||||||
|
connect(this, &ChatPage::newSyncResponse, &ChatPage::startRemoveFallbackKeyTimer);
|
||||||
emit trySyncCb();
|
emit trySyncCb();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -495,7 +505,7 @@ ChatPage::tryInitialSync()
|
|||||||
|
|
||||||
// Upload one time keys for the device.
|
// Upload one time keys for the device.
|
||||||
nhlog::crypto()->info("generating one time keys");
|
nhlog::crypto()->info("generating one time keys");
|
||||||
olm::client()->generate_one_time_keys(MAX_ONETIME_KEYS);
|
olm::client()->generate_one_time_keys(MAX_ONETIME_KEYS, true);
|
||||||
|
|
||||||
http::client()->upload_keys(
|
http::client()->upload_keys(
|
||||||
olm::client()->create_upload_keys_request(),
|
olm::client()->create_upload_keys_request(),
|
||||||
@ -519,6 +529,7 @@ ChatPage::tryInitialSync()
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
olm::client()->forget_old_fallback_key();
|
||||||
olm::mark_keys_as_published();
|
olm::mark_keys_as_published();
|
||||||
|
|
||||||
for (const auto &entry : res.one_time_key_counts)
|
for (const auto &entry : res.one_time_key_counts)
|
||||||
@ -608,7 +619,7 @@ ChatPage::handleSyncResponse(const mtx::responses::Sync &res, const std::string
|
|||||||
nhlog::net()->debug("sync completed: {}", res.next_batch);
|
nhlog::net()->debug("sync completed: {}", res.next_batch);
|
||||||
|
|
||||||
// Ensure that we have enough one-time keys available.
|
// Ensure that we have enough one-time keys available.
|
||||||
ensureOneTimeKeyCount(res.device_one_time_keys_count);
|
ensureOneTimeKeyCount(res.device_one_time_keys_count, res.device_unused_fallback_key_types);
|
||||||
|
|
||||||
// TODO: fine grained error handling
|
// TODO: fine grained error handling
|
||||||
try {
|
try {
|
||||||
@ -989,26 +1000,38 @@ ChatPage::verifyOneTimeKeyCountAfterStartup()
|
|||||||
nhlog::crypto()->info(
|
nhlog::crypto()->info(
|
||||||
"Fetched server key count {} {}", count, mtx::crypto::SIGNED_CURVE25519);
|
"Fetched server key count {} {}", count, mtx::crypto::SIGNED_CURVE25519);
|
||||||
|
|
||||||
ensureOneTimeKeyCount(key_counts);
|
ensureOneTimeKeyCount(key_counts, std::nullopt);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
ChatPage::ensureOneTimeKeyCount(const std::map<std::string, uint16_t> &counts)
|
ChatPage::ensureOneTimeKeyCount(const std::map<std::string, uint16_t> &counts,
|
||||||
|
const std::optional<std::vector<std::string>> &unused_fallback_keys)
|
||||||
{
|
{
|
||||||
if (auto count = counts.find(mtx::crypto::SIGNED_CURVE25519); count != counts.end()) {
|
if (auto count = counts.find(mtx::crypto::SIGNED_CURVE25519); count != counts.end()) {
|
||||||
|
bool replace_fallback_key = false;
|
||||||
|
if (unused_fallback_keys &&
|
||||||
|
std::find(unused_fallback_keys->begin(),
|
||||||
|
unused_fallback_keys->end(),
|
||||||
|
mtx::crypto::SIGNED_CURVE25519) == unused_fallback_keys->end())
|
||||||
|
replace_fallback_key = true;
|
||||||
nhlog::crypto()->debug(
|
nhlog::crypto()->debug(
|
||||||
"Updated server key count {} {}", count->second, mtx::crypto::SIGNED_CURVE25519);
|
"Updated server key count {} {}, fallback keys supported: {}, new fallback key: {}",
|
||||||
|
count->second,
|
||||||
|
mtx::crypto::SIGNED_CURVE25519,
|
||||||
|
unused_fallback_keys.has_value(),
|
||||||
|
replace_fallback_key);
|
||||||
|
|
||||||
if (count->second < MAX_ONETIME_KEYS) {
|
if (count->second < MAX_ONETIME_KEYS || replace_fallback_key) {
|
||||||
const size_t nkeys = MAX_ONETIME_KEYS - count->second;
|
const size_t nkeys = MAX_ONETIME_KEYS - count->second;
|
||||||
|
|
||||||
nhlog::crypto()->info("uploading {} {} keys", nkeys, mtx::crypto::SIGNED_CURVE25519);
|
nhlog::crypto()->info("uploading {} {} keys", nkeys, mtx::crypto::SIGNED_CURVE25519);
|
||||||
olm::client()->generate_one_time_keys(nkeys);
|
olm::client()->generate_one_time_keys(nkeys, replace_fallback_key);
|
||||||
|
|
||||||
http::client()->upload_keys(
|
http::client()->upload_keys(
|
||||||
olm::client()->create_upload_keys_request(),
|
olm::client()->create_upload_keys_request(),
|
||||||
[](const mtx::responses::UploadKeys &, mtx::http::RequestErr err) {
|
[replace_fallback_key, this](const mtx::responses::UploadKeys &,
|
||||||
|
mtx::http::RequestErr err) {
|
||||||
if (err) {
|
if (err) {
|
||||||
nhlog::crypto()->warn("failed to update one-time keys: {}", err);
|
nhlog::crypto()->warn("failed to update one-time keys: {}", err);
|
||||||
|
|
||||||
@ -1018,6 +1041,10 @@ ChatPage::ensureOneTimeKeyCount(const std::map<std::string, uint16_t> &counts)
|
|||||||
|
|
||||||
// mark as published anyway, otherwise we may end up in a loop.
|
// mark as published anyway, otherwise we may end up in a loop.
|
||||||
olm::mark_keys_as_published();
|
olm::mark_keys_as_published();
|
||||||
|
|
||||||
|
if (replace_fallback_key) {
|
||||||
|
emit startRemoveFallbackKeyTimer();
|
||||||
|
}
|
||||||
});
|
});
|
||||||
} else if (count->second > 2 * MAX_ONETIME_KEYS) {
|
} else if (count->second > 2 * MAX_ONETIME_KEYS) {
|
||||||
nhlog::crypto()->warn("too many one-time keys, deleting 1");
|
nhlog::crypto()->warn("too many one-time keys, deleting 1");
|
||||||
@ -1035,6 +1062,14 @@ ChatPage::ensureOneTimeKeyCount(const std::map<std::string, uint16_t> &counts)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
ChatPage::removeOldFallbackKey()
|
||||||
|
{
|
||||||
|
olm::client()->forget_old_fallback_key();
|
||||||
|
olm::mark_keys_as_published();
|
||||||
|
disconnect(this, &ChatPage::newSyncResponse, this, &ChatPage::removeOldFallbackKey);
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
ChatPage::getProfileInfo()
|
ChatPage::getProfileInfo()
|
||||||
{
|
{
|
||||||
|
@ -127,6 +127,7 @@ signals:
|
|||||||
void leftRoom(const QString &room_id);
|
void leftRoom(const QString &room_id);
|
||||||
void newRoom(const QString &room_id);
|
void newRoom(const QString &room_id);
|
||||||
void changeToRoom(const QString &room_id);
|
void changeToRoom(const QString &room_id);
|
||||||
|
void startRemoveFallbackKeyTimer();
|
||||||
|
|
||||||
void initializeViews(const mtx::responses::Sync &rooms);
|
void initializeViews(const mtx::responses::Sync &rooms);
|
||||||
void initializeEmptyViews();
|
void initializeEmptyViews();
|
||||||
@ -183,7 +184,9 @@ private:
|
|||||||
void tryInitialSync();
|
void tryInitialSync();
|
||||||
void trySync();
|
void trySync();
|
||||||
void verifyOneTimeKeyCountAfterStartup();
|
void verifyOneTimeKeyCountAfterStartup();
|
||||||
void ensureOneTimeKeyCount(const std::map<std::string, uint16_t> &counts);
|
void ensureOneTimeKeyCount(const std::map<std::string, uint16_t> &counts,
|
||||||
|
const std::optional<std::vector<std::string>> &fallback_keys);
|
||||||
|
void removeOldFallbackKey();
|
||||||
void getProfileInfo();
|
void getProfileInfo();
|
||||||
void getBackupVersion();
|
void getBackupVersion();
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user