aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/CMakeLists.txt4
-rw-r--r--src/client/QXmppAtmManager.cpp23
-rw-r--r--src/client/QXmppAtmManager.h11
-rw-r--r--src/client/QXmppAtmTrustMemoryStorage.cpp145
-rw-r--r--src/client/QXmppAtmTrustMemoryStorage.h33
-rw-r--r--src/client/QXmppAtmTrustStorage.cpp80
-rw-r--r--src/client/QXmppAtmTrustStorage.h24
-rw-r--r--src/client/QXmppTrustMemoryStorage.cpp221
-rw-r--r--src/client/QXmppTrustMemoryStorage.h21
-rw-r--r--src/client/QXmppTrustStorage.cpp142
-rw-r--r--src/client/QXmppTrustStorage.h33
-rw-r--r--tests/qxmppatmmanager/tst_qxmppatmmanager.cpp16
-rw-r--r--tests/qxmpptrustmemorystorage/tst_qxmpptrustmemorystorage.cpp550
13 files changed, 978 insertions, 325 deletions
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index 1efd3c21..5f1e5eb5 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -91,6 +91,8 @@ set(INSTALL_HEADER_FILES
# Client
client/QXmppArchiveManager.h
client/QXmppAtmManager.h
+ client/QXmppAtmTrustMemoryStorage.h
+ client/QXmppAtmTrustStorage.h
client/QXmppAttentionManager.h
client/QXmppBookmarkManager.h
client/QXmppCarbonManager.h
@@ -196,6 +198,8 @@ set(SOURCE_FILES
# Client
client/QXmppArchiveManager.cpp
client/QXmppAtmManager.cpp
+ client/QXmppAtmTrustMemoryStorage.cpp
+ client/QXmppAtmTrustStorage.cpp
client/QXmppAttentionManager.cpp
client/QXmppBookmarkManager.cpp
client/QXmppCarbonManager.cpp
diff --git a/src/client/QXmppAtmManager.cpp b/src/client/QXmppAtmManager.cpp
index 4155e993..c4fe2cad 100644
--- a/src/client/QXmppAtmManager.cpp
+++ b/src/client/QXmppAtmManager.cpp
@@ -8,13 +8,11 @@
#include "QXmppClient.h"
#include "QXmppConstants_p.h"
#include "QXmppFutureUtils_p.h"
+#include "QXmppMessage.h"
#include "QXmppTrustMessageElement.h"
+#include "QXmppTrustMessageKeyOwner.h"
#include "QXmppUtils.h"
-#include <QCoreApplication>
-#include <QDomElement>
-#include <QList>
-
using namespace QXmpp::Private;
///
@@ -27,21 +25,10 @@ using namespace QXmpp::Private;
/// storage interface must be added.
/// That implementation has to be adapted to your storage such as a database.
/// In case you only need memory and no peristent storage, you can use the
-/// existing implementation:
+/// existing implementation and add the storage with it:
///
///\code
-/// QXmppTrustStorage *trustStorage = new QXmppTrustMemoryStorage;
-/// \endcode
-///
-/// You can set a security policy used by ATM via the trust manager.
-/// Is is recommended to apply TOAKAFA for good security and usability when
-/// using \xep{0384, OMEMO Encryption}:
-/// \code
-/// trustStorage->setSecurityPolicy("urn:xmpp:omemo:2", QXmppTrustStorage::Toakafa);
-/// \endcode
-///
-/// Afterwards, this manager must be added with the storage:
-/// \code
+/// QXmppAtmTrustStorage *trustStorage = new QXmppAtmTrustMemoryStorage;
/// QXmppAtmManager *manager = new QXmppAtmManager(trustStorage);
/// client->addExtension(manager);
/// \endcode
@@ -73,7 +60,7 @@ using namespace QXmpp::Private;
///
/// \param trustStorage trust storage implementation
///
-QXmppAtmManager::QXmppAtmManager(QXmppTrustStorage *trustStorage)
+QXmppAtmManager::QXmppAtmManager(QXmppAtmTrustStorage *trustStorage)
{
m_trustStorage = trustStorage;
}
diff --git a/src/client/QXmppAtmManager.h b/src/client/QXmppAtmManager.h
index 5c2dc1e7..042d1342 100644
--- a/src/client/QXmppAtmManager.h
+++ b/src/client/QXmppAtmManager.h
@@ -5,18 +5,19 @@
#ifndef QXMPPATMMANAGER_H
#define QXMPPATMMANAGER_H
+#include "QXmppAtmTrustStorage.h"
#include "QXmppClientExtension.h"
-#include "QXmppMessage.h"
#include "QXmppSendResult.h"
-#include "QXmppTrustMessageKeyOwner.h"
-#include "QXmppTrustStorage.h"
+
+class QXmppMessage;
+class QXmppTrustMessageKeyOwner;
class QXMPP_EXPORT QXmppAtmManager : public QXmppClientExtension
{
Q_OBJECT
public:
- QXmppAtmManager(QXmppTrustStorage *trustStorage);
+ QXmppAtmManager(QXmppAtmTrustStorage *trustStorage);
QFuture<void> makeTrustDecisions(const QString &encryption, const QString &keyOwnerJid, const QList<QByteArray> &keyIdsForAuthentication, const QList<QByteArray> &keyIdsForDistrusting = {});
/// \cond
@@ -41,7 +42,7 @@ private:
QFuture<QXmpp::SendResult> sendTrustMessage(const QString &encryption, const QList<QXmppTrustMessageKeyOwner> &keyOwners, const QString &recipientJid);
- QXmppTrustStorage *m_trustStorage;
+ QXmppAtmTrustStorage *m_trustStorage;
friend class tst_QXmppAtmManager;
};
diff --git a/src/client/QXmppAtmTrustMemoryStorage.cpp b/src/client/QXmppAtmTrustMemoryStorage.cpp
new file mode 100644
index 00000000..404c5564
--- /dev/null
+++ b/src/client/QXmppAtmTrustMemoryStorage.cpp
@@ -0,0 +1,145 @@
+// SPDX-FileCopyrightText: 2022 Melvin Keskin <melvo@olomono.de>
+//
+// SPDX-License-Identifier: LGPL-2.1-or-later
+
+#include "QXmppAtmTrustMemoryStorage.h"
+
+#include "QXmppFutureUtils_p.h"
+#include "QXmppTrustMessageKeyOwner.h"
+
+using namespace QXmpp::Private;
+
+///
+/// \class QXmppAtmTrustMemoryStorage
+///
+/// \brief The QXmppAtmTrustMemoryStorage class stores trust data for
+/// \xep{0450, Automatic Trust Management (ATM)} in the memory.
+///
+/// \warning THIS API IS NOT FINALIZED YET!
+///
+/// \since QXmpp 1.5
+///
+
+struct UnprocessedKey
+{
+ QByteArray id;
+ QString ownerJid;
+ QByteArray senderKeyId;
+ bool trust;
+};
+
+class QXmppAtmTrustMemoryStoragePrivate
+{
+public:
+ // encryption protocols mapped to trust message data received from endpoints
+ // with unauthenticated keys
+ QMultiHash<QString, UnprocessedKey> keys;
+};
+
+///
+/// Constructs an ATM trust memory storage.
+///
+QXmppAtmTrustMemoryStorage::QXmppAtmTrustMemoryStorage()
+ : d(new QXmppAtmTrustMemoryStoragePrivate)
+{
+}
+
+QXmppAtmTrustMemoryStorage::~QXmppAtmTrustMemoryStorage() = default;
+
+/// \cond
+QFuture<void> QXmppAtmTrustMemoryStorage::addKeysForPostponedTrustDecisions(const QString &encryption, const QByteArray &senderKeyId, const QList<QXmppTrustMessageKeyOwner> &keyOwners)
+{
+ const auto addKeys = [&](const QXmppTrustMessageKeyOwner &keyOwner, bool trust, const QList<QByteArray> &keyIds) {
+ for (const auto &keyId : keyIds) {
+ auto isKeyFound = false;
+
+ for (auto itr = d->keys.find(encryption); itr != d->keys.end() && itr.key() == encryption; ++itr) {
+ auto &key = itr.value();
+ if (key.id == keyId && key.ownerJid == keyOwner.jid() && key.senderKeyId == senderKeyId) {
+ // Update the stored trust if it differs from the new one.
+ if (key.trust != trust) {
+ key.trust = trust;
+ }
+
+ isKeyFound = true;
+ break;
+ }
+ }
+
+ // Create a new entry and store it if there is no such entry yet.
+ if (!isKeyFound) {
+ UnprocessedKey key;
+ key.id = keyId;
+ key.ownerJid = keyOwner.jid();
+ key.senderKeyId = senderKeyId;
+ key.trust = trust;
+ d->keys.insert(encryption, key);
+ }
+ }
+ };
+
+ for (const auto &keyOwner : keyOwners) {
+ addKeys(keyOwner, true, keyOwner.trustedKeys());
+ addKeys(keyOwner, false, keyOwner.distrustedKeys());
+ }
+
+ return makeReadyFuture();
+}
+
+QFuture<void> QXmppAtmTrustMemoryStorage::removeKeysForPostponedTrustDecisions(const QString &encryption, const QList<QByteArray> &keyIdsForAuthentication, const QList<QByteArray> &keyIdsForDistrusting)
+{
+ for (auto itr = d->keys.find(encryption);
+ itr != d->keys.end() && itr.key() == encryption;) {
+ const auto &key = itr.value();
+ if ((key.trust && keyIdsForAuthentication.contains(key.id)) ||
+ (!key.trust && keyIdsForDistrusting.contains(key.id))) {
+ itr = d->keys.erase(itr);
+ } else {
+ ++itr;
+ }
+ }
+
+ return makeReadyFuture();
+}
+
+QFuture<void> QXmppAtmTrustMemoryStorage::removeKeysForPostponedTrustDecisions(const QString &encryption, const QList<QByteArray> &senderKeyIds)
+{
+ for (auto itr = d->keys.find(encryption);
+ itr != d->keys.end() && itr.key() == encryption;) {
+ if (senderKeyIds.contains(itr.value().senderKeyId)) {
+ itr = d->keys.erase(itr);
+ } else {
+ ++itr;
+ }
+ }
+
+ return makeReadyFuture();
+}
+
+QFuture<void> QXmppAtmTrustMemoryStorage::removeKeysForPostponedTrustDecisions(const QString &encryption)
+{
+ d->keys.remove(encryption);
+ return makeReadyFuture();
+}
+
+QFuture<QHash<bool, QMultiHash<QString, QByteArray>>> QXmppAtmTrustMemoryStorage::keysForPostponedTrustDecisions(const QString &encryption, const QList<QByteArray> &senderKeyIds)
+{
+ QHash<bool, QMultiHash<QString, QByteArray>> keys;
+
+ const auto storedKeys = d->keys.values(encryption);
+ for (const auto &key : storedKeys) {
+ if (senderKeyIds.contains(key.senderKeyId) || senderKeyIds.isEmpty()) {
+ keys[key.trust].insert(key.ownerJid, key.id);
+ }
+ }
+
+ return makeReadyFuture(std::move(keys));
+}
+
+QFuture<void> QXmppAtmTrustMemoryStorage::resetAll(const QString &encryption)
+{
+ QXmppTrustMemoryStorage::resetAll(encryption);
+ d->keys.remove(encryption);
+ return makeReadyFuture();
+}
+/// \endcond
diff --git a/src/client/QXmppAtmTrustMemoryStorage.h b/src/client/QXmppAtmTrustMemoryStorage.h
new file mode 100644
index 00000000..432c2058
--- /dev/null
+++ b/src/client/QXmppAtmTrustMemoryStorage.h
@@ -0,0 +1,33 @@
+// SPDX-FileCopyrightText: 2022 Melvin Keskin <melvo@olomono.de>
+//
+// SPDX-License-Identifier: LGPL-2.1-or-later
+
+#ifndef QXMPPATMTRUSTMEMORYSTORAGE_H
+#define QXMPPATMTRUSTMEMORYSTORAGE_H
+
+#include "QXmppAtmTrustStorage.h"
+#include "QXmppTrustMemoryStorage.h"
+
+class QXmppAtmTrustMemoryStoragePrivate;
+
+class QXMPP_EXPORT QXmppAtmTrustMemoryStorage : virtual public QXmppAtmTrustStorage, public QXmppTrustMemoryStorage
+{
+public:
+ QXmppAtmTrustMemoryStorage();
+ ~QXmppAtmTrustMemoryStorage();
+
+ /// \cond
+ QFuture<void> addKeysForPostponedTrustDecisions(const QString &encryption, const QByteArray &senderKeyId, const QList<QXmppTrustMessageKeyOwner> &keyOwners) override;
+ QFuture<void> removeKeysForPostponedTrustDecisions(const QString &encryption, const QList<QByteArray> &keyIdsForAuthentication, const QList<QByteArray> &keyIdsForDistrusting) override;
+ QFuture<void> removeKeysForPostponedTrustDecisions(const QString &encryption, const QList<QByteArray> &senderKeyIds) override;
+ QFuture<void> removeKeysForPostponedTrustDecisions(const QString &encryption) override;
+ QFuture<QHash<bool, QMultiHash<QString, QByteArray>>> keysForPostponedTrustDecisions(const QString &encryption, const QList<QByteArray> &senderKeyIds = {}) override;
+
+ QFuture<void> resetAll(const QString &encryption) override;
+ /// \endcond
+
+private:
+ std::unique_ptr<QXmppAtmTrustMemoryStoragePrivate> d;
+};
+
+#endif // QXMPPATMTRUSTMEMORYSTORAGE_H
diff --git a/src/client/QXmppAtmTrustStorage.cpp b/src/client/QXmppAtmTrustStorage.cpp
new file mode 100644
index 00000000..70ce2822
--- /dev/null
+++ b/src/client/QXmppAtmTrustStorage.cpp
@@ -0,0 +1,80 @@
+// SPDX-FileCopyrightText: 2022 Melvin Keskin <melvo@olomono.de>
+//
+// SPDX-License-Identifier: LGPL-2.1-or-later
+
+///
+/// \class QXmppAtmTrustStorage
+///
+/// \brief The QXmppAtmTrustStorage class stores trust data for
+/// \xep{0450, Automatic Trust Management (ATM)}.
+///
+/// \warning THIS API IS NOT FINALIZED YET!
+///
+/// \since QXmpp 1.5
+///
+
+///
+/// \fn QXmppAtmTrustStorage::addKeysForPostponedTrustDecisions(const QString &encryption, const QByteArray &senderKeyId, const QList<QXmppTrustMessageKeyOwner> &keyOwners)
+///
+/// Adds keys that cannot be authenticated or distrusted directly because the
+/// key of the trust message's sender is not yet authenticated.
+///
+/// Those keys are being authenticated or distrusted once the sender's key is
+/// authenticated.
+/// Each element of keyOwners (i.e., keyOwner) can contain keys for postponed
+/// authentication as trustedKeys or for postponed distrusting as
+/// distrustedKeys.
+///
+/// If keys of keyOwner.trustedKeys() are already stored for postponed
+/// distrusting, they are changed to be used for postponed authentication.
+/// If keys of keyOwner.distrustedKeys() are already stored for postponed
+/// authentication, they are changed to be used for postponed distrusting.
+/// If the same keys are in keyOwner.trustedKeys() and
+/// keyOwner.distrustedKeys(), they are used for postponed distrusting.
+///
+/// \param encryption encryption protocol namespace
+/// \param senderKeyId key ID of the trust message's sender
+/// \param keyOwners key owners containing key IDs for postponed trust decisions
+///
+
+///
+/// \fn QXmppAtmTrustStorage::removeKeysForPostponedTrustDecisions(const QString &encryption, const QList<QByteArray> &keyIdsForAuthentication, const QList<QByteArray> &keyIdsForDistrusting)
+///
+/// Removes keys for postponed authentication or distrusting.
+///
+/// \param encryption encryption protocol namespace
+/// \param keyIdsForAuthentication IDs of the keys for postponed authentication
+/// \param keyIdsForDistrusting IDs of the keys for postponed distrusting
+///
+
+///
+/// \fn QXmppAtmTrustStorage::removeKeysForPostponedTrustDecisions(const QString &encryption, const QList<QByteArray> &senderKeyIds)
+///
+/// Removes keys for postponed authentication or distrusting by the trust
+/// message sender's key ID.
+///
+/// \param encryption encryption protocol namespace
+/// \param senderKeyIds key IDs of the trust messages' senders
+///
+
+///
+/// \fn QXmppAtmTrustStorage::removeKeysForPostponedTrustDecisions(const QString &encryption)
+///
+/// Removes all keys for postponed authentication or distrusting for encryption.
+///
+/// \param encryption encryption protocol namespace
+///
+
+///
+/// \fn QXmppAtmTrustStorage::keysForPostponedTrustDecisions(const QString &encryption, const QList<QByteArray> &senderKeyIds = {})
+///
+/// Returns the JIDs of key owners mapped to the IDs of their keys stored for
+/// postponed authentication (true) or postponed distrusting (false).
+///
+/// If senderKeyIds is empty, all keys for encryption are returned.
+///
+/// \param encryption encryption protocol namespace
+/// \param senderKeyIds key IDs of the trust messages' senders
+///
+/// \return the key owner JIDs mapped to their keys
+///
diff --git a/src/client/QXmppAtmTrustStorage.h b/src/client/QXmppAtmTrustStorage.h
new file mode 100644
index 00000000..e801c7df
--- /dev/null
+++ b/src/client/QXmppAtmTrustStorage.h
@@ -0,0 +1,24 @@
+// SPDX-FileCopyrightText: 2022 Melvin Keskin <melvo@olomono.de>
+//
+// SPDX-License-Identifier: LGPL-2.1-or-later
+
+#ifndef QXMPPATMTRUSTSTORAGE_H
+#define QXMPPATMTRUSTSTORAGE_H
+
+#include "QXmppTrustStorage.h"
+
+class QXmppTrustMessageKeyOwner;
+
+class QXMPP_EXPORT QXmppAtmTrustStorage : virtual public QXmppTrustStorage
+{
+public:
+ virtual ~QXmppAtmTrustStorage() = default;
+
+ virtual QFuture<void> addKeysForPostponedTrustDecisions(const QString &encryption, const QByteArray &senderKeyId, const QList<QXmppTrustMessageKeyOwner> &keyOwners) = 0;
+ virtual QFuture<void> removeKeysForPostponedTrustDecisions(const QString &encryption, const QList<QByteArray> &keyIdsForAuthentication, const QList<QByteArray> &keyIdsForDistrusting) = 0;
+ virtual QFuture<void> removeKeysForPostponedTrustDecisions(const QString &encryption, const QList<QByteArray> &senderKeyIds) = 0;
+ virtual QFuture<void> removeKeysForPostponedTrustDecisions(const QString &encryption) = 0;
+ virtual QFuture<QHash<bool, QMultiHash<QString, QByteArray>>> keysForPostponedTrustDecisions(const QString &encryption, const QList<QByteArray> &senderKeyIds = {}) = 0;
+};
+
+#endif // QXMPPATMTRUSTSTORAGE_H
diff --git a/src/client/QXmppTrustMemoryStorage.cpp b/src/client/QXmppTrustMemoryStorage.cpp
index f5e99b33..5a1b6e61 100644
--- a/src/client/QXmppTrustMemoryStorage.cpp
+++ b/src/client/QXmppTrustMemoryStorage.cpp
@@ -5,7 +5,6 @@
#include "QXmppTrustMemoryStorage.h"
#include "QXmppFutureUtils_p.h"
-#include "QXmppTrustMessageKeyOwner.h"
using namespace QXmpp::Private;
@@ -20,21 +19,13 @@ using namespace QXmpp::Private;
/// \since QXmpp 1.5
///
-struct ProcessedKey
+struct Key
{
QByteArray id;
QString ownerJid;
QXmppTrustStorage::TrustLevel trustLevel;
};
-struct UnprocessedKey
-{
- QByteArray id;
- QString ownerJid;
- QByteArray senderKeyId;
- bool trust;
-};
-
class QXmppTrustMemoryStoragePrivate
{
public:
@@ -45,11 +36,7 @@ public:
QMap<QString, QByteArray> ownKeys;
// encryption protocols mapped to keys with specified trust levels
- QMultiHash<QString, ProcessedKey> processedKeys;
-
- // encryption protocols mapped to trust message data received from endpoints
- // with unauthenticated keys
- QMultiHash<QString, UnprocessedKey> unprocessedKeys;
+ QMultiHash<QString, Key> keys;
};
///
@@ -63,16 +50,15 @@ QXmppTrustMemoryStorage::QXmppTrustMemoryStorage()
QXmppTrustMemoryStorage::~QXmppTrustMemoryStorage() = default;
/// \cond
-QFuture<void> QXmppTrustMemoryStorage::setSecurityPolicies(const QString &encryption, const QXmppTrustStorage::SecurityPolicy securityPolicy)
+QFuture<void> QXmppTrustMemoryStorage::setSecurityPolicy(const QString &encryption, const QXmppTrustStorage::SecurityPolicy securityPolicy)
{
- if (encryption.isEmpty()) {
- d->securityPolicies.clear();
- } else if (securityPolicy == QXmppTrustStorage::NoSecurityPolicy) {
- d->securityPolicies.remove(encryption);
- } else {
- d->securityPolicies.insert(encryption, securityPolicy);
- }
+ d->securityPolicies.insert(encryption, securityPolicy);
+ return makeReadyFuture();
+}
+QFuture<void> QXmppTrustMemoryStorage::resetSecurityPolicy(const QString &encryption)
+{
+ d->securityPolicies.remove(encryption);
return makeReadyFuture();
}
@@ -81,13 +67,13 @@ QFuture<QXmppTrustStorage::SecurityPolicy> QXmppTrustMemoryStorage::securityPoli
return makeReadyFuture(std::move(d->securityPolicies.value(encryption)));
}
-QFuture<void> QXmppTrustMemoryStorage::addOwnKey(const QString &encryption, const QByteArray &keyId)
+QFuture<void> QXmppTrustMemoryStorage::setOwnKey(const QString &encryption, const QByteArray &keyId)
{
d->ownKeys.insert(encryption, keyId);
return makeReadyFuture();
}
-QFuture<void> QXmppTrustMemoryStorage::removeOwnKey(const QString &encryption)
+QFuture<void> QXmppTrustMemoryStorage::resetOwnKey(const QString &encryption)
{
d->ownKeys.remove(encryption);
return makeReadyFuture();
@@ -102,11 +88,11 @@ QFuture<QByteArray> QXmppTrustMemoryStorage::ownKey(const QString &encryption)
QFuture<void> QXmppTrustMemoryStorage::addKeys(const QString &encryption, const QString &keyOwnerJid, const QList<QByteArray> &keyIds, const QXmppTrustStorage::TrustLevel trustLevel)
{
for (const auto &keyId : keyIds) {
- ProcessedKey key;
+ Key key;
key.id = keyId;
key.ownerJid = keyOwnerJid;
key.trustLevel = trustLevel;
- d->processedKeys.insert(encryption, key);
+ d->keys.insert(encryption, key);
}
return makeReadyFuture();
@@ -114,30 +100,44 @@ QFuture<void> QXmppTrustMemoryStorage::addKeys(const QString &encryption, const
QFuture<void> QXmppTrustMemoryStorage::removeKeys(const QString &encryption, const QList<QByteArray> &keyIds)
{
- if (encryption.isEmpty()) {
- d->processedKeys.clear();
- } else if (keyIds.isEmpty()) {
- d->processedKeys.remove(encryption);
- } else {
- for (auto itr = d->processedKeys.find(encryption);
- itr != d->processedKeys.end() && itr.key() == encryption;) {
- if (keyIds.contains(itr.value().id)) {
- itr = d->processedKeys.erase(itr);
- } else {
- itr++;
- }
+ for (auto itr = d->keys.find(encryption);
+ itr != d->keys.end() && itr.key() == encryption;) {
+ if (keyIds.contains(itr.value().id)) {
+ itr = d->keys.erase(itr);
+ } else {
+ ++itr;
}
}
return makeReadyFuture();
}
+QFuture<void> QXmppTrustMemoryStorage::removeKeys(const QString &encryption, const QString &keyOwnerJid)
+{
+ for (auto itr = d->keys.find(encryption);
+ itr != d->keys.end() && itr.key() == encryption;) {
+ if (itr.value().ownerJid == keyOwnerJid) {
+ itr = d->keys.erase(itr);
+ } else {
+ ++itr;
+ }
+ }
+
+ return makeReadyFuture();
+}
+
+QFuture<void> QXmppTrustMemoryStorage::removeKeys(const QString &encryption)
+{
+ d->keys.remove(encryption);
+ return makeReadyFuture();
+}
+
QFuture<QHash<QXmppTrustStorage::TrustLevel, QMultiHash<QString, QByteArray>>> QXmppTrustMemoryStorage::keys(const QString &encryption, const TrustLevels trustLevels)
{
QHash<TrustLevel, QMultiHash<QString, QByteArray>> keys;
- const auto processedKeys = d->processedKeys.values(encryption);
- for (const auto &key : processedKeys) {
+ const auto storedKeys = d->keys.values(encryption);
+ for (const auto &key : storedKeys) {
const auto trustLevel = key.trustLevel;
if (trustLevels.testFlag(trustLevel) || !trustLevels) {
keys[trustLevel].insert(key.ownerJid, key.id);
@@ -147,6 +147,34 @@ QFuture<QHash<QXmppTrustStorage::TrustLevel, QMultiHash<QString, QByteArray>>> Q
return makeReadyFuture(std::move(keys));
}
+QFuture<QHash<QString, QHash<QByteArray, QXmppTrustStorage::TrustLevel>>> QXmppTrustMemoryStorage::keys(const QString &encryption, const QList<QString> &keyOwnerJids, TrustLevels trustLevels)
+{
+ QHash<QString, QHash<QByteArray, QXmppTrustStorage::TrustLevel>> keys;
+
+ const auto storedKeys = d->keys.values(encryption);
+ for (const auto &key : storedKeys) {
+ const auto keyOwnerJid = key.ownerJid;
+ const auto trustLevel = key.trustLevel;
+ if (keyOwnerJids.contains(keyOwnerJid) && (trustLevels.testFlag(trustLevel) || !trustLevels)) {
+ keys[keyOwnerJid].insert(key.id, trustLevel);
+ }
+ }
+
+ return makeReadyFuture(std::move(keys));
+}
+
+QFuture<bool> QXmppTrustMemoryStorage::hasKey(const QString &encryption, const QString &keyOwnerJid, TrustLevels trustLevels)
+{
+ const auto storedKeys = d->keys.values(encryption);
+ for (const auto &key : storedKeys) {
+ if (key.ownerJid == keyOwnerJid && trustLevels.testFlag(key.trustLevel)) {
+ return makeReadyFuture(std::move(true));
+ }
+ }
+
+ return makeReadyFuture(std::move(false));
+}
+
QFuture<void> QXmppTrustMemoryStorage::setTrustLevel(const QString &encryption, const QMultiHash<QString, QByteArray> &keyIds, const TrustLevel trustLevel)
{
for (auto itr = keyIds.constBegin(); itr != keyIds.constEnd(); ++itr) {
@@ -155,13 +183,13 @@ QFuture<void> QXmppTrustMemoryStorage::setTrustLevel(const QString &encryption,
auto isKeyFound = false;
- for (auto itrProcessedKeys = d->processedKeys.find(encryption);
- itrProcessedKeys != d->processedKeys.end() && itrProcessedKeys.key() == encryption;
- ++itrProcessedKeys) {
- auto &key = itrProcessedKeys.value();
+ for (auto itrKeys = d->keys.find(encryption);
+ itrKeys != d->keys.end() && itrKeys.key() == encryption;
+ ++itrKeys) {
+ auto &key = itrKeys.value();
if (key.id == keyId && key.ownerJid == keyOwnerJid) {
+ // Update the stored trust level if it differs from the new one.
if (key.trustLevel != trustLevel) {
- // Update the stored trust level if it differs from the new one.
key.trustLevel = trustLevel;
}
@@ -170,13 +198,13 @@ QFuture<void> QXmppTrustMemoryStorage::setTrustLevel(const QString &encryption,
}
}
+ // Create a new entry and store it if there is no such entry yet.
if (!isKeyFound) {
- // Create a new entry and store it if there is no such entry yet.
- ProcessedKey key;
+ Key key;
key.id = keyId;
key.ownerJid = keyOwnerJid;
key.trustLevel = trustLevel;
- d->processedKeys.insert(encryption, key);
+ d->keys.insert(encryption, key);
}
}
@@ -185,7 +213,7 @@ QFuture<void> QXmppTrustMemoryStorage::setTrustLevel(const QString &encryption,
QFuture<void> QXmppTrustMemoryStorage::setTrustLevel(const QString &encryption, const QList<QString> &keyOwnerJids, const QXmppTrustStorage::TrustLevel oldTrustLevel, const QXmppTrustStorage::TrustLevel newTrustLevel)
{
- for (auto itr = d->processedKeys.find(encryption); itr != d->processedKeys.end() && itr.key() == encryption; ++itr) {
+ for (auto itr = d->keys.find(encryption); itr != d->keys.end() && itr.key() == encryption; ++itr) {
auto &key = itr.value();
if (keyOwnerJids.contains(key.ownerJid) && key.trustLevel == oldTrustLevel) {
key.trustLevel = newTrustLevel;
@@ -197,101 +225,22 @@ QFuture<void> QXmppTrustMemoryStorage::setTrustLevel(const QString &encryption,
QFuture<QXmppTrustStorage::TrustLevel> QXmppTrustMemoryStorage::trustLevel(const QString &encryption, const QByteArray &keyId)
{
- const auto processedKeys = d->processedKeys.values(encryption);
- for (const auto &key : processedKeys) {
+ const auto keys = d->keys.values(encryption);
+ for (const auto &key : keys) {
if (key.id == keyId) {
return makeReadyFuture(std::move(QXmppTrustStorage::TrustLevel(key.trustLevel)));
}
}
- return makeReadyFuture(std::move(TrustLevel::AutomaticallyDistrusted));
-}
-
-QFuture<void> QXmppTrustMemoryStorage::addKeysForPostponedTrustDecisions(const QString &encryption, const QByteArray &senderKeyId, const QList<QXmppTrustMessageKeyOwner> &keyOwners)
-{
- const auto addKeys = [&](const QXmppTrustMessageKeyOwner &keyOwner, bool trust, const QList<QByteArray> &keyIds) {
- for (const auto &keyId : keyIds) {
- auto isKeyFound = false;
-
- for (auto itr = d->unprocessedKeys.find(encryption); itr != d->unprocessedKeys.end() && itr.key() == encryption; ++itr) {
- auto &key = itr.value();
- if (key.id == keyId && key.ownerJid == keyOwner.jid() && key.senderKeyId == senderKeyId) {
- if (key.trust != trust) {
- // Update the stored trust if it differs from the new one.
- key.trust = trust;
- }
-
- isKeyFound = true;
- break;
- }
- }
-
- if (!isKeyFound) {
- // Create a new entry and store it if there is no such entry yet.
- UnprocessedKey key;
- key.id = keyId;
- key.ownerJid = keyOwner.jid();
- key.senderKeyId = senderKeyId;
- key.trust = trust;
- d->unprocessedKeys.insert(encryption, key);
- }
- }
- };
-
- for (const auto &keyOwner : keyOwners) {
- addKeys(keyOwner, true, keyOwner.trustedKeys());
- addKeys(keyOwner, false, keyOwner.distrustedKeys());
- }
-
- return makeReadyFuture();
-}
-
-QFuture<void> QXmppTrustMemoryStorage::removeKeysForPostponedTrustDecisions(const QString &encryption, const QList<QByteArray> &keyIdsForAuthentication, const QList<QByteArray> &keyIdsForDistrusting)
-{
- for (auto itr = d->unprocessedKeys.find(encryption);
- itr != d->unprocessedKeys.end() && itr.key() == encryption;) {
- const auto &key = itr.value();
- if ((key.trust && keyIdsForAuthentication.contains(key.id)) ||
- (!key.trust && keyIdsForDistrusting.contains(key.id))) {
- itr = d->unprocessedKeys.erase(itr);
- } else {
- ++itr;
- }
- }
- return makeReadyFuture();
+ return makeReadyFuture(std::move(QXmppTrustStorage::Undecided));
}
-QFuture<void> QXmppTrustMemoryStorage::removeKeysForPostponedTrustDecisions(const QString &encryption, const QList<QByteArray> &senderKeyIds)
+QFuture<void> QXmppTrustMemoryStorage::resetAll(const QString &encryption)
{
- if (encryption.isEmpty()) {
- d->unprocessedKeys.clear();
- } else if (senderKeyIds.isEmpty()) {
- d->unprocessedKeys.remove(encryption);
- } else {
- for (auto itr = d->unprocessedKeys.find(encryption);
- itr != d->unprocessedKeys.end() && itr.key() == encryption;) {
- if (senderKeyIds.contains(itr.value().senderKeyId)) {
- itr = d->unprocessedKeys.erase(itr);
- } else {
- ++itr;
- }
- }
- }
+ d->securityPolicies.remove(encryption);
+ d->ownKeys.remove(encryption);
+ d->keys.remove(encryption);
return makeReadyFuture();
}
-
-QFuture<QHash<bool, QMultiHash<QString, QByteArray>>> QXmppTrustMemoryStorage::keysForPostponedTrustDecisions(const QString &encryption, const QList<QByteArray> &senderKeyIds)
-{
- QHash<bool, QMultiHash<QString, QByteArray>> keys;
-
- const auto unprocessedKeys = d->unprocessedKeys.values(encryption);
- for (const auto &key : unprocessedKeys) {
- if (senderKeyIds.contains(key.senderKeyId) || senderKeyIds.isEmpty()) {
- keys[key.trust].insert(key.ownerJid, key.id);
- }
- }
-
- return makeReadyFuture(std::move(keys));
-}
/// \endcond
diff --git a/src/client/QXmppTrustMemoryStorage.h b/src/client/QXmppTrustMemoryStorage.h
index 63b8a14e..08696039 100644
--- a/src/client/QXmppTrustMemoryStorage.h
+++ b/src/client/QXmppTrustMemoryStorage.h
@@ -5,39 +5,40 @@
#ifndef QXMPPTRUSTMEMORYSTORAGE_H
#define QXMPPTRUSTMEMORYSTORAGE_H
-#include "QXmppGlobal.h"
#include "QXmppTrustStorage.h"
#include <memory>
class QXmppTrustMemoryStoragePrivate;
-class QXMPP_EXPORT QXmppTrustMemoryStorage : public QXmppTrustStorage
+class QXMPP_EXPORT QXmppTrustMemoryStorage : virtual public QXmppTrustStorage
{
public:
QXmppTrustMemoryStorage();
~QXmppTrustMemoryStorage();
/// \cond
- QFuture<void> setSecurityPolicies(const QString &encryption = {}, SecurityPolicy securityPolicy = QXmppTrustStorage::NoSecurityPolicy) override;
+ QFuture<void> setSecurityPolicy(const QString &encryption, SecurityPolicy securityPolicy) override;
+ QFuture<void> resetSecurityPolicy(const QString &encryption) override;
QFuture<SecurityPolicy> securityPolicy(const QString &encryption) override;
- QFuture<void> addOwnKey(const QString &encryption, const QByteArray &keyId) override;
- QFuture<void> removeOwnKey(const QString &encryption) override;
+ QFuture<void> setOwnKey(const QString &encryption, const QByteArray &keyId) override;
+ QFuture<void> resetOwnKey(const QString &encryption) override;
QFuture<QByteArray> ownKey(const QString &encryption) override;
QFuture<void> addKeys(const QString &encryption, const QString &keyOwnerJid, const QList<QByteArray> &keyIds, TrustLevel trustLevel = TrustLevel::AutomaticallyDistrusted) override;
- QFuture<void> removeKeys(const QString &encryption = {}, const QList<QByteArray> &keyIds = {}) override;
+ QFuture<void> removeKeys(const QString &encryption, const QList<QByteArray> &keyIds) override;
+ QFuture<void> removeKeys(const QString &encryption, const QString &keyOwnerJid) override;
+ QFuture<void> removeKeys(const QString &encryption) override;
QFuture<QHash<TrustLevel, QMultiHash<QString, QByteArray>>> keys(const QString &encryption, TrustLevels trustLevels = {}) override;
+ QFuture<QHash<QString, QHash<QByteArray, TrustLevel>>> keys(const QString &encryption, const QList<QString> &keyOwnerJids, TrustLevels trustLevels = {}) override;
+ QFuture<bool> hasKey(const QString &encryption, const QString &keyOwnerJid, TrustLevels trustLevels) override;
QFuture<void> setTrustLevel(const QString &encryption, const QMultiHash<QString, QByteArray> &keyIds, const TrustLevel trustLevel) override;
QFuture<void> setTrustLevel(const QString &encryption, const QList<QString> &keyOwnerJids, const TrustLevel oldTrustLevel, const TrustLevel newTrustLevel) override;
QFuture<TrustLevel> trustLevel(const QString &encryption, const QByteArray &keyId) override;
- QFuture<void> addKeysForPostponedTrustDecisions(const QString &encryption, const QByteArray &senderKeyId, const QList<QXmppTrustMessageKeyOwner> &keyOwners) override;
- QFuture<void> removeKeysForPostponedTrustDecisions(const QString &encryption, const QList<QByteArray> &keyIdsForAuthentication, const QList<QByteArray> &keyIdsForDistrusting) override;
- QFuture<void> removeKeysForPostponedTrustDecisions(const QString &encryption = {}, const QList<QByteArray> &senderKeyIds = {}) override;
- QFuture<QHash<bool, QMultiHash<QString, QByteArray>>> keysForPostponedTrustDecisions(const QString &encryption, const QList<QByteArray> &senderKeyIds = {}) override;
+ QFuture<void> resetAll(const QString &encryption) override;
/// \endcond
private:
diff --git a/src/client/QXmppTrustStorage.cpp b/src/client/QXmppTrustStorage.cpp
index dc26d1ed..149eccfe 100644
--- a/src/client/QXmppTrustStorage.cpp
+++ b/src/client/QXmppTrustStorage.cpp
@@ -8,26 +8,31 @@
/// \brief The QXmppTrustStorage class stores trust data for end-to-end
/// encryption.
///
+/// The term "key" is used for a public long-term key.
+///
/// \warning THIS API IS NOT FINALIZED YET!
///
/// \since QXmpp 1.5
///
///
-/// \fn QXmppTrustStorage::setSecurityPolicies(const QString &encryption = {}, SecurityPolicy securityPolicy = SecurityPolicy::NoSecurityPolicy)
-///
-/// Sets the security policy for an encryption protocol or resets the set
-/// security policies.
+/// \fn QXmppTrustStorage::setSecurityPolicy(const QString &encryption, SecurityPolicy securityPolicy)
///
-/// If securityPolicy is not passed, the set security policy for encryption is
-/// reset.
-/// If also encryption is not passed, all set security policies are reset.
+/// Sets the security policy for an encryption protocol.
///
/// \param encryption encryption protocol namespace
/// \param securityPolicy security policy being applied
///
///
+/// \fn QXmppTrustStorage::resetSecurityPolicy(const QString &encryption)
+///
+/// Resets the security policy for an encryption protocol.
+///
+/// \param encryption encryption protocol namespace
+///
+
+///
/// \fn QXmppTrustStorage::securityPolicy(const QString &encryption)
///
/// Returns the security policy for an encryption protocol.
@@ -38,18 +43,20 @@
///
///
-/// \fn QXmppTrustStorage::addOwnKey(const QString &encryption, const QByteArray &keyId)
+/// \fn QXmppTrustStorage::setOwnKey(const QString &encryption, const QByteArray &keyId)
///
-/// Adds an own key (i.e., the key used by this client instance).
+/// Sets the own key (i.e., the key used by this client instance) for an
+/// encryption protocol.
///
/// \param encryption encryption protocol namespace
/// \param keyId ID of the key
///
///
-/// \fn QXmppTrustStorage::removeOwnKey(const QString &encryption)
+/// \fn QXmppTrustStorage::resetOwnKey(const QString &encryption)
///
-/// Removes an own key (i.e., the key used by this client instance).
+/// Resets the own key (i.e., the key used by this client instance) for an
+/// encryption protocol.
///
/// \param encryption encryption protocol namespace
///
@@ -57,7 +64,8 @@
///
/// \fn QXmppTrustStorage::ownKey(const QString &encryption)
///
-/// Returns an own key (i.e., the key used by this client instance).
+/// Returns the own key (i.e., the key used by this client instance) for an
+/// encryption protocol.
///
/// \param encryption encryption protocol namespace
///
@@ -80,120 +88,110 @@
///
/// Removes keys.
///
-/// If keyIds is not passed, all keys for encryption are removed.
-/// If encryption is also not passed, all keys are removed.
-///
/// \param encryption encryption protocol namespace
/// \param keyIds IDs of the keys
///
///
-/// \fn QXmppTrustStorage::keys(const QString &encryption, TrustLevels trustLevels = {})
-///
-/// Returns the JIDs of the key owners mapped to the IDs of their keys with a
-/// specific trust level.
+/// \fn QXmppTrustStorage::removeKeys(const QString &encryption, const QString &keyOwnerJid)
///
-/// If no trust levels are passed, all keys are returned.
+/// Removes all keys of a key owner.
///
/// \param encryption encryption protocol namespace
-/// \param trustLevels trust levels of the keys
+/// \param keyOwnerJid key owner's bare JID
+///
+
///
-/// \return the key owner JIDs mapped to their keys with a specific trust level
+/// \fn QXmppTrustStorage::removeKeys(const QString &encryption)
+///
+/// Removes all keys for encryption.
+///
+/// \param encryption encryption protocol namespace
///
///
-/// \fn QXmppTrustStorage::setTrustLevel(const QString &encryption, const QMultiHash<QString, QByteArray> &keyIds, TrustLevel trustLevel)
+/// \fn QXmppTrustStorage::keys(const QString &encryption, TrustLevels trustLevels = {})
///
-/// Sets the trust level of keys.
+/// Returns the JIDs of all key owners mapped to the IDs of their keys with
+/// specific trust levels.
///
-/// If a key is not stored, it is added to the storage.
+/// If no trust levels are passed, all keys for encryption are returned.
///
/// \param encryption encryption protocol namespace
-/// \param keyIds key owners' bare JIDs mapped to the IDs of their keys
-/// \param trustLevel trust level being set
+/// \param trustLevels trust levels of the keys
+///
+/// \return the key owner JIDs mapped to their keys with specific trust levels
///
///
-/// \fn QXmppTrustStorage::setTrustLevel(const QString &encryption, const QList<QString> &keyOwnerJids, TrustLevel oldTrustLevel, TrustLevel newTrustLevel)
+/// \fn QXmppTrustStorage::keys(const QString &encryption, const QList<QString> &keyOwnerJids, TrustLevels trustLevels = {})
///
-/// Sets the trust level of keys specified by their key owner and trust level.
+/// Returns the IDs of keys mapped to their trust levels for specific key
+/// owners.
+///
+/// If no trust levels are passed, all keys for encryption and keyOwnerJids are
+/// returned.
///
/// \param encryption encryption protocol namespace
/// \param keyOwnerJids key owners' bare JIDs
-/// \param oldTrustLevel trust level being changed
-/// \param newTrustLevel trust level being set
+/// \param trustLevels trust levels of the keys
///
-
+/// \return the key IDs mapped to their trust levels for specific key owners
///
-/// \fn QXmppTrustStorage::trustLevel(const QString &encryption, const QByteArray &keyId)
+
///
-/// Returns the trust level of a key.
+/// \fn QXmppTrustStorage::hasKey(const QString &encryption, const QString &keyOwnerJid, TrustLevels trustLevels)
///
-/// If the key is not stored, it is seen as automatically distrusted.
+/// Returns whether at least one key of a key owner with a specific trust level
+/// is stored.
///
/// \param encryption encryption protocol namespace
-/// \param keyId ID of the key
+/// \param keyOwnerJid key owner's bare JID
+/// \param trustLevels possible trust levels of the key
///
-/// \return the key's trust level
+/// \return whether a key of the key owner with a passed trust level is stored
///
///
-/// \fn QXmppTrustStorage::addKeysForPostponedTrustDecisions(const QString &encryption, const QByteArray &senderKeyId, const QList<QXmppTrustMessageKeyOwner> &keyOwners)
-///
-/// Adds keys that cannot be authenticated or distrusted directly because the
-/// key of the trust message's sender is not yet authenticated.
+/// \fn QXmppTrustStorage::setTrustLevel(const QString &encryption, const QMultiHash<QString, QByteArray> &keyIds, TrustLevel trustLevel)
///
-/// Those keys are being authenticated or distrusted once the sender's key is
-/// authenticated.
-/// Each element of keyOwners (i.e., keyOwner) can contain keys for postponed
-/// authentication as trustedKeys or for postponed distrusting as
-/// distrustedKeys.
+/// Sets the trust level of keys.
///
-/// If keys of keyOwner.trustedKeys() are already stored for postponed
-/// distrusting, they are changed to be used for postponed authentication.
-/// If keys of keyOwner.distrustedKeys() are already stored for postponed
-/// authentication, they are changed to be used for postponed distrusting.
-/// If the same keys are in keyOwner.trustedKeys() and
-/// keyOwner.distrustedKeys(), they are used for postponed distrusting.
+/// If a key is not stored, it is added to the storage.
///
/// \param encryption encryption protocol namespace
-/// \param senderKeyId key ID of the trust message's sender
-/// \param keyOwners key owners containing key IDs for postponed trust decisions
+/// \param keyIds key owners' bare JIDs mapped to the IDs of their keys
+/// \param trustLevel trust level being set
///
///
-/// \fn QXmppTrustStorage::removeKeysForPostponedTrustDecisions(const QString &encryption, const QList<QByteArray> &keyIdsForAuthentication, const QList<QByteArray> &keyIdsForDistrusting)
+/// \fn QXmppTrustStorage::setTrustLevel(const QString &encryption, const QList<QString> &keyOwnerJids, TrustLevel oldTrustLevel, TrustLevel newTrustLevel)
///
-/// Removes keys for postponed authentication or distrusting.
+/// Sets the trust level of keys specified by their key owner and trust level.
///
/// \param encryption encryption protocol namespace
-/// \param keyIdsForAuthentication IDs of the keys for postponed authentication
-/// \param keyIdsForDistrusting IDs of the keys for postponed distrusting
+/// \param keyOwnerJids key owners' bare JIDs
+/// \param oldTrustLevel trust level being changed
+/// \param newTrustLevel trust level being set
///
///
-/// \fn QXmppTrustStorage::removeKeysForPostponedTrustDecisions(const QString &encryption = {}, const QList<QByteArray> &senderKeyIds = {})
+/// \fn QXmppTrustStorage::trustLevel(const QString &encryption, const QByteArray &keyId)
///
-/// Removes keys for postponed authentication or distrusting by the trust
-/// message's sender's key ID.
+/// Returns the trust level of a key.
///
-/// If senderKeyIds is empty, all keys for encryption are removed.
-/// If encryption is empty too, all keys are removed.
+/// If the key is not stored, the trust in that key is undecided.
///
/// \param encryption encryption protocol namespace
-/// \param senderKeyIds key IDs of the trust messages' senders
+/// \param keyId ID of the key
///
-
+/// \return the key's trust level
///
-/// \fn QXmppTrustStorage::keysForPostponedTrustDecisions(const QString &encryption, const QList<QByteArray> &senderKeyIds = {})
+
///
-/// Returns the JIDs of key owners mapped to the IDs of their keys stored for
-/// postponed authentication (true) or postponed distrusting (false).
+/// \fn QXmppTrustStorage::resetAll(const QString &encryption)
///
-/// If senderKeyIds is empty, all keys for encryption are returned.
+/// Resets all data for encryption.
///
/// \param encryption encryption protocol namespace
-/// \param senderKeyIds key IDs of the trust messages' senders
-///
-/// \return the key owner JIDs mapped to their keys
///
diff --git a/src/client/QXmppTrustStorage.h b/src/client/QXmppTrustStorage.h
index 2c7b593e..dffbcfae 100644
--- a/src/client/QXmppTrustStorage.h
+++ b/src/client/QXmppTrustStorage.h
@@ -9,8 +9,6 @@
#include <QFuture>
-class QXmppTrustMessageKeyOwner;
-
class QXMPP_EXPORT QXmppTrustStorage
{
public:
@@ -20,7 +18,7 @@ public:
///
enum SecurityPolicy {
NoSecurityPolicy, ///< New keys must be trusted manually.
- Toakafa, ///< New keys are trusted automatically until the first authentication but automatically distrusted afterwards.
+ Toakafa, ///< New keys are trusted automatically until the first authentication but automatically distrusted afterwards. \see \xep{0450, Automatic Trust Management (ATM)}
};
///
@@ -28,35 +26,38 @@ public:
/// protocols
///
enum TrustLevel {
- AutomaticallyDistrusted = 1, ///< The key is automatically distrusted (e.g., by ATM's security policy).
- ManuallyDistrusted = 2, ///< The key is manually distrusted (e.g., by clicking a button or ATM).
- AutomaticallyTrusted = 4, ///< The key is automatically trusted (e.g., by the client for all keys of a bare JID until one of it is authenticated).
- ManuallyTrusted = 8, ///< The key is manually trusted (e.g., by clicking a button).
- Authenticated = 16, ///< The key is authenticated (e.g., by QR code scanning or ATM).
+ Undecided = 1, ///< The key's trust is not decided.
+ AutomaticallyDistrusted = 2, ///< The key is automatically distrusted (e.g., by the security policy TOAKAFA). \see SecurityPolicy
+ ManuallyDistrusted = 4, ///< The key is manually distrusted (e.g., by clicking a button or \xep{0450, Automatic Trust Management (ATM)}).
+ AutomaticallyTrusted = 8, ///< The key is automatically trusted (e.g., by the client for all keys of a bare JID until one of it is authenticated).
+ ManuallyTrusted = 16, ///< The key is manually trusted (e.g., by clicking a button).
+ Authenticated = 32, ///< The key is authenticated (e.g., by QR code scanning or \xep{0450, Automatic Trust Management (ATM)}).
};
Q_DECLARE_FLAGS(TrustLevels, TrustLevel)
virtual ~QXmppTrustStorage() = default;
- virtual QFuture<void> setSecurityPolicies(const QString &encryption = {}, SecurityPolicy securityPolicy = SecurityPolicy::NoSecurityPolicy) = 0;
+ virtual QFuture<void> setSecurityPolicy(const QString &encryption, SecurityPolicy securityPolicy) = 0;
+ virtual QFuture<void> resetSecurityPolicy(const QString &encryption) = 0;
virtual QFuture<SecurityPolicy> securityPolicy(const QString &encryption) = 0;
- virtual QFuture<void> addOwnKey(const QString &encryption, const QByteArray &keyId) = 0;
- virtual QFuture<void> removeOwnKey(const QString &encryption) = 0;
+ virtual QFuture<void> setOwnKey(const QString &encryption, const QByteArray &keyId) = 0;
+ virtual QFuture<void> resetOwnKey(const QString &encryption) = 0;
virtual QFuture<QByteArray> ownKey(const QString &encryption) = 0;
virtual QFuture<void> addKeys(const QString &encryption, const QString &keyOwnerJid, const QList<QByteArray> &keyIds, TrustLevel trustLevel = TrustLevel::AutomaticallyDistrusted) = 0;
- virtual QFuture<void> removeKeys(const QString &encryption = {}, const QList<QByteArray> &keyIds = {}) = 0;
+ virtual QFuture<void> removeKeys(const QString &encryption, const QList<QByteArray> &keyIds) = 0;
+ virtual QFuture<void> removeKeys(const QString &encryption, const QString &keyOwnerJid) = 0;
+ virtual QFuture<void> removeKeys(const QString &encryption) = 0;
virtual QFuture<QHash<TrustLevel, QMultiHash<QString, QByteArray>>> keys(const QString &encryption, TrustLevels trustLevels = {}) = 0;
+ virtual QFuture<QHash<QString, QHash<QByteArray, TrustLevel>>> keys(const QString &encryption, const QList<QString> &keyOwnerJids, TrustLevels trustLevels = {}) = 0;
+ virtual QFuture<bool> hasKey(const QString &encryption, const QString &keyOwnerJid, TrustLevels trustLevels) = 0;
virtual QFuture<void> setTrustLevel(const QString &encryption, const QMultiHash<QString, QByteArray> &keyIds, TrustLevel trustLevel) = 0;
virtual QFuture<void> setTrustLevel(const QString &encryption, const QList<QString> &keyOwnerJids, TrustLevel oldTrustLevel, TrustLevel newTrustLevel) = 0;
virtual QFuture<TrustLevel> trustLevel(const QString &encryption, const QByteArray &keyId) = 0;
- virtual QFuture<void> addKeysForPostponedTrustDecisions(const QString &encryption, const QByteArray &senderKeyId, const QList<QXmppTrustMessageKeyOwner> &keyOwners) = 0;
- virtual QFuture<void> removeKeysForPostponedTrustDecisions(const QString &encryption, const QList<QByteArray> &keyIdsForAuthentication, const QList<QByteArray> &keyIdsForDistrusting) = 0;
- virtual QFuture<void> removeKeysForPostponedTrustDecisions(const QString &encryption = {}, const QList<QByteArray> &senderKeyIds = {}) = 0;
- virtual QFuture<QHash<bool, QMultiHash<QString, QByteArray>>> keysForPostponedTrustDecisions(const QString &encryption, const QList<QByteArray> &senderKeyIds = {}) = 0;
+ virtual QFuture<void> resetAll(const QString &encryption) = 0;
};
Q_DECLARE_METATYPE(QXmppTrustStorage::SecurityPolicy)
diff --git a/tests/qxmppatmmanager/tst_qxmppatmmanager.cpp b/tests/qxmppatmmanager/tst_qxmppatmmanager.cpp
index c5899e0a..4ff4e079 100644
--- a/tests/qxmppatmmanager/tst_qxmppatmmanager.cpp
+++ b/tests/qxmppatmmanager/tst_qxmppatmmanager.cpp
@@ -3,12 +3,14 @@
// SPDX-License-Identifier: LGPL-2.1-or-later
#include "QXmppAtmManager.h"
+#include "QXmppAtmTrustMemoryStorage.h"
#include "QXmppCarbonManager.h"
#include "QXmppClient.h"
#include "QXmppConstants.cpp"
#include "QXmppConstants_p.h"
-#include "QXmppTrustMemoryStorage.h"
+#include "QXmppMessage.h"
#include "QXmppTrustMessageElement.h"
+#include "QXmppTrustMessageKeyOwner.h"
#include "QXmppUtils.h"
#include "util.h"
@@ -57,13 +59,13 @@ private:
QXmppClient m_client;
QXmppLogger m_logger;
QXmppAtmManager *m_manager;
- QXmppTrustMemoryStorage *m_trustStorage;
+ QXmppAtmTrustMemoryStorage *m_trustStorage;
QXmppCarbonManager *m_carbonManager;
};
void tst_QXmppAtmManager::initTestCase()
{
- m_trustStorage = new QXmppTrustMemoryStorage;
+ m_trustStorage = new QXmppAtmTrustMemoryStorage;
m_manager = new QXmppAtmManager(m_trustStorage);
m_client.addExtension(m_manager);
m_client.configuration().setJid("alice@example.org/phone");
@@ -446,7 +448,7 @@ void tst_QXmppAtmManager::testAuthenticate()
clearTrustStorage();
QFETCH(QXmppTrustStorage::SecurityPolicy, securityPolicy);
- m_trustStorage->setSecurityPolicies(ns_omemo, securityPolicy);
+ m_trustStorage->setSecurityPolicy(ns_omemo, securityPolicy);
QMultiHash<QString, QByteArray> authenticatedKeys = { { QStringLiteral("alice@example.org"),
QByteArray::fromBase64(QByteArrayLiteral("rQIL2albuSR1i06EZAp1uZ838zUeEgGIq2whwu3s+Zg=")) },
@@ -859,7 +861,7 @@ void tst_QXmppAtmManager::testHandleMessage()
// Remove the sender key as soon as the method being tested is executed.
if (areTrustDecisionsValid) {
- m_trustStorage->removeKeys(ns_omemo, { senderKey });
+ m_trustStorage->removeKeys(ns_omemo, QList { senderKey });
}
if (areTrustDecisionsValid) {
@@ -2070,8 +2072,8 @@ void tst_QXmppAtmManager::testMakeTrustDecisionsContactKeysDone()
void tst_QXmppAtmManager::clearTrustStorage()
{
- m_trustStorage->removeKeys();
- m_trustStorage->removeKeysForPostponedTrustDecisions();
+ m_trustStorage->removeKeys(ns_omemo);
+ m_trustStorage->removeKeysForPostponedTrustDecisions(ns_omemo);
}
QTEST_MAIN(tst_QXmppAtmManager)
diff --git a/tests/qxmpptrustmemorystorage/tst_qxmpptrustmemorystorage.cpp b/tests/qxmpptrustmemorystorage/tst_qxmpptrustmemorystorage.cpp
index d7827b7f..ff7537dc 100644
--- a/tests/qxmpptrustmemorystorage/tst_qxmpptrustmemorystorage.cpp
+++ b/tests/qxmpptrustmemorystorage/tst_qxmpptrustmemorystorage.cpp
@@ -2,6 +2,7 @@
//
// SPDX-License-Identifier: LGPL-2.1-or-later
+#include "QXmppAtmTrustMemoryStorage.h"
#include "QXmppConstants.cpp"
#include "QXmppConstants_p.h"
#include "QXmppTrustMemoryStorage.h"
@@ -14,44 +15,42 @@ class tst_QXmppTrustMemoryStorage : public QObject
Q_OBJECT
private slots:
- void testSecurityPolicies();
+ // QXmppTrustMemoryStorage
+ void testSecurityPolicy();
void testOwnKeys();
void testKeys();
void testTrustLevels();
- void testKeysForPostponedTrustDecisions();
+ void testResetAll();
+
+ // QXmppAtmTrustMemoryStorage
+ void atmTestKeysForPostponedTrustDecisions();
+ void atmTestResetAll();
private:
QXmppTrustMemoryStorage m_trustStorage;
+ QXmppAtmTrustMemoryStorage m_atmTrustStorage;
};
-void tst_QXmppTrustMemoryStorage::testSecurityPolicies()
+void tst_QXmppTrustMemoryStorage::testSecurityPolicy()
{
auto future = m_trustStorage.securityPolicy(ns_ox);
QVERIFY(future.isFinished());
auto result = future.result();
QCOMPARE(result, QXmppTrustStorage::NoSecurityPolicy);
- m_trustStorage.setSecurityPolicies(ns_ox, QXmppTrustStorage::Toakafa);
- m_trustStorage.setSecurityPolicies(ns_omemo, QXmppTrustStorage::Toakafa);
+ m_trustStorage.setSecurityPolicy(ns_omemo, QXmppTrustStorage::Toakafa);
future = m_trustStorage.securityPolicy(ns_ox);
QVERIFY(future.isFinished());
result = future.result();
- QCOMPARE(result, QXmppTrustStorage::Toakafa);
+ QCOMPARE(result, QXmppTrustStorage::NoSecurityPolicy);
future = m_trustStorage.securityPolicy(ns_omemo);
QVERIFY(future.isFinished());
result = future.result();
QCOMPARE(result, QXmppTrustStorage::Toakafa);
- m_trustStorage.setSecurityPolicies(ns_ox);
-
- future = m_trustStorage.securityPolicy(ns_ox);
- QVERIFY(future.isFinished());
- result = future.result();
- QCOMPARE(result, QXmppTrustStorage::NoSecurityPolicy);
-
- m_trustStorage.setSecurityPolicies();
+ m_trustStorage.resetSecurityPolicy(ns_omemo);
future = m_trustStorage.securityPolicy(ns_omemo);
QVERIFY(future.isFinished());
@@ -61,13 +60,18 @@ void tst_QXmppTrustMemoryStorage::testSecurityPolicies()
void tst_QXmppTrustMemoryStorage::testOwnKeys()
{
- m_trustStorage.addOwnKey(ns_ox, QByteArray::fromBase64(QByteArrayLiteral("aFABnX7Q/rbTgjBySYzrT2FsYCVYb49mbca5yB734KQ=")));
- m_trustStorage.addOwnKey(ns_omemo, QByteArray::fromBase64(QByteArrayLiteral("IhpPjiKLchgrAG5cpSfTvdzPjZ5v6vTOluHEUehkgCA=")));
-
- // own OX key
auto future = m_trustStorage.ownKey(ns_ox);
QVERIFY(future.isFinished());
auto result = future.result();
+ QVERIFY(result.isEmpty());
+
+ m_trustStorage.setOwnKey(ns_ox, QByteArray::fromBase64(QByteArrayLiteral("aFABnX7Q/rbTgjBySYzrT2FsYCVYb49mbca5yB734KQ=")));
+ m_trustStorage.setOwnKey(ns_omemo, QByteArray::fromBase64(QByteArrayLiteral("IhpPjiKLchgrAG5cpSfTvdzPjZ5v6vTOluHEUehkgCA=")));
+
+ // own OX key
+ future = m_trustStorage.ownKey(ns_ox);
+ QVERIFY(future.isFinished());
+ result = future.result();
QCOMPARE(result, QByteArray::fromBase64(QByteArrayLiteral("aFABnX7Q/rbTgjBySYzrT2FsYCVYb49mbca5yB734KQ=")));
// own OMEMO key
@@ -76,9 +80,15 @@ void tst_QXmppTrustMemoryStorage::testOwnKeys()
result = future.result();
QCOMPARE(result, QByteArray::fromBase64(QByteArrayLiteral("IhpPjiKLchgrAG5cpSfTvdzPjZ5v6vTOluHEUehkgCA=")));
- m_trustStorage.removeOwnKey(ns_omemo);
+ m_trustStorage.resetOwnKey(ns_omemo);
+
+ // own OX key
+ future = m_trustStorage.ownKey(ns_ox);
+ QVERIFY(future.isFinished());
+ result = future.result();
+ QCOMPARE(result, QByteArray::fromBase64(QByteArrayLiteral("aFABnX7Q/rbTgjBySYzrT2FsYCVYb49mbca5yB734KQ=")));
- // no stored own OMEMO key
+ // no own OMEMO key
future = m_trustStorage.ownKey(ns_omemo);
QVERIFY(future.isFinished());
result = future.result();
@@ -87,6 +97,33 @@ void tst_QXmppTrustMemoryStorage::testOwnKeys()
void tst_QXmppTrustMemoryStorage::testKeys()
{
+ // no OMEMO keys
+ auto future = m_trustStorage.keys(ns_omemo);
+ QVERIFY(future.isFinished());
+ auto result = future.result();
+ QVERIFY(result.isEmpty());
+
+ // no OMEMO keys (via JIDs)
+ auto futureForJids = m_trustStorage.keys(ns_omemo,
+ { QStringLiteral("alice@example.org"), QStringLiteral("bob@example.com") });
+ QVERIFY(futureForJids.isFinished());
+ auto resultForJids = futureForJids.result();
+
+ // no automatically trusted and authenticated OMEMO keys
+ future = m_trustStorage.keys(ns_omemo,
+ QXmppTrustStorage::AutomaticallyTrusted | QXmppTrustStorage::Authenticated);
+ QVERIFY(future.isFinished());
+ result = future.result();
+ QVERIFY(result.isEmpty());
+
+ // no automatically trusted and authenticated OMEMO key from Alice
+ auto futureBool = m_trustStorage.hasKey(ns_omemo,
+ QStringLiteral("alice@example.org"),
+ QXmppTrustStorage::AutomaticallyTrusted | QXmppTrustStorage::Authenticated);
+ QVERIFY(futureBool.isFinished());
+ auto resultBool = futureBool.result();
+ QVERIFY(!resultBool);
+
// Store keys with the default trust level.
m_trustStorage.addKeys(
ns_omemo,
@@ -149,10 +186,27 @@ void tst_QXmppTrustMemoryStorage::testKeys()
QMultiHash<QString, QByteArray> authenticatedKeys = { { QStringLiteral("bob@example.com"),
QByteArray::fromBase64(QByteArrayLiteral("YjVI04NcbTPvXLaA95RO84HPcSvyOgEZ2r5cTyUs0C8=")) } };
+ QHash<QByteArray, QXmppTrustStorage::TrustLevel> keysAlice = { { QByteArray::fromBase64(QByteArrayLiteral("WaAnpWyW1hnFooH3oJo9Ba5XYoksnLPeJRTAjxPbv38=")),
+ QXmppTrustStorage::AutomaticallyDistrusted },
+ { QByteArray::fromBase64(QByteArrayLiteral("/1eK3R2LtjPBT3el8f0q4DvzqUJSfFy5fkKkKPNFNYw=")),
+ QXmppTrustStorage::AutomaticallyDistrusted },
+ { QByteArray::fromBase64(QByteArrayLiteral("aFABnX7Q/rbTgjBySYzrT2FsYCVYb49mbca5yB734KQ=")),
+ QXmppTrustStorage::ManuallyDistrusted },
+ { QByteArray::fromBase64(QByteArrayLiteral("Ciemp4ZNzRJxnRD+k28vAie0kXJrwl4IrbfDy7n6OxE=")),
+ QXmppTrustStorage::AutomaticallyTrusted } };
+ QHash<QByteArray, QXmppTrustStorage::TrustLevel> keysBob = { { QByteArray::fromBase64(QByteArrayLiteral("rvSXBRd+EICMhQvVgcREQJxxP+T4EBmai4mYHBfJQGg=")),
+ QXmppTrustStorage::AutomaticallyTrusted },
+ { QByteArray::fromBase64(QByteArrayLiteral("tCP1CI3pqSTVGzFYFyPYUMfMZ9Ck/msmfD0wH/VtJBM=")),
+ QXmppTrustStorage::ManuallyTrusted },
+ { QByteArray::fromBase64(QByteArrayLiteral("2fhJtrgoMJxfLI3084/YkYh9paqiSiLFDVL2m0qAgX4=")),
+ QXmppTrustStorage::ManuallyTrusted },
+ { QByteArray::fromBase64(QByteArrayLiteral("YjVI04NcbTPvXLaA95RO84HPcSvyOgEZ2r5cTyUs0C8=")),
+ QXmppTrustStorage::Authenticated } };
+
// all OMEMO keys
- auto future = m_trustStorage.keys(ns_omemo);
+ future = m_trustStorage.keys(ns_omemo);
QVERIFY(future.isFinished());
- auto result = future.result();
+ result = future.result();
QCOMPARE(
result,
QHash({ std::pair(
@@ -172,7 +226,8 @@ void tst_QXmppTrustMemoryStorage::testKeys()
authenticatedKeys) }));
// automatically trusted and authenticated OMEMO keys
- future = m_trustStorage.keys(ns_omemo, QXmppTrustStorage::AutomaticallyTrusted | QXmppTrustStorage::Authenticated);
+ future = m_trustStorage.keys(ns_omemo,
+ QXmppTrustStorage::AutomaticallyTrusted | QXmppTrustStorage::Authenticated);
QVERIFY(future.isFinished());
result = future.result();
QCOMPARE(
@@ -184,6 +239,73 @@ void tst_QXmppTrustMemoryStorage::testKeys()
QXmppTrustStorage::Authenticated,
authenticatedKeys) }));
+ // all OMEMO keys (via JIDs)
+ futureForJids = m_trustStorage.keys(ns_omemo,
+ { QStringLiteral("alice@example.org"), QStringLiteral("bob@example.com") });
+ QVERIFY(futureForJids.isFinished());
+ resultForJids = futureForJids.result();
+ QCOMPARE(
+ resultForJids,
+ QHash({ std::pair(
+ QStringLiteral("alice@example.org"),
+ keysAlice),
+ std::pair(
+ QStringLiteral("bob@example.com"),
+ keysBob) }));
+
+ // Alice's OMEMO keys
+ futureForJids = m_trustStorage.keys(ns_omemo,
+ { QStringLiteral("alice@example.org") });
+ QVERIFY(futureForJids.isFinished());
+ resultForJids = futureForJids.result();
+ QCOMPARE(
+ resultForJids,
+ QHash({ std::pair(
+ QStringLiteral("alice@example.org"),
+ keysAlice) }));
+
+ keysAlice = { { QByteArray::fromBase64(QByteArrayLiteral("Ciemp4ZNzRJxnRD+k28vAie0kXJrwl4IrbfDy7n6OxE=")),
+ QXmppTrustStorage::AutomaticallyTrusted } };
+ keysBob = { { QByteArray::fromBase64(QByteArrayLiteral("rvSXBRd+EICMhQvVgcREQJxxP+T4EBmai4mYHBfJQGg=")),
+ QXmppTrustStorage::AutomaticallyTrusted },
+ { QByteArray::fromBase64(QByteArrayLiteral("YjVI04NcbTPvXLaA95RO84HPcSvyOgEZ2r5cTyUs0C8=")),
+ QXmppTrustStorage::Authenticated } };
+
+ // automatically trusted and authenticated OMEMO keys (via JIDs)
+ futureForJids = m_trustStorage.keys(ns_omemo,
+ { QStringLiteral("alice@example.org"), QStringLiteral("bob@example.com") },
+ QXmppTrustStorage::AutomaticallyTrusted | QXmppTrustStorage::Authenticated);
+ QVERIFY(futureForJids.isFinished());
+ resultForJids = futureForJids.result();
+ QCOMPARE(
+ resultForJids,
+ QHash({ std::pair(
+ QStringLiteral("alice@example.org"),
+ keysAlice),
+ std::pair(
+ QStringLiteral("bob@example.com"),
+ keysBob) }));
+
+ // Alice's automatically trusted and authenticated OMEMO keys
+ futureForJids = m_trustStorage.keys(ns_omemo,
+ { QStringLiteral("alice@example.org") },
+ QXmppTrustStorage::AutomaticallyTrusted | QXmppTrustStorage::Authenticated);
+ QVERIFY(futureForJids.isFinished());
+ resultForJids = futureForJids.result();
+ QCOMPARE(
+ resultForJids,
+ QHash({ std::pair(
+ QStringLiteral("alice@example.org"),
+ keysAlice) }));
+
+ // at least one automatically trusted or authenticated OMEMO key from Alice
+ futureBool = m_trustStorage.hasKey(ns_omemo,
+ QStringLiteral("alice@example.org"),
+ QXmppTrustStorage::AutomaticallyTrusted | QXmppTrustStorage::Authenticated);
+ QVERIFY(futureBool.isFinished());
+ resultBool = futureBool.result();
+ QVERIFY(resultBool);
+
m_trustStorage.removeKeys(ns_omemo,
{ QByteArray::fromBase64(QByteArrayLiteral("WaAnpWyW1hnFooH3oJo9Ba5XYoksnLPeJRTAjxPbv38=")),
QByteArray::fromBase64(QByteArrayLiteral("Ciemp4ZNzRJxnRD+k28vAie0kXJrwl4IrbfDy7n6OxE=")) });
@@ -193,7 +315,20 @@ void tst_QXmppTrustMemoryStorage::testKeys()
automaticallyTrustedKeys = { { QStringLiteral("bob@example.com"),
QByteArray::fromBase64(QByteArrayLiteral("rvSXBRd+EICMhQvVgcREQJxxP+T4EBmai4mYHBfJQGg=")) } };
- // all OMEMO keys after removal
+ keysAlice = { { QByteArray::fromBase64(QByteArrayLiteral("/1eK3R2LtjPBT3el8f0q4DvzqUJSfFy5fkKkKPNFNYw=")),
+ QXmppTrustStorage::AutomaticallyDistrusted },
+ { QByteArray::fromBase64(QByteArrayLiteral("aFABnX7Q/rbTgjBySYzrT2FsYCVYb49mbca5yB734KQ=")),
+ QXmppTrustStorage::ManuallyDistrusted } };
+ keysBob = { { QByteArray::fromBase64(QByteArrayLiteral("rvSXBRd+EICMhQvVgcREQJxxP+T4EBmai4mYHBfJQGg=")),
+ QXmppTrustStorage::AutomaticallyTrusted },
+ { QByteArray::fromBase64(QByteArrayLiteral("tCP1CI3pqSTVGzFYFyPYUMfMZ9Ck/msmfD0wH/VtJBM=")),
+ QXmppTrustStorage::ManuallyTrusted },
+ { QByteArray::fromBase64(QByteArrayLiteral("2fhJtrgoMJxfLI3084/YkYh9paqiSiLFDVL2m0qAgX4=")),
+ QXmppTrustStorage::ManuallyTrusted },
+ { QByteArray::fromBase64(QByteArrayLiteral("YjVI04NcbTPvXLaA95RO84HPcSvyOgEZ2r5cTyUs0C8=")),
+ QXmppTrustStorage::Authenticated } };
+
+ // OMEMO keys after removal
future = m_trustStorage.keys(ns_omemo);
QVERIFY(future.isFinished());
result = future.result();
@@ -215,6 +350,76 @@ void tst_QXmppTrustMemoryStorage::testKeys()
QXmppTrustStorage::Authenticated,
authenticatedKeys) }));
+ // OMEMO keys after removal (via JIDs)
+ futureForJids = m_trustStorage.keys(ns_omemo,
+ { QStringLiteral("alice@example.org"), QStringLiteral("bob@example.com") });
+ QVERIFY(futureForJids.isFinished());
+ resultForJids = futureForJids.result();
+ QCOMPARE(
+ resultForJids,
+ QHash({ std::pair(
+ QStringLiteral("alice@example.org"),
+ keysAlice),
+ std::pair(
+ QStringLiteral("bob@example.com"),
+ keysBob) }));
+
+ // Alice's OMEMO keys after removal
+ futureForJids = m_trustStorage.keys(ns_omemo,
+ { QStringLiteral("alice@example.org") });
+ QVERIFY(futureForJids.isFinished());
+ resultForJids = futureForJids.result();
+ QCOMPARE(
+ resultForJids,
+ QHash({ std::pair(
+ QStringLiteral("alice@example.org"),
+ keysAlice) }));
+
+ keysAlice = { { QByteArray::fromBase64(QByteArrayLiteral("Ciemp4ZNzRJxnRD+k28vAie0kXJrwl4IrbfDy7n6OxE=")),
+ QXmppTrustStorage::AutomaticallyTrusted } };
+ keysBob = { { QByteArray::fromBase64(QByteArrayLiteral("rvSXBRd+EICMhQvVgcREQJxxP+T4EBmai4mYHBfJQGg=")),
+ QXmppTrustStorage::AutomaticallyTrusted },
+ { QByteArray::fromBase64(QByteArrayLiteral("YjVI04NcbTPvXLaA95RO84HPcSvyOgEZ2r5cTyUs0C8=")),
+ QXmppTrustStorage::Authenticated } };
+
+ // automatically trusted and authenticated OMEMO keys after removal (via JIDs)
+ futureForJids = m_trustStorage.keys(ns_omemo,
+ { QStringLiteral("alice@example.org"), QStringLiteral("bob@example.com") },
+ QXmppTrustStorage::AutomaticallyTrusted | QXmppTrustStorage::Authenticated);
+ QVERIFY(futureForJids.isFinished());
+ resultForJids = futureForJids.result();
+ QCOMPARE(
+ resultForJids,
+ QHash({ std::pair(
+ QStringLiteral("bob@example.com"),
+ keysBob) }));
+
+ // Alice's automatically trusted and authenticated OMEMO keys after removal
+ futureForJids = m_trustStorage.keys(ns_omemo,
+ { QStringLiteral("alice@example.org") },
+ QXmppTrustStorage::AutomaticallyTrusted | QXmppTrustStorage::Authenticated);
+ QVERIFY(futureForJids.isFinished());
+ resultForJids = futureForJids.result();
+ QVERIFY(resultForJids.isEmpty());
+
+ m_trustStorage.removeKeys(ns_omemo, QStringLiteral("alice@example.org"));
+
+ // OMEMO keys after removing Alice's keys
+ future = m_trustStorage.keys(ns_omemo);
+ QVERIFY(future.isFinished());
+ result = future.result();
+ QCOMPARE(
+ result,
+ QHash({ std::pair(
+ QXmppTrustStorage::AutomaticallyTrusted,
+ automaticallyTrustedKeys),
+ std::pair(
+ QXmppTrustStorage::ManuallyTrusted,
+ manuallyTrustedKeys),
+ std::pair(
+ QXmppTrustStorage::Authenticated,
+ authenticatedKeys) }));
+
m_trustStorage.removeKeys(ns_omemo);
// no stored OMEMO keys
@@ -228,6 +433,11 @@ void tst_QXmppTrustMemoryStorage::testKeys()
{ QStringLiteral("alice@example.org"),
QByteArray::fromBase64(QByteArrayLiteral("IhpPjiKLchgrAG5cpSfTvdzPjZ5v6vTOluHEUehkgCA=")) } };
+ keysAlice = { { QByteArray::fromBase64(QByteArrayLiteral("aFABnX7Q/rbTgjBySYzrT2FsYCVYb49mbca5yB734KQ=")),
+ QXmppTrustStorage::Authenticated },
+ { QByteArray::fromBase64(QByteArrayLiteral("IhpPjiKLchgrAG5cpSfTvdzPjZ5v6vTOluHEUehkgCA=")),
+ QXmppTrustStorage::Authenticated } };
+
// remaining OX keys
future = m_trustStorage.keys(ns_ox);
QVERIFY(future.isFinished());
@@ -238,13 +448,50 @@ void tst_QXmppTrustMemoryStorage::testKeys()
QXmppTrustStorage::Authenticated,
authenticatedKeys) }));
- m_trustStorage.removeKeys();
+ // remaining OX keys (via JIDs)
+ futureForJids = m_trustStorage.keys(ns_ox,
+ { QStringLiteral("alice@example.org"), QStringLiteral("bob@example.com") });
+ QVERIFY(futureForJids.isFinished());
+ resultForJids = futureForJids.result();
+ QCOMPARE(
+ resultForJids,
+ QHash({ std::pair(
+ QStringLiteral("alice@example.org"),
+ keysAlice) }));
+
+ // Alice's remaining OX keys
+ futureForJids = m_trustStorage.keys(ns_ox,
+ { QStringLiteral("alice@example.org") });
+ QVERIFY(futureForJids.isFinished());
+ resultForJids = futureForJids.result();
+ QCOMPARE(
+ resultForJids,
+ QHash({ std::pair(
+ QStringLiteral("alice@example.org"),
+ keysAlice) }));
+
+ m_trustStorage.removeKeys(ns_ox);
// no stored OX keys
future = m_trustStorage.keys(ns_ox);
QVERIFY(future.isFinished());
result = future.result();
QVERIFY(result.isEmpty());
+
+ // no stored OX keys (via JIDs)
+ futureForJids = m_trustStorage.keys(ns_ox,
+ { QStringLiteral("alice@example.org"), QStringLiteral("bob@example.com") });
+ QVERIFY(futureForJids.isFinished());
+ resultForJids = futureForJids.result();
+ QVERIFY(resultForJids.isEmpty());
+
+ // no automatically trusted or authenticated OX key from Alice
+ futureBool = m_trustStorage.hasKey(ns_ox,
+ QStringLiteral("alice@example.org"),
+ QXmppTrustStorage::AutomaticallyTrusted | QXmppTrustStorage::Authenticated);
+ QVERIFY(futureBool.isFinished());
+ resultBool = futureBool.result();
+ QVERIFY(!resultBool);
}
void tst_QXmppTrustMemoryStorage::testTrustLevels()
@@ -325,7 +572,7 @@ void tst_QXmppTrustMemoryStorage::testTrustLevels()
QByteArray::fromBase64(QByteArrayLiteral("WXL4EDfzUGbVPQWjT9pmBeiCpCBzYZv3lUAaj+UbPyE=")));
QVERIFY(future.isFinished());
result = future.result();
- QCOMPARE(result, QXmppTrustStorage::AutomaticallyDistrusted);
+ QCOMPARE(result, QXmppTrustStorage::Undecided);
// Set the trust levels of all authenticated keys belonging to Alice and
// Bob.
@@ -356,13 +603,111 @@ void tst_QXmppTrustMemoryStorage::testTrustLevels()
QByteArray::fromBase64(QByteArrayLiteral("wE06Gwf8f4DvDLFDoaCsGs8ibcUjf84WIOA2FAjPI3o=")));
QVERIFY(future.isFinished());
result = future.result();
- QCOMPARE(result, QXmppTrustStorage::AutomaticallyDistrusted);
+ QCOMPARE(result, QXmppTrustStorage::Undecided);
- m_trustStorage.removeKeys();
+ m_trustStorage.removeKeys(ns_ox);
+ m_trustStorage.removeKeys(ns_omemo);
}
-void tst_QXmppTrustMemoryStorage::testKeysForPostponedTrustDecisions()
+void tst_QXmppTrustMemoryStorage::testResetAll()
{
+ m_trustStorage.setSecurityPolicy(ns_ox, QXmppTrustStorage::Toakafa);
+ m_trustStorage.setSecurityPolicy(ns_omemo, QXmppTrustStorage::Toakafa);
+
+ m_trustStorage.setOwnKey(ns_ox, QByteArray::fromBase64(QByteArrayLiteral("aFABnX7Q/rbTgjBySYzrT2FsYCVYb49mbca5yB734KQ=")));
+ m_trustStorage.setOwnKey(ns_omemo, QByteArray::fromBase64(QByteArrayLiteral("IhpPjiKLchgrAG5cpSfTvdzPjZ5v6vTOluHEUehkgCA=")));
+
+ m_trustStorage.addKeys(
+ ns_omemo,
+ QStringLiteral("alice@example.org"),
+ { QByteArray::fromBase64(QByteArrayLiteral("WaAnpWyW1hnFooH3oJo9Ba5XYoksnLPeJRTAjxPbv38=")),
+ QByteArray::fromBase64(QByteArrayLiteral("/1eK3R2LtjPBT3el8f0q4DvzqUJSfFy5fkKkKPNFNYw=")) });
+
+ m_trustStorage.addKeys(
+ ns_omemo,
+ QStringLiteral("alice@example.org"),
+ { QByteArray::fromBase64(QByteArrayLiteral("aFABnX7Q/rbTgjBySYzrT2FsYCVYb49mbca5yB734KQ=")) },
+ QXmppTrustStorage::ManuallyDistrusted);
+
+ m_trustStorage.addKeys(
+ ns_omemo,
+ QStringLiteral("alice@example.org"),
+ { QByteArray::fromBase64(QByteArrayLiteral("Ciemp4ZNzRJxnRD+k28vAie0kXJrwl4IrbfDy7n6OxE=")) },
+ QXmppTrustStorage::AutomaticallyTrusted);
+
+ m_trustStorage.addKeys(
+ ns_omemo,
+ QStringLiteral("bob@example.com"),
+ { QByteArray::fromBase64(QByteArrayLiteral("rvSXBRd+EICMhQvVgcREQJxxP+T4EBmai4mYHBfJQGg=")) },
+ QXmppTrustStorage::AutomaticallyTrusted);
+
+ m_trustStorage.addKeys(
+ ns_omemo,
+ QStringLiteral("bob@example.com"),
+ { QByteArray::fromBase64(QByteArrayLiteral("tCP1CI3pqSTVGzFYFyPYUMfMZ9Ck/msmfD0wH/VtJBM=")),
+ QByteArray::fromBase64(QByteArrayLiteral("2fhJtrgoMJxfLI3084/YkYh9paqiSiLFDVL2m0qAgX4=")) },
+ QXmppTrustStorage::ManuallyTrusted);
+
+ m_trustStorage.addKeys(
+ ns_omemo,
+ QStringLiteral("bob@example.com"),
+ { QByteArray::fromBase64(QByteArrayLiteral("YjVI04NcbTPvXLaA95RO84HPcSvyOgEZ2r5cTyUs0C8=")) },
+ QXmppTrustStorage::Authenticated);
+
+ m_trustStorage.addKeys(
+ ns_ox,
+ QStringLiteral("alice@example.org"),
+ { QByteArray::fromBase64(QByteArrayLiteral("aFABnX7Q/rbTgjBySYzrT2FsYCVYb49mbca5yB734KQ=")),
+ QByteArray::fromBase64(QByteArrayLiteral("IhpPjiKLchgrAG5cpSfTvdzPjZ5v6vTOluHEUehkgCA=")) },
+ QXmppTrustStorage::Authenticated);
+
+ m_trustStorage.resetAll(ns_omemo);
+
+ auto future = m_trustStorage.securityPolicy(ns_omemo);
+ QVERIFY(future.isFinished());
+ auto result = future.result();
+ QCOMPARE(result, QXmppTrustStorage::NoSecurityPolicy);
+
+ future = m_trustStorage.securityPolicy(ns_ox);
+ QVERIFY(future.isFinished());
+ result = future.result();
+ QCOMPARE(result, QXmppTrustStorage::Toakafa);
+
+ auto futureKey = m_trustStorage.ownKey(ns_omemo);
+ QVERIFY(futureKey.isFinished());
+ auto resultKey = futureKey.result();
+ QVERIFY(resultKey.isEmpty());
+
+ futureKey = m_trustStorage.ownKey(ns_ox);
+ QVERIFY(futureKey.isFinished());
+ resultKey = futureKey.result();
+ QCOMPARE(resultKey, QByteArray::fromBase64(QByteArrayLiteral("aFABnX7Q/rbTgjBySYzrT2FsYCVYb49mbca5yB734KQ=")));
+
+ auto futureKeys = m_trustStorage.keys(ns_omemo);
+ QVERIFY(futureKeys.isFinished());
+ auto resultKeys = futureKeys.result();
+ QVERIFY(resultKeys.isEmpty());
+
+ const QMultiHash<QString, QByteArray> authenticatedKeys = { { QStringLiteral("alice@example.org"),
+ QByteArray::fromBase64(QByteArrayLiteral("aFABnX7Q/rbTgjBySYzrT2FsYCVYb49mbca5yB734KQ=")) },
+ { QStringLiteral("alice@example.org"),
+ QByteArray::fromBase64(QByteArrayLiteral("IhpPjiKLchgrAG5cpSfTvdzPjZ5v6vTOluHEUehkgCA=")) } };
+
+ futureKeys = m_trustStorage.keys(ns_ox);
+ QVERIFY(futureKeys.isFinished());
+ resultKeys = futureKeys.result();
+ QCOMPARE(
+ resultKeys,
+ QHash({ std::pair(
+ QXmppTrustStorage::Authenticated,
+ authenticatedKeys) }));
+}
+
+void tst_QXmppTrustMemoryStorage::atmTestKeysForPostponedTrustDecisions()
+{
+ // The key 7y1t0LnmNBeXJka43XejFPLrKtQlSFATrYmy7xHaKYU=
+ // is set for both postponed authentication and distrusting.
+ // Thus, it is only stored for postponed distrusting.
QXmppTrustMessageKeyOwner keyOwnerAlice;
keyOwnerAlice.setJid(QStringLiteral("alice@example.org"));
keyOwnerAlice.setTrustedKeys({ QByteArray::fromBase64(QByteArrayLiteral("Wl53ZchbtAtCZQCHROiD20W7UnKTQgWQrjTHAVNw1ic=")),
@@ -375,21 +720,18 @@ void tst_QXmppTrustMemoryStorage::testKeysForPostponedTrustDecisions()
keyOwnerBobTrustedKeys.setJid(QStringLiteral("bob@example.com"));
keyOwnerBobTrustedKeys.setTrustedKeys({ QByteArray::fromBase64(QByteArrayLiteral("GgTqeRLp1M+MEenzFQym2oqer9PfHukS4brJDQl5ARE=")) });
- // The key 7y1t0LnmNBeXJka43XejFPLrKtQlSFATrYmy7xHaKYU=
- // is passed for both postponed authentication and distrusting.
- // Thus, it is only stored for postponed distrusting.
- m_trustStorage.addKeysForPostponedTrustDecisions(ns_omemo,
- QByteArray::fromBase64(QByteArrayLiteral("Mp6Y4wOF3aMcl38lb/VNbdPF9ucGFqSx2eyaEsqyHKE=")),
- { keyOwnerAlice, keyOwnerBobTrustedKeys });
+ m_atmTrustStorage.addKeysForPostponedTrustDecisions(ns_omemo,
+ QByteArray::fromBase64(QByteArrayLiteral("Mp6Y4wOF3aMcl38lb/VNbdPF9ucGFqSx2eyaEsqyHKE=")),
+ { keyOwnerAlice, keyOwnerBobTrustedKeys });
QXmppTrustMessageKeyOwner keyOwnerBobDistrustedKeys;
keyOwnerBobDistrustedKeys.setJid(QStringLiteral("bob@example.com"));
keyOwnerBobDistrustedKeys.setDistrustedKeys({ QByteArray::fromBase64(QByteArrayLiteral("sD6ilugEBeKxPsdDEyX43LSGKHKWd5MFEdhT+4RpsxA=")),
QByteArray::fromBase64(QByteArrayLiteral("X5tJ1D5rEeaeQE8eqhBKAj4KUZGYe3x+iHifaTBY1kM=")) });
- m_trustStorage.addKeysForPostponedTrustDecisions(ns_omemo,
- QByteArray::fromBase64(QByteArrayLiteral("IL5iwDQwquH7yjb5RAiIP+nvYiBUsNCXtKB8IpKc9QU=")),
- { keyOwnerBobDistrustedKeys });
+ m_atmTrustStorage.addKeysForPostponedTrustDecisions(ns_omemo,
+ QByteArray::fromBase64(QByteArrayLiteral("IL5iwDQwquH7yjb5RAiIP+nvYiBUsNCXtKB8IpKc9QU=")),
+ { keyOwnerBobDistrustedKeys });
QXmppTrustMessageKeyOwner keyOwnerCarol;
keyOwnerCarol.setJid(QStringLiteral("carol@example.net"));
@@ -398,9 +740,9 @@ void tst_QXmppTrustMemoryStorage::testKeysForPostponedTrustDecisions()
keyOwnerCarol.setDistrustedKeys({ QByteArray::fromBase64(QByteArrayLiteral("N0B2StHKk1/slwg1rzybTFzjdg7FChc+3cXmTU/rS8g=")),
QByteArray::fromBase64(QByteArrayLiteral("wsEN32UHCiNjYqTG/J63hY4Nu8tZT42Ni1FxrgyRQ5g=")) });
- m_trustStorage.addKeysForPostponedTrustDecisions(ns_ox,
- QByteArray::fromBase64(QByteArrayLiteral("IL5iwDQwquH7yjb5RAiIP+nvYiBUsNCXtKB8IpKc9QU=")),
- { keyOwnerCarol });
+ m_atmTrustStorage.addKeysForPostponedTrustDecisions(ns_ox,
+ QByteArray::fromBase64(QByteArrayLiteral("IL5iwDQwquH7yjb5RAiIP+nvYiBUsNCXtKB8IpKc9QU=")),
+ { keyOwnerCarol });
QMultiHash<QString, QByteArray> trustedKeys = { { QStringLiteral("alice@example.org"),
QByteArray::fromBase64(QByteArrayLiteral("Wl53ZchbtAtCZQCHROiD20W7UnKTQgWQrjTHAVNw1ic=")) },
@@ -413,8 +755,8 @@ void tst_QXmppTrustMemoryStorage::testKeysForPostponedTrustDecisions()
{ QStringLiteral("alice@example.org"),
QByteArray::fromBase64(QByteArrayLiteral("7y1t0LnmNBeXJka43XejFPLrKtQlSFATrYmy7xHaKYU=")) } };
- auto future = m_trustStorage.keysForPostponedTrustDecisions(ns_omemo,
- { QByteArray::fromBase64(QByteArrayLiteral("Mp6Y4wOF3aMcl38lb/VNbdPF9ucGFqSx2eyaEsqyHKE=")) });
+ auto future = m_atmTrustStorage.keysForPostponedTrustDecisions(ns_omemo,
+ { QByteArray::fromBase64(QByteArrayLiteral("Mp6Y4wOF3aMcl38lb/VNbdPF9ucGFqSx2eyaEsqyHKE=")) });
QVERIFY(future.isFinished());
auto result = future.result();
QCOMPARE(
@@ -435,9 +777,9 @@ void tst_QXmppTrustMemoryStorage::testKeysForPostponedTrustDecisions()
{ QStringLiteral("bob@example.com"),
QByteArray::fromBase64(QByteArrayLiteral("X5tJ1D5rEeaeQE8eqhBKAj4KUZGYe3x+iHifaTBY1kM=")) } };
- future = m_trustStorage.keysForPostponedTrustDecisions(ns_omemo,
- { QByteArray::fromBase64(QByteArrayLiteral("Mp6Y4wOF3aMcl38lb/VNbdPF9ucGFqSx2eyaEsqyHKE=")),
- QByteArray::fromBase64(QByteArrayLiteral("IL5iwDQwquH7yjb5RAiIP+nvYiBUsNCXtKB8IpKc9QU=")) });
+ future = m_atmTrustStorage.keysForPostponedTrustDecisions(ns_omemo,
+ { QByteArray::fromBase64(QByteArrayLiteral("Mp6Y4wOF3aMcl38lb/VNbdPF9ucGFqSx2eyaEsqyHKE=")),
+ QByteArray::fromBase64(QByteArrayLiteral("IL5iwDQwquH7yjb5RAiIP+nvYiBUsNCXtKB8IpKc9QU=")) });
QVERIFY(future.isFinished());
result = future.result();
QCOMPARE(
@@ -450,7 +792,7 @@ void tst_QXmppTrustMemoryStorage::testKeysForPostponedTrustDecisions()
distrustedKeys) }));
// Retrieve all keys.
- future = m_trustStorage.keysForPostponedTrustDecisions(ns_omemo);
+ future = m_atmTrustStorage.keysForPostponedTrustDecisions(ns_omemo);
QVERIFY(future.isFinished());
result = future.result();
QCOMPARE(
@@ -468,7 +810,7 @@ void tst_QXmppTrustMemoryStorage::testKeysForPostponedTrustDecisions()
// sD6ilugEBeKxPsdDEyX43LSGKHKWd5MFEdhT+4RpsxA= for the
// sending endpoint with the key
// IL5iwDQwquH7yjb5RAiIP+nvYiBUsNCXtKB8IpKc9QU=.
- m_trustStorage.addKeysForPostponedTrustDecisions(
+ m_atmTrustStorage.addKeysForPostponedTrustDecisions(
ns_omemo,
QByteArray::fromBase64(QByteArrayLiteral("IL5iwDQwquH7yjb5RAiIP+nvYiBUsNCXtKB8IpKc9QU=")),
{ keyOwnerBobTrustedKeys });
@@ -478,8 +820,8 @@ void tst_QXmppTrustMemoryStorage::testKeysForPostponedTrustDecisions()
distrustedKeys = { { QStringLiteral("bob@example.com"),
QByteArray::fromBase64(QByteArrayLiteral("X5tJ1D5rEeaeQE8eqhBKAj4KUZGYe3x+iHifaTBY1kM=")) } };
- future = m_trustStorage.keysForPostponedTrustDecisions(ns_omemo,
- { QByteArray::fromBase64(QByteArrayLiteral("IL5iwDQwquH7yjb5RAiIP+nvYiBUsNCXtKB8IpKc9QU=")) });
+ future = m_atmTrustStorage.keysForPostponedTrustDecisions(ns_omemo,
+ { QByteArray::fromBase64(QByteArrayLiteral("IL5iwDQwquH7yjb5RAiIP+nvYiBUsNCXtKB8IpKc9QU=")) });
QVERIFY(future.isFinished());
result = future.result();
QCOMPARE(
@@ -491,10 +833,10 @@ void tst_QXmppTrustMemoryStorage::testKeysForPostponedTrustDecisions()
false,
distrustedKeys) }));
- m_trustStorage.removeKeysForPostponedTrustDecisions(ns_omemo,
- { QByteArray::fromBase64(QByteArrayLiteral("Mp6Y4wOF3aMcl38lb/VNbdPF9ucGFqSx2eyaEsqyHKE=")) });
+ m_atmTrustStorage.removeKeysForPostponedTrustDecisions(ns_omemo,
+ { QByteArray::fromBase64(QByteArrayLiteral("Mp6Y4wOF3aMcl38lb/VNbdPF9ucGFqSx2eyaEsqyHKE=")) });
- future = m_trustStorage.keysForPostponedTrustDecisions(ns_omemo);
+ future = m_atmTrustStorage.keysForPostponedTrustDecisions(ns_omemo);
QVERIFY(future.isFinished());
result = future.result();
QCOMPARE(
@@ -506,11 +848,43 @@ void tst_QXmppTrustMemoryStorage::testKeysForPostponedTrustDecisions()
false,
distrustedKeys) }));
- // Remove all OMEMO keys including those stored for sender key
- // IL5iwDQwquH7yjb5RAiIP+nvYiBUsNCXtKB8IpKc9QU=.
- m_trustStorage.removeKeysForPostponedTrustDecisions(ns_omemo);
+ m_atmTrustStorage.addKeysForPostponedTrustDecisions(
+ ns_omemo,
+ QByteArray::fromBase64(QByteArrayLiteral("Mp6Y4wOF3aMcl38lb/VNbdPF9ucGFqSx2eyaEsqyHKE=")),
+ { keyOwnerAlice });
+
+ // The key QR05jrab7PFkSLhtdzyXrPfCqhkNCYCrlWATaBMTenE= is not removed
+ // because its ID is passed within the parameter "keyIdsForDistrusting" but
+ // stored for postponed authentication.
+ m_atmTrustStorage.removeKeysForPostponedTrustDecisions(ns_omemo,
+ { QByteArray::fromBase64(QByteArrayLiteral("Wl53ZchbtAtCZQCHROiD20W7UnKTQgWQrjTHAVNw1ic=")),
+ QByteArray::fromBase64(QByteArrayLiteral("sD6ilugEBeKxPsdDEyX43LSGKHKWd5MFEdhT+4RpsxA=")) },
+ { QByteArray::fromBase64(QByteArrayLiteral("mB98hhdVps++skUuy4TGy/Vp6RQXLJO4JGf86FAUjyc=")),
+ QByteArray::fromBase64(QByteArrayLiteral("QR05jrab7PFkSLhtdzyXrPfCqhkNCYCrlWATaBMTenE=")) });
+
+ trustedKeys = { { QStringLiteral("alice@example.org"),
+ QByteArray::fromBase64(QByteArrayLiteral("QR05jrab7PFkSLhtdzyXrPfCqhkNCYCrlWATaBMTenE=")) } };
+ distrustedKeys = { { QStringLiteral("alice@example.org"),
+ QByteArray::fromBase64(QByteArrayLiteral("7y1t0LnmNBeXJka43XejFPLrKtQlSFATrYmy7xHaKYU=")) },
+ { QStringLiteral("bob@example.com"),
+ QByteArray::fromBase64(QByteArrayLiteral("X5tJ1D5rEeaeQE8eqhBKAj4KUZGYe3x+iHifaTBY1kM=")) } };
+
+ future = m_atmTrustStorage.keysForPostponedTrustDecisions(ns_omemo);
+ QVERIFY(future.isFinished());
+ result = future.result();
+ QCOMPARE(
+ result,
+ QHash({ std::pair(
+ true,
+ trustedKeys),
+ std::pair(
+ false,
+ distrustedKeys) }));
+
+ // Remove all OMEMO keys.
+ m_atmTrustStorage.removeKeysForPostponedTrustDecisions(ns_omemo);
- future = m_trustStorage.keysForPostponedTrustDecisions(ns_omemo);
+ future = m_atmTrustStorage.keysForPostponedTrustDecisions(ns_omemo);
QVERIFY(future.isFinished());
result = future.result();
QVERIFY(result.isEmpty());
@@ -525,7 +899,7 @@ void tst_QXmppTrustMemoryStorage::testKeysForPostponedTrustDecisions()
QByteArray::fromBase64(QByteArrayLiteral("wsEN32UHCiNjYqTG/J63hY4Nu8tZT42Ni1FxrgyRQ5g=")) } };
// remaining OX keys
- future = m_trustStorage.keysForPostponedTrustDecisions(ns_ox);
+ future = m_atmTrustStorage.keysForPostponedTrustDecisions(ns_ox);
QVERIFY(future.isFinished());
result = future.result();
QCOMPARE(
@@ -537,15 +911,69 @@ void tst_QXmppTrustMemoryStorage::testKeysForPostponedTrustDecisions()
false,
distrustedKeys) }));
- m_trustStorage.removeKeysForPostponedTrustDecisions();
+ m_atmTrustStorage.removeKeysForPostponedTrustDecisions(ns_ox);
// no OX keys
- future = m_trustStorage.keysForPostponedTrustDecisions(ns_ox);
+ future = m_atmTrustStorage.keysForPostponedTrustDecisions(ns_ox);
QVERIFY(future.isFinished());
result = future.result();
QVERIFY(result.isEmpty());
+}
- m_trustStorage.removeKeys();
+void tst_QXmppTrustMemoryStorage::atmTestResetAll()
+{
+ QXmppTrustMessageKeyOwner keyOwnerAlice;
+ keyOwnerAlice.setJid(QStringLiteral("alice@example.org"));
+ keyOwnerAlice.setTrustedKeys({ QByteArray::fromBase64(QByteArrayLiteral("Wl53ZchbtAtCZQCHROiD20W7UnKTQgWQrjTHAVNw1ic=")),
+ QByteArray::fromBase64(QByteArrayLiteral("QR05jrab7PFkSLhtdzyXrPfCqhkNCYCrlWATaBMTenE=")) });
+ keyOwnerAlice.setDistrustedKeys({ QByteArray::fromBase64(QByteArrayLiteral("mB98hhdVps++skUuy4TGy/Vp6RQXLJO4JGf86FAUjyc=")) });
+
+ QXmppTrustMessageKeyOwner keyOwnerBobTrustedKeys;
+ keyOwnerBobTrustedKeys.setJid(QStringLiteral("bob@example.com"));
+ keyOwnerBobTrustedKeys.setTrustedKeys({ QByteArray::fromBase64(QByteArrayLiteral("GgTqeRLp1M+MEenzFQym2oqer9PfHukS4brJDQl5ARE=")) });
+
+ m_atmTrustStorage.addKeysForPostponedTrustDecisions(ns_omemo,
+ QByteArray::fromBase64(QByteArrayLiteral("Mp6Y4wOF3aMcl38lb/VNbdPF9ucGFqSx2eyaEsqyHKE=")),
+ { keyOwnerAlice, keyOwnerBobTrustedKeys });
+
+ QXmppTrustMessageKeyOwner keyOwnerCarol;
+ keyOwnerCarol.setJid(QStringLiteral("carol@example.net"));
+ keyOwnerCarol.setTrustedKeys({ QByteArray::fromBase64(QByteArrayLiteral("WcL+cEMpEeK+dpqg3Xd3amctzwP8h2MqwXcEzFf6LpU=")),
+ QByteArray::fromBase64(QByteArrayLiteral("bH3R31z0N97K1fUwG3+bdBrVPuDfXguQapHudkfa5nE=")) });
+ keyOwnerCarol.setDistrustedKeys({ QByteArray::fromBase64(QByteArrayLiteral("N0B2StHKk1/slwg1rzybTFzjdg7FChc+3cXmTU/rS8g=")),
+ QByteArray::fromBase64(QByteArrayLiteral("wsEN32UHCiNjYqTG/J63hY4Nu8tZT42Ni1FxrgyRQ5g=")) });
+
+ m_atmTrustStorage.addKeysForPostponedTrustDecisions(ns_ox,
+ QByteArray::fromBase64(QByteArrayLiteral("IL5iwDQwquH7yjb5RAiIP+nvYiBUsNCXtKB8IpKc9QU=")),
+ { keyOwnerCarol });
+
+ m_atmTrustStorage.resetAll(ns_omemo);
+
+ auto futureKeysForPostponedTrustDecisions = m_atmTrustStorage.keysForPostponedTrustDecisions(ns_omemo);
+ QVERIFY(futureKeysForPostponedTrustDecisions.isFinished());
+ auto resultKeysForPostponedTrustDecisions = futureKeysForPostponedTrustDecisions.result();
+ QVERIFY(resultKeysForPostponedTrustDecisions.isEmpty());
+
+ QMultiHash<QString, QByteArray> trustedKeys = { { QStringLiteral("carol@example.net"),
+ QByteArray::fromBase64(QByteArrayLiteral("WcL+cEMpEeK+dpqg3Xd3amctzwP8h2MqwXcEzFf6LpU=")) },
+ { QStringLiteral("carol@example.net"),
+ QByteArray::fromBase64(QByteArrayLiteral("bH3R31z0N97K1fUwG3+bdBrVPuDfXguQapHudkfa5nE=")) } };
+ QMultiHash<QString, QByteArray> distrustedKeys = { { QStringLiteral("carol@example.net"),
+ QByteArray::fromBase64(QByteArrayLiteral("N0B2StHKk1/slwg1rzybTFzjdg7FChc+3cXmTU/rS8g=")) },
+ { QStringLiteral("carol@example.net"),
+ QByteArray::fromBase64(QByteArrayLiteral("wsEN32UHCiNjYqTG/J63hY4Nu8tZT42Ni1FxrgyRQ5g=")) } };
+
+ futureKeysForPostponedTrustDecisions = m_atmTrustStorage.keysForPostponedTrustDecisions(ns_ox);
+ QVERIFY(futureKeysForPostponedTrustDecisions.isFinished());
+ resultKeysForPostponedTrustDecisions = futureKeysForPostponedTrustDecisions.result();
+ QCOMPARE(
+ resultKeysForPostponedTrustDecisions,
+ QHash({ std::pair(
+ true,
+ trustedKeys),
+ std::pair(
+ false,
+ distrustedKeys) }));
}
QTEST_MAIN(tst_QXmppTrustMemoryStorage)