aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMelvin Keskin <melvo@olomono.de>2022-01-23 18:11:48 +0100
committerLinus Jahn <lnj@kaidan.im>2022-03-03 13:49:50 +0100
commitec1480a11ee69924712b3b1b10cde7fbf6ba1866 (patch)
tree9b6afbd3b3869fda4ccdded7859de743c607d5ca
parent4f77a9d91d5841771d27821ced76c7c6801790f5 (diff)
downloadqxmpp-ec1480a11ee69924712b3b1b10cde7fbf6ba1866.tar.gz
Add QXmppE2eeMetadata used by QXmppStanza
That class contains addtional data needed for end-to-end encryption purposes. 'senderKey' is moved from QXmppMessage to QXmppE2eeMetadata. 'sceTimestamp' is introduced.
-rw-r--r--src/base/QXmppMessage.cpp41
-rw-r--r--src/base/QXmppMessage.h3
-rw-r--r--src/base/QXmppStanza.cpp140
-rw-r--r--src/base/QXmppStanza.h26
-rw-r--r--src/client/QXmppAtmManager.cpp2
-rw-r--r--tests/qxmppatmmanager/tst_qxmppatmmanager.cpp10
-rw-r--r--tests/qxmppmessage/tst_qxmppmessage.cpp8
-rw-r--r--tests/qxmppstanza/tst_qxmppstanza.cpp32
8 files changed, 206 insertions, 56 deletions
diff --git a/src/base/QXmppMessage.cpp b/src/base/QXmppMessage.cpp
index e2d4a003..ec285d0a 100644
--- a/src/base/QXmppMessage.cpp
+++ b/src/base/QXmppMessage.cpp
@@ -14,8 +14,6 @@
#include "QXmppTrustMessageElement.h"
#include "QXmppUtils.h"
-#include <optional>
-
#include <QDateTime>
#include <QDomElement>
#include <QTextStream>
@@ -94,7 +92,6 @@ public:
QString thread;
QString parentThread;
QXmppMessage::Type type;
- QByteArray senderKey;
// XEP-0066: Out of Band Data
QString outOfBandUrl;
@@ -312,44 +309,6 @@ void QXmppMessage::setParentThread(const QString &parent)
}
///
-/// Returns the ID of this message's sender's public long-term key.
-///
-/// The key ID is not part of a transmitted message and thus not de- /
-/// serialized.
-/// Instead, the key ID is set by an encryption protocol such as
-/// \xep{0384, OMEMO Encryption} when it decrypts this message.
-/// It can be used by trust management protocols such as
-/// \xep{0450, Automatic Trust Management (ATM)}.
-///
-/// \return the ID of the sender's key
-///
-/// \since QXmpp 1.5
-///
-QByteArray QXmppMessage::senderKey() const
-{
- return d->senderKey;
-}
-
-///
-/// Sets the ID of this message's sender's public long-term key.
-///
-/// The key ID is not part of a transmitted message and thus not de- /
-/// serialized.
-/// Instead, the key ID is set by an encryption protocol such as
-/// \xep{0384, OMEMO Encryption} when it decrypts this message.
-/// It can be used by trust management protocols such as
-/// \xep{0450, Automatic Trust Management (ATM)}.
-///
-/// \param keyId ID of the sender's key
-///
-/// \since QXmpp 1.5
-///
-void QXmppMessage::setSenderKey(const QByteArray &keyId)
-{
- d->senderKey = keyId;
-}
-
-///
/// Returns a possibly attached URL from \xep{0066}: Out of Band Data
///
/// \since QXmpp 1.0
diff --git a/src/base/QXmppMessage.h b/src/base/QXmppMessage.h
index bc209435..bdd47800 100644
--- a/src/base/QXmppMessage.h
+++ b/src/base/QXmppMessage.h
@@ -120,9 +120,6 @@ public:
QXmppMessage::Type type() const;
void setType(QXmppMessage::Type);
- QByteArray senderKey() const;
- void setSenderKey(const QByteArray &keyId);
-
// XEP-0066: Out of Band Data
QString outOfBandUrl() const;
void setOutOfBandUrl(const QString &);
diff --git a/src/base/QXmppStanza.cpp b/src/base/QXmppStanza.cpp
index 70c87420..25b9baac 100644
--- a/src/base/QXmppStanza.cpp
+++ b/src/base/QXmppStanza.cpp
@@ -1,6 +1,7 @@
// SPDX-FileCopyrightText: 2009 Manjeet Dahiya <manjeetdahiya@gmail.com>
// SPDX-FileCopyrightText: 2010 Jeremy Lainé <jeremy.laine@m4x.org>
// SPDX-FileCopyrightText: 2015 Georg Rudoy <0xd34df00d@gmail.com>
+// SPDX-FileCopyrightText: 2022 Melvin Keskin <melvo@olomono.de>
//
// SPDX-License-Identifier: LGPL-2.1-or-later
@@ -489,6 +490,124 @@ void QXmppStanza::Error::toXml(QXmlStreamWriter *writer) const
}
/// \endcond
+///
+/// \class QXmppE2eeMetadata
+///
+/// \brief The QXmppE2eeMetadata class contains data used for end-to-end
+/// encryption purposes.
+///
+/// \since QXmpp 1.5
+///
+
+class QXmppE2eeMetadataPrivate : public QSharedData
+{
+public:
+ QByteArray senderKey;
+
+ // XEP-0420: Stanza Content Encryption
+ QDateTime sceTimestamp;
+};
+
+///
+/// Constructs a class for end-to-end encryption metadata.
+///
+QXmppE2eeMetadata::QXmppE2eeMetadata()
+ : d(new QXmppE2eeMetadataPrivate)
+{
+}
+
+///
+/// Constructs a copy of \a other.
+///
+/// \param other
+///
+QXmppE2eeMetadata::QXmppE2eeMetadata(const QXmppE2eeMetadata &other) = default;
+
+QXmppE2eeMetadata::~QXmppE2eeMetadata() = default;
+
+///
+/// Assigns \a other to this end-to-end encryption metadata class.
+///
+/// \param other
+///
+QXmppE2eeMetadata &QXmppE2eeMetadata::operator=(const QXmppE2eeMetadata &other) = default;
+
+///
+/// Returns the ID of this stanza's sender's public long-term key.
+///
+/// The sender key ID is not part of a transmitted stanza and thus not de- /
+/// serialized.
+/// Instead, the key ID is set by an encryption protocol such as
+/// \xep{0384, OMEMO Encryption} during decryption.
+/// It can be used by trust management protocols such as
+/// \xep{0450, Automatic Trust Management (ATM)}.
+///
+/// \return the ID of the sender's key
+///
+/// \since QXmpp 1.5
+///
+QByteArray QXmppE2eeMetadata::senderKey() const
+{
+ return d->senderKey;
+}
+
+///
+/// Sets the ID of this stanza's sender's public long-term key.
+///
+/// The sender key ID is not part of a transmitted stanza and thus not de- /
+/// serialized.
+/// Instead, it is set by an encryption protocol such as
+/// \xep{0384, OMEMO Encryption} during decryption.
+/// It can be used by trust management protocols such as
+/// \xep{0450, Automatic Trust Management (ATM)}.
+///
+/// \param keyId ID of the sender's key
+///
+/// \since QXmpp 1.5
+///
+void QXmppE2eeMetadata::setSenderKey(const QByteArray &keyId)
+{
+ d->senderKey = keyId;
+}
+
+///
+/// Returns the timestamp affix element's content as defined by
+/// \xep{0420, Stanza Content Encryption} (SCE).
+///
+/// The SCE timestamp is part of an encrypted stanza's SCE envelope,
+/// not an unencrypted direct child of a transmitted stanza and thus not de- /
+/// serialized by it.
+/// Instead, it is set by an encryption protocol such as
+/// \xep{0384, OMEMO Encryption} after decryption.
+/// It can be used by trust management protocols such as
+/// \xep{0450, Automatic Trust Management (ATM)}.
+///
+/// \since QXmpp 1.5
+///
+QDateTime QXmppE2eeMetadata::sceTimestamp() const
+{
+ return d->sceTimestamp;
+}
+
+///
+/// Sets the timestamp affix element's content as defined by
+/// \xep{0420, Stanza Content Encryption} (SCE).
+///
+/// The SCE timestamp is part of an encrypted stanza's SCE envelope,
+/// not an unencrypted direct child of a transmitted stanza and thus not de- /
+/// serialized by it.
+/// Instead, it is set by an encryption protocol such as
+/// \xep{0384, OMEMO Encryption} after decryption.
+/// It can be used by trust management protocols such as
+/// \xep{0450, Automatic Trust Management (ATM)}.
+///
+/// \since QXmpp 1.5
+///
+void QXmppE2eeMetadata::setSceTimestamp(const QDateTime &timestamp)
+{
+ d->sceTimestamp = timestamp;
+}
+
class QXmppStanzaPrivate : public QSharedData
{
public:
@@ -499,6 +618,7 @@ public:
QXmppStanza::Error error;
QXmppElementList extensions;
QList<QXmppExtendedAddress> extendedAddresses;
+ QXmppE2eeMetadata e2eeMetadata;
};
///
@@ -651,6 +771,26 @@ void QXmppStanza::setExtendedAddresses(const QList<QXmppExtendedAddress> &addres
d->extendedAddresses = addresses;
}
+///
+/// Returns additional data for end-to-end encryption purposes.
+///
+/// \since QXmpp 1.5
+///
+QXmppE2eeMetadata QXmppStanza::e2eeMetadata() const
+{
+ return d->e2eeMetadata;
+}
+
+///
+/// Sets additional data for end-to-end encryption purposes.
+///
+/// \since QXmpp 1.5
+///
+void QXmppStanza::setE2eeMetadata(const QXmppE2eeMetadata &e2eeMetadata)
+{
+ d->e2eeMetadata = e2eeMetadata;
+}
+
/// \cond
void QXmppStanza::generateAndSetNextId()
{
diff --git a/src/base/QXmppStanza.h b/src/base/QXmppStanza.h
index 84f731c5..34cd1aed 100644
--- a/src/base/QXmppStanza.h
+++ b/src/base/QXmppStanza.h
@@ -1,6 +1,7 @@
// SPDX-FileCopyrightText: 2009 Manjeet Dahiya <manjeetdahiya@gmail.com>
// SPDX-FileCopyrightText: 2010 Jeremy Lainé <jeremy.laine@m4x.org>
// SPDX-FileCopyrightText: 2015 Georg Rudoy <0xd34df00d@gmail.com>
+// SPDX-FileCopyrightText: 2022 Melvin Keskin <melvo@olomono.de>
//
// SPDX-License-Identifier: LGPL-2.1-or-later
@@ -63,6 +64,28 @@ private:
QSharedDataPointer<QXmppExtendedAddressPrivate> d;
};
+class QXmppE2eeMetadataPrivate;
+
+class QXMPP_EXPORT QXmppE2eeMetadata
+{
+public:
+ QXmppE2eeMetadata();
+ QXmppE2eeMetadata(const QXmppE2eeMetadata &other);
+ ~QXmppE2eeMetadata();
+
+ QXmppE2eeMetadata &operator=(const QXmppE2eeMetadata &other);
+
+ QByteArray senderKey() const;
+ void setSenderKey(const QByteArray &keyId);
+
+ // XEP-0420: Stanza Content Encryption
+ QDateTime sceTimestamp() const;
+ void setSceTimestamp(const QDateTime &timestamp);
+
+private:
+ QSharedDataPointer<QXmppE2eeMetadataPrivate> d;
+};
+
class QXmppStanzaPrivate;
class QXmppStanzaErrorPrivate;
@@ -202,6 +225,9 @@ public:
QList<QXmppExtendedAddress> extendedAddresses() const;
void setExtendedAddresses(const QList<QXmppExtendedAddress> &extendedAddresses);
+ QXmppE2eeMetadata e2eeMetadata() const;
+ void setE2eeMetadata(const QXmppE2eeMetadata &e2eeMetadata);
+
/// \cond
void parse(const QDomElement &element) override;
diff --git a/src/client/QXmppAtmManager.cpp b/src/client/QXmppAtmManager.cpp
index 829daa20..957ed8ef 100644
--- a/src/client/QXmppAtmManager.cpp
+++ b/src/client/QXmppAtmManager.cpp
@@ -297,7 +297,7 @@ QFuture<void> QXmppAtmManager::handleMessage(const QXmppMessage &message)
trustMessageElement->usage() == ns_atm &&
message.from() != client()->configuration().jid()) {
const auto senderJid = QXmppUtils::jidToBareJid(message.from());
- const auto senderKey = message.senderKey();
+ const auto senderKey = message.e2eeMetadata().senderKey();
const auto encryption = trustMessageElement->encryption();
auto future = m_trustStorage->trustLevel(encryption, senderKey);
diff --git a/tests/qxmppatmmanager/tst_qxmppatmmanager.cpp b/tests/qxmppatmmanager/tst_qxmppatmmanager.cpp
index 4ff4e079..e8fd08a4 100644
--- a/tests/qxmppatmmanager/tst_qxmppatmmanager.cpp
+++ b/tests/qxmppatmmanager/tst_qxmppatmmanager.cpp
@@ -742,6 +742,9 @@ void tst_QXmppAtmManager::testHandleMessage_data()
keyOwnerBob.setDistrustedKeys({ { QByteArray::fromBase64(QByteArrayLiteral("b3EsvoNBgUpiQD9KRHmosP/rR7T+3BA84MQw4N6eZmU=")) },
{ QByteArray::fromBase64(QByteArrayLiteral("guRlZo0QVxX3TbzdhyOwzdlorG0Znndo/P9NsWtMkk4=")) } });
+ QXmppE2eeMetadata e2eeMetadata;
+ e2eeMetadata.setSenderKey(QByteArray::fromBase64(QByteArrayLiteral("RwyI/3m9l4wgju9JduFxb5MEJvBNRDfPfo1Ewhl1DEI=")));
+
QList<QXmppTrustMessageKeyOwner> keyOwners;
keyOwners << keyOwnerAlice << keyOwnerBob;
@@ -752,7 +755,7 @@ void tst_QXmppAtmManager::testHandleMessage_data()
QXmppMessage message;
message.setFrom(m_client.configuration().jid());
- message.setSenderKey(QByteArray::fromBase64(QByteArrayLiteral("RwyI/3m9l4wgju9JduFxb5MEJvBNRDfPfo1Ewhl1DEI=")));
+ message.setE2eeMetadata(e2eeMetadata);
message.setTrustMessageElement(trustMessageElement);
QTest::newRow("carbonForOwnMessage")
@@ -815,8 +818,9 @@ void tst_QXmppAtmManager::testHandleMessage_data()
<< true
<< true;
+ e2eeMetadata.setSenderKey(QByteArray::fromBase64(QByteArrayLiteral("qfNJsEMZ8jru0dS76DtYaTxZjiVQ5lpJWBiyaUj9UGU=")));
message.setFrom(QStringLiteral("bob@example.com/notebook"));
- message.setSenderKey(QByteArray::fromBase64(QByteArrayLiteral("qfNJsEMZ8jru0dS76DtYaTxZjiVQ5lpJWBiyaUj9UGU=")));
+ message.setE2eeMetadata(e2eeMetadata);
QTest::newRow("senderKeyFromContactNotAuthenticated")
<< message
@@ -838,7 +842,7 @@ void tst_QXmppAtmManager::testHandleMessage()
QFETCH(bool, isSenderKeyAuthenticated);
const auto senderJid = QXmppUtils::jidToBareJid(message.from());
- const auto senderKey = message.senderKey();
+ const auto senderKey = message.e2eeMetadata().senderKey();
// Add the sender key in preparation for the test.
if (areTrustDecisionsValid) {
diff --git a/tests/qxmppmessage/tst_qxmppmessage.cpp b/tests/qxmppmessage/tst_qxmppmessage.cpp
index 2b1c0e1d..60a6562c 100644
--- a/tests/qxmppmessage/tst_qxmppmessage.cpp
+++ b/tests/qxmppmessage/tst_qxmppmessage.cpp
@@ -54,7 +54,6 @@ private slots:
void testMixInvitation();
void testTrustMessageElement();
void testOmemoElement();
- void testSenderkey();
};
void tst_QXmppMessage::testBasic_data()
@@ -1197,12 +1196,5 @@ void tst_QXmppMessage::testOmemoElement()
serializePacket(message2, xmlOut2);
}
-void tst_QXmppMessage::testSenderkey()
-{
- QXmppMessage message;
- message.setSenderKey(QByteArray::fromBase64(QByteArrayLiteral("aFABnX7Q/rbTgjBySYzrT2FsYCVYb49mbca5yB734KQ=")));
- QCOMPARE(message.senderKey(), QByteArray::fromBase64(QByteArrayLiteral("aFABnX7Q/rbTgjBySYzrT2FsYCVYb49mbca5yB734KQ=")));
-}
-
QTEST_MAIN(tst_QXmppMessage)
#include "tst_qxmppmessage.moc"
diff --git a/tests/qxmppstanza/tst_qxmppstanza.cpp b/tests/qxmppstanza/tst_qxmppstanza.cpp
index cff33e43..98be3d63 100644
--- a/tests/qxmppstanza/tst_qxmppstanza.cpp
+++ b/tests/qxmppstanza/tst_qxmppstanza.cpp
@@ -1,4 +1,5 @@
// SPDX-FileCopyrightText: 2012 Jeremy Lainé <jeremy.laine@m4x.org>
+// SPDX-FileCopyrightText: 2022 Melvin Keskin <melvo@olomono.de>
//
// SPDX-License-Identifier: LGPL-2.1-or-later
@@ -7,6 +8,12 @@
#include "util.h"
#include <QObject>
+class QXmppStanzaStub : public QXmppStanza
+{
+public:
+ void toXml(QXmlStreamWriter *writer) const override {};
+};
+
class tst_QXmppStanza : public QObject
{
Q_OBJECT
@@ -19,6 +26,9 @@ private slots:
void testErrorCases();
void testErrorFileTooLarge();
void testErrorRetry();
+
+ void testSenderKey();
+ void testSceTimestamp();
};
void tst_QXmppStanza::testExtendedAddress_data()
@@ -372,5 +382,27 @@ void tst_QXmppStanza::testErrorRetry()
QCOMPARE(error.retryDate(), QDateTime(QDate(1985, 10, 26), QTime(1, 35)));
}
+void tst_QXmppStanza::testSenderKey()
+{
+ QXmppStanzaStub stanza;
+ auto e2eeMetadata = stanza.e2eeMetadata();
+ QVERIFY(e2eeMetadata.senderKey().isEmpty());
+ e2eeMetadata.setSenderKey(QByteArray::fromBase64(QByteArrayLiteral("aFABnX7Q/rbTgjBySYzrT2FsYCVYb49mbca5yB734KQ=")));
+ stanza.setE2eeMetadata(e2eeMetadata);
+ e2eeMetadata = stanza.e2eeMetadata();
+ QCOMPARE(e2eeMetadata.senderKey(), QByteArray::fromBase64(QByteArrayLiteral("aFABnX7Q/rbTgjBySYzrT2FsYCVYb49mbca5yB734KQ=")));
+}
+
+void tst_QXmppStanza::testSceTimestamp()
+{
+ QXmppStanzaStub stanza;
+ auto e2eeMetadata = stanza.e2eeMetadata();
+ QVERIFY(e2eeMetadata.sceTimestamp().isNull());
+ e2eeMetadata.setSceTimestamp(QDateTime(QDate(2022, 01, 01), QTime()));
+ stanza.setE2eeMetadata(e2eeMetadata);
+ e2eeMetadata = stanza.e2eeMetadata();
+ QCOMPARE(e2eeMetadata.sceTimestamp(), QDateTime(QDate(2022, 01, 01), QTime()));
+}
+
QTEST_MAIN(tst_QXmppStanza)
#include "tst_qxmppstanza.moc"