mirror of
https://github.com/Nheko-Reborn/nheko.git
synced 2024-11-22 19:08:58 +03:00
Fix in room verification
This commit is contained in:
parent
8a4d85f801
commit
64d5a193f1
5 changed files with 103 additions and 107 deletions
|
@ -7,6 +7,8 @@ import im.nheko 1.0
|
||||||
ApplicationWindow {
|
ApplicationWindow {
|
||||||
property var flow
|
property var flow
|
||||||
|
|
||||||
|
onClosing: TimelineManager.removeVerificationFlow(flow)
|
||||||
|
|
||||||
title: stack.currentItem.title
|
title: stack.currentItem.title
|
||||||
id: dialog
|
id: dialog
|
||||||
|
|
||||||
|
|
|
@ -13,6 +13,15 @@ static constexpr int TIMEOUT = 2 * 60 * 1000; // 2 minutes
|
||||||
|
|
||||||
namespace msgs = mtx::events::msg;
|
namespace msgs = mtx::events::msg;
|
||||||
|
|
||||||
|
static mtx::events::msg::KeyVerificationMac
|
||||||
|
key_verification_mac(mtx::crypto::SAS *sas,
|
||||||
|
mtx::identifiers::User sender,
|
||||||
|
const std::string &senderDevice,
|
||||||
|
mtx::identifiers::User receiver,
|
||||||
|
const std::string &receiverDevice,
|
||||||
|
const std::string &transactionId,
|
||||||
|
std::map<std::string, std::string> keys);
|
||||||
|
|
||||||
DeviceVerificationFlow::DeviceVerificationFlow(QObject *,
|
DeviceVerificationFlow::DeviceVerificationFlow(QObject *,
|
||||||
DeviceVerificationFlow::Type flow_type,
|
DeviceVerificationFlow::Type flow_type,
|
||||||
TimelineModel *model,
|
TimelineModel *model,
|
||||||
|
@ -45,11 +54,7 @@ DeviceVerificationFlow::DeviceVerificationFlow(QObject *,
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (const auto &[algorithm, key] :
|
this->their_keys = res;
|
||||||
res.device_keys.at(deviceId.toStdString()).keys) {
|
|
||||||
// TODO: Verify Signatures
|
|
||||||
this->device_keys[algorithm] = key;
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
|
|
||||||
if (model) {
|
if (model) {
|
||||||
|
@ -115,7 +120,7 @@ DeviceVerificationFlow::DeviceVerificationFlow(QObject *,
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
error_ = User;
|
error_ = User;
|
||||||
Emit errorChanged();
|
emit errorChanged();
|
||||||
setState(Failed);
|
setState(Failed);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -160,6 +165,8 @@ DeviceVerificationFlow::DeviceVerificationFlow(QObject *,
|
||||||
"|" + this->transaction_id;
|
"|" + this->transaction_id;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
nhlog::ui()->info("Info is: '{}'", info);
|
||||||
|
|
||||||
if (this->sender == false) {
|
if (this->sender == false) {
|
||||||
this->sendVerificationKey();
|
this->sendVerificationKey();
|
||||||
} else {
|
} else {
|
||||||
|
@ -193,28 +200,40 @@ DeviceVerificationFlow::DeviceVerificationFlow(QObject *,
|
||||||
if (msg.relates_to.value().event_id != this->relation.event_id)
|
if (msg.relates_to.value().event_id != this->relation.event_id)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
std::string info = "MATRIX_KEY_VERIFICATION_MAC" + this->toClient.to_string() +
|
|
||||||
this->deviceId.toStdString() +
|
|
||||||
http::client()->user_id().to_string() +
|
|
||||||
http::client()->device_id() + this->transaction_id;
|
|
||||||
|
|
||||||
std::vector<std::string> key_list;
|
std::map<std::string, std::string> key_list;
|
||||||
std::string key_string;
|
std::string key_string;
|
||||||
for (auto mac : msg.mac) {
|
for (const auto &mac : msg.mac) {
|
||||||
key_string += mac.first + ",";
|
for (const auto &[deviceid, key] : their_keys.device_keys)
|
||||||
if (device_keys[mac.first] != "") {
|
if (key.keys.count(mac.first))
|
||||||
if (mac.second ==
|
key_list[mac.first] = key.keys.at(mac.first);
|
||||||
this->sas->calculate_mac(this->device_keys[mac.first],
|
|
||||||
info + mac.first)) {
|
if (their_keys.master_keys.keys.count(mac.first))
|
||||||
} else {
|
key_list[mac.first] = their_keys.master_keys.keys[mac.first];
|
||||||
|
if (their_keys.user_signing_keys.keys.count(mac.first))
|
||||||
|
key_list[mac.first] =
|
||||||
|
their_keys.user_signing_keys.keys[mac.first];
|
||||||
|
if (their_keys.self_signing_keys.keys.count(mac.first))
|
||||||
|
key_list[mac.first] =
|
||||||
|
their_keys.self_signing_keys.keys[mac.first];
|
||||||
|
}
|
||||||
|
auto macs = key_verification_mac(sas.get(),
|
||||||
|
toClient,
|
||||||
|
this->deviceId.toStdString(),
|
||||||
|
http::client()->user_id(),
|
||||||
|
http::client()->device_id(),
|
||||||
|
this->transaction_id,
|
||||||
|
key_list);
|
||||||
|
|
||||||
|
for (const auto &[key, mac] : macs.mac) {
|
||||||
|
if (mac != msg.mac.at(key)) {
|
||||||
this->cancelVerification(
|
this->cancelVerification(
|
||||||
DeviceVerificationFlow::Error::KeyMismatch);
|
DeviceVerificationFlow::Error::KeyMismatch);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
key_string = key_string.substr(0, key_string.length() - 1);
|
if (msg.keys == macs.keys) {
|
||||||
if (msg.keys == this->sas->calculate_mac(key_string, info + "KEY_IDS")) {
|
|
||||||
this->isMacVerified = true;
|
this->isMacVerified = true;
|
||||||
this->acceptDevice();
|
this->acceptDevice();
|
||||||
} else {
|
} else {
|
||||||
|
@ -630,9 +649,13 @@ DeviceVerificationFlow::NewInRoomVerification(QObject *parent_,
|
||||||
QString event_id_)
|
QString event_id_)
|
||||||
{
|
{
|
||||||
QSharedPointer<DeviceVerificationFlow> flow(
|
QSharedPointer<DeviceVerificationFlow> flow(
|
||||||
new DeviceVerificationFlow(parent_, Type::RoomMsg, timelineModel_, other_user_, ""));
|
new DeviceVerificationFlow(parent_,
|
||||||
|
Type::RoomMsg,
|
||||||
|
timelineModel_,
|
||||||
|
other_user_,
|
||||||
|
QString::fromStdString(msg.from_device)));
|
||||||
|
|
||||||
flow->event_id = event_id_.toStdString();
|
flow->setEventId(event_id_.toStdString());
|
||||||
|
|
||||||
if (std::find(msg.methods.begin(),
|
if (std::find(msg.methods.begin(),
|
||||||
msg.methods.end(),
|
msg.methods.end(),
|
||||||
|
|
|
@ -56,7 +56,6 @@ using sas_ptr = std::unique_ptr<mtx::crypto::SAS>;
|
||||||
class DeviceVerificationFlow : public QObject
|
class DeviceVerificationFlow : public QObject
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
// Q_CLASSINFO("RegisterEnumClassesUnscoped", "false")
|
|
||||||
Q_PROPERTY(QString state READ state NOTIFY stateChanged)
|
Q_PROPERTY(QString state READ state NOTIFY stateChanged)
|
||||||
Q_PROPERTY(Error error READ error NOTIFY errorChanged)
|
Q_PROPERTY(Error error READ error NOTIFY errorChanged)
|
||||||
Q_PROPERTY(QString userId READ getUserId CONSTANT)
|
Q_PROPERTY(QString userId READ getUserId CONSTANT)
|
||||||
|
@ -179,11 +178,7 @@ private:
|
||||||
//! Completes the verification flow
|
//! Completes the verification flow
|
||||||
void acceptDevice();
|
void acceptDevice();
|
||||||
|
|
||||||
// for to_device messages
|
|
||||||
std::string transaction_id;
|
std::string transaction_id;
|
||||||
// for room messages
|
|
||||||
std::optional<std::string> room_id;
|
|
||||||
std::optional<std::string> event_id;
|
|
||||||
|
|
||||||
bool sender;
|
bool sender;
|
||||||
Type type;
|
Type type;
|
||||||
|
@ -198,7 +193,7 @@ private:
|
||||||
nlohmann::json canonical_json;
|
nlohmann::json canonical_json;
|
||||||
|
|
||||||
std::vector<int> sasList;
|
std::vector<int> sasList;
|
||||||
std::map<std::string, std::string> device_keys;
|
UserKeyCache their_keys;
|
||||||
TimelineModel *model_;
|
TimelineModel *model_;
|
||||||
mtx::common::RelatesTo relation;
|
mtx::common::RelatesTo relation;
|
||||||
|
|
||||||
|
|
|
@ -280,8 +280,6 @@ EventStore::handleSync(const mtx::responses::Timeline &events)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
handle_room_verification(event);
|
|
||||||
|
|
||||||
// decrypting and checking some encrypted messages
|
// decrypting and checking some encrypted messages
|
||||||
if (auto encrypted =
|
if (auto encrypted =
|
||||||
std::get_if<mtx::events::EncryptedEvent<mtx::events::msg::Encrypted>>(
|
std::get_if<mtx::events::EncryptedEvent<mtx::events::msg::Encrypted>>(
|
||||||
|
@ -292,81 +290,65 @@ EventStore::handleSync(const mtx::responses::Timeline &events)
|
||||||
[](auto e) { return (e.sender != utils::localUser().toStdString()); },
|
[](auto e) { return (e.sender != utils::localUser().toStdString()); },
|
||||||
*d_event)) {
|
*d_event)) {
|
||||||
handle_room_verification(*d_event);
|
handle_room_verification(*d_event);
|
||||||
} else {
|
|
||||||
// only the key.verification.ready sent by localuser's other device
|
|
||||||
// is of significance as it is used for detecting accepted request
|
|
||||||
if (std::get_if<mtx::events::RoomEvent<
|
|
||||||
mtx::events::msg::KeyVerificationReady>>(d_event)) {
|
|
||||||
auto msg = std::get_if<mtx::events::RoomEvent<
|
|
||||||
mtx::events::msg::KeyVerificationReady>>(d_event);
|
|
||||||
ChatPage::instance()->receivedDeviceVerificationReady(
|
|
||||||
msg->content);
|
|
||||||
}
|
}
|
||||||
|
// else {
|
||||||
|
// // only the key.verification.ready sent by localuser's other
|
||||||
|
// device
|
||||||
|
// // is of significance as it is used for detecting accepted request
|
||||||
|
// if (std::get_if<mtx::events::RoomEvent<
|
||||||
|
// mtx::events::msg::KeyVerificationReady>>(d_event)) {
|
||||||
|
// auto msg = std::get_if<mtx::events::RoomEvent<
|
||||||
|
// mtx::events::msg::KeyVerificationReady>>(d_event);
|
||||||
|
// ChatPage::instance()->receivedDeviceVerificationReady(
|
||||||
|
// msg->content);
|
||||||
|
// }
|
||||||
|
//}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (last_verification_request_event.has_value()) {
|
namespace {
|
||||||
if (last_verification_request_event.value().origin_server_ts >
|
template<class... Ts>
|
||||||
last_verification_cancel_event.origin_server_ts) {
|
struct overloaded : Ts...
|
||||||
emit startDMVerification(last_verification_request_event.value());
|
{
|
||||||
last_verification_request_event = {};
|
using Ts::operator()...;
|
||||||
}
|
};
|
||||||
}
|
template<class... Ts>
|
||||||
|
overloaded(Ts...) -> overloaded<Ts...>;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
EventStore::handle_room_verification(mtx::events::collections::TimelineEvents event)
|
EventStore::handle_room_verification(mtx::events::collections::TimelineEvents event)
|
||||||
{
|
{
|
||||||
if (std::get_if<mtx::events::RoomEvent<mtx::events::msg::KeyVerificationRequest>>(&event)) {
|
std::visit(
|
||||||
auto msg =
|
overloaded{
|
||||||
std::get<mtx::events::RoomEvent<mtx::events::msg::KeyVerificationRequest>>(event);
|
[this](const mtx::events::RoomEvent<mtx::events::msg::KeyVerificationRequest> &msg) {
|
||||||
last_verification_request_event = msg;
|
emit startDMVerification(msg);
|
||||||
return;
|
},
|
||||||
} else if (std::get_if<mtx::events::RoomEvent<mtx::events::msg::KeyVerificationCancel>>(
|
[](const mtx::events::RoomEvent<mtx::events::msg::KeyVerificationCancel> &msg) {
|
||||||
&event)) {
|
|
||||||
auto msg =
|
|
||||||
std::get<mtx::events::RoomEvent<mtx::events::msg::KeyVerificationCancel>>(event);
|
|
||||||
last_verification_cancel_event = msg;
|
|
||||||
ChatPage::instance()->receivedDeviceVerificationCancel(msg.content);
|
ChatPage::instance()->receivedDeviceVerificationCancel(msg.content);
|
||||||
return;
|
},
|
||||||
} else if (std::get_if<mtx::events::RoomEvent<mtx::events::msg::KeyVerificationAccept>>(
|
[](const mtx::events::RoomEvent<mtx::events::msg::KeyVerificationAccept> &msg) {
|
||||||
&event)) {
|
|
||||||
auto msg =
|
|
||||||
std::get<mtx::events::RoomEvent<mtx::events::msg::KeyVerificationAccept>>(event);
|
|
||||||
ChatPage::instance()->receivedDeviceVerificationAccept(msg.content);
|
ChatPage::instance()->receivedDeviceVerificationAccept(msg.content);
|
||||||
return;
|
},
|
||||||
} else if (std::get_if<mtx::events::RoomEvent<mtx::events::msg::KeyVerificationKey>>(
|
[](const mtx::events::RoomEvent<mtx::events::msg::KeyVerificationKey> &msg) {
|
||||||
&event)) {
|
|
||||||
auto msg =
|
|
||||||
std::get<mtx::events::RoomEvent<mtx::events::msg::KeyVerificationKey>>(event);
|
|
||||||
ChatPage::instance()->receivedDeviceVerificationKey(msg.content);
|
ChatPage::instance()->receivedDeviceVerificationKey(msg.content);
|
||||||
return;
|
},
|
||||||
} else if (std::get_if<mtx::events::RoomEvent<mtx::events::msg::KeyVerificationMac>>(
|
[](const mtx::events::RoomEvent<mtx::events::msg::KeyVerificationMac> &msg) {
|
||||||
&event)) {
|
|
||||||
auto msg =
|
|
||||||
std::get<mtx::events::RoomEvent<mtx::events::msg::KeyVerificationMac>>(event);
|
|
||||||
ChatPage::instance()->receivedDeviceVerificationMac(msg.content);
|
ChatPage::instance()->receivedDeviceVerificationMac(msg.content);
|
||||||
return;
|
},
|
||||||
} else if (std::get_if<mtx::events::RoomEvent<mtx::events::msg::KeyVerificationReady>>(
|
[](const mtx::events::RoomEvent<mtx::events::msg::KeyVerificationReady> &msg) {
|
||||||
&event)) {
|
|
||||||
auto msg =
|
|
||||||
std::get<mtx::events::RoomEvent<mtx::events::msg::KeyVerificationReady>>(event);
|
|
||||||
ChatPage::instance()->receivedDeviceVerificationReady(msg.content);
|
ChatPage::instance()->receivedDeviceVerificationReady(msg.content);
|
||||||
return;
|
},
|
||||||
} else if (std::get_if<mtx::events::RoomEvent<mtx::events::msg::KeyVerificationDone>>(
|
[](const mtx::events::RoomEvent<mtx::events::msg::KeyVerificationDone> &msg) {
|
||||||
&event)) {
|
|
||||||
auto msg =
|
|
||||||
std::get<mtx::events::RoomEvent<mtx::events::msg::KeyVerificationDone>>(event);
|
|
||||||
ChatPage::instance()->receivedDeviceVerificationDone(msg.content);
|
ChatPage::instance()->receivedDeviceVerificationDone(msg.content);
|
||||||
return;
|
},
|
||||||
} else if (std::get_if<mtx::events::RoomEvent<mtx::events::msg::KeyVerificationStart>>(
|
[](const mtx::events::RoomEvent<mtx::events::msg::KeyVerificationStart> &msg) {
|
||||||
&event)) {
|
|
||||||
auto msg =
|
|
||||||
std::get<mtx::events::RoomEvent<mtx::events::msg::KeyVerificationStart>>(event);
|
|
||||||
ChatPage::instance()->receivedDeviceVerificationStart(msg.content, msg.sender);
|
ChatPage::instance()->receivedDeviceVerificationStart(msg.content, msg.sender);
|
||||||
return;
|
},
|
||||||
}
|
[](const auto &) {},
|
||||||
|
},
|
||||||
|
event);
|
||||||
}
|
}
|
||||||
|
|
||||||
QVariantList
|
QVariantList
|
||||||
|
|
|
@ -99,7 +99,7 @@ signals:
|
||||||
void messageSent(std::string txn_id, std::string event_id);
|
void messageSent(std::string txn_id, std::string event_id);
|
||||||
void messageFailed(std::string txn_id);
|
void messageFailed(std::string txn_id);
|
||||||
void startDMVerification(
|
void startDMVerification(
|
||||||
mtx::events::RoomEvent<mtx::events::msg::KeyVerificationRequest> &msg);
|
const mtx::events::RoomEvent<mtx::events::msg::KeyVerificationRequest> &msg);
|
||||||
void updateFlowEventId(std::string event_id);
|
void updateFlowEventId(std::string event_id);
|
||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
|
@ -123,10 +123,4 @@ private:
|
||||||
|
|
||||||
std::string current_txn;
|
std::string current_txn;
|
||||||
int current_txn_error_count = 0;
|
int current_txn_error_count = 0;
|
||||||
|
|
||||||
// probably not the best way to do
|
|
||||||
std::optional<mtx::events::RoomEvent<mtx::events::msg::KeyVerificationRequest>>
|
|
||||||
last_verification_request_event;
|
|
||||||
mtx::events::RoomEvent<mtx::events::msg::KeyVerificationCancel>
|
|
||||||
last_verification_cancel_event;
|
|
||||||
};
|
};
|
||||||
|
|
Loading…
Reference in a new issue