diff options
| author | Xavier Del Campo Romero <xavi.dcr@tutanota.com> | 2023-06-29 14:10:06 +0200 |
|---|---|---|
| committer | Xavier Del Campo Romero <xavi.dcr@tutanota.com> | 2023-08-30 02:46:41 +0200 |
| commit | 6ecc6b6f0272a47d41ce5d619eaa779a29fcf9df (patch) | |
| tree | b304ad33ecadcd1209347b67d525506356d149f0 /omemo_db.cpp | |
| parent | 48cfe26383feb2fcf6638905060c605af8eb2c69 (diff) | |
WIP OMEMO
Diffstat (limited to 'omemo_db.cpp')
| -rw-r--r-- | omemo_db.cpp | 374 |
1 files changed, 374 insertions, 0 deletions
diff --git a/omemo_db.cpp b/omemo_db.cpp new file mode 100644 index 0000000..bc8751b --- /dev/null +++ b/omemo_db.cpp @@ -0,0 +1,374 @@ +#include "omemo_db.h" +#include <QXmppConfiguration.h> +#include <QXmppFutureUtils_p.h> +#include <QXmppPromise.h> +#include <qt5keychain/keychain.h> +#include <QEventLoop> +#include <QtConcurrent> +#include <QString> +#include <iostream> +#include <optional> + +static const QString service_ns = "xxcc/omemo/"; + +OmemoDb::OmemoDb(const QString &jid) : + jid(jid) +{ +} + +QString OmemoDb::service() const +{ + return service_ns + jid; +} + +QXmppTask<QXmppOmemoStorage::OmemoData> OmemoDb::allData() +{ + return QXmpp::Private::makeReadyTask(QXmppOmemoStorage::OmemoData()); +} + +int OmemoDb::storeOwnKeyId(const QString &service, const uint32_t id) +{ + QKeychain::WritePasswordJob job(service); + QEventLoop loop; + + loop.connect(&job, &QKeychain::Job::finished, &loop, &QEventLoop::quit); + job.setKey("device/keyid"); + job.setTextData(QString::number(id, 16)); + job.start(); + loop.exec(); + + if (job.error()) + { + std::cerr << "Failed to store own key ID: " + << qPrintable(job.errorString()) << std::endl; + return -1; + } + + return 0; +} + +int OmemoDb::storePrivateIdentityKey(const QString &service, + const QByteArray &privateIdentityKey) +{ + QKeychain::WritePasswordJob job(service); + QEventLoop loop; + + loop.connect(&job, &QKeychain::Job::finished, &loop, &QEventLoop::quit); + job.setKey("device/privateIdentityKey"); + job.setBinaryData(privateIdentityKey); + job.start(); + loop.exec(); + + if (job.error()) + { + std::cerr << "Failed to store private identity key: " + << qPrintable(job.errorString()) << std::endl; + return -1; + } + + return 0; +} + +int OmemoDb::storePublicIdentityKey(const QString &service, + const QByteArray &publicIdentityKey) +{ + QKeychain::WritePasswordJob job(service); + QEventLoop loop; + + loop.connect(&job, &QKeychain::Job::finished, &loop, &QEventLoop::quit); + job.setKey("device/publicIdentityKey"); + job.setBinaryData(publicIdentityKey); + job.start(); + loop.exec(); + + if (job.error()) + { + std::cerr << "Failed to store public identity key: " + << qPrintable(job.errorString()) << std::endl; + return -1; + } + + return 0; +} + +int OmemoDb::storeLatestSignedPreKeyId(const QString &service, + const uint32_t latestSignedPreKeyId) +{ + QKeychain::WritePasswordJob job(service); + QEventLoop loop; + + loop.connect(&job, &QKeychain::Job::finished, &loop, &QEventLoop::quit); + job.setKey("device/latestSignedPreKeyId"); + job.setTextData(QString::number(latestSignedPreKeyId, 16)); + job.start(); + loop.exec(); + + if (job.error()) + { + std::cerr << "Failed to store latest signed prekey ID: " + << qPrintable(job.errorString()) << std::endl; + return -1; + } + + return 0; +} + +int OmemoDb::storeLatestPreKeyId(const QString &service, + const uint32_t latestPreKeyId) +{ + QKeychain::WritePasswordJob job(service); + QEventLoop loop; + + loop.connect(&job, &QKeychain::Job::finished, &loop, &QEventLoop::quit); + job.setKey("device/latestPreKeyId"); + job.setTextData(QString::number(latestPreKeyId, 16)); + job.start(); + loop.exec(); + + if (job.error()) + { + std::cerr << "Failed to store latest prekey ID: " + << qPrintable(job.errorString()) << std::endl; + return -1; + } + + return 0; +} + +QXmppTask<void> OmemoDb::setOwnDevice(const std::optional<OwnDevice> &device) +{ + if (!device.has_value()) + return QXmpp::Private::makeReadyTask(); + + QXmppPromise<void> promise; + + auto future = QtConcurrent::run( + [=] () mutable + { + const auto &d = device.value(); + const auto srv = service(); + + storeDeviceLabel(srv, d.label) + || storeOwnKeyId(srv, d.id) + || storePrivateIdentityKey(srv, d.privateIdentityKey) + || storePublicIdentityKey(srv, d.publicIdentityKey) + || storeLatestSignedPreKeyId(srv, d.latestSignedPreKeyId) + || storeLatestPreKeyId(srv, d.latestPreKeyId); + + promise.finish(); + }); + + return promise.task(); +} + +QXmppTask<void> OmemoDb::addSignedPreKeyPair(const uint32_t keyId, + const SignedPreKeyPair &keyPair) +{ + return QXmpp::Private::makeReadyTask(); +} + +QXmppTask<void> OmemoDb::removeSignedPreKeyPair(uint32_t keyId) +{ + return QXmpp::Private::makeReadyTask(); +} + +QXmppTask<void> OmemoDb::addPreKeyPairs( + const QHash<uint32_t, QByteArray> &keyPairs) +{ + return QXmpp::Private::makeReadyTask(); +} + +QXmppTask<void> OmemoDb::removePreKeyPair(const uint32_t keyId) +{ + return QXmpp::Private::makeReadyTask(); +} + +int OmemoDb::storeDeviceLabel(const QString &service, const QString &label) +{ + QKeychain::WritePasswordJob job(service); + QEventLoop loop; + + loop.connect(&job, &QKeychain::Job::finished, &loop, &QEventLoop::quit); + job.setKey("device/label"); + job.setTextData(label); + job.start(); + loop.exec(); + + if (job.error()) + { + std::cerr << "Failed to store device label: " + << qPrintable(job.errorString()) << std::endl; + return -1; + } + + return 0; +} + +int OmemoDb::storeKeyId(const QString &service, const QByteArray &keyId) +{ + QKeychain::WritePasswordJob job(service); + QEventLoop loop; + + loop.connect(&job, &QKeychain::Job::finished, &loop, &QEventLoop::quit); + job.setKey("device/key_id"); + job.setBinaryData(keyId); + job.start(); + loop.exec(); + + if (job.error()) + { + std::cerr << "Failed to store device keyID: " + << qPrintable(job.errorString()) << std::endl; + return -1; + } + + return 0; +} + +int OmemoDb::storeSession(const QString &service, const QByteArray &session) +{ + QKeychain::WritePasswordJob job(service); + QEventLoop loop; + + loop.connect(&job, &QKeychain::Job::finished, &loop, &QEventLoop::quit); + job.setKey("device/session"); + job.setBinaryData(session); + job.start(); + loop.exec(); + + if (job.error()) + { + std::cerr << "Failed to store device session: " + << qPrintable(job.errorString()) << std::endl; + return -1; + } + + return 0; +} + +int OmemoDb::storeUnrespondedSentStanzasCount(const QString &service, + const int count) +{ + QKeychain::WritePasswordJob job(service); + QEventLoop loop; + + loop.connect(&job, &QKeychain::Job::finished, &loop, &QEventLoop::quit); + job.setKey("device/unresponded_sent_stanzas"); + job.setTextData(QString::number(count)); + job.start(); + loop.exec(); + + if (job.error()) + { + std::cerr << "Failed to store device unresponded sent stanzas: " + << qPrintable(job.errorString()) << std::endl; + return -1; + } + + return 0; +} + +int OmemoDb::storeUnrespondedReceivedStanzasCount(const QString &service, + const int count) +{ + QKeychain::WritePasswordJob job(service); + QEventLoop loop; + + loop.connect(&job, &QKeychain::Job::finished, &loop, &QEventLoop::quit); + job.setKey("device/unresponded_received_stanzas"); + job.setTextData(QString::number(count)); + job.start(); + loop.exec(); + + if (job.error()) + { + std::cerr << "Failed to store device unresponded received stanzas: " + << qPrintable(job.errorString()) << std::endl; + return -1; + } + + return 0; +} + +int OmemoDb::storeRemovalFromDeviceListDate(const QString &service, + const QDateTime &dt) +{ + QKeychain::WritePasswordJob job(service); + QEventLoop loop; + + loop.connect(&job, &QKeychain::Job::finished, &loop, &QEventLoop::quit); + job.setKey("device/unresponded_received_stanzas"); + job.setTextData(QString::number(dt.currentMSecsSinceEpoch())); + job.start(); + loop.exec(); + + if (job.error()) + { + std::cerr << "Failed to store device unresponded received stanzas: " + << qPrintable(job.errorString()) << std::endl; + return -1; + } + + return 0; +} + +QXmppTask<void> OmemoDb::addDevice(const QString &jid, + const uint32_t deviceId, const Device &device) +{ + const QString fullservice = service_ns + jid; + QXmppPromise<void> promise; + + auto future = QtConcurrent::run( + [=] () mutable + { + storeDeviceLabel(fullservice, device.label) + || storeKeyId(fullservice, device.keyId) + || storeSession(fullservice, device.session) + || storeUnrespondedSentStanzasCount(fullservice, + device.unrespondedSentStanzasCount) + || storeUnrespondedReceivedStanzasCount(fullservice, + device.unrespondedSentStanzasCount) + || storeRemovalFromDeviceListDate(fullservice, + device.removalFromDeviceListDate); + + promise.finish(); + }); + + return promise.task(); +} + +QXmppTask<void> OmemoDb::removeDevice(const QString &jid, + const uint32_t deviceId) +{ +#if 0 + const QString fullservice = service_ns + jid; + QKeychain::DeletePasswordJob job(fullservice); + QEventLoop loop; + + loop.connect(&job, &QKeychain::Job::finished, &loop, &QEventLoop::quit); + job.setKey("device/unresponded_received_stanzas"); + job.setTextData(QString::number(dt.currentMSecsSinceEpoch())); + job.start(); + loop.exec(); + + if (job.error()) + { + std::cerr << "Failed to store device unresponded received stanzas: " + << qPrintable(job.errorString()) << std::endl; + return -1; + } + + return 0; +#endif + return QXmpp::Private::makeReadyTask(); +} + +QXmppTask<void> OmemoDb::removeDevices(const QString &jid) +{ + return QXmpp::Private::makeReadyTask(); +} + +QXmppTask<void> OmemoDb::resetAll() +{ + return QXmpp::Private::makeReadyTask(); +} |
