aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorLinus Jahn <lnj@kaidan.im>2023-03-11 00:29:02 +0100
committerLinus Jahn <lnj@kaidan.im>2023-03-11 00:29:02 +0100
commit463111576fb1476192acd2d8fe415b8482a8a696 (patch)
treee87e3bb8f8724f019954692ac22b0d6386dfa5e7 /src
parent6ea3edfd83a0bf1558d43e48eac563730276c175 (diff)
parent4897c9b6a36e961fb44d2bce04a698f979a423d5 (diff)
Merge branch '1.5'
Diffstat (limited to 'src')
-rw-r--r--src/CMakeLists.txt12
-rw-r--r--src/base/QXmppGeolocItem.cpp2
-rw-r--r--src/base/QXmppGeolocItem.h4
-rw-r--r--src/base/QXmppMixInfoItem.h4
-rw-r--r--src/base/QXmppMixItems.cpp4
-rw-r--r--src/base/QXmppMixParticipantItem.h4
-rw-r--r--src/base/QXmppOmemoElement_p.h2
-rw-r--r--src/base/QXmppPromise.h4
-rw-r--r--src/base/QXmppPubSubBaseItem.cpp (renamed from src/base/QXmppPubSubItem.cpp)56
-rw-r--r--src/base/QXmppPubSubBaseItem.h (renamed from src/base/QXmppPubSubItem.h)27
-rw-r--r--src/base/QXmppPubSubEvent.h4
-rw-r--r--src/base/QXmppPubSubIq.cpp8
-rw-r--r--src/base/QXmppPubSubIq_p.h9
-rw-r--r--src/base/QXmppSasl.cpp8
-rw-r--r--src/base/QXmppUserTuneItem.cpp2
-rw-r--r--src/base/QXmppUserTuneItem.h4
-rw-r--r--src/base/compat/QXmppPubSubIq.cpp210
-rw-r--r--src/base/compat/QXmppPubSubIq.h66
-rw-r--r--src/base/compat/QXmppPubSubItem.cpp76
-rw-r--r--src/base/compat/QXmppPubSubItem.h42
-rw-r--r--src/client/QXmppCarbonManagerV2.cpp8
-rw-r--r--src/client/QXmppDiscoveryManager.h2
-rw-r--r--src/client/QXmppEntityTimeManager.h2
-rw-r--r--src/client/QXmppFileEncryption.cpp2
-rw-r--r--src/client/QXmppFileEncryption.h8
-rw-r--r--src/client/QXmppMamManager.cpp9
-rw-r--r--src/client/QXmppPubSubManager.cpp10
-rw-r--r--src/client/QXmppPubSubManager.h14
-rw-r--r--src/client/QXmppSceEnvelope_p.h6
-rw-r--r--src/omemo/CMakeLists.txt4
-rw-r--r--src/omemo/QXmppOmemoData.cpp9
-rw-r--r--src/omemo/QXmppOmemoDeviceList_p.h2
-rw-r--r--src/omemo/QXmppOmemoItems_p.h6
-rw-r--r--src/omemo/QXmppOmemoManager.cpp12
-rw-r--r--src/omemo/QXmppOmemoManager_p.cpp166
-rw-r--r--src/omemo/QXmppOmemoManager_p.h20
36 files changed, 602 insertions, 226 deletions
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index fc463303..82e99619 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -54,7 +54,7 @@ set(INSTALL_HEADER_FILES
base/QXmppPubSubAffiliation.h
base/QXmppPubSubEvent.h
base/QXmppPubSubIq_p.h
- base/QXmppPubSubItem.h
+ base/QXmppPubSubBaseItem.h
base/QXmppPubSubMetadata.h
base/QXmppPubSubNodeConfig.h
base/QXmppPubSubPublishOptions.h
@@ -83,6 +83,8 @@ set(INSTALL_HEADER_FILES
base/QXmppUtils.h
base/QXmppVCardIq.h
base/QXmppVersionIq.h
+ base/compat/QXmppPubSubIq.h
+ base/compat/QXmppPubSubItem.h
# Client
client/QXmppArchiveManager.h
@@ -188,7 +190,7 @@ set(SOURCE_FILES
base/QXmppPubSubAffiliation.cpp
base/QXmppPubSubEvent.cpp
base/QXmppPubSubIq.cpp
- base/QXmppPubSubItem.cpp
+ base/QXmppPubSubBaseItem.cpp
base/QXmppPubSubMetadata.cpp
base/QXmppPubSubNodeConfig.cpp
base/QXmppPubSubSubscribeOptions.cpp
@@ -216,6 +218,8 @@ set(SOURCE_FILES
base/QXmppUtils.cpp
base/QXmppVCardIq.cpp
base/QXmppVersionIq.cpp
+ base/compat/QXmppPubSubIq.cpp
+ base/compat/QXmppPubSubItem.cpp
# Client
client/QXmppArchiveManager.cpp
@@ -365,8 +369,10 @@ generate_export_header(qxmpp
install(
TARGETS qxmpp
- DESTINATION "${CMAKE_INSTALL_LIBDIR}"
EXPORT QXmppTarget
+ RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
+ LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
+ ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
)
install(
diff --git a/src/base/QXmppGeolocItem.cpp b/src/base/QXmppGeolocItem.cpp
index b6bf0b85..32e08189 100644
--- a/src/base/QXmppGeolocItem.cpp
+++ b/src/base/QXmppGeolocItem.cpp
@@ -146,7 +146,7 @@ bool QXmppGeolocItem::isItem(const QDomElement &itemElement)
payload.namespaceURI() == ns_geoloc;
};
- return QXmppPubSubItem::isItem(itemElement, isPayloadValid);
+ return QXmppPubSubBaseItem::isItem(itemElement, isPayloadValid);
}
/// \cond
diff --git a/src/base/QXmppGeolocItem.h b/src/base/QXmppGeolocItem.h
index 05d42dba..58914b1b 100644
--- a/src/base/QXmppGeolocItem.h
+++ b/src/base/QXmppGeolocItem.h
@@ -5,7 +5,7 @@
#ifndef QXMPPGEOLOCITEM_H
#define QXMPPGEOLOCITEM_H
-#include "QXmppPubSubItem.h"
+#include "QXmppPubSubBaseItem.h"
#include <optional>
@@ -13,7 +13,7 @@
class QXmppGeolocItemPrivate;
-class QXMPP_EXPORT QXmppGeolocItem : public QXmppPubSubItem
+class QXMPP_EXPORT QXmppGeolocItem : public QXmppPubSubBaseItem
{
public:
QXmppGeolocItem();
diff --git a/src/base/QXmppMixInfoItem.h b/src/base/QXmppMixInfoItem.h
index 9a28decb..313c3e14 100644
--- a/src/base/QXmppMixInfoItem.h
+++ b/src/base/QXmppMixInfoItem.h
@@ -5,11 +5,11 @@
#ifndef QXMPPMIXINFOITEM_H
#define QXMPPMIXINFOITEM_H
-#include "QXmppPubSubItem.h"
+#include "QXmppPubSubBaseItem.h"
class QXmppMixInfoItemPrivate;
-class QXMPP_EXPORT QXmppMixInfoItem : public QXmppPubSubItem
+class QXMPP_EXPORT QXmppMixInfoItem : public QXmppPubSubBaseItem
{
public:
QXmppMixInfoItem();
diff --git a/src/base/QXmppMixItems.cpp b/src/base/QXmppMixItems.cpp
index e08dd3f2..a19edbb0 100644
--- a/src/base/QXmppMixItems.cpp
+++ b/src/base/QXmppMixItems.cpp
@@ -138,7 +138,7 @@ void QXmppMixInfoItem::setContactJids(QStringList contactJids)
///
bool QXmppMixInfoItem::isItem(const QDomElement &element)
{
- return QXmppPubSubItem::isItem(element, [](const QDomElement &payload) {
+ return QXmppPubSubBaseItem::isItem(element, [](const QDomElement &payload) {
// check FORM_TYPE without parsing a full QXmppDataForm
if (payload.tagName() != u'x' || payload.namespaceURI() != ns_data) {
return false;
@@ -264,7 +264,7 @@ void QXmppMixParticipantItem::serializePayload(QXmlStreamWriter *writer) const
///
bool QXmppMixParticipantItem::isItem(const QDomElement &element)
{
- return QXmppPubSubItem::isItem(element, [](const QDomElement &payload) {
+ return QXmppPubSubBaseItem::isItem(element, [](const QDomElement &payload) {
return payload.tagName() == QStringLiteral("participant") &&
payload.namespaceURI() == ns_mix;
});
diff --git a/src/base/QXmppMixParticipantItem.h b/src/base/QXmppMixParticipantItem.h
index f0f2abaa..ce179fbe 100644
--- a/src/base/QXmppMixParticipantItem.h
+++ b/src/base/QXmppMixParticipantItem.h
@@ -5,11 +5,11 @@
#ifndef QXMPPMIXPARTICIPANTITEM_H
#define QXMPPMIXPARTICIPANTITEM_H
-#include "QXmppPubSubItem.h"
+#include "QXmppPubSubBaseItem.h"
class QXmppMixParticipantItemPrivate;
-class QXMPP_EXPORT QXmppMixParticipantItem : public QXmppPubSubItem
+class QXMPP_EXPORT QXmppMixParticipantItem : public QXmppPubSubBaseItem
{
public:
QXmppMixParticipantItem();
diff --git a/src/base/QXmppOmemoElement_p.h b/src/base/QXmppOmemoElement_p.h
index 1e160479..cd95ea00 100644
--- a/src/base/QXmppOmemoElement_p.h
+++ b/src/base/QXmppOmemoElement_p.h
@@ -7,13 +7,13 @@
#define QXMPPOMEMOELEMENT_H
#include "QXmppGlobal.h"
+#include "QXmppOmemoEnvelope_p.h"
#include <optional>
#include <QMultiMap>
class QDomElement;
-class QXmppOmemoEnvelope;
class QXmlStreamWriter;
class QXMPP_EXPORT QXmppOmemoElement
diff --git a/src/base/QXmppPromise.h b/src/base/QXmppPromise.h
index 4900dae1..6408ad0c 100644
--- a/src/base/QXmppPromise.h
+++ b/src/base/QXmppPromise.h
@@ -45,7 +45,7 @@ public:
#ifdef QXMPP_DOC
void reportFinished(T &&value)
#else
- template<typename U, std::enable_if_t<!std::is_void_v<T> && std::is_same_v<T, U>> * = nullptr>
+ template<typename U, typename TT = T, std::enable_if_t<!std::is_void_v<TT> && std::is_same_v<TT, U>> * = nullptr>
void finish(U &&value)
#endif
{
@@ -61,7 +61,7 @@ public:
}
/// \cond
- template<typename U, std::enable_if_t<!std::is_void_v<T> && std::is_constructible_v<T, U> && !std::is_same_v<T, U>> * = nullptr>
+ template<typename U, typename TT = T, std::enable_if_t<!std::is_void_v<TT> && std::is_constructible_v<TT, U> && !std::is_same_v<TT, U>> * = nullptr>
void finish(U &&value)
{
Q_ASSERT(!d.isFinished());
diff --git a/src/base/QXmppPubSubItem.cpp b/src/base/QXmppPubSubBaseItem.cpp
index f87c5d6e..43b1aa88 100644
--- a/src/base/QXmppPubSubItem.cpp
+++ b/src/base/QXmppPubSubBaseItem.cpp
@@ -3,47 +3,47 @@
//
// SPDX-License-Identifier: LGPL-2.1-or-later
-#include "QXmppPubSubItem.h"
+#include "QXmppPubSubBaseItem.h"
#include "QXmppElement.h"
#include "QXmppUtils.h"
#include <QDomElement>
-class QXmppPubSubItemPrivate : public QSharedData
+class QXmppPubSubBaseItemPrivate : public QSharedData
{
public:
- QXmppPubSubItemPrivate(const QString &id, const QString &publisher);
+ QXmppPubSubBaseItemPrivate(const QString &id, const QString &publisher);
QString id;
QString publisher;
};
-QXmppPubSubItemPrivate::QXmppPubSubItemPrivate(const QString &id, const QString &publisher)
+QXmppPubSubBaseItemPrivate::QXmppPubSubBaseItemPrivate(const QString &id, const QString &publisher)
: id(id), publisher(publisher)
{
}
///
-/// \class QXmppPubSubItem
+/// \class QXmppPubSubBaseItem
///
-/// The QXmppPubSubItem class represents a publish-subscribe item as defined by
+/// The QXmppPubSubBaseItem class represents a publish-subscribe item as defined by
/// \xep{0060, Publish-Subscribe}.
///
/// To access the payload of an item, you need to create a derived class of this
-/// and override QXmppPubSubItem::parsePayload() and
-/// QXmppPubSubItem::serializePayload().
+/// and override QXmppPubSubBaseItem::parsePayload() and
+/// QXmppPubSubBaseItem::serializePayload().
///
-/// It is also required that you override QXmppPubSubItem::isItem() and also
+/// It is also required that you override QXmppPubSubBaseItem::isItem() and also
/// check for the correct payload of the PubSub item. This can be easily done by
/// using the protected overload of isItem() with an function that checks the
/// tag name and namespace of the payload. The function is only called if a
/// payload exists.
///
/// In short, you need to reimplement these methods:
-/// * QXmppPubSubItem::parsePayload()
-/// * QXmppPubSubItem::serializePayload()
-/// * QXmppPubSubItem::isItem()
+/// * QXmppPubSubBaseItem::parsePayload()
+/// * QXmppPubSubBaseItem::serializePayload()
+/// * QXmppPubSubBaseItem::isItem()
///
/// \since QXmpp 1.5
///
@@ -54,25 +54,25 @@ QXmppPubSubItemPrivate::QXmppPubSubItemPrivate(const QString &id, const QString
/// \param id
/// \param publisher
///
-QXmppPubSubItem::QXmppPubSubItem(const QString &id, const QString &publisher)
- : d(new QXmppPubSubItemPrivate(id, publisher))
+QXmppPubSubBaseItem::QXmppPubSubBaseItem(const QString &id, const QString &publisher)
+ : d(new QXmppPubSubBaseItemPrivate(id, publisher))
{
}
/// Default copy-constructor
-QXmppPubSubItem::QXmppPubSubItem(const QXmppPubSubItem &iq) = default;
+QXmppPubSubBaseItem::QXmppPubSubBaseItem(const QXmppPubSubBaseItem &iq) = default;
/// Default move-constructor
-QXmppPubSubItem::QXmppPubSubItem(QXmppPubSubItem &&) = default;
-QXmppPubSubItem::~QXmppPubSubItem() = default;
+QXmppPubSubBaseItem::QXmppPubSubBaseItem(QXmppPubSubBaseItem &&) = default;
+QXmppPubSubBaseItem::~QXmppPubSubBaseItem() = default;
/// Default assignment operator
-QXmppPubSubItem &QXmppPubSubItem::operator=(const QXmppPubSubItem &iq) = default;
+QXmppPubSubBaseItem &QXmppPubSubBaseItem::operator=(const QXmppPubSubBaseItem &iq) = default;
/// Default move-assignment operator
-QXmppPubSubItem &QXmppPubSubItem::operator=(QXmppPubSubItem &&iq) = default;
+QXmppPubSubBaseItem &QXmppPubSubBaseItem::operator=(QXmppPubSubBaseItem &&iq) = default;
///
/// Returns the ID of the PubSub item.
///
-QString QXmppPubSubItem::id() const
+QString QXmppPubSubBaseItem::id() const
{
return d->id;
}
@@ -82,7 +82,7 @@ QString QXmppPubSubItem::id() const
///
/// \param id
///
-void QXmppPubSubItem::setId(const QString &id)
+void QXmppPubSubBaseItem::setId(const QString &id)
{
d->id = id;
}
@@ -90,7 +90,7 @@ void QXmppPubSubItem::setId(const QString &id)
///
/// Returns the JID of the publisher of the item.
///
-QString QXmppPubSubItem::publisher() const
+QString QXmppPubSubBaseItem::publisher() const
{
return d->publisher;
}
@@ -98,13 +98,13 @@ QString QXmppPubSubItem::publisher() const
///
/// Sets the JID of the publisher of the item.
///
-void QXmppPubSubItem::setPublisher(const QString &publisher)
+void QXmppPubSubBaseItem::setPublisher(const QString &publisher)
{
d->publisher = publisher;
}
/// \cond
-void QXmppPubSubItem::parse(const QDomElement &element)
+void QXmppPubSubBaseItem::parse(const QDomElement &element)
{
d->id = element.attribute(QStringLiteral("id"));
d->publisher = element.attribute(QStringLiteral("publisher"));
@@ -112,7 +112,7 @@ void QXmppPubSubItem::parse(const QDomElement &element)
parsePayload(element.firstChildElement());
}
-void QXmppPubSubItem::toXml(QXmlStreamWriter *writer) const
+void QXmppPubSubBaseItem::toXml(QXmlStreamWriter *writer) const
{
writer->writeStartElement(QStringLiteral("item"));
helperToXmlAddAttribute(writer, QStringLiteral("id"), d->id);
@@ -127,7 +127,7 @@ void QXmppPubSubItem::toXml(QXmlStreamWriter *writer) const
///
/// Returns true, if the element is possibly a PubSub item.
///
-bool QXmppPubSubItem::isItem(const QDomElement &element)
+bool QXmppPubSubBaseItem::isItem(const QDomElement &element)
{
return element.tagName() == QStringLiteral("item");
}
@@ -137,7 +137,7 @@ bool QXmppPubSubItem::isItem(const QDomElement &element)
///
/// This method needs to be overriden to perform the payload-specific parsing.
///
-void QXmppPubSubItem::parsePayload(const QDomElement &)
+void QXmppPubSubBaseItem::parsePayload(const QDomElement &)
{
}
@@ -147,6 +147,6 @@ void QXmppPubSubItem::parsePayload(const QDomElement &)
/// This method needs to be overriden to perform the payload-specific
/// serialization.
///
-void QXmppPubSubItem::serializePayload(QXmlStreamWriter *) const
+void QXmppPubSubBaseItem::serializePayload(QXmlStreamWriter *) const
{
}
diff --git a/src/base/QXmppPubSubItem.h b/src/base/QXmppPubSubBaseItem.h
index e585de9d..20702662 100644
--- a/src/base/QXmppPubSubItem.h
+++ b/src/base/QXmppPubSubBaseItem.h
@@ -3,8 +3,7 @@
//
// SPDX-License-Identifier: LGPL-2.1-or-later
-#ifndef QXMPPPUBSUBITEM_H
-#define QXMPPPUBSUBITEM_H
+#pragma once
#include "QXmppGlobal.h"
@@ -13,18 +12,18 @@
#include <QSharedDataPointer>
class QXmlStreamWriter;
-class QXmppPubSubItemPrivate;
+class QXmppPubSubBaseItemPrivate;
-class QXMPP_EXPORT QXmppPubSubItem
+class QXMPP_EXPORT QXmppPubSubBaseItem
{
public:
- QXmppPubSubItem(const QString &id = {}, const QString &publisher = {});
- QXmppPubSubItem(const QXmppPubSubItem &);
- QXmppPubSubItem(QXmppPubSubItem &&);
- virtual ~QXmppPubSubItem();
+ QXmppPubSubBaseItem(const QString &id = {}, const QString &publisher = {});
+ QXmppPubSubBaseItem(const QXmppPubSubBaseItem &);
+ QXmppPubSubBaseItem(QXmppPubSubBaseItem &&);
+ virtual ~QXmppPubSubBaseItem();
- QXmppPubSubItem &operator=(const QXmppPubSubItem &);
- QXmppPubSubItem &operator=(QXmppPubSubItem &&);
+ QXmppPubSubBaseItem &operator=(const QXmppPubSubBaseItem &);
+ QXmppPubSubBaseItem &operator=(QXmppPubSubBaseItem &&);
QString id() const;
void setId(const QString &id);
@@ -47,7 +46,7 @@ protected:
static bool isItem(const QDomElement &element, PayloadChecker isPayloadValid);
private:
- QSharedDataPointer<QXmppPubSubItemPrivate> d;
+ QSharedDataPointer<QXmppPubSubBaseItemPrivate> d;
};
///
@@ -70,7 +69,7 @@ private:
/// \endcode
///
template<typename PayloadChecker>
-bool QXmppPubSubItem::isItem(const QDomElement &element, PayloadChecker isPayloadValid)
+bool QXmppPubSubBaseItem::isItem(const QDomElement &element, PayloadChecker isPayloadValid)
{
if (!isItem(element)) {
return false;
@@ -85,6 +84,4 @@ bool QXmppPubSubItem::isItem(const QDomElement &element, PayloadChecker isPayloa
return true;
}
-Q_DECLARE_METATYPE(QXmppPubSubItem)
-
-#endif // QXMPPPUBSUBITEM_H
+Q_DECLARE_METATYPE(QXmppPubSubBaseItem)
diff --git a/src/base/QXmppPubSubEvent.h b/src/base/QXmppPubSubEvent.h
index 0faf62b6..3625c8aa 100644
--- a/src/base/QXmppPubSubEvent.h
+++ b/src/base/QXmppPubSubEvent.h
@@ -15,7 +15,7 @@
class QXmppDataForm;
class QXmppPubSubEventPrivate;
-class QXmppPubSubItem;
+class QXmppPubSubBaseItem;
class QXMPP_EXPORT QXmppPubSubEventBase : public QXmppMessage
{
@@ -73,7 +73,7 @@ private:
QSharedDataPointer<QXmppPubSubEventPrivate> d;
};
-template<typename T = QXmppPubSubItem>
+template<typename T = QXmppPubSubBaseItem>
class QXmppPubSubEvent : public QXmppPubSubEventBase
{
public:
diff --git a/src/base/QXmppPubSubIq.cpp b/src/base/QXmppPubSubIq.cpp
index d45df2d3..27da0e4b 100644
--- a/src/base/QXmppPubSubIq.cpp
+++ b/src/base/QXmppPubSubIq.cpp
@@ -81,7 +81,9 @@ static const QStringList PUBSUB_QUERIES = {
QStringLiteral("unsubscribe"),
};
-class QXmppPubSubIqPrivate : public QSharedData
+namespace QXmpp::Private {
+
+class PubSubIqPrivate : public QSharedData
{
public:
PubSubIqBase::QueryType queryType = PubSubIqBase::Items;
@@ -95,11 +97,13 @@ public:
std::optional<QXmppResultSetReply> itemsContinuation;
};
+}
+
///
/// Constructs a PubSub IQ.
///
PubSubIqBase::PubSubIqBase()
- : d(new QXmppPubSubIqPrivate)
+ : d(new PubSubIqPrivate)
{
}
diff --git a/src/base/QXmppPubSubIq_p.h b/src/base/QXmppPubSubIq_p.h
index eb5ed43f..c8828579 100644
--- a/src/base/QXmppPubSubIq_p.h
+++ b/src/base/QXmppPubSubIq_p.h
@@ -14,14 +14,15 @@
#include <QSharedDataPointer>
class QXmppDataForm;
-class QXmppPubSubIqPrivate;
-class QXmppPubSubItem;
+class QXmppPubSubBaseItem;
class QXmppPubSubSubscription;
class QXmppPubSubAffiliation;
class QXmppResultSetReply;
namespace QXmpp::Private {
+class PubSubIqPrivate;
+
class QXMPP_EXPORT PubSubIqBase : public QXmppIq
{
public:
@@ -100,10 +101,10 @@ private:
static std::optional<QueryType> queryTypeFromDomElement(const QDomElement &element);
static bool queryTypeIsOwnerIq(QueryType type);
- QSharedDataPointer<QXmppPubSubIqPrivate> d;
+ QSharedDataPointer<PubSubIqPrivate> d;
};
-template<typename T = QXmppPubSubItem>
+template<typename T = QXmppPubSubBaseItem>
class PubSubIq : public PubSubIqBase
{
public:
diff --git a/src/base/QXmppSasl.cpp b/src/base/QXmppSasl.cpp
index d566dc5c..184732a3 100644
--- a/src/base/QXmppSasl.cpp
+++ b/src/base/QXmppSasl.cpp
@@ -876,8 +876,12 @@ QMap<QByteArray, QByteArray> QXmppSaslDigestMd5::parseMessage(const QByteArray &
const QByteArray key = ba.mid(startIndex, pos - startIndex).trimmed();
pos++;
- // check whether string is quoted
- if (ba.at(pos) == '"') {
+ if (pos == ba.size()) {
+ // end of the input
+ map.insert(key, QByteArray());
+ startIndex = pos;
+ } else if (ba.at(pos) == '"') {
+ // check whether string is quoted
// skip opening quote
pos++;
int endPos = ba.indexOf('"', pos);
diff --git a/src/base/QXmppUserTuneItem.cpp b/src/base/QXmppUserTuneItem.cpp
index 6d8fb8bf..55d30333 100644
--- a/src/base/QXmppUserTuneItem.cpp
+++ b/src/base/QXmppUserTuneItem.cpp
@@ -224,7 +224,7 @@ bool QXmppTuneItem::isItem(const QDomElement &itemElement)
payload.namespaceURI() == ns_tune;
};
- return QXmppPubSubItem::isItem(itemElement, isPayloadValid);
+ return QXmppPubSubBaseItem::isItem(itemElement, isPayloadValid);
}
/// \cond
diff --git a/src/base/QXmppUserTuneItem.h b/src/base/QXmppUserTuneItem.h
index 03bafb1e..c4b1f0a8 100644
--- a/src/base/QXmppUserTuneItem.h
+++ b/src/base/QXmppUserTuneItem.h
@@ -5,7 +5,7 @@
#ifndef QXMPPUSERTUNEITEM_H
#define QXMPPUSERTUNEITEM_H
-#include "QXmppPubSubItem.h"
+#include "QXmppPubSubBaseItem.h"
#include <chrono>
#include <optional>
@@ -16,7 +16,7 @@
class QXmppTuneItemPrivate;
class QUrl;
-class QXMPP_EXPORT QXmppTuneItem : public QXmppPubSubItem
+class QXMPP_EXPORT QXmppTuneItem : public QXmppPubSubBaseItem
{
public:
QXmppTuneItem();
diff --git a/src/base/compat/QXmppPubSubIq.cpp b/src/base/compat/QXmppPubSubIq.cpp
new file mode 100644
index 00000000..9df2fdf1
--- /dev/null
+++ b/src/base/compat/QXmppPubSubIq.cpp
@@ -0,0 +1,210 @@
+// SPDX-FileCopyrightText: 2010 Jeremy Lainé <jeremy.laine@m4x.org>
+//
+// SPDX-License-Identifier: LGPL-2.1-or-later
+
+#include "QXmppPubSubIq.h"
+
+#include "QXmppConstants_p.h"
+#include "QXmppUtils.h"
+
+#include <QDomElement>
+#include <QSharedData>
+
+/// \cond
+QT_WARNING_PUSH
+QT_WARNING_DISABLE_DEPRECATED
+
+static const QStringList PUBSUB_QUERIES = {
+ QStringLiteral("affiliations"),
+ QStringLiteral("default"),
+ QStringLiteral("items"),
+ QStringLiteral("publish"),
+ QStringLiteral("retract"),
+ QStringLiteral("subscribe"),
+ QStringLiteral("subscription"),
+ QStringLiteral("subscriptions"),
+ QStringLiteral("unsubscribe"),
+};
+
+class QXmppPubSubIqPrivate : public QSharedData
+{
+public:
+ QXmppPubSubIqPrivate();
+
+ QXmppPubSubIq::QueryType queryType;
+ QString queryJid;
+ QString queryNode;
+ QList<QXmppPubSubItem> items;
+ QString subscriptionId;
+ QString subscriptionType;
+};
+
+QXmppPubSubIqPrivate::QXmppPubSubIqPrivate()
+ : queryType(QXmppPubSubIq::ItemsQuery)
+{
+}
+
+QXmppPubSubIq::QXmppPubSubIq()
+ : d(new QXmppPubSubIqPrivate)
+{
+}
+
+QXmppPubSubIq::QXmppPubSubIq(const QXmppPubSubIq &iq) = default;
+
+QXmppPubSubIq::~QXmppPubSubIq() = default;
+
+QXmppPubSubIq &QXmppPubSubIq::operator=(const QXmppPubSubIq &iq) = default;
+
+/// Returns the PubSub queryType for this IQ.
+
+QXmppPubSubIq::QueryType QXmppPubSubIq::queryType() const
+{
+ return d->queryType;
+}
+
+/// Sets the PubSub queryType for this IQ.
+///
+/// \param queryType
+
+void QXmppPubSubIq::setQueryType(QXmppPubSubIq::QueryType queryType)
+{
+ d->queryType = queryType;
+}
+
+/// Returns the JID being queried.
+
+QString QXmppPubSubIq::queryJid() const
+{
+ return d->queryJid;
+}
+
+/// Sets the JID being queried.
+///
+/// \param queryJid
+
+void QXmppPubSubIq::setQueryJid(const QString &queryJid)
+{
+ d->queryJid = queryJid;
+}
+
+/// Returns the node being queried.
+
+QString QXmppPubSubIq::queryNode() const
+{
+ return d->queryNode;
+}
+
+/// Sets the node being queried.
+///
+/// \param queryNode
+
+void QXmppPubSubIq::setQueryNode(const QString &queryNode)
+{
+ d->queryNode = queryNode;
+}
+
+/// Returns the subscription ID.
+
+QString QXmppPubSubIq::subscriptionId() const
+{
+ return d->subscriptionId;
+}
+
+/// Sets the subscription ID.
+///
+/// \param subscriptionId
+
+void QXmppPubSubIq::setSubscriptionId(const QString &subscriptionId)
+{
+ d->subscriptionId = subscriptionId;
+}
+
+/// Returns the IQ's items.
+
+QList<QXmppPubSubItem> QXmppPubSubIq::items() const
+{
+ return d->items;
+}
+
+/// Sets the IQ's items.
+///
+/// \param items
+
+void QXmppPubSubIq::setItems(const QList<QXmppPubSubItem> &items)
+{
+ d->items = items;
+}
+
+bool QXmppPubSubIq::isPubSubIq(const QDomElement &element)
+{
+ return element.firstChildElement(QStringLiteral("pubsub")).namespaceURI() == ns_pubsub;
+}
+
+void QXmppPubSubIq::parseElementFromChild(const QDomElement &element)
+{
+ const QDomElement pubSubElement = element.firstChildElement(QStringLiteral("pubsub"));
+
+ const QDomElement queryElement = pubSubElement.firstChildElement();
+
+ // determine query type
+ const QString tagName = queryElement.tagName();
+ int queryType = PUBSUB_QUERIES.indexOf(queryElement.tagName());
+ if (queryType > -1)
+ d->queryType = QueryType(queryType);
+
+ d->queryJid = queryElement.attribute(QStringLiteral("jid"));
+ d->queryNode = queryElement.attribute(QStringLiteral("node"));
+
+ // parse contents
+ QDomElement childElement;
+ switch (d->queryType) {
+ case QXmppPubSubIq::ItemsQuery:
+ case QXmppPubSubIq::PublishQuery:
+ case QXmppPubSubIq::RetractQuery:
+ childElement = queryElement.firstChildElement(QStringLiteral("item"));
+ while (!childElement.isNull()) {
+ QXmppPubSubItem item;
+ item.parse(childElement);
+ d->items << item;
+ childElement = childElement.nextSiblingElement(QStringLiteral("item"));
+ }
+ break;
+ case QXmppPubSubIq::SubscriptionQuery:
+ d->subscriptionId = queryElement.attribute(QStringLiteral("subid"));
+ d->subscriptionType = queryElement.attribute(QStringLiteral("subscription"));
+ break;
+ default:
+ break;
+ }
+}
+
+void QXmppPubSubIq::toXmlElementFromChild(QXmlStreamWriter *writer) const
+{
+ writer->writeStartElement(QStringLiteral("pubsub"));
+ writer->writeDefaultNamespace(ns_pubsub);
+
+ // write query type
+ writer->writeStartElement(PUBSUB_QUERIES.at(d->queryType));
+ helperToXmlAddAttribute(writer, QStringLiteral("jid"), d->queryJid);
+ helperToXmlAddAttribute(writer, QStringLiteral("node"), d->queryNode);
+
+ // write contents
+ switch (d->queryType) {
+ case QXmppPubSubIq::ItemsQuery:
+ case QXmppPubSubIq::PublishQuery:
+ case QXmppPubSubIq::RetractQuery:
+ for (const auto &item : d->items)
+ item.toXml(writer);
+ break;
+ case QXmppPubSubIq::SubscriptionQuery:
+ helperToXmlAddAttribute(writer, QStringLiteral("subid"), d->subscriptionId);
+ helperToXmlAddAttribute(writer, QStringLiteral("subscription"), d->subscriptionType);
+ break;
+ default:
+ break;
+ }
+ writer->writeEndElement();
+ writer->writeEndElement();
+}
+QT_WARNING_POP
+/// \endcond
diff --git a/src/base/compat/QXmppPubSubIq.h b/src/base/compat/QXmppPubSubIq.h
new file mode 100644
index 00000000..057efa98
--- /dev/null
+++ b/src/base/compat/QXmppPubSubIq.h
@@ -0,0 +1,66 @@
+// SPDX-FileCopyrightText: 2010 Jeremy Lainé <jeremy.laine@m4x.org>
+//
+// SPDX-License-Identifier: LGPL-2.1-or-later
+
+#ifndef QXMPPPUBSUBIQ_H
+#define QXMPPPUBSUBIQ_H
+
+#include "QXmppIq.h"
+
+#include <QSharedDataPointer>
+
+#if QXMPP_DEPRECATED_SINCE(1, 2)
+#include "QXmppPubSubItem.h"
+#endif
+
+class QXmppPubSubIqPrivate;
+
+#if QXMPP_DEPRECATED_SINCE(1, 5)
+class QXMPP_EXPORT QXmppPubSubIq : public QXmppIq
+{
+public:
+ enum [[deprecated]] QueryType {
+ AffiliationsQuery,
+ DefaultQuery,
+ ItemsQuery,
+ PublishQuery,
+ RetractQuery,
+ SubscribeQuery,
+ SubscriptionQuery,
+ SubscriptionsQuery,
+ UnsubscribeQuery
+ };
+
+ [[deprecated]] QXmppPubSubIq();
+ QXmppPubSubIq(const QXmppPubSubIq &iq);
+ ~QXmppPubSubIq();
+
+ QXmppPubSubIq &operator=(const QXmppPubSubIq &iq);
+
+ [[deprecated]] QXmppPubSubIq::QueryType queryType() const;
+ [[deprecated]] void setQueryType(QXmppPubSubIq::QueryType queryType);
+
+ [[deprecated]] QString queryJid() const;
+ [[deprecated]] void setQueryJid(const QString &jid);
+
+ [[deprecated]] QString queryNode() const;
+ [[deprecated]] void setQueryNode(const QString &node);
+
+ [[deprecated]] QList<QXmppPubSubItem> items() const;
+ [[deprecated]] void setItems(const QList<QXmppPubSubItem> &items);
+
+ [[deprecated]] QString subscriptionId() const;
+ [[deprecated]] void setSubscriptionId(const QString &id);
+
+ [[deprecated]] static bool isPubSubIq(const QDomElement &element);
+
+protected:
+ void parseElementFromChild(const QDomElement &) override;
+ void toXmlElementFromChild(QXmlStreamWriter *writer) const override;
+
+private:
+ QSharedDataPointer<QXmppPubSubIqPrivate> d;
+};
+#endif
+
+#endif // QXMPPPUBSUBIQ_H
diff --git a/src/base/compat/QXmppPubSubItem.cpp b/src/base/compat/QXmppPubSubItem.cpp
new file mode 100644
index 00000000..cfd2724e
--- /dev/null
+++ b/src/base/compat/QXmppPubSubItem.cpp
@@ -0,0 +1,76 @@
+// SPDX-FileCopyrightText: 2010 Jeremy Lainé <jeremy.laine@m4x.org>
+//
+// SPDX-License-Identifier: LGPL-2.1-or-later
+
+#include "QXmppPubSubItem.h"
+
+#include "QXmppElement.h"
+#include "QXmppUtils.h"
+
+#include <QDomElement>
+
+/// \cond
+class QXmppPubSubItemPrivate : public QSharedData
+{
+public:
+ QString id;
+ QXmppElement contents;
+};
+
+QXmppPubSubItem::QXmppPubSubItem()
+ : d(new QXmppPubSubItemPrivate)
+{
+}
+
+QXmppPubSubItem::QXmppPubSubItem(const QXmppPubSubItem &iq) = default;
+
+QXmppPubSubItem::~QXmppPubSubItem() = default;
+
+QXmppPubSubItem &QXmppPubSubItem::operator=(const QXmppPubSubItem &iq) = default;
+
+/// Returns the ID of the PubSub item.
+
+QString QXmppPubSubItem::id() const
+{
+ return d->id;
+}
+
+/// Sets the ID of the PubSub item.
+///
+/// \param id
+
+void QXmppPubSubItem::setId(const QString &id)
+{
+ d->id = id;
+}
+
+/// Returns the contents of the PubSub item.
+
+QXmppElement QXmppPubSubItem::contents() const
+{
+ return d->contents;
+}
+
+/// Sets the contents of the PubSub item.
+///
+/// \param contents
+
+void QXmppPubSubItem::setContents(const QXmppElement &contents)
+{
+ d->contents = contents;
+}
+
+void QXmppPubSubItem::parse(const QDomElement &element)
+{
+ d->id = element.attribute(QStringLiteral("id"));
+ d->contents = QXmppElement(element.firstChildElement());
+}
+
+void QXmppPubSubItem::toXml(QXmlStreamWriter *writer) const
+{
+ writer->writeStartElement(QStringLiteral("item"));
+ helperToXmlAddAttribute(writer, QStringLiteral("id"), d->id);
+ d->contents.toXml(writer);
+ writer->writeEndElement();
+}
+/// \endcond
diff --git a/src/base/compat/QXmppPubSubItem.h b/src/base/compat/QXmppPubSubItem.h
new file mode 100644
index 00000000..1d8dc4d3
--- /dev/null
+++ b/src/base/compat/QXmppPubSubItem.h
@@ -0,0 +1,42 @@
+// SPDX-FileCopyrightText: 2010 Jeremy Lainé <jeremy.laine@m4x.org>
+//
+// SPDX-License-Identifier: LGPL-2.1-or-later
+
+#ifndef QXMPPPUBSUBITEM_H
+#define QXMPPPUBSUBITEM_H
+
+#include "QXmppGlobal.h"
+
+#include <QSharedDataPointer>
+
+class QDomElement;
+class QXmlStreamWriter;
+
+class QXmppElement;
+class QXmppPubSubItemPrivate;
+
+#if QXMPP_DEPRECATED_SINCE(1, 5)
+class QXMPP_EXPORT QXmppPubSubItem
+{
+public:
+ [[deprecated]] QXmppPubSubItem();
+ QXmppPubSubItem(const QXmppPubSubItem &iq);
+ ~QXmppPubSubItem();
+
+ QXmppPubSubItem &operator=(const QXmppPubSubItem &iq);
+
+ [[deprecated]] QString id() const;
+ [[deprecated]] void setId(const QString &id);
+
+ [[deprecated]] QXmppElement contents() const;
+ [[deprecated]] void setContents(const QXmppElement &contents);
+
+ [[deprecated]] void parse(const QDomElement &element);
+ [[deprecated]] void toXml(QXmlStreamWriter *writer) const;
+
+private:
+ QSharedDataPointer<QXmppPubSubItemPrivate> d;
+};
+#endif
+
+#endif // QXMPPPUBSUBITEM_H
diff --git a/src/client/QXmppCarbonManagerV2.cpp b/src/client/QXmppCarbonManagerV2.cpp
index 0f48370e..7959cab3 100644
--- a/src/client/QXmppCarbonManagerV2.cpp
+++ b/src/client/QXmppCarbonManagerV2.cpp
@@ -18,9 +18,10 @@ using namespace QXmpp::Private;
class CarbonEnableIq : public QXmppIq
{
public:
- CarbonEnableIq()
+ CarbonEnableIq(const QString &jid)
: QXmppIq()
{
+ setTo(jid);
setType(QXmppIq::Set);
}
@@ -30,7 +31,8 @@ public:
}
void toXmlElementFromChild(QXmlStreamWriter *writer) const override
{
- writer->writeStartElement(ns_carbons, "enable");
+ writer->writeStartElement(QStringLiteral("enable"));
+ writer->writeDefaultNamespace(ns_carbons);
writer->writeEndElement();
}
};
@@ -163,7 +165,7 @@ void QXmppCarbonManagerV2::enableCarbons()
return;
}
- client()->sendIq(CarbonEnableIq()).then(this, [this](QXmppClient::IqResult domResult) {
+ client()->sendIq(CarbonEnableIq(client()->configuration().jidBare())).then(this, [this](QXmppClient::IqResult domResult) {
if (auto err = parseIq(std::move(domResult))) {
warning("Could not enable message carbons: " % err->description);
} else {
diff --git a/src/client/QXmppDiscoveryManager.h b/src/client/QXmppDiscoveryManager.h
index 10744a0d..d45e63a4 100644
--- a/src/client/QXmppDiscoveryManager.h
+++ b/src/client/QXmppDiscoveryManager.h
@@ -15,7 +15,7 @@ class QXmppTask;
class QXmppDataForm;
class QXmppDiscoveryIq;
class QXmppDiscoveryManagerPrivate;
-class QXmppError;
+struct QXmppError;
/// \brief The QXmppDiscoveryManager class makes it possible to discover information
/// about other entities as defined by \xep{0030}: Service Discovery.
diff --git a/src/client/QXmppEntityTimeManager.h b/src/client/QXmppEntityTimeManager.h
index 3b090feb..87219122 100644
--- a/src/client/QXmppEntityTimeManager.h
+++ b/src/client/QXmppEntityTimeManager.h
@@ -13,7 +13,7 @@
template<class T>
class QXmppTask;
class QXmppEntityTimeIq;
-class QXmppError;
+struct QXmppError;
///
/// \brief The QXmppEntityTimeManager class provided the functionality to get
diff --git a/src/client/QXmppFileEncryption.cpp b/src/client/QXmppFileEncryption.cpp
index ba78821e..e767769a 100644
--- a/src/client/QXmppFileEncryption.cpp
+++ b/src/client/QXmppFileEncryption.cpp
@@ -7,6 +7,8 @@
#include <QByteArray>
#include <QtCrypto>
+#undef min
+
using namespace QCA;
constexpr std::size_t AES128_BLOCK_SIZE = 128 / 8;
diff --git a/src/client/QXmppFileEncryption.h b/src/client/QXmppFileEncryption.h
index 5bd52c7e..e50bf83c 100644
--- a/src/client/QXmppFileEncryption.h
+++ b/src/client/QXmppFileEncryption.h
@@ -23,9 +23,9 @@ enum Direction {
Decode,
};
-QByteArray process(const QByteArray &data, Cipher cipherConfig, Direction direction, const QByteArray &key, const QByteArray &iv);
-QByteArray generateKey(Cipher cipher);
-QByteArray generateInitializationVector(Cipher);
+QXMPP_EXPORT QByteArray process(const QByteArray &data, Cipher cipherConfig, Direction direction, const QByteArray &key, const QByteArray &iv);
+QXMPP_EXPORT QByteArray generateKey(Cipher cipher);
+QXMPP_EXPORT QByteArray generateInitializationVector(Cipher);
// export for tests
class QXMPP_EXPORT EncryptionDevice : public QIODevice
@@ -50,7 +50,7 @@ private:
std::unique_ptr<QCA::Cipher> m_cipher;
};
-class DecryptionDevice : public QIODevice
+class QXMPP_EXPORT DecryptionDevice : public QIODevice
{
public:
DecryptionDevice(std::unique_ptr<QIODevice> output, Cipher config, const QByteArray &key, const QByteArray &iv);
diff --git a/src/client/QXmppMamManager.cpp b/src/client/QXmppMamManager.cpp
index f173aa01..c39a3411 100644
--- a/src/client/QXmppMamManager.cpp
+++ b/src/client/QXmppMamManager.cpp
@@ -264,11 +264,14 @@ QXmppTask<QXmppMamManager::RetrieveResult> QXmppMamManager::retrieveMessages(con
if (auto *e2eeExt = client()->encryptionExtension()) {
auto &messages = itr->second.messages;
auto running = std::make_shared<uint>(0);
+ // handle case when no message is encrypted
+ auto hasEncryptedMessages = false;
for (auto i = 0; i < messages.size(); i++) {
if (!e2eeExt->isEncrypted(messages.at(i))) {
continue;
}
+ hasEncryptedMessages = true;
auto message = messages.at(i);
(*running)++;
@@ -290,6 +293,12 @@ QXmppTask<QXmppMamManager::RetrieveResult> QXmppMamManager::retrieveMessages(con
}
});
}
+
+ if (!hasEncryptedMessages) {
+ // finish here, no decryptMessage callback will do it
+ itr->second.finish();
+ d->ongoingRequests.erase(itr);
+ }
} else {
itr->second.finish();
d->ongoingRequests.erase(itr);
diff --git a/src/client/QXmppPubSubManager.cpp b/src/client/QXmppPubSubManager.cpp
index 18ad9d7a..de7a9db0 100644
--- a/src/client/QXmppPubSubManager.cpp
+++ b/src/client/QXmppPubSubManager.cpp
@@ -10,7 +10,7 @@
#include "QXmppConstants_p.h"
#include "QXmppPubSubAffiliation.h"
#include "QXmppPubSubEventHandler.h"
-#include "QXmppPubSubItem.h"
+#include "QXmppPubSubBaseItem.h"
#include "QXmppPubSubSubscribeOptions.h"
#include "QXmppPubSubSubscription.h"
#include "QXmppStanza.h"
@@ -435,7 +435,7 @@ auto QXmppPubSubManager::retractItem(const QString &jid, const QString &nodeName
request.setType(QXmppIq::Set);
request.setQueryType(PubSubIq<>::Retract);
request.setQueryNode(nodeName);
- request.setItems({ QXmppPubSubItem(itemId) });
+ request.setItems({ QXmppPubSubBaseItem(itemId) });
request.setTo(jid);
return client()->sendGenericIq(std::move(request));
@@ -1006,10 +1006,10 @@ PubSubIq<> QXmppPubSubManager::requestItemsIq(const QString &jid, const QString
request.setQueryNode(nodeName);
if (!itemIds.isEmpty()) {
- QVector<QXmppPubSubItem> items;
+ QVector<QXmppPubSubBaseItem> items;
items.reserve(itemIds.size());
for (const auto &id : itemIds) {
- items << QXmppPubSubItem(id);
+ items << QXmppPubSubBaseItem(id);
}
request.setItems(items);
}
@@ -1038,7 +1038,7 @@ auto QXmppPubSubManager::publishItems(PubSubIqBase &&request) -> QXmppTask<Publi
return chainIq(client()->sendIq(std::move(request)), this,
[](const PubSubIq<> &iq) -> PublishItemsResult {
- const auto itemToId = [](const QXmppPubSubItem &item) {
+ const auto itemToId = [](const QXmppPubSubBaseItem &item) {
return item.id();
};
diff --git a/src/client/QXmppPubSubManager.h b/src/client/QXmppPubSubManager.h
index 73a5b4d4..154f585d 100644
--- a/src/client/QXmppPubSubManager.h
+++ b/src/client/QXmppPubSubManager.h
@@ -79,13 +79,13 @@ public:
QXmppTask<InstantNodeResult> createInstantNode(const QString &jid, const QXmppPubSubNodeConfig &config);
QXmppTask<Result> deleteNode(const QString &jid, const QString &nodeName);
QXmppTask<ItemIdsResult> requestItemIds(const QString &serviceJid, const QString &nodeName);
- template<typename T = QXmppPubSubItem>
+ template<typename T = QXmppPubSubBaseItem>
QXmppTask<ItemResult<T>> requestItem(const QString &jid, const QString &nodeName, const QString &itemId);
- template<typename T = QXmppPubSubItem>
+ template<typename T = QXmppPubSubBaseItem>
QXmppTask<ItemResult<T>> requestItem(const QString &jid, const QString &nodeName, StandardItemId itemId);
- template<typename T = QXmppPubSubItem>
+ template<typename T = QXmppPubSubBaseItem>
QXmppTask<ItemsResult<T>> requestItems(const QString &jid, const QString &nodeName);
- template<typename T = QXmppPubSubItem>
+ template<typename T = QXmppPubSubBaseItem>
QXmppTask<ItemsResult<T>> requestItems(const QString &jid, const QString &nodeName, const QStringList &itemIds);
template<typename T>
QXmppTask<PublishItemResult> publishItem(const QString &jid, const QString &nodeName, const T &item);
@@ -118,11 +118,11 @@ public:
QXmppTask<Result> createOwnPepNode(const QString &nodeName) { return createNode(client()->configuration().jidBare(), nodeName); }
QXmppTask<Result> createOwnPepNode(const QString &nodeName, const QXmppPubSubNodeConfig &config) { return createNode(client()->configuration().jidBare(), nodeName, config); }
QXmppTask<Result> deleteOwnPepNode(const QString &nodeName) { return deleteNode(client()->configuration().jidBare(), nodeName); }
- template<typename T = QXmppPubSubItem>
+ template<typename T = QXmppPubSubBaseItem>
QXmppTask<ItemResult<T>> requestOwnPepItem(const QString &nodeName, const QString &itemId) { return requestItem<T>(client()->configuration().jidBare(), nodeName, itemId); }
- template<typename T = QXmppPubSubItem>
+ template<typename T = QXmppPubSubBaseItem>
QXmppTask<ItemResult<T>> requestOwnPepItem(const QString &nodeName, StandardItemId itemId) { return requestItem<T>(client()->configuration().jidBare(), nodeName, itemId); }
- template<typename T = QXmppPubSubItem>
+ template<typename T = QXmppPubSubBaseItem>
QXmppTask<ItemsResult<T>> requestOwnPepItems(const QString &nodeName) { return requestItems(client()->configuration().jidBare(), nodeName); }
QXmppTask<ItemIdsResult> requestOwnPepItemIds(const QString &nodeName) { return requestItemIds(client()->configuration().jidBare(), nodeName); }
template<typename T>
diff --git a/src/client/QXmppSceEnvelope_p.h b/src/client/QXmppSceEnvelope_p.h
index 4a92378d..b40da9fd 100644
--- a/src/client/QXmppSceEnvelope_p.h
+++ b/src/client/QXmppSceEnvelope_p.h
@@ -25,8 +25,8 @@
class QXmppSceEnvelopeReader
{
public:
- QXmppSceEnvelopeReader(const QDomElement &element)
- : element(element)
+ QXmppSceEnvelopeReader(QDomElement &&element)
+ : element(std::move(element))
{
}
@@ -51,7 +51,7 @@ public:
// rpad is usually not needed (but can be parsed manually if really needed)
private:
- const QDomElement &element;
+ QDomElement element;
};
class QXmppSceEnvelopeWriter
diff --git a/src/omemo/CMakeLists.txt b/src/omemo/CMakeLists.txt
index 0ec3c0f0..89e1f06c 100644
--- a/src/omemo/CMakeLists.txt
+++ b/src/omemo/CMakeLists.txt
@@ -54,8 +54,10 @@ set_target_properties(QXmppOmemo PROPERTIES
install(
TARGETS QXmppOmemo
- DESTINATION ${CMAKE_INSTALL_LIBDIR}
EXPORT QXmppOmemoTargets
+ RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
+ LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
+ ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
)
install(
diff --git a/src/omemo/QXmppOmemoData.cpp b/src/omemo/QXmppOmemoData.cpp
index d1dd2a88..43e00c35 100644
--- a/src/omemo/QXmppOmemoData.cpp
+++ b/src/omemo/QXmppOmemoData.cpp
@@ -3,19 +3,18 @@
//
// SPDX-License-Identifier: LGPL-2.1-or-later
-#include "QXmppConstants_p.h"
#include "QXmppOmemoDeviceBundle_p.h"
#include "QXmppOmemoDeviceElement_p.h"
#include "QXmppOmemoDeviceList_p.h"
#include "QXmppOmemoElement_p.h"
-#include "QXmppOmemoEnvelope_p.h"
#include "QXmppOmemoIq_p.h"
#include "QXmppOmemoItems_p.h"
-#include "QXmppUtils.h"
#include <QDomElement>
#include <QHash>
+const char *ns_omemo_2 = "urn:xmpp:omemo:2";
+
/// \cond
///
/// \class QXmppOmemoDeviceElement
@@ -425,7 +424,7 @@ void QXmppOmemoDeviceBundleItem::setDeviceBundle(const QXmppOmemoDeviceBundle &d
bool QXmppOmemoDeviceBundleItem::isItem(const QDomElement &itemElement)
{
- return QXmppPubSubItem::isItem(itemElement, QXmppOmemoDeviceBundle::isOmemoDeviceBundle);
+ return QXmppPubSubBaseItem::isItem(itemElement, QXmppOmemoDeviceBundle::isOmemoDeviceBundle);
}
void QXmppOmemoDeviceBundleItem::parsePayload(const QDomElement &payloadElement)
@@ -450,7 +449,7 @@ void QXmppOmemoDeviceListItem::setDeviceList(const QXmppOmemoDeviceList &deviceL
bool QXmppOmemoDeviceListItem::isItem(const QDomElement &itemElement)
{
- return QXmppPubSubItem::isItem(itemElement, QXmppOmemoDeviceList::isOmemoDeviceList);
+ return QXmppPubSubBaseItem::isItem(itemElement, QXmppOmemoDeviceList::isOmemoDeviceList);
}
void QXmppOmemoDeviceListItem::parsePayload(const QDomElement &payloadElement)
diff --git a/src/omemo/QXmppOmemoDeviceList_p.h b/src/omemo/QXmppOmemoDeviceList_p.h
index 76bff435..46ac724d 100644
--- a/src/omemo/QXmppOmemoDeviceList_p.h
+++ b/src/omemo/QXmppOmemoDeviceList_p.h
@@ -7,12 +7,12 @@
#define QXMPPOMEMODEVICELIST_H
#include "QXmppGlobal.h"
+#include "QXmppOmemoDeviceElement_p.h"
#include "QList"
class QDomElement;
class QXmlStreamWriter;
-class QXmppOmemoDeviceElement;
class QXMPP_AUTOTEST_EXPORT QXmppOmemoDeviceList : public QList<QXmppOmemoDeviceElement>
{
diff --git a/src/omemo/QXmppOmemoItems_p.h b/src/omemo/QXmppOmemoItems_p.h
index 9b816ed8..abc6a65f 100644
--- a/src/omemo/QXmppOmemoItems_p.h
+++ b/src/omemo/QXmppOmemoItems_p.h
@@ -7,9 +7,9 @@
#include "QXmppOmemoDeviceBundle_p.h"
#include "QXmppOmemoDeviceList_p.h"
-#include "QXmppPubSubItem.h"
+#include "QXmppPubSubBaseItem.h"
-class QXmppOmemoDeviceBundleItem : public QXmppPubSubItem
+class QXmppOmemoDeviceBundleItem : public QXmppPubSubBaseItem
{
public:
QXmppOmemoDeviceBundle deviceBundle() const;
@@ -25,7 +25,7 @@ private:
QXmppOmemoDeviceBundle m_deviceBundle;
};
-class QXmppOmemoDeviceListItem : public QXmppPubSubItem
+class QXmppOmemoDeviceListItem : public QXmppPubSubBaseItem
{
public:
QXmppOmemoDeviceList deviceList() const;
diff --git a/src/omemo/QXmppOmemoManager.cpp b/src/omemo/QXmppOmemoManager.cpp
index 55a21190..0aab152d 100644
--- a/src/omemo/QXmppOmemoManager.cpp
+++ b/src/omemo/QXmppOmemoManager.cpp
@@ -4,11 +4,7 @@
// SPDX-License-Identifier: LGPL-2.1-or-later
#include "QXmppClient.h"
-#include "QXmppConstants_p.h"
-#include "QXmppOmemoDeviceElement_p.h"
-#include "QXmppOmemoDeviceList_p.h"
#include "QXmppOmemoElement_p.h"
-#include "QXmppOmemoEnvelope_p.h"
#include "QXmppOmemoIq_p.h"
#include "QXmppOmemoItems_p.h"
#include "QXmppOmemoManager_p.h"
@@ -18,6 +14,9 @@
#include <QStringBuilder>
+#undef max
+#undef interface
+
using namespace QXmpp;
using namespace QXmpp::Private;
using namespace QXmpp::Omemo::Private;
@@ -669,7 +668,7 @@ QXmppOmemoOwnDevice Manager::ownDevice()
QXmppOmemoOwnDevice device;
device.setLabel(ownDevice.label);
- device.setKeyId(createKeyId(ownDevice.publicIdentityKey));
+ device.setKeyId(ownDevice.publicIdentityKey);
return device;
}
@@ -885,13 +884,16 @@ QXmppTask<void> Manager::buildMissingSessions(const QList<QString> &jids)
auto future = d->buildSessionWithDeviceBundle(jid, deviceId, device);
future.then(this, [=](auto) mutable {
if (++(*processedDevicesCount) == devicesCount) {
+ interface.finish();
}
});
} else if (++(*processedDevicesCount) == devicesCount) {
+ interface.finish();
}
}
}
} else {
+ interface.finish();
}
return interface.task();
diff --git a/src/omemo/QXmppOmemoManager_p.cpp b/src/omemo/QXmppOmemoManager_p.cpp
index 2e08da04..1c86d80b 100644
--- a/src/omemo/QXmppOmemoManager_p.cpp
+++ b/src/omemo/QXmppOmemoManager_p.cpp
@@ -7,13 +7,12 @@
#include "QXmppOmemoManager_p.h"
-#include "QXmppConstants_p.h"
#include "QXmppOmemoDeviceElement_p.h"
#include "QXmppOmemoElement_p.h"
#include "QXmppOmemoEnvelope_p.h"
#include "QXmppOmemoIq_p.h"
#include "QXmppOmemoItems_p.h"
-#include "QXmppPubSubItem.h"
+#include "QXmppPubSubBaseItem.h"
#include "QXmppSceEnvelope_p.h"
#include "QXmppTrustManager.h"
#include "QXmppUtils.h"
@@ -25,6 +24,9 @@
#include <QRandomGenerator>
#include <QStringBuilder>
+#undef max
+#undef interface
+
using namespace QXmpp;
using namespace QXmpp::Private;
using namespace QXmpp::Omemo::Private;
@@ -33,27 +35,19 @@ using Error = QXmppStanza::Error;
using Manager = QXmppOmemoManager;
using ManagerPrivate = QXmppOmemoManagerPrivate;
+const char *ns_client = "jabber:client";
+const char *ns_pubsub_auto_create = "http://jabber.org/protocol/pubsub#auto-create";
+const char *ns_pubsub_config_node = "http://jabber.org/protocol/pubsub#config-node";
+const char *ns_pubsub_config_node_max = "http://jabber.org/protocol/pubsub#config-node-max";
+const char *ns_pubsub_create_and_configure = "http://jabber.org/protocol/pubsub#create-and-configure";
+const char *ns_pubsub_create_nodes = "http://jabber.org/protocol/pubsub#create-nodes";
+const char *ns_pubsub_publish = "http://jabber.org/protocol/pubsub#publish";
+const char *ns_pubsub_publish_options = "http://jabber.org/protocol/pubsub#publish-options";
+
namespace QXmpp::Omemo::Private {
const QString PAYLOAD_MESSAGE_AUTHENTICATION_CODE_TYPE = QStringLiteral("hmac(sha256)");
-//
-// Creates a key ID.
-//
-// The first byte representing a version string used by the OMEMO library but
-// not needed for trust management is removed.
-// It corresponds to the fingerprint shown to users which also does not contain
-// the first byte.
-//
-// \param key key for whom its ID is created
-//
-// \return the key ID
-//
-QByteArray createKeyId(const QByteArray &key)
-{
- return QByteArray(key).remove(0, 1);
-}
-
} // namespace QXmpp::Omemo::Private
//
@@ -710,13 +704,7 @@ bool ManagerPrivate::setUpIdentityKeyPair(ratchet_identity_key_pair **identityKe
const auto privateIdentityKey = privateIdentityKeyBuffer.toByteArray();
ownDevice.privateIdentityKey = privateIdentityKey;
- BufferPtr publicIdentityKeyBuffer;
-
- if (ec_public_key_serialize(publicIdentityKeyBuffer.ptrRef(), ratchet_identity_key_pair_get_public(*identityKeyPair)) < 0) {
- warning("Public identity key could not be serialized");
- return false;
- }
-
+ BufferPtr publicIdentityKeyBuffer(ec_public_key_get_ed(ratchet_identity_key_pair_get_public(*identityKeyPair)));
const auto publicIdentityKey = publicIdentityKeyBuffer.toByteArray();
deviceBundle.setPublicIdentityKey(publicIdentityKey);
ownDevice.publicIdentityKey = publicIdentityKey;
@@ -832,18 +820,12 @@ bool ManagerPrivate::updateSignedPreKeyPair(ratchet_identity_key_pair *identityK
signedPreKeyPairs.insert(latestSignedPreKeyId, signedPreKeyPairForStorage);
omemoStorage->addSignedPreKeyPair(latestSignedPreKeyId, signedPreKeyPairForStorage);
- BufferPtr signedPublicPreKeyBuffer;
-
- if (ec_public_key_serialize(signedPublicPreKeyBuffer.ptrRef(), ec_key_pair_get_public(session_signed_pre_key_get_key_pair(signedPreKeyPair.get()))) < 0) {
- warning("Signed public pre key could not be serialized");
- return false;
- }
-
+ BufferPtr signedPublicPreKeyBuffer(ec_public_key_get_mont(ec_key_pair_get_public(session_signed_pre_key_get_key_pair(signedPreKeyPair.get()))));
const auto signedPublicPreKeyByteArray = signedPublicPreKeyBuffer.toByteArray();
deviceBundle.setSignedPublicPreKeyId(latestSignedPreKeyId);
deviceBundle.setSignedPublicPreKey(signedPublicPreKeyByteArray);
- deviceBundle.setSignedPublicPreKeySignature(QByteArray(reinterpret_cast<const char *>(session_signed_pre_key_get_signature(signedPreKeyPair.get())), session_signed_pre_key_get_signature_len(signedPreKeyPair.get())));
+ deviceBundle.setSignedPublicPreKeySignature(QByteArray(reinterpret_cast<const char *>(session_signed_pre_key_get_signature_omemo(signedPreKeyPair.get())), session_signed_pre_key_get_signature_omemo_len(signedPreKeyPair.get())));
ownDevice.latestSignedPreKeyId = latestSignedPreKeyId;
@@ -921,7 +903,6 @@ bool ManagerPrivate::updatePreKeyPairs(uint32_t count)
node != nullptr;
node = signal_protocol_key_helper_key_list_next(node)) {
BufferSecurePtr preKeyPairBuffer;
- BufferPtr publicPreKeyBuffer;
auto preKeyPair = signal_protocol_key_helper_key_list_element(node);
@@ -934,11 +915,7 @@ bool ManagerPrivate::updatePreKeyPairs(uint32_t count)
serializedPreKeyPairs.insert(preKeyId, preKeyPairBuffer.toByteArray());
- if (ec_public_key_serialize(publicPreKeyBuffer.ptrRef(), ec_key_pair_get_public(session_pre_key_get_key_pair(preKeyPair))) < 0) {
- warning("Public pre key could not be serialized");
- return false;
- }
-
+ BufferPtr publicPreKeyBuffer(ec_public_key_get_mont(ec_key_pair_get_public(session_pre_key_get_key_pair(preKeyPair))));
const auto serializedPublicPreKey = publicPreKeyBuffer.toByteArray();
deviceBundle.addPublicPreKey(preKeyId, serializedPublicPreKey);
}
@@ -1017,7 +994,7 @@ bool ManagerPrivate::generateIdentityKeyPair(ratchet_identity_key_pair **identit
RefCountedPtr<ec_public_key> publicIdentityKey;
- if (curve_decode_point(publicIdentityKey.ptrRef(), signal_buffer_data(publicIdentityKeyBuffer.get()), signal_buffer_len(publicIdentityKeyBuffer.get()), globalContext.get()) < 0) {
+ if (curve_decode_point_ed(publicIdentityKey.ptrRef(), signal_buffer_data(publicIdentityKeyBuffer.get()), signal_buffer_len(publicIdentityKeyBuffer.get()), globalContext.get()) < 0) {
warning("Public identity key could not be deserialized");
return false;
}
@@ -1234,15 +1211,14 @@ QXmppTask<std::optional<QXmppOmemoElement>> ManagerPrivate::encryptStanza(const
if (optionalDeviceBundle && devices.value(jid).contains(deviceId)) {
auto &deviceBeingModified = devices[jid][deviceId];
const auto &deviceBundle = *optionalDeviceBundle;
- const auto key = deviceBundle.publicIdentityKey();
- deviceBeingModified.keyId = createKeyId(key);
+ deviceBeingModified.keyId = deviceBundle.publicIdentityKey();
auto future = q->trustLevel(jid, deviceBeingModified.keyId);
future.then(q, [=](TrustLevel trustLevel) mutable {
// Store the retrieved key's trust level if it is not stored
// yet.
if (trustLevel == TrustLevel::Undecided) {
- auto future = storeKeyDependingOnSecurityPolicy(jid, key);
+ auto future = storeKeyDependingOnSecurityPolicy(jid, deviceBeingModified.keyId);
future.then(q, [=](TrustLevel trustLevel) mutable {
omemoStorage->addDevice(jid, deviceId, deviceBeingModified);
Q_EMIT q->deviceChanged(jid, deviceId);
@@ -1473,8 +1449,6 @@ QXmppTask<std::optional<QXmppMessage>> ManagerPrivate::decryptMessage(QXmppMessa
future.then(q, [=](std::optional<QCA::SecureArray> payloadDecryptionData) mutable {
if (!payloadDecryptionData) {
warning("Empty OMEMO message could not be successfully processed");
- } else if (payloadDecryptionData->isEmpty()) {
- warning("Empty OMEMO message could not be successfully processed");
} else {
q->debug("Successfully processed empty OMEMO message");
}
@@ -1576,48 +1550,38 @@ QXmppTask<std::optional<DecryptionResult>> ManagerPrivate::decryptStanza(T stanz
QXmppSceEnvelopeReader sceEnvelopeReader(document.documentElement());
if (sceEnvelopeReader.from() != senderJid) {
- warning("Sender '" % senderJid % "' of stanza does not match SCE 'from' affix element '" % sceEnvelopeReader.from() % "'");
- interface.finish(std::nullopt);
- } else {
- const auto recipientJid = QXmppUtils::jidToBareJid(stanza.to());
- auto isSceAffixElementValid = true;
+ q->info("Sender '" % senderJid % "' of stanza does not match SCE 'from' affix element '" % sceEnvelopeReader.from() % "'");
+ }
- if (isMessageStanza) {
- if (const auto &message = dynamic_cast<const QXmppMessage &>(stanza); message.type() == QXmppMessage::GroupChat && (sceEnvelopeReader.to() != recipientJid)) {
- warning("Recipient of group chat message does not match SCE affix element '<to/>'");
- isSceAffixElementValid = false;
- }
- } else {
- if (sceEnvelopeReader.to() != recipientJid) {
- warning("Recipient of IQ does not match SCE affix element '<to/>'");
- isSceAffixElementValid = false;
- }
+ if (const auto recipientJid = QXmppUtils::jidToBareJid(stanza.to()); isMessageStanza) {
+ if (const auto &message = dynamic_cast<const QXmppMessage &>(stanza); message.type() == QXmppMessage::GroupChat && (sceEnvelopeReader.to() != recipientJid)) {
+ warning("Recipient of group chat message does not match SCE affix element '<to/>'");
+ interface.finish(std::nullopt);
+ return;
}
+ } else if (sceEnvelopeReader.to() != recipientJid) {
+ q->info("Recipient of IQ does not match SCE affix element '<to/>'");
+ }
- if (!isSceAffixElementValid) {
- interface.finish(std::nullopt);
- } else {
- auto &device = devices[senderJid][senderDeviceId];
- device.unrespondedSentStanzasCount = 0;
+ auto &device = devices[senderJid][senderDeviceId];
+ device.unrespondedSentStanzasCount = 0;
- // Send a heartbeat message to the sender if too many stanzas were
- // received responding to none.
- if (device.unrespondedReceivedStanzasCount == UNRESPONDED_STANZAS_UNTIL_HEARTBEAT_MESSAGE_IS_SENT) {
- sendEmptyMessage(senderJid, senderDeviceId);
- device.unrespondedReceivedStanzasCount = 0;
- } else {
- ++device.unrespondedReceivedStanzasCount;
- }
+ // Send a heartbeat message to the sender if too many stanzas were
+ // received responding to none.
+ if (device.unrespondedReceivedStanzasCount == UNRESPONDED_STANZAS_UNTIL_HEARTBEAT_MESSAGE_IS_SENT) {
+ sendEmptyMessage(senderJid, senderDeviceId);
+ device.unrespondedReceivedStanzasCount = 0;
+ } else {
+ ++device.unrespondedReceivedStanzasCount;
+ }
- QXmppE2eeMetadata e2eeMetadata;
- e2eeMetadata.setSceTimestamp(sceEnvelopeReader.timestamp());
- e2eeMetadata.setEncryption(QXmpp::Omemo2);
- const auto &senderDevice = devices.value(senderJid).value(senderDeviceId);
- e2eeMetadata.setSenderKey(senderDevice.keyId);
+ QXmppE2eeMetadata e2eeMetadata;
+ e2eeMetadata.setSceTimestamp(sceEnvelopeReader.timestamp());
+ e2eeMetadata.setEncryption(QXmpp::Omemo2);
+ const auto &senderDevice = devices.value(senderJid).value(senderDeviceId);
+ e2eeMetadata.setSenderKey(senderDevice.keyId);
- interface.finish(DecryptionResult { sceEnvelopeReader.contentElement(), e2eeMetadata });
- }
- }
+ interface.finish(DecryptionResult { sceEnvelopeReader.contentElement(), e2eeMetadata });
}
});
@@ -1648,9 +1612,6 @@ QXmppTask<QByteArray> ManagerPrivate::extractSceEnvelope(const QString &senderJi
if (!payloadDecryptionData) {
warning("Data for decrypting OMEMO payload could not be extracted");
interface.finish(QByteArray());
- } else if (payloadDecryptionData->isEmpty()) {
- warning("Data for decrypting OMEMO payload could not be extracted");
- interface.finish(QByteArray());
} else {
interface.finish(decryptPayload(*payloadDecryptionData, omemoPayload));
}
@@ -1669,8 +1630,7 @@ QXmppTask<QByteArray> ManagerPrivate::extractSceEnvelope(const QString &senderJi
// \param omemoEnvelope OMEMO envelope containing the payload decryption data
// \param isMessageStanza whether the received stanza is a message stanza
//
-// \return the serialized payload decryption data if it could be extracted, otherwise a
-// default-constructed secure array
+// \return the serialized payload decryption data if it could be extracted, otherwise std::nullopt
//
QXmppTask<std::optional<QCA::SecureArray>> ManagerPrivate::extractPayloadDecryptionData(const QString &senderJid, uint32_t senderDeviceId, const QXmppOmemoEnvelope &omemoEnvelope, bool isMessageStanza)
{
@@ -1728,11 +1688,10 @@ QXmppTask<std::optional<QCA::SecureArray>> ManagerPrivate::extractPayloadDecrypt
const auto key = publicIdentityKeyBuffer.toByteArray();
auto &device = devices[senderJid][senderDeviceId];
auto &storedKeyId = device.keyId;
- const auto createdKeyId = createKeyId(key);
// Store the key if its ID has changed.
- if (storedKeyId != createdKeyId) {
- storedKeyId = createdKeyId;
+ if (storedKeyId != key) {
+ storedKeyId = key;
omemoStorage->addDevice(senderJid, senderDeviceId, device);
Q_EMIT q->deviceChanged(senderJid, senderDeviceId);
}
@@ -1781,12 +1740,7 @@ QXmppTask<std::optional<QCA::SecureArray>> ManagerPrivate::extractPayloadDecrypt
auto future = q->trustLevel(senderJid, storedKeyId);
future.then(q, [=](TrustLevel trustLevel) mutable {
if (trustLevel == TrustLevel::Undecided) {
- auto future = storeKeyDependingOnSecurityPolicy(senderJid, key);
- future.then(q, [=](auto) mutable {
- interface.finish(std::nullopt);
- });
- } else {
- interface.finish(std::nullopt);
+ storeKeyDependingOnSecurityPolicy(senderJid, key);
}
});
}
@@ -3338,8 +3292,7 @@ QXmppTask<bool> ManagerPrivate::buildSessionWithDeviceBundle(const QString &jid,
future.then(q, [=, &device](std::optional<QXmppOmemoDeviceBundle> optionalDeviceBundle) mutable {
if (optionalDeviceBundle) {
const auto &deviceBundle = *optionalDeviceBundle;
- const auto key = deviceBundle.publicIdentityKey();
- device.keyId = createKeyId(key);
+ device.keyId = deviceBundle.publicIdentityKey();
auto future = q->trustLevel(jid, device.keyId);
future.then(q, [=](TrustLevel trustLevel) mutable {
@@ -3372,7 +3325,7 @@ QXmppTask<bool> ManagerPrivate::buildSessionWithDeviceBundle(const QString &jid,
if (trustLevel == TrustLevel::Undecided) {
// Store the key's trust level if it is not stored yet.
- auto future = storeKeyDependingOnSecurityPolicy(jid, key);
+ auto future = storeKeyDependingOnSecurityPolicy(jid, device.keyId);
future.then(q, [=](TrustLevel trustLevel) mutable {
buildSessionDependingOnTrustLevel(trustLevel);
});
@@ -3517,7 +3470,7 @@ bool ManagerPrivate::deserializePublicIdentityKey(ec_public_key **publicIdentity
return false;
}
- if (curve_decode_point(publicIdentityKey, signal_buffer_data(publicIdentityKeyBuffer.get()), signal_buffer_len(publicIdentityKeyBuffer.get()), globalContext.get()) < 0) {
+ if (curve_decode_point_ed(publicIdentityKey, signal_buffer_data(publicIdentityKeyBuffer.get()), signal_buffer_len(publicIdentityKeyBuffer.get()), globalContext.get()) < 0) {
warning("Public identity key could not be deserialized");
return false;
}
@@ -3542,7 +3495,7 @@ bool ManagerPrivate::deserializeSignedPublicPreKey(ec_public_key **signedPublicP
return false;
}
- if (curve_decode_point(signedPublicPreKey, signal_buffer_data(signedPublicPreKeyBuffer.get()), signal_buffer_len(signedPublicPreKeyBuffer.get()), globalContext.get()) < 0) {
+ if (curve_decode_point_mont(signedPublicPreKey, signal_buffer_data(signedPublicPreKeyBuffer.get()), signal_buffer_len(signedPublicPreKeyBuffer.get()), globalContext.get()) < 0) {
warning("Signed public pre key could not be deserialized");
return false;
}
@@ -3567,7 +3520,7 @@ bool ManagerPrivate::deserializePublicPreKey(ec_public_key **publicPreKey, const
return false;
}
- if (curve_decode_point(publicPreKey, signal_buffer_data(publicPreKeyBuffer.get()), signal_buffer_len(publicPreKeyBuffer.get()), globalContext.get()) < 0) {
+ if (curve_decode_point_mont(publicPreKey, signal_buffer_data(publicPreKeyBuffer.get()), signal_buffer_len(publicPreKeyBuffer.get()), globalContext.get()) < 0) {
warning("Public pre key could not be deserialized");
return false;
}
@@ -3633,16 +3586,11 @@ QXmppTask<QXmpp::SendResult> ManagerPrivate::sendEmptyMessage(const QString &rec
//
// Sets the key of this client instance's device.
//
-// The first byte representing a version string used by the OMEMO library but
-// not needed for trust management is removed before storing it.
-// It corresponds to the fingerprint shown to users which also does not contain
-// the first byte.
-//
QXmppTask<void> ManagerPrivate::storeOwnKey() const
{
QXmppPromise<void> interface;
- auto future = trustManager->setOwnKey(ns_omemo_2, createKeyId(ownDevice.publicIdentityKey));
+ auto future = trustManager->setOwnKey(ns_omemo_2, ownDevice.publicIdentityKey);
future.then(q, [=]() mutable {
interface.finish();
});
@@ -3715,7 +3663,7 @@ QXmppTask<TrustLevel> ManagerPrivate::storeKey(const QString &keyOwnerJid, const
{
QXmppPromise<TrustLevel> interface;
- auto future = trustManager->addKeys(ns_omemo_2, keyOwnerJid, { createKeyId(key) }, trustLevel);
+ auto future = trustManager->addKeys(ns_omemo_2, keyOwnerJid, { key }, trustLevel);
future.then(q, [=]() mutable {
Q_EMIT q->trustLevelsChanged({ { keyOwnerJid, key } });
interface.finish(std::move(trustLevel));
diff --git a/src/omemo/QXmppOmemoManager_p.h b/src/omemo/QXmppOmemoManager_p.h
index 6875a571..96f10f94 100644
--- a/src/omemo/QXmppOmemoManager_p.h
+++ b/src/omemo/QXmppOmemoManager_p.h
@@ -18,6 +18,8 @@
#include <QTimer>
#include <QtCrypto>
+#undef max
+
class QXmppTrustManager;
class QXmppOmemoManager;
class QXmppPubSubManager;
@@ -34,6 +36,11 @@ using namespace std::chrono_literals;
namespace QXmpp::Omemo::Private {
+// XMPP namespaces
+constexpr auto ns_omemo_2 = "urn:xmpp:omemo:2";
+constexpr auto ns_omemo_2_bundles = "urn:xmpp:omemo:2:bundles";
+constexpr auto ns_omemo_2_devices = "urn:xmpp:omemo:2:devices";
+
// default possible trust levels a key must have to be used for encryption
// The class documentation must be adapted if the trust levels are modified.
constexpr auto ACCEPTED_TRUST_LEVELS = TrustLevel::AutomaticallyTrusted | TrustLevel::ManuallyTrusted | TrustLevel::Authenticated;
@@ -84,14 +91,14 @@ constexpr QCA::Cipher::Padding PAYLOAD_CIPHER_PADDING = QCA::Cipher::PKCS7;
constexpr auto HKDF_INFO = "OMEMO Payload";
constexpr int HKDF_KEY_SIZE = 32;
constexpr int HKDF_SALT_SIZE = 32;
-constexpr int HKDF_OUTPUT_SIZE = 60;
+constexpr int HKDF_OUTPUT_SIZE = 80;
extern const QString PAYLOAD_MESSAGE_AUTHENTICATION_CODE_TYPE;
constexpr uint32_t PAYLOAD_MESSAGE_AUTHENTICATION_CODE_SIZE = 16;
constexpr int PAYLOAD_KEY_SIZE = 32;
constexpr uint32_t PAYLOAD_INITIALIZATION_VECTOR_SIZE = 16;
-constexpr uint32_t PAYLOAD_AUTHENTICATION_KEY_SIZE = 16;
+constexpr uint32_t PAYLOAD_AUTHENTICATION_KEY_SIZE = 32;
// boundaries for the count of characters in SCE's <rpad/> element
constexpr uint32_t SCE_RPAD_SIZE_MIN = 0;
@@ -115,8 +122,6 @@ struct IqDecryptionResult
QXmppE2eeMetadata e2eeMetadata;
};
-QByteArray createKeyId(const QByteArray &key);
-
} // namespace QXmpp::Omemo::Private
using namespace QXmpp::Private;
@@ -168,9 +173,10 @@ public:
QXmppOmemoManagerPrivate(QXmppOmemoManager *parent, QXmppOmemoStorage *omemoStorage);
void init();
- bool initGlobalContext();
- bool initLocking();
- bool initCryptoProvider();
+ // exports for unit tests
+ QXMPP_EXPORT bool initGlobalContext();
+ QXMPP_EXPORT bool initLocking();
+ QXMPP_EXPORT bool initCryptoProvider();
void initStores();
signal_protocol_identity_key_store createIdentityKeyStore() const;