diff --git a/qomemo/CMakeLists.txt b/qomemo/CMakeLists.txt index 7391404..8b194be 100644 --- a/qomemo/CMakeLists.txt +++ b/qomemo/CMakeLists.txt @@ -1,23 +1,23 @@ target_sources(squawk PRIVATE - bundle.cpp - bundle.h - database.cpp - database.h - device.cpp - device.h - device_key_storage.cpp - device_key_storage.h - device_service.cpp - device_service.h - qomemo.cpp - qomemo.h - sce.cpp - sce.h - user_device_list.cpp - user_device_list.h - qxmpp_omemo_manager.cpp - qxmpp_omemo_manager.h - ) + bundle.cpp + bundle.h + database.cpp + database.h + device.cpp + device.h + device_key_storage.cpp + device_key_storage.h + device_service.cpp + device_service.h + qomemo.cpp + qomemo.h + sce.cpp + sce.h + user_device_list.cpp + user_device_list.h + qxmpp_omemo_manager.cpp + qxmpp_omemo_manager.h + ) add_subdirectory(signal) add_subdirectory(variant) diff --git a/qomemo/TODO b/qomemo/TODO deleted file mode 100644 index 6a5709d..0000000 --- a/qomemo/TODO +++ /dev/null @@ -1,12 +0,0 @@ -* Generate device w/ keys -* PubSub set urn:xmpp:omemo:1:devices to announce new device -* PubSub set urn:xmpp:omemo:1:bundles to announce new key bundles -* PubSub get urn:xmpp:omemo:1:bundles to get user bundles - -Sending a message: -* Create urn:xmpp:sce:0 with padding and content -* Add with header (key list) and payload (b64) - -Receiving a message: -* Check => -* Decrypt (TODO) \ No newline at end of file diff --git a/qomemo/bundle.cpp b/qomemo/bundle.cpp index 91f630d..691a65e 100644 --- a/qomemo/bundle.cpp +++ b/qomemo/bundle.cpp @@ -13,117 +13,117 @@ using namespace QXmpp::Factories; QXmppElement QXmpp::Omemo::PreKey::toXml() const { - auto pk = createElement("preKeyPublic"); - pk.setAttribute("preKeyId", QString::number(id)); - // TODO: Base64 - pk.setValue(data); + auto pk = createElement("preKeyPublic"); + pk.setAttribute("preKeyId", QString::number(id)); + // TODO: Base64 + pk.setValue(data); - return pk; + return pk; } void QXmpp::Omemo::PreKey::fromXml(const QXmppElement &element) { - if (!elementMatches(element, "preKeyPublic")) - return; + if (!elementMatches(element, "preKeyPublic")) + return; - id = element.attribute("preKeyId").toInt(); - // TODO: Base64 - data = element.value(); + id = element.attribute("preKeyId").toInt(); + // TODO: Base64 + data = element.value(); } QXmppElement QXmpp::Omemo::Bundle::toXml() const { - auto spkNode = createElement("signedPreKeyPublic"); - spkNode.setAttribute("signedPreKeyId", QString::number(spkId)); - spkNode.setValue(spk); + auto spkNode = createElement("signedPreKeyPublic"); + spkNode.setAttribute("signedPreKeyId", QString::number(spkId)); + spkNode.setValue(spk); - auto spksNode = createElement("signedPreKeySignature"); - spksNode.setValue(spks); + auto spksNode = createElement("signedPreKeySignature"); + spksNode.setValue(spks); - auto ikNode = createElement("identityKey"); - ikNode.setValue(ik); + auto ikNode = createElement("identityKey"); + ikNode.setValue(ik); - auto prekeysNode = createElement("prekeys"); - for (const auto &pk : prekeys) { - prekeysNode.appendChild(pk.toXml()); - } + auto prekeysNode = createElement("prekeys"); + for (const auto &pk : prekeys) { + prekeysNode.appendChild(pk.toXml()); + } - auto result = createElement("bundle", "eu.siacs.conversations.axolotl"); - result.appendChild(spkNode); - result.appendChild(spksNode); - result.appendChild(ikNode); - result.appendChild(prekeysNode); + auto result = createElement("bundle", "eu.siacs.conversations.axolotl"); + result.appendChild(spkNode); + result.appendChild(spksNode); + result.appendChild(ikNode); + result.appendChild(prekeysNode); - return result; + return result; } QXmppIq QXmpp::Omemo::Bundle::toIq(int deviceId) const { - QXmppIq iq{}; + QXmppIq iq{}; - iq.setType(QXmppIq::Set); + iq.setType(QXmppIq::Set); - auto item = createElement("item"); - item.appendChild(toXml()); + auto item = createElement("item"); + item.appendChild(toXml()); - auto publish = createElement("publish"); - publish.setAttribute( - "node", - QString("eu.siacs.conversations.axolotl.bundles:%s").arg(deviceId)); - publish.appendChild(item); + auto publish = createElement("publish"); + publish.setAttribute( + "node", + QString("eu.siacs.conversations.axolotl.bundles:%s").arg(deviceId)); + publish.appendChild(item); - auto pubSub = createElement("pubsub", "http://jabber.org/protocol/pubsub"); - pubSub.appendChild(publish); - pubSub.appendChild(createOpenPublishOptions()); + auto pubSub = createElement("pubsub", "http://jabber.org/protocol/pubsub"); + pubSub.appendChild(publish); + pubSub.appendChild(createOpenPublishOptions()); - iq.extensions().push_back(pubSub); + iq.extensions().push_back(pubSub); - return iq; + return iq; } void QXmpp::Omemo::Bundle::fromXml(const QXmppElement &element) { - if (!elementMatches(element, "bundle", "eu.siacs.conversations.axolotl")) - return; + if (!elementMatches(element, "bundle", "eu.siacs.conversations.axolotl")) + return; - auto spkNode = element.firstChildElement("spk"); - if (spkNode.isNull()) { - qWarning() << "'bundle': missing 'spk'"; - return; - } - spk = spkNode.value(); - spkId = spkNode.attribute("id").toInt(); + auto spkNode = element.firstChildElement("spk"); + if (spkNode.isNull()) { + qWarning() << "'bundle': missing 'spk'"; + return; + } + spk = spkNode.value(); + spkId = spkNode.attribute("id").toInt(); - auto spksNode = element.firstChildElement("spks"); - if (spksNode.isNull()) { - qWarning() << "'bundle': missing 'spks'"; - return; - } - spks = spksNode.value(); + auto spksNode = element.firstChildElement("spks"); + if (spksNode.isNull()) { + qWarning() << "'bundle': missing 'spks'"; + return; + } + spks = spksNode.value(); - auto ikNode = element.firstChildElement("ik"); - if (ikNode.isNull()) { - qWarning() << "'bundle': missing 'ik'"; - return; - } - ik = ikNode.value(); + auto ikNode = element.firstChildElement("ik"); + if (ikNode.isNull()) { + qWarning() << "'bundle': missing 'ik'"; + return; + } + ik = ikNode.value(); - auto prekeysNode = element.firstChildElement("prekeys"); - auto pkNode = prekeysNode.firstChildElement("pk"); + auto prekeysNode = element.firstChildElement("prekeys"); + auto pkNode = prekeysNode.firstChildElement("pk"); - prekeys.clear(); - while (!pkNode.isNull()) { - PreKey pk{}; - pk.fromXml(pkNode); - prekeys.push_back(pk); - } + prekeys.clear(); + while (!pkNode.isNull()) { + PreKey pk{}; + pk.fromXml(pkNode); + prekeys.push_back(pk); + } } QXmppPubSubIq QXmpp::Omemo::Bundle::fetchDeviceBundleIq(int deviceId) { - QXmppPubSubIq iq{}; - iq.setType(QXmppIq::Get); - iq.setQueryNode( - QString("eu.siacs.conversations.axolotl.bundles:%1").arg(deviceId)); + QXmppPubSubIq iq{}; + iq.setType(QXmppIq::Get); + iq.setQueryNode( + QString("eu.siacs.conversations.axolotl.bundles:%1").arg(deviceId)); - QXmppPubSubItem item{}; - item.setId(QString::number(deviceId)); - iq.setItems({item}); + QXmppPubSubItem item{}; + item.setId(QString::number(deviceId)); + iq.setItems({item}); - return iq; + return iq; } \ No newline at end of file diff --git a/qomemo/bundle.h b/qomemo/bundle.h index bfa9fff..428277b 100644 --- a/qomemo/bundle.h +++ b/qomemo/bundle.h @@ -8,34 +8,36 @@ #include class QXmppPubSubIq; + class QXmppElement; + class QXmppIq; namespace QXmpp::Omemo { -class PreKey { -public: - [[nodiscard]] QXmppElement toXml() const; - /// Expects a - void fromXml(const QXmppElement &element); + class PreKey { + public: + [[nodiscard]] QXmppElement toXml() const; + /// Expects a + void fromXml(const QXmppElement &element); - int id; - QString data; -}; + int id; + QString data; + }; -class Bundle { -public: - [[nodiscard]] static QXmppPubSubIq fetchDeviceBundleIq(int deviceId); + class Bundle { + public: + [[nodiscard]] static QXmppPubSubIq fetchDeviceBundleIq(int deviceId); - [[nodiscard]] QXmppElement toXml() const; - [[nodiscard]] QXmppIq toIq(int deviceId) const; - void fromXml(const QXmppElement &element); + [[nodiscard]] QXmppElement toXml() const; + [[nodiscard]] QXmppIq toIq(int deviceId) const; + void fromXml(const QXmppElement &element); - QString spk; - int spkId; - QString spks; - QString ik; - QList prekeys; -}; + QString spk; + int spkId; + QString spks; + QString ik; + QList prekeys; + }; } // namespace QXmpp::Omemo diff --git a/qomemo/database.cpp b/qomemo/database.cpp index 3644522..2314a80 100644 --- a/qomemo/database.cpp +++ b/qomemo/database.cpp @@ -13,114 +13,114 @@ using namespace QXmpp::Omemo; Database::Database(QString jid) : jid(std::move(jid)) { - auto cacheLocation = - QStandardPaths::writableLocation(QStandardPaths::CacheLocation); - auto path = QString("%1/.omemo/%2").arg(cacheLocation, jid); - QDir cache(path); + auto cacheLocation = + QStandardPaths::writableLocation(QStandardPaths::CacheLocation); + auto path = QString("%1/.omemo/%2").arg(cacheLocation, jid); + QDir cache(path); - if (!cache.exists() && !cache.mkpath(path)) { - qWarning() << "Could not create:" << path; - throw QException(); - } + if (!cache.exists() && !cache.mkpath(path)) { + qWarning() << "Could not create:" << path; + throw QException(); + } - mdb_env_create(&env); + mdb_env_create(&env); - mdb_env_set_maxdbs(env, 5); - mdb_env_set_mapsize(env, 512UL * 1024UL * 1024UL); - mdb_env_open(env, path.toStdString().c_str(), 0, 0664); + mdb_env_set_maxdbs(env, 5); + mdb_env_set_mapsize(env, 512UL * 1024UL * 1024UL); + mdb_env_open(env, path.toStdString().c_str(), 0, 0664); - MDB_txn *txn; - mdb_txn_begin(env, nullptr, 0, &txn); - mdb_dbi_open(txn, "keys", MDB_CREATE, &dbiKeys); - mdb_dbi_open(txn, "devices", MDB_CREATE, &dbiDevices); - mdb_dbi_open(txn, "identity_keys", MDB_CREATE, &dbiIdentityKeys); - mdb_txn_commit(txn); + MDB_txn *txn; + mdb_txn_begin(env, nullptr, 0, &txn); + mdb_dbi_open(txn, "keys", MDB_CREATE, &dbiKeys); + mdb_dbi_open(txn, "devices", MDB_CREATE, &dbiDevices); + mdb_dbi_open(txn, "identity_keys", MDB_CREATE, &dbiIdentityKeys); + mdb_txn_commit(txn); } Database::~Database() { - mdb_dbi_close(env, dbiKeys); - mdb_dbi_close(env, dbiDevices); - mdb_dbi_close(env, dbiIdentityKeys); - mdb_env_close(env); + mdb_dbi_close(env, dbiKeys); + mdb_dbi_close(env, dbiDevices); + mdb_dbi_close(env, dbiIdentityKeys); + mdb_env_close(env); } QBuffer Database::loadIdentityKeySecret(int deviceId) { return QBuffer(); } bool Database::saveIdentityKeySecret(int deviceId, const QBuffer &identityKeySecret) { - MDB_val mdbKey, mdbValue; - auto key = QString("%1/secret").arg(QString::number(deviceId)).toStdString(); + MDB_val mdbKey, mdbValue; + auto key = QString("%1/secret").arg(QString::number(deviceId)).toStdString(); - mdbKey.mv_data = key.data(); - mdbKey.mv_size = key.size(); + mdbKey.mv_data = key.data(); + mdbKey.mv_size = key.size(); - mdbValue.mv_data = const_cast(identityKeySecret.data().data()); - mdbValue.mv_size = identityKeySecret.size(); + mdbValue.mv_data = const_cast(identityKeySecret.data().data()); + mdbValue.mv_size = identityKeySecret.size(); - MDB_txn *txn; - mdb_txn_begin(env, nullptr, 0, &txn); - auto err = mdb_put(txn, dbiIdentityKeys, &mdbKey, &mdbValue, MDB_NOOVERWRITE); - if (!err) { - mdb_txn_commit(txn); - return true; - } + MDB_txn *txn; + mdb_txn_begin(env, nullptr, 0, &txn); + auto err = mdb_put(txn, dbiIdentityKeys, &mdbKey, &mdbValue, MDB_NOOVERWRITE); + if (!err) { + mdb_txn_commit(txn); + return true; + } - qWarning() << "could not save identity key secret:" << mdb_strerror(err); - mdb_txn_abort(txn); + qWarning() << "could not save identity key secret:" << mdb_strerror(err); + mdb_txn_abort(txn); - return false; + return false; } int Database::loadActiveDeviceId() { - MDB_val key, value; + MDB_val key, value; - key.mv_data = (void *)"active"; - key.mv_size = sizeof("active"); + key.mv_data = (void *) "active"; + key.mv_size = sizeof("active"); - MDB_txn *txn; - mdb_txn_begin(env, nullptr, 0, &txn); + MDB_txn *txn; + mdb_txn_begin(env, nullptr, 0, &txn); - auto err = mdb_get(txn, dbiIdentityKeys, &key, &value); - if (err) { - qWarning() << "could not load active device id:" << mdb_strerror(err); - return 0; - } + auto err = mdb_get(txn, dbiIdentityKeys, &key, &value); + if (err) { + qWarning() << "could not load active device id:" << mdb_strerror(err); + return 0; + } - if (value.mv_size != sizeof(int)) { - qWarning() << "mv_size is" << value.mv_size << "instead of" << sizeof(int); - return 0; - } + if (value.mv_size != sizeof(int)) { + qWarning() << "mv_size is" << value.mv_size << "instead of" << sizeof(int); + return 0; + } - auto id = *reinterpret_cast(value.mv_data); + auto id = *reinterpret_cast(value.mv_data); - mdb_txn_abort(txn); + mdb_txn_abort(txn); - return id; + return id; } bool Database::saveActiveDeviceId(int deviceId) { - MDB_val key, value; + MDB_val key, value; - key.mv_data = (void *)"active"; - key.mv_size = sizeof("active"); + key.mv_data = (void *) "active"; + key.mv_size = sizeof("active"); - value.mv_data = &deviceId; - value.mv_size = sizeof(deviceId); + value.mv_data = &deviceId; + value.mv_size = sizeof(deviceId); - MDB_txn *txn; - mdb_txn_begin(env, nullptr, 0, &txn); + MDB_txn *txn; + mdb_txn_begin(env, nullptr, 0, &txn); - auto err = mdb_put(txn, dbiIdentityKeys, &key, &value, 0); - if (err) { - qWarning() << "could not save active device id" << mdb_strerror(err); - return false; - } + auto err = mdb_put(txn, dbiIdentityKeys, &key, &value, 0); + if (err) { + qWarning() << "could not save active device id" << mdb_strerror(err); + return false; + } - err = mdb_txn_commit(txn); - if (err) { - qWarning() << "could not save active device id" << mdb_strerror(err); - return false; - } + err = mdb_txn_commit(txn); + if (err) { + qWarning() << "could not save active device id" << mdb_strerror(err); + return false; + } - return true; + return true; } diff --git a/qomemo/database.h b/qomemo/database.h index 4584b2e..3f9b933 100644 --- a/qomemo/database.h +++ b/qomemo/database.h @@ -10,31 +10,31 @@ namespace QXmpp::Omemo { -class Database { -public: - explicit Database(QString jid); - ~Database(); - Database(const Database &) = delete; - Database(Database &&) = delete; - Database &operator=(const Database &) = delete; + class Database { + public: + explicit Database(QString jid); + ~Database(); + Database(const Database &) = delete; + Database(Database &&) = delete; + Database &operator=(const Database &) = delete; - QBuffer loadIdentityKey(); - bool saveIdentityKey(const QBuffer &identityKey); + QBuffer loadIdentityKey(); + bool saveIdentityKey(const QBuffer &identityKey); - int loadActiveDeviceId(); - bool saveActiveDeviceId(int deviceId); + int loadActiveDeviceId(); + bool saveActiveDeviceId(int deviceId); - QBuffer loadIdentityKeySecret(int deviceId); - bool saveIdentityKeySecret(int deviceId, const QBuffer &identityKeySecret); + QBuffer loadIdentityKeySecret(int deviceId); + bool saveIdentityKeySecret(int deviceId, const QBuffer &identityKeySecret); - const QString jid; + const QString jid; -private: - MDB_env *env{}; - MDB_dbi dbiDevices{}; - MDB_dbi dbiKeys{}; - MDB_dbi dbiPreKeys{}; - MDB_dbi dbiIdentityKeys{}; -}; + private: + MDB_env *env{}; + MDB_dbi dbiDevices{}; + MDB_dbi dbiKeys{}; + MDB_dbi dbiPreKeys{}; + MDB_dbi dbiIdentityKeys{}; + }; } // namespace QXmpp::Omemo diff --git a/qomemo/device.h b/qomemo/device.h index 4af6ada..6a67a19 100644 --- a/qomemo/device.h +++ b/qomemo/device.h @@ -7,18 +7,19 @@ #include class QXmppElement; + class QXmppIq; namespace QXmpp::Omemo { -class Device { -public: - int id; -}; + class Device { + public: + int id; + }; -class DeviceList { -public: - QList devices; -}; + class DeviceList { + public: + QList devices; + }; } // namespace QXmpp::Omemo diff --git a/qomemo/device_key_storage.cpp b/qomemo/device_key_storage.cpp index 1ba017e..d8c74df 100644 --- a/qomemo/device_key_storage.cpp +++ b/qomemo/device_key_storage.cpp @@ -6,10 +6,9 @@ #include int QXmpp::Omemo::DeviceKeyStorage::generateDeviceId() { - QRandomGenerator random{}; + QRandomGenerator random{}; - return 1 + random.bounded(INT32_MAX - 1); + return 1 + random.bounded(INT32_MAX - 1); } -QXmpp::Omemo::DeviceKeyStorage::DeviceKeyStorage(int deviceId) - : deviceId(deviceId) {} +QXmpp::Omemo::DeviceKeyStorage::DeviceKeyStorage(int deviceId) : deviceId(deviceId) {} diff --git a/qomemo/device_key_storage.h b/qomemo/device_key_storage.h index a0d8ce2..efeade9 100644 --- a/qomemo/device_key_storage.h +++ b/qomemo/device_key_storage.h @@ -6,13 +6,13 @@ namespace QXmpp::Omemo { -class DeviceKeyStorage { -public: - static int generateDeviceId(); + class DeviceKeyStorage { + public: + static int generateDeviceId(); - explicit DeviceKeyStorage(int deviceId); + explicit DeviceKeyStorage(int deviceId); - const int deviceId; -}; + const int deviceId; + }; } // namespace QXmpp::Omemo diff --git a/qomemo/device_service.cpp b/qomemo/device_service.cpp index fcc6b72..306f383 100644 --- a/qomemo/device_service.cpp +++ b/qomemo/device_service.cpp @@ -7,10 +7,9 @@ QXmpp::Omemo::DeviceService::DeviceService(QObject *parent) : QObject(parent) {} -void QXmpp::Omemo::DeviceService::onDeviceListReceived( - const QString &jid, const QXmpp::Omemo::DeviceList &list) { +void QXmpp::Omemo::DeviceService::onDeviceListReceived(const QString &jid, const QXmpp::Omemo::DeviceList &list) { - for (const auto &device : list.devices) { - qInfo() << "Got device for" << jid << ":" << device.id; - } + for (const auto &device : list.devices) { + qInfo() << "Got device for" << jid << ":" << device.id; + } } diff --git a/qomemo/device_service.h b/qomemo/device_service.h index c4aa04e..a9529c4 100644 --- a/qomemo/device_service.h +++ b/qomemo/device_service.h @@ -11,19 +11,19 @@ namespace QXmpp::Omemo { -class DeviceList; + class DeviceList; -class DeviceService : public QObject { - Q_OBJECT + class DeviceService : public QObject { + Q_OBJECT -public: - explicit DeviceService(QObject *parent); + public: + explicit DeviceService(QObject *parent); -public slots: - void onDeviceListReceived(const QString &jid, const DeviceList &list); + public slots: + void onDeviceListReceived(const QString &jid, const QXmpp::Omemo::DeviceList &list); -private: - QMap device_lists{}; -}; + private: + QMap device_lists{}; + }; } // namespace QXmpp::Omemo diff --git a/qomemo/qomemo.cpp b/qomemo/qomemo.cpp index d078f37..2b67119 100644 --- a/qomemo/qomemo.cpp +++ b/qomemo/qomemo.cpp @@ -13,82 +13,82 @@ using namespace QXmpp::Factories; QXmppElement QXmpp::Omemo::EncryptedMessage::header() const { - auto result = createElement("header"); - result.setAttribute("sid", QString::number(fromDeviceId)); + auto result = createElement("header"); + result.setAttribute("sid", QString::number(fromDeviceId)); - auto ivNode = createElement("iv"); - ivNode.setValue(iv); + auto ivNode = createElement("iv"); + ivNode.setValue(iv); - for (const auto &key : keys) { - result.appendChild(key.toXml()); - } + for (const auto &key : keys) { + result.appendChild(key.toXml()); + } - return result; + return result; } QXmppElement QXmpp::Omemo::EncryptedMessage::toXml() const { - auto result = createElement("encrypted", "eu.siacs.conversations.axolotl"); + auto result = createElement("encrypted", "eu.siacs.conversations.axolotl"); - result.appendChild(header()); - // TODO: Payload is optional - result.appendChild(payload()); + result.appendChild(header()); + // TODO: Payload is optional + result.appendChild(payload()); - return result; + return result; } QXmppElement QXmpp::Omemo::EncryptedMessage::payload() const { - QBuffer buffer; - buffer.open(QIODevice::ReadWrite); - QXmlStreamWriter writer(&buffer); - message.toXml(&writer); + QBuffer buffer; + buffer.open(QIODevice::ReadWrite); + QXmlStreamWriter writer(&buffer); + message.toXml(&writer); - QDomDocument doc; - doc.setContent(buffer.data(), true); + QDomDocument doc; + doc.setContent(buffer.data(), true); - QXmppElement root(doc.documentElement()); - root.setTagName("payload"); + QXmppElement root(doc.documentElement()); + root.setTagName("payload"); - return root; + return root; } QXmppElement QXmpp::Omemo::EncryptedMessage::content() const { - auto envelope = createElement("content", "urn:xmpp:sce:0"); + auto envelope = createElement("content", "urn:xmpp:sce:0"); - envelope.appendChild(payload()); + envelope.appendChild(payload()); - if (!from.isEmpty()) { - auto fromNode = createElement("from"); - fromNode.setAttribute("jid", from); - envelope.appendChild(fromNode); - } + if (!from.isEmpty()) { + auto fromNode = createElement("from"); + fromNode.setAttribute("jid", from); + envelope.appendChild(fromNode); + } - if (!to.isEmpty()) { - auto toNode = createElement("to"); - toNode.setAttribute("jid", to); - envelope.appendChild(toNode); - } + if (!to.isEmpty()) { + auto toNode = createElement("to"); + toNode.setAttribute("jid", to); + envelope.appendChild(toNode); + } - if (!timestamp.isNull()) { - auto timeNode = createElement("time"); - timeNode.setAttribute("stamp", timestamp.toString(Qt::DateFormat::ISODate)); - envelope.appendChild(timeNode); - } + if (!timestamp.isNull()) { + auto timeNode = createElement("time"); + timeNode.setAttribute("stamp", timestamp.toString(Qt::DateFormat::ISODate)); + envelope.appendChild(timeNode); + } - auto rpad = createElement("rpad"); - rpad.setValue(QXmpp::Sce::generatePadding()); - envelope.appendChild(rpad); + auto rpad = createElement("rpad"); + rpad.setValue(QXmpp::Sce::generatePadding()); + envelope.appendChild(rpad); - return envelope; + return envelope; } QXmppElement QXmpp::Omemo::MessageKey::toXml() const { - auto result = createElement("key"); + auto result = createElement("key"); - result.setAttribute("rid", QString::number(receivingDeviceId)); - if (prekey) - result.setAttribute("prekey", "true"); + result.setAttribute("rid", QString::number(receivingDeviceId)); + if (prekey) + result.setAttribute("prekey", "true"); - result.setValue(key); + result.setValue(key); - return result; + return result; } diff --git a/qomemo/qomemo.h b/qomemo/qomemo.h index b79ef1b..1e0c71a 100644 --- a/qomemo/qomemo.h +++ b/qomemo/qomemo.h @@ -11,32 +11,32 @@ namespace QXmpp::Omemo { -class MessageKey { -public: - [[nodiscard]] QXmppElement toXml() const; + class MessageKey { + public: + [[nodiscard]] QXmppElement toXml() const; - int receivingDeviceId{}; - bool prekey{}; - QString key{}; -}; + int receivingDeviceId{}; + bool prekey{}; + QString key{}; + }; -class EncryptedMessage { -public: - [[nodiscard]] QXmppElement header() const; - [[nodiscard]] QXmppElement content() const; - [[nodiscard]] QXmppElement toXml() const; - [[nodiscard]] QXmppElement payload() const; + class EncryptedMessage { + public: + [[nodiscard]] QXmppElement header() const; + [[nodiscard]] QXmppElement content() const; + [[nodiscard]] QXmppElement toXml() const; + [[nodiscard]] QXmppElement payload() const; - int fromDeviceId{}; + int fromDeviceId{}; - QList keys{}; - QString from{}; - QString to{}; - QDateTime timestamp{}; + QList keys{}; + QString from{}; + QString to{}; + QDateTime timestamp{}; - QString iv{}; + QString iv{}; - QXmppMessage message{}; -}; + QXmppMessage message{}; + }; } // namespace QXmpp::Omemo diff --git a/qomemo/qxmpp_omemo_manager.cpp b/qomemo/qxmpp_omemo_manager.cpp index 062b934..844a189 100644 --- a/qomemo/qxmpp_omemo_manager.cpp +++ b/qomemo/qxmpp_omemo_manager.cpp @@ -16,60 +16,59 @@ using namespace QXmpp::Omemo; Manager::Manager() - : deviceService(new DeviceService(this)), - omemoVariant(new Variant::Conversations) { - connect(this, &Manager::deviceListReceived, deviceService.get(), - &DeviceService::onDeviceListReceived); + : deviceService(new DeviceService(this)), + omemoVariant(new Variant::Conversations) { + connect(this, &Manager::deviceListReceived, deviceService.get(), &DeviceService::onDeviceListReceived); } bool QXmpp::Omemo::Manager::handleStanza(const QDomElement &stanza) { - QString str{}; - QTextStream info(&str); - stanza.save(info, 4); + QString str{}; + QTextStream info(&str); + stanza.save(info, 4); - std::cout << str.toStdString(); + std::cout << str.toStdString(); - if (stanza.tagName() == "iq") { - if (stanza.attribute("type") == "result") { - auto pubsub = stanza.firstChildElement("pubsub"); - if (!pubsub.isNull()) { - auto items = pubsub.firstChildElement("items"); - if (items.attribute("node") == - "eu.siacs.conversations.axolotl.devicelist") { - auto item = items.firstChildElement("item"); - if (!item.isNull()) { - auto list = item.firstChildElement("list"); - if (!list.isNull()) { - DeviceList deviceList = omemoVariant->deviceListFromXml(list); - emit deviceListReceived(stanza.attribute("from"), deviceList); + if (stanza.tagName() == "iq") { + if (stanza.attribute("type") == "result") { + auto pubsub = stanza.firstChildElement("pubsub"); + if (!pubsub.isNull()) { + auto items = pubsub.firstChildElement("items"); + if (items.attribute("node") == + "eu.siacs.conversations.axolotl.devicelist") { + auto item = items.firstChildElement("item"); + if (!item.isNull()) { + auto list = item.firstChildElement("list"); + if (!list.isNull()) { + DeviceList deviceList = omemoVariant->deviceListFromXml(list); + emit deviceListReceived(stanza.attribute("from"), deviceList); - return true; + return true; + } + } + } } - } } - } } - } - return false; + return false; } void QXmpp::Omemo::Manager::setClient(QXmppClient *client) { - QXmppClientExtension::setClient(client); + QXmppClientExtension::setClient(client); - if (!client) - return; + if (!client) + return; - QObject::connect(client, &QXmppClient::connected, this, - &Manager::fetchOwnDevices); + QObject::connect(client, &QXmppClient::connected, this, + &Manager::fetchOwnDevices); } void QXmpp::Omemo::Manager::fetchOwnDevices() { - QXmppPubSubIq iq{}; - iq.setFrom(client()->configuration().jid()); - iq.setTo(client()->configuration().jidBare()); - iq.setType(QXmppIq::Get); - iq.setQueryNode("eu.siacs.conversations.axolotl.devicelist"); + QXmppPubSubIq iq{}; + iq.setFrom(client()->configuration().jid()); + iq.setTo(client()->configuration().jidBare()); + iq.setType(QXmppIq::Get); + iq.setQueryNode("eu.siacs.conversations.axolotl.devicelist"); - client()->sendPacket(iq); + client()->sendPacket(iq); } diff --git a/qomemo/qxmpp_omemo_manager.h b/qomemo/qxmpp_omemo_manager.h index 377c77d..aae7467 100644 --- a/qomemo/qxmpp_omemo_manager.h +++ b/qomemo/qxmpp_omemo_manager.h @@ -12,27 +12,27 @@ namespace QXmpp::Omemo { -class Manager : public QXmppClientExtension { - Q_OBJECT; + class Manager : public QXmppClientExtension { + Q_OBJECT; -public: - Manager(); - ~Manager() override = default; + public: + Manager(); + ~Manager() override = default; - bool handleStanza(const QDomElement &stanza) override; + bool handleStanza(const QDomElement &stanza) override; -public slots: - void fetchOwnDevices(); + public slots: + void fetchOwnDevices(); -signals: - void deviceListReceived(const QString &jid, const DeviceList &list); + signals: + void deviceListReceived(const QString &jid, const QXmpp::Omemo::DeviceList &list); -protected: - void setClient(QXmppClient *client) override; + protected: + void setClient(QXmppClient *client) override; -private: - QScopedPointer deviceService; - QScopedPointer omemoVariant; -}; + private: + QScopedPointer deviceService; + QScopedPointer omemoVariant; + }; } // namespace QXmpp::Omemo diff --git a/qomemo/sce.cpp b/qomemo/sce.cpp index decb8b3..b94cede 100644 --- a/qomemo/sce.cpp +++ b/qomemo/sce.cpp @@ -6,19 +6,21 @@ #include +#define RPAD_ALPHABET "!\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~" + constexpr int RPAD_MAX_LENGTH = 200; QString QXmpp::Sce::generatePadding() { - QRandomGenerator random{}; - QString result{}; - QString alphabet{ QStringLiteral("!\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~") }; + QRandomGenerator random{}; + QString result{}; + QString alphabet{QStringLiteral(RPAD_ALPHABET)}; - auto length = random.bounded(RPAD_MAX_LENGTH); - result.resize(length); + auto length = random.bounded(RPAD_MAX_LENGTH); + result.resize(length); - for (auto i = 0; i < length; ++i) { - result[i] = alphabet[random.bounded(alphabet.length())]; - } + for (auto i = 0; i < length; ++i) { + result[i] = alphabet[random.bounded(alphabet.length())]; + } - return result; + return result; } diff --git a/qomemo/sce.h b/qomemo/sce.h index 91a7b2c..497aa3d 100644 --- a/qomemo/sce.h +++ b/qomemo/sce.h @@ -9,6 +9,6 @@ namespace QXmpp::Sce { -QString generatePadding(); + QString generatePadding(); } diff --git a/qomemo/signal/stores/signed_pre_key_store.cpp b/qomemo/signal/stores/signed_pre_key_store.cpp index 0156894..43bae1e 100644 --- a/qomemo/signal/stores/signed_pre_key_store.cpp +++ b/qomemo/signal/stores/signed_pre_key_store.cpp @@ -35,7 +35,8 @@ int Signal::Store::SignedPreKeyStore::loadSignedPreKey(signal_buffer **record, u return 0; } -int Signal::Store::SignedPreKeyStore::storeSignedPreKey(uint32_t signed_pre_key_id, uint8_t *record, size_t record_len) { +int +Signal::Store::SignedPreKeyStore::storeSignedPreKey(uint32_t signed_pre_key_id, uint8_t *record, size_t record_len) { return 0; } diff --git a/qomemo/user_device_list.cpp b/qomemo/user_device_list.cpp index 9a3f18a..5910ed2 100644 --- a/qomemo/user_device_list.cpp +++ b/qomemo/user_device_list.cpp @@ -6,5 +6,4 @@ #include -QXmpp::Omemo::UserDeviceList::UserDeviceList(QString jid) - : jid(std::move(jid)) {} +QXmpp::Omemo::UserDeviceList::UserDeviceList(QString jid) : jid(std::move(jid)) {} diff --git a/qomemo/user_device_list.h b/qomemo/user_device_list.h index 27e407a..00465aa 100644 --- a/qomemo/user_device_list.h +++ b/qomemo/user_device_list.h @@ -8,11 +8,11 @@ namespace QXmpp::Omemo { -class UserDeviceList { -public: - explicit UserDeviceList(QString jid); + class UserDeviceList { + public: + explicit UserDeviceList(QString jid); - const QString jid; -}; + const QString jid; + }; } // namespace QXmpp::Omemo diff --git a/qomemo/variant/conversations.cpp b/qomemo/variant/conversations.cpp index b2f85c4..4fc6af6 100644 --- a/qomemo/variant/conversations.cpp +++ b/qomemo/variant/conversations.cpp @@ -13,66 +13,66 @@ using namespace QXmpp::Omemo; using namespace QXmpp::Factories; QXmppElement Variant::Conversations::deviceToXml(const Device &device) { - auto result = createElement("device"); - result.setAttribute("id", QString::number(device.id)); + auto result = createElement("device"); + result.setAttribute("id", QString::number(device.id)); - return result; + return result; } Device Variant::Conversations::deviceFromXml(const QXmppElement &xml) { - Device result{}; + Device result{}; + + if (!elementMatches(xml, "device")) + return result; + + result.id = xml.attribute("id").toInt(); - if (!elementMatches(xml, "device")) return result; - - result.id = xml.attribute("id").toInt(); - - return result; } QXmppElement Variant::Conversations::deviceListToXml(const DeviceList &deviceList) { - auto element = createElement("list", "eu.siacs.conversations.axolotl"); + auto element = createElement("list", "eu.siacs.conversations.axolotl"); - for (const auto &device : deviceList.devices) { - element.appendChild(deviceToXml(device)); - } + for (const auto &device : deviceList.devices) { + element.appendChild(deviceToXml(device)); + } - return element; + return element; } DeviceList Variant::Conversations::deviceListFromXml(const QXmppElement &xml) { - DeviceList result{}; + DeviceList result{}; + + if (!elementMatches(xml, "list", "eu.siacs.conversations.axolotl")) + return result; + + auto deviceElement = xml.firstChildElement("device"); + while (!deviceElement.isNull()) { + result.devices.push_back(deviceFromXml(deviceElement)); + deviceElement = deviceElement.nextSiblingElement("device"); + } - if (!elementMatches(xml, "list", "eu.siacs.conversations.axolotl")) return result; - - auto deviceElement = xml.firstChildElement("device"); - while (!deviceElement.isNull()) { - result.devices.push_back(deviceFromXml(deviceElement)); - deviceElement = deviceElement.nextSiblingElement("device"); - } - - return result; } QXmppIq Variant::Conversations::deviceListSetIq(const DeviceList &deviceList) { - QXmppIq iq{}; + QXmppIq iq{}; - iq.setType(QXmppIq::Set); + iq.setType(QXmppIq::Set); - auto item = createElement("item"); - item.appendChild(deviceListToXml(deviceList)); + auto item = createElement("item"); + item.appendChild(deviceListToXml(deviceList)); - auto publish = createElement("publish"); - publish.setAttribute("node", "eu.siacs.conversations.axolotl.devicelist"); - publish.appendChild(item); + auto publish = createElement("publish"); + publish.setAttribute("node", "eu.siacs.conversations.axolotl.devicelist"); + publish.appendChild(item); - auto pubSub = createElement("pubsub", "http://jabber.org/protocol/pubsub"); - pubSub.appendChild(publish); - pubSub.appendChild(createOpenPublishOptions()); + auto pubSub = createElement("pubsub", "http://jabber.org/protocol/pubsub"); + pubSub.appendChild(publish); + pubSub.appendChild(createOpenPublishOptions()); - iq.extensions().push_back(pubSub); + iq.extensions().push_back(pubSub); - return iq; + return iq; } diff --git a/qomemo/variant/conversations.h b/qomemo/variant/conversations.h index 917dbcd..923e29b 100644 --- a/qomemo/variant/conversations.h +++ b/qomemo/variant/conversations.h @@ -8,16 +8,16 @@ namespace QXmpp::Omemo::Variant { -class Conversations : public Base { -public: - ~Conversations() override = default; + class Conversations : public Base { + public: + ~Conversations() override = default; - QXmppElement deviceToXml(const Device &device) override; - Device deviceFromXml(const QXmppElement &xml) override; + QXmppElement deviceToXml(const Device &device) override; + Device deviceFromXml(const QXmppElement &xml) override; - QXmppElement deviceListToXml(const DeviceList &deviceList) override; - DeviceList deviceListFromXml(const QXmppElement &xml) override; - QXmppIq deviceListSetIq(const DeviceList &deviceList) override; -}; + QXmppElement deviceListToXml(const DeviceList &deviceList) override; + DeviceList deviceListFromXml(const QXmppElement &xml) override; + QXmppIq deviceListSetIq(const DeviceList &deviceList) override; + }; } // namespace QXmpp::Omemo::Variant diff --git a/qomemo/variant/omemo_base.h b/qomemo/variant/omemo_base.h index fd11f31..58910fe 100644 --- a/qomemo/variant/omemo_base.h +++ b/qomemo/variant/omemo_base.h @@ -5,27 +5,29 @@ #pragma once class QXmppElement; + class QXmppIq; namespace QXmpp::Omemo { -class Device; -class DeviceList; + class Device; -namespace Variant { + class DeviceList; -class Base { -public: - virtual ~Base() = default; + namespace Variant { - virtual QXmppElement deviceToXml(const Device &device) = 0; - virtual Device deviceFromXml(const QXmppElement &xml) = 0; + class Base { + public: + virtual ~Base() = default; - virtual QXmppElement deviceListToXml(const DeviceList &deviceList) = 0; - virtual DeviceList deviceListFromXml(const QXmppElement &xml) = 0; - virtual QXmppIq deviceListSetIq(const DeviceList &deviceList) = 0; -}; + virtual QXmppElement deviceToXml(const Device &device) = 0; + virtual Device deviceFromXml(const QXmppElement &xml) = 0; -} // namespace Variant + virtual QXmppElement deviceListToXml(const DeviceList &deviceList) = 0; + virtual DeviceList deviceListFromXml(const QXmppElement &xml) = 0; + virtual QXmppIq deviceListSetIq(const DeviceList &deviceList) = 0; + }; + + } // namespace Variant } // namespace QXmpp::Omemo