some further work on omemo, far from done yet

This commit is contained in:
Blue 2023-03-02 21:17:06 +03:00
parent 6f32e99593
commit 77dd28b600
Signed by untrusted user: blue
GPG Key ID: 9B203B252A63EE38
18 changed files with 161 additions and 43 deletions

View File

@ -106,6 +106,8 @@ Account::Account(const QString& p_login, const QString& p_server, const QString&
#ifdef WITH_OMEMO #ifdef WITH_OMEMO
client.addExtension(tm); client.addExtension(tm);
client.addExtension(om); client.addExtension(om);
om->setSecurityPolicy(QXmpp::Toakafa);
om->setNewDeviceAutoSessionBuildingEnabled(true);
if (oh->hasOwnDevice()) { if (oh->hasOwnDevice()) {
QXmppTask<bool> future = om->load(); QXmppTask<bool> future = om->load();

View File

@ -110,10 +110,10 @@ void Core::DiscoveryHandler::onInfoReceived(const QXmppDiscoveryIq& info)
} }
} }
acc->setPepSupport(pepSupported ? Shared::Support::supported : Shared::Support::unsupported); acc->setPepSupport(pepSupported ? Shared::Support::supported : Shared::Support::unsupported);
} else { } else {
qDebug() << "Received info for account" << accName << "about" << from;
QString node = info.queryNode(); QString node = info.queryNode();
if (!node.isEmpty()) { if (!node.isEmpty()) {
qDebug() << "Received features and identities for account" << accName << "about" << from;
QStringList feats = info.features(); QStringList feats = info.features();
std::set<Shared::Identity> identities; std::set<Shared::Identity> identities;
std::set<QString> features(feats.begin(), feats.end()); std::set<QString> features(feats.begin(), feats.end());
@ -135,7 +135,7 @@ void Core::DiscoveryHandler::onInfoReceived(const QXmppDiscoveryIq& info)
} else { } else {
Contact* cont = acc->rh->getContact(from); Contact* cont = acc->rh->getContact(from);
if (cont != nullptr) { if (cont != nullptr) {
qDebug() << "Received info for account" << accName << "about" << from; qDebug() << "Received info for account" << accName << "about contact" << from;
QList<QXmppDiscoveryIq::Identity> identities = info.identities(); QList<QXmppDiscoveryIq::Identity> identities = info.identities();
bool pepSupported = false; bool pepSupported = false;
for (const QXmppDiscoveryIq::Identity& identity : identities) { for (const QXmppDiscoveryIq::Identity& identity : identities) {

View File

@ -154,6 +154,19 @@ QXmppTask<void> Core::OmemoHandler::resetAll() {
return Core::makeReadyTask(); return Core::makeReadyTask();
} }
void Core::OmemoHandler::getDevices(const QString& jid, std::list<Shared::KeyInfo>& out) const {
QHash<uint32_t, Device> devs;
try {
devs = devices->getRecord(jid);
} catch (const DataBase::NotFound& error) {}
for (QHash<uint32_t, Device>::const_iterator itr = devs.begin(), end = devs.end(); itr != end; ++itr) {
const Device& dev = itr.value();
out.emplace_back(itr.key(), dev.keyId, dev.label, QDateTime(), Shared::TrustLevel::undecided, Shared::EncryptionProtocol::omemo2, false);
}
}
QDataStream & operator >> (QDataStream& in, QXmppOmemoStorage::Device& device) { QDataStream & operator >> (QDataStream& in, QXmppOmemoStorage::Device& device) {
in >> device.label; in >> device.label;
in >> device.keyId; in >> device.keyId;

View File

@ -17,9 +17,15 @@
#ifndef CORE_OMEMOHANDLER_H #ifndef CORE_OMEMOHANDLER_H
#define CORE_OMEMOHANDLER_H #define CORE_OMEMOHANDLER_H
#include <map>
#include <list>
#include <QXmppOmemoStorage.h> #include <QXmppOmemoStorage.h>
#include <cache.h> #include <cache.h>
#include <shared/keyinfo.h>
#include <shared/enums.h>
Q_DECLARE_METATYPE(QXmppOmemoStorage::OwnDevice); Q_DECLARE_METATYPE(QXmppOmemoStorage::OwnDevice);
Q_DECLARE_METATYPE(QXmppOmemoStorage::Device); Q_DECLARE_METATYPE(QXmppOmemoStorage::Device);
@ -34,24 +40,26 @@ public:
OmemoHandler(Account* account); OmemoHandler(Account* account);
~OmemoHandler() override; ~OmemoHandler() override;
QXmppTask<OmemoData> allData() override; virtual QXmppTask<OmemoData> allData() override;
QXmppTask<void> setOwnDevice(const std::optional<OwnDevice> &device) override; virtual QXmppTask<void> setOwnDevice(const std::optional<OwnDevice> &device) override;
QXmppTask<void> addSignedPreKeyPair(uint32_t keyId, const QXmppOmemoStorage::SignedPreKeyPair &keyPair) override; virtual QXmppTask<void> addSignedPreKeyPair(uint32_t keyId, const QXmppOmemoStorage::SignedPreKeyPair &keyPair) override;
QXmppTask<void> removeSignedPreKeyPair(uint32_t keyId) override; virtual QXmppTask<void> removeSignedPreKeyPair(uint32_t keyId) override;
QXmppTask<void> addPreKeyPairs(const QHash<uint32_t, QByteArray> &keyPairs) override; virtual QXmppTask<void> addPreKeyPairs(const QHash<uint32_t, QByteArray> &keyPairs) override;
QXmppTask<void> removePreKeyPair(uint32_t keyId) override; virtual QXmppTask<void> removePreKeyPair(uint32_t keyId) override;
QXmppTask<void> addDevice(const QString &jid, uint32_t deviceId, const Device &device) override; virtual QXmppTask<void> addDevice(const QString &jid, uint32_t deviceId, const Device &device) override;
QXmppTask<void> removeDevice(const QString &jid, uint32_t deviceId) override; virtual QXmppTask<void> removeDevice(const QString &jid, uint32_t deviceId) override;
QXmppTask<void> removeDevices(const QString &jid) override; virtual QXmppTask<void> removeDevices(const QString &jid) override;
QXmppTask<void> resetAll() override; virtual QXmppTask<void> resetAll() override;
bool hasOwnDevice(); bool hasOwnDevice();
void getDevices(const QString& jid, std::list<Shared::KeyInfo>& out) const;
private: private:
Account* acc; Account* acc;
std::optional<OwnDevice> ownDevice; std::optional<OwnDevice> ownDevice;

View File

@ -326,6 +326,20 @@ QXmppTask<void> TrustHandler::setSecurityPolicy(
return Core::makeReadyTask(); return Core::makeReadyTask();
} }
Core::TrustHandler::Keys Core::TrustHandler::getKeys(const QString& protocol, const QString& jid) const {
std::map<QString, KeyCache*>::const_iterator itr = keysByProtocol.find(protocol);
if (itr != keysByProtocol.end()) {
try {
Keys map = itr->second->getRecord(jid);
return map;
} catch (const DataBase::NotFound& e) {
return Keys();
}
} else {
return Keys();
}
}
Shared::TrustLevel Core::TrustHandler::convert(Core::TrustHandler::TL level) Shared::TrustLevel Core::TrustHandler::convert(Core::TrustHandler::TL level)
{ {
switch (level) { switch (level) {

View File

@ -41,27 +41,29 @@ public:
typedef std::map<QByteArray, Shared::TrustLevel> Keys; typedef std::map<QByteArray, Shared::TrustLevel> Keys;
typedef DataBase::Cache<QString, Keys> KeyCache; typedef DataBase::Cache<QString, Keys> KeyCache;
virtual QXmppTask<void> resetAll(CSR encryption); virtual QXmppTask<void> resetAll(CSR encryption) override;
virtual QXmppTask<TL> trustLevel(CSR encryption, CSR keyOwnerJid, const QByteArray& keyId); virtual QXmppTask<TL> trustLevel(CSR encryption, CSR keyOwnerJid, const QByteArray& keyId) override;
virtual QXmppTask<HashSM> setTrustLevel(CSR encryption, CLSR keyOwnerJids, TL oldTrustLevel, TL newTrustLevel); virtual QXmppTask<HashSM> setTrustLevel(CSR encryption, CLSR keyOwnerJids, TL oldTrustLevel, TL newTrustLevel) override;
virtual QXmppTask<HashSM> setTrustLevel(CSR encryption, const MultySB& keyIds, TL trustLevel); virtual QXmppTask<HashSM> setTrustLevel(CSR encryption, const MultySB& keyIds, TL trustLevel) override;
virtual QXmppTask<bool> hasKey(CSR encryption, CSR keyOwnerJid, QXmpp::TrustLevels trustLevels); virtual QXmppTask<bool> hasKey(CSR encryption, CSR keyOwnerJid, QXmpp::TrustLevels trustLevels) override;
virtual QXmppTask<HSHBTL> keys(CSR encryption, CLSR keyOwnerJids, QXmpp::TrustLevels trustLevels); virtual QXmppTask<HSHBTL> keys(CSR encryption, CLSR keyOwnerJids, QXmpp::TrustLevels trustLevels) override;
virtual QXmppTask<QHash<TL, MultySB>> keys(CSR encryption, QXmpp::TrustLevels trustLevels); virtual QXmppTask<QHash<TL, MultySB>> keys(CSR encryption, QXmpp::TrustLevels trustLevels) override;
virtual QXmppTask<void> removeKeys(CSR encryption); virtual QXmppTask<void> removeKeys(CSR encryption) override;
virtual QXmppTask<void> removeKeys(CSR encryption, CSR keyOwnerJid); virtual QXmppTask<void> removeKeys(CSR encryption, CSR keyOwnerJid) override;
virtual QXmppTask<void> removeKeys(CSR encryption, CLBAR keyIds); virtual QXmppTask<void> removeKeys(CSR encryption, CLBAR keyIds) override;
virtual QXmppTask<void> addKeys(CSR encryption, CSR keyOwnerJid, CLBAR keyIds, TL trustLevel); virtual QXmppTask<void> addKeys(CSR encryption, CSR keyOwnerJid, CLBAR keyIds, TL trustLevel) override;
virtual QXmppTask<QByteArray> ownKey(CSR encryption); virtual QXmppTask<QByteArray> ownKey(CSR encryption) override;
virtual QXmppTask<void> resetOwnKey(CSR encryption); virtual QXmppTask<void> resetOwnKey(CSR encryption) override;
virtual QXmppTask<void> setOwnKey(CSR encryption, const QByteArray& keyId); virtual QXmppTask<void> setOwnKey(CSR encryption, const QByteArray& keyId) override;
virtual QXmppTask<QXmpp::TrustSecurityPolicy> securityPolicy(CSR encryption); virtual QXmppTask<QXmpp::TrustSecurityPolicy> securityPolicy(CSR encryption) override;
virtual QXmppTask<void> resetSecurityPolicy(CSR encryption); virtual QXmppTask<void> resetSecurityPolicy(CSR encryption) override;
virtual QXmppTask<void> setSecurityPolicy(CSR encryption, QXmpp::TrustSecurityPolicy securityPolicy); virtual QXmppTask<void> setSecurityPolicy(CSR encryption, QXmpp::TrustSecurityPolicy securityPolicy) override;
static TL convert(Shared::TrustLevel level); static TL convert(Shared::TrustLevel level);
static Shared::TrustLevel convert(TL level); static Shared::TrustLevel convert(TL level);
Keys getKeys(const QString& protocol, const QString& jid) const;
private: private:
KeyCache* createNewCache(const QString& encryption); KeyCache* createNewCache(const QString& encryption);
KeyCache* getCache(const QString& encryption); KeyCache* getCache(const QString& encryption);

View File

@ -17,6 +17,8 @@
#include "vcardhandler.h" #include "vcardhandler.h"
#include "core/account.h" #include "core/account.h"
constexpr const char* ns_omemo_2 = "urn:xmpp:omemo:2";
Core::VCardHandler::VCardHandler(Account* account): Core::VCardHandler::VCardHandler(Account* account):
QObject(), QObject(),
acc(account), acc(account),
@ -102,6 +104,20 @@ void Core::VCardHandler::onVCardReceived(const QXmppVCardIq& card) {
Shared::Info info(jid, Shared::EntryType::contact); Shared::Info info(jid, Shared::EntryType::contact);
item->handleResponseVCard(card, resource, info.getVCardRef()); item->handleResponseVCard(card, resource, info.getVCardRef());
#ifdef WITH_OMEMO
std::list<Shared::KeyInfo>& aks = info.getActiveKeysRef();
acc->oh->getDevices(jid, aks);
std::map<QByteArray, Shared::TrustLevel> trustLevels = acc->th->getKeys(ns_omemo_2, jid);
qDebug() << "OMEMO info for " << jid << " devices:" << aks.size() << ", trustLevels:" << trustLevels.size();
for (Shared::KeyInfo& key : aks) {
std::map<QByteArray, Shared::TrustLevel>::const_iterator itr = trustLevels.find(key.fingerPrint);
if (itr != trustLevels.end()) {
key.trustLevel = itr->second;
qDebug() << "Found a trust level for a device!";
}
}
#endif
emit acc->infoReady(info); emit acc->infoReady(info);
} }

2
external/qxmpp vendored

@ -1 +1 @@
Subproject commit d2c2acd4848f815d0dc3d108f8bc306f9015fc89 Subproject commit 9d5762499fbddb3dd1ed8eeca16f9db70adc27d0

View File

@ -160,7 +160,9 @@ static const TrustLevel TrustLevelHighest = TrustLevel::undecided;
static const TrustLevel TrustLevelLowest = TrustLevel::authenticated; static const TrustLevel TrustLevelLowest = TrustLevel::authenticated;
enum class EncryptionProtocol { enum class EncryptionProtocol {
omemo omemo,
omemo1,
omemo2
}; };
Q_ENUM_NS(EncryptionProtocol) Q_ENUM_NS(EncryptionProtocol)

View File

@ -43,7 +43,7 @@ Shared::KeyInfo::KeyInfo():
label(), label(),
lastInteraction(), lastInteraction(),
trustLevel(TrustLevel::undecided), trustLevel(TrustLevel::undecided),
protocol(EncryptionProtocol::omemo), protocol(EncryptionProtocol::omemo2),
currentDevice(false) currentDevice(false)
{ {
} }

View File

@ -36,7 +36,7 @@ public:
const QString& label, const QString& label,
const QDateTime& lastInteraction, const QDateTime& lastInteraction,
TrustLevel trustLevel, TrustLevel trustLevel,
EncryptionProtocol protocol = EncryptionProtocol::omemo, EncryptionProtocol protocol = EncryptionProtocol::omemo2,
bool currentDevice = false bool currentDevice = false
); );
KeyInfo(); KeyInfo();

View File

@ -134,5 +134,11 @@ void Models::Keys::setTrustLevel(int row, Shared::TrustLevel level) {
dataChanged(index, index, {Keys::Dirty}); dataChanged(index, index, {Keys::Dirty});
} }
void Models::Keys::clear() {
beginResetModel();
keys.clear();
modified.clear();
endResetModel();
}

View File

@ -33,6 +33,7 @@ public:
~Keys(); ~Keys();
void addKey(const Shared::KeyInfo& info); void addKey(const Shared::KeyInfo& info);
void clear();
QVariant data(const QModelIndex & index, int role = Qt::DisplayRole) const override; QVariant data(const QModelIndex & index, int role = Qt::DisplayRole) const override;
int rowCount(const QModelIndex& parent = QModelIndex()) const override; int rowCount(const QModelIndex& parent = QModelIndex()) const override;

View File

@ -24,6 +24,9 @@ UI::Info::Info(const QString& p_jid, QWidget* parent):
m_ui(new Ui::Info()), m_ui(new Ui::Info()),
contactGeneral(nullptr), contactGeneral(nullptr),
contactContacts(nullptr), contactContacts(nullptr),
#ifdef WITH_OMEMO
omemo(nullptr),
#endif
description(nullptr), description(nullptr),
overlay(new QWidget()), overlay(new QWidget()),
progress(new Progress(100)), progress(new Progress(100)),
@ -57,6 +60,9 @@ void UI::Info::setData(const Shared::Info& info) {
initializeContactGeneral(jid, card, editable); initializeContactGeneral(jid, card, editable);
initializeContactContacts(jid, card, editable); initializeContactContacts(jid, card, editable);
initializeDescription(card.getDescription(), editable); initializeDescription(card.getDescription(), editable);
#ifdef WITH_OMEMO
initializeOmemo(info.getActiveKeysRef());
#endif
type = info.getType(); type = info.getType();
} }
break; break;
@ -170,5 +176,24 @@ void UI::Info::clear() {
description->deleteLater(); description->deleteLater();
description = nullptr; description = nullptr;
} }
#ifdef WITH_OMEMO
if (omemo != nullptr) {
omemo->deleteLater();
omemo = nullptr;
}
#endif
type = Shared::EntryType::none; type = Shared::EntryType::none;
} }
#ifdef WITH_OMEMO
void UI::Info::initializeOmemo(const std::list<Shared::KeyInfo>& keys) {
if (omemo == nullptr) {
omemo = new Omemo();
m_ui->tabWidget->addTab(omemo, omemo->title());
}
omemo->setData(keys);
}
#endif

View File

@ -17,6 +17,8 @@
#ifndef UI_WIDGETS_INFO_H #ifndef UI_WIDGETS_INFO_H
#define UI_WIDGETS_INFO_H #define UI_WIDGETS_INFO_H
#include <list>
#include <QWidget> #include <QWidget>
#include <QScopedPointer> #include <QScopedPointer>
#include <QGraphicsOpacityEffect> #include <QGraphicsOpacityEffect>
@ -30,6 +32,10 @@
#include "contactgeneral.h" #include "contactgeneral.h"
#include "contactcontacts.h" #include "contactcontacts.h"
#include "description.h" #include "description.h"
#ifdef WITH_OMEMO
#include "omemo/omemo.h"
#endif
namespace UI { namespace UI {
namespace Ui namespace Ui
@ -58,6 +64,9 @@ private:
void initializeContactGeneral(const QString& jid, const Shared::VCard& card, bool editable); void initializeContactGeneral(const QString& jid, const Shared::VCard& card, bool editable);
void initializeContactContacts(const QString& jid, const Shared::VCard& card, bool editable); void initializeContactContacts(const QString& jid, const Shared::VCard& card, bool editable);
void initializeDescription(const QString& description, bool editable); void initializeDescription(const QString& description, bool editable);
#ifdef WITH_OMEMO
void initializeOmemo(const std::list<Shared::KeyInfo>& keys);
#endif
void initializeOverlay(); void initializeOverlay();
void initializeButtonBox(); void initializeButtonBox();
void clear(); void clear();
@ -68,6 +77,9 @@ private:
QScopedPointer<Ui::Info> m_ui; QScopedPointer<Ui::Info> m_ui;
ContactGeneral* contactGeneral; ContactGeneral* contactGeneral;
ContactContacts* contactContacts; ContactContacts* contactContacts;
#ifdef WITH_OMEMO
Omemo* omemo;
#endif
Description* description; Description* description;
QWidget* overlay; QWidget* overlay;
Progress* progress; Progress* progress;

View File

@ -20,7 +20,7 @@
#include <random> #include <random>
constexpr uint8_t fingerprintLength = 32; constexpr uint8_t fingerprintLength = 32;
Omemo::Omemo(QWidget* parent): UI::Omemo::Omemo(QWidget* parent):
QWidget(parent), QWidget(parent),
m_ui(new Ui::Omemo()), m_ui(new Ui::Omemo()),
keysDelegate(), keysDelegate(),
@ -31,8 +31,6 @@ Omemo::Omemo(QWidget* parent):
{ {
m_ui->setupUi(this); m_ui->setupUi(this);
generateMockData();
m_ui->keysView->setItemDelegate(&keysDelegate); m_ui->keysView->setItemDelegate(&keysDelegate);
m_ui->keysView->setModel(&keysModel); m_ui->keysView->setModel(&keysModel);
m_ui->unusedKeysView->setItemDelegate(&unusedKeysDelegate); m_ui->unusedKeysView->setItemDelegate(&unusedKeysDelegate);
@ -42,12 +40,12 @@ Omemo::Omemo(QWidget* parent):
connect(m_ui->keysView, &QWidget::customContextMenuRequested, this, &Omemo::onActiveKeysContextMenu); connect(m_ui->keysView, &QWidget::customContextMenuRequested, this, &Omemo::onActiveKeysContextMenu);
} }
Omemo::~Omemo() UI::Omemo::~Omemo()
{ {
contextMenu->deleteLater(); contextMenu->deleteLater();
} }
void Omemo::generateMockData() { void UI::Omemo::generateMockData() {
std::random_device rd; std::random_device rd;
std::uniform_int_distribution<char> dist(CHAR_MIN, CHAR_MAX); std::uniform_int_distribution<char> dist(CHAR_MIN, CHAR_MAX);
for (int i = 0; i < 5; ++i) { for (int i = 0; i < 5; ++i) {
@ -67,7 +65,19 @@ void Omemo::generateMockData() {
} }
} }
void Omemo::onActiveKeysContextMenu(const QPoint& pos) { void UI::Omemo::setData(const std::list<Shared::KeyInfo>& keys) {
keysModel.clear();
unusedKeysModel.clear();
for (const Shared::KeyInfo& key : keys) {
keysModel.addKey(key);
}
}
const QString UI::Omemo::title() const {
return m_ui->OMEMOHeading->text();}
void UI::Omemo::onActiveKeysContextMenu(const QPoint& pos) {
contextMenu->clear(); contextMenu->clear();
QModelIndex index = m_ui->keysView->indexAt(pos); QModelIndex index = m_ui->keysView->indexAt(pos);
if (index.isValid()) { if (index.isValid()) {

View File

@ -17,6 +17,8 @@
#ifndef VCARD_OMEMO_H #ifndef VCARD_OMEMO_H
#define VCARD_OMEMO_H #define VCARD_OMEMO_H
#include <list>
#include <QWidget> #include <QWidget>
#include <QScopedPointer> #include <QScopedPointer>
#include <QMenu> #include <QMenu>
@ -24,7 +26,9 @@
#include "ui/models/info/omemo/keys.h" #include "ui/models/info/omemo/keys.h"
#include "keydelegate.h" #include "keydelegate.h"
#include "shared/icons.h" #include "shared/icons.h"
#include "shared/keyinfo.h"
namespace UI {
namespace Ui namespace Ui
{ {
class Omemo; class Omemo;
@ -36,6 +40,9 @@ public:
Omemo(QWidget* parent = nullptr); Omemo(QWidget* parent = nullptr);
~Omemo(); ~Omemo();
void setData(const std::list<Shared::KeyInfo>& keys);
const QString title() const;
private slots: private slots:
void onActiveKeysContextMenu(const QPoint& pos); void onActiveKeysContextMenu(const QPoint& pos);
@ -50,5 +57,5 @@ private:
Models::Keys unusedKeysModel; Models::Keys unusedKeysModel;
QMenu* contextMenu; QMenu* contextMenu;
}; };
}
#endif // VCARD_OMEMO_H #endif // VCARD_OMEMO_H

View File

@ -1,7 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0"> <ui version="4.0">
<class>Omemo</class> <class>UI::Omemo</class>
<widget class="QWidget" name="Omemo"> <widget class="QWidget" name="UI::Omemo">
<property name="geometry"> <property name="geometry">
<rect> <rect>
<x>0</x> <x>0</x>