aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorLinus Jahn <lnj@kaidan.im>2023-04-07 16:21:10 +0200
committerLinus Jahn <lnj@kaidan.im>2023-04-07 16:21:10 +0200
commitab4bdf2da41a26f462fe3a333a34e32c999e2a6d (patch)
tree2501bde9b6da885056166c769befa7f7d4729e49 /src
parentc8e13f6fd3df8dcab0170dda6f54eaf5175d8437 (diff)
parentb44a7ee310bd2c9bc7c0d234ab7a96c501d20559 (diff)
Merge branch '1.5'
Diffstat (limited to 'src')
-rw-r--r--src/CMakeLists.txt35
-rw-r--r--src/base/QXmppMamIq.h4
-rw-r--r--src/base/QXmppPubSubIq_p.h2
-rw-r--r--src/client/QXmppMamManager.cpp3
-rw-r--r--src/client/QXmppMamManager.h2
-rw-r--r--src/omemo/CMakeLists.txt32
-rw-r--r--src/omemo/QXmppOmemoConfig.cmake.in4
-rw-r--r--src/omemo/QXmppOmemoData.cpp2
-rw-r--r--src/omemo/QXmppOmemoManager.cpp58
-rw-r--r--src/omemo/QXmppOmemoManager_p.cpp139
-rw-r--r--src/omemo/QXmppOmemoManager_p.h4
11 files changed, 154 insertions, 131 deletions
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index 82e99619..929554c4 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -276,28 +276,28 @@ set(SOURCE_FILES
)
if(BUILD_SHARED)
- add_library(qxmpp SHARED ${SOURCE_FILES})
+ add_library(${QXMPP_TARGET} SHARED ${SOURCE_FILES})
else()
- add_library(qxmpp STATIC ${SOURCE_FILES})
+ add_library(${QXMPP_TARGET} STATIC ${SOURCE_FILES})
endif()
-set_target_properties(qxmpp PROPERTIES
+set_target_properties(${QXMPP_TARGET} PROPERTIES
VERSION ${PROJECT_VERSION}
SOVERSION ${SO_VERSION}
EXPORT_NAME QXmpp
)
-target_include_directories(qxmpp
+target_include_directories(${QXMPP_TARGET}
PUBLIC
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/base>
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/client>
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/server>
- $<INSTALL_INTERFACE:include/qxmpp>
+ $<INSTALL_INTERFACE:include/${QXMPP_TARGET}>
PRIVATE
${CMAKE_CURRENT_BINARY_DIR}
)
-target_link_libraries(qxmpp
+target_link_libraries(${QXMPP_TARGET}
PUBLIC
Qt${QT_VERSION_MAJOR}::Core
Qt${QT_VERSION_MAJOR}::Network
@@ -316,21 +316,21 @@ if(WITH_GSTREAMER)
client/QXmppCallStream.h
)
- target_sources(qxmpp
+ target_sources(${QXMPP_TARGET}
PRIVATE
client/QXmppCall.cpp
client/QXmppCallManager.cpp
client/QXmppCallStream.cpp
)
- target_link_libraries(qxmpp
+ target_link_libraries(${QXMPP_TARGET}
PRIVATE
${GLIB2_LIBRARIES}
${GOBJECT_LIBRARIES}
${GSTREAMER_LIBRARY}
)
- target_include_directories(qxmpp
+ target_include_directories(${QXMPP_TARGET}
PRIVATE
${GLIB2_INCLUDE_DIR}
${GOBJECT_INCLUDE_DIR}
@@ -340,13 +340,13 @@ endif()
if(BUILD_OMEMO)
# required to be used in QXmppMessage
- target_sources(qxmpp PRIVATE base/QXmppOmemoDataBase.cpp)
+ target_sources(${QXMPP_TARGET} PRIVATE base/QXmppOmemoDataBase.cpp)
endif()
if(WITH_QCA)
- target_sources(qxmpp PRIVATE client/QXmppEncryptedFileSharingProvider.cpp client/QXmppFileEncryption.cpp client/QcaInitializer.cpp)
+ target_sources(${QXMPP_TARGET} PRIVATE client/QXmppEncryptedFileSharingProvider.cpp client/QXmppFileEncryption.cpp client/QcaInitializer.cpp)
set(INSTALL_HEADER_FILES ${INSTALL_HEADER_FILES} client/QXmppEncryptedFileSharingProvider.h)
- target_link_libraries(qxmpp PRIVATE qca-qt${QT_VERSION_MAJOR})
+ target_link_libraries(${QXMPP_TARGET} PRIVATE qca-qt${QT_VERSION_MAJOR})
endif()
# qxmpp_export.h generation
@@ -363,12 +363,13 @@ set(QXMPP_CUSTOM_EXPORT_CONTENT "
#define QXMPP_VERSION_PATCH ${PROJECT_VERSION_PATCH}
")
-generate_export_header(qxmpp
+generate_export_header(${QXMPP_TARGET}
+ BASE_NAME qxmpp
CUSTOM_CONTENT_FROM_VARIABLE QXMPP_CUSTOM_EXPORT_CONTENT
)
install(
- TARGETS qxmpp
+ TARGETS ${QXMPP_TARGET}
EXPORT QXmppTarget
RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
@@ -377,20 +378,20 @@ install(
install(
EXPORT QXmppTarget
- DESTINATION "${CMAKE_INSTALL_LIBDIR}/cmake/qxmpp"
+ DESTINATION "${CMAKE_INSTALL_LIBDIR}/cmake/${QXMPP_TARGET}"
FILE QXmpp.cmake
NAMESPACE QXmpp::
COMPONENT Devel
)
export(
- TARGETS qxmpp
+ TARGETS ${QXMPP_TARGET}
FILE QXmpp.cmake
)
install(
FILES ${INSTALL_HEADER_FILES} ${CMAKE_CURRENT_BINARY_DIR}/qxmpp_export.h
- DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}/qxmpp"
+ DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}/${QXMPP_TARGET}"
)
# submodules
diff --git a/src/base/QXmppMamIq.h b/src/base/QXmppMamIq.h
index 6a1df144..78d5c77a 100644
--- a/src/base/QXmppMamIq.h
+++ b/src/base/QXmppMamIq.h
@@ -14,7 +14,7 @@
class QXmppMamQueryIqPrivate;
class QXmppMamResultIqPrivate;
-class QXmppMamQueryIq : public QXmppIq
+class QXMPP_EXPORT QXmppMamQueryIq : public QXmppIq
{
public:
QXmppMamQueryIq();
@@ -46,7 +46,7 @@ private:
QSharedDataPointer<QXmppMamQueryIqPrivate> d;
};
-class QXmppMamResultIq : public QXmppIq
+class QXMPP_EXPORT QXmppMamResultIq : public QXmppIq
{
public:
QXmppMamResultIq();
diff --git a/src/base/QXmppPubSubIq_p.h b/src/base/QXmppPubSubIq_p.h
index c8828579..0ff1de04 100644
--- a/src/base/QXmppPubSubIq_p.h
+++ b/src/base/QXmppPubSubIq_p.h
@@ -152,7 +152,7 @@ void PubSubIq<T>::parseItems(const QDomElement &queryElement)
childElement = childElement.nextSiblingElement(QStringLiteral("item"))) {
T item;
item.parse(childElement);
- m_items << std::move(item);
+ m_items.push_back(std::move(item));
}
}
diff --git a/src/client/QXmppMamManager.cpp b/src/client/QXmppMamManager.cpp
index fe0735c7..046f01b0 100644
--- a/src/client/QXmppMamManager.cpp
+++ b/src/client/QXmppMamManager.cpp
@@ -339,7 +339,8 @@ QXmppTask<QXmppMamManager::RetrieveResult> QXmppMamManager::retrieveMessages(con
// because some decryptMessage() jobs could finish instantly
state.runningDecryptionJobs = encryptedCount;
- for (auto i = 0; i < state.messages.size(); i++) {
+ int size = state.messages.size();
+ for (auto i = 0; i < size; i++) {
if (!messagesEncrypted[i]) {
continue;
}
diff --git a/src/client/QXmppMamManager.h b/src/client/QXmppMamManager.h
index 71cb4311..548d56d6 100644
--- a/src/client/QXmppMamManager.h
+++ b/src/client/QXmppMamManager.h
@@ -40,7 +40,7 @@ class QXMPP_EXPORT QXmppMamManager : public QXmppClientExtension
Q_OBJECT
public:
- struct RetrievedMessages
+ struct QXMPP_EXPORT RetrievedMessages
{
QXmppMamResultIq result;
QVector<QXmppMessage> messages;
diff --git a/src/omemo/CMakeLists.txt b/src/omemo/CMakeLists.txt
index 89e1f06c..9086ec64 100644
--- a/src/omemo/CMakeLists.txt
+++ b/src/omemo/CMakeLists.txt
@@ -4,8 +4,8 @@
include(CMakePackageConfigHelpers)
-set(OMEMO_CMAKE_DIR "${CMAKE_INSTALL_LIBDIR}/cmake/QXmppOmemo")
-set(OMEMO_HEADER_DIR "${CMAKE_INSTALL_FULL_INCLUDEDIR}/qxmpp/omemo")
+set(OMEMO_CMAKE_DIR "${CMAKE_INSTALL_LIBDIR}/cmake/${QXMPPOMEMO_TARGET}")
+set(OMEMO_HEADER_DIR "${CMAKE_INSTALL_FULL_INCLUDEDIR}/${QXMPP_TARGET}/Omemo")
set(OMEMO_INSTALL_HEADER_FILES
QXmppOmemoManager.h
QXmppOmemoMemoryStorage.h
@@ -20,17 +20,21 @@ set(OMEMO_SOURCE_FILES
QXmppOmemoStorage.cpp
)
-add_library(QXmppOmemo SHARED ${OMEMO_SOURCE_FILES})
+if(BUILD_SHARED)
+ add_library(${QXMPPOMEMO_TARGET} SHARED ${OMEMO_SOURCE_FILES})
+else()
+ add_library(${QXMPPOMEMO_TARGET} STATIC ${OMEMO_SOURCE_FILES})
+endif()
-target_link_libraries(QXmppOmemo
+target_link_libraries(${QXMPPOMEMO_TARGET}
PUBLIC
- qxmpp
+ ${QXMPP_TARGET}
Qt${QT_VERSION_MAJOR}::Core
PRIVATE
PkgConfig::OmemoC
qca-qt${QT_VERSION_MAJOR}
)
-target_include_directories(QXmppOmemo
+target_include_directories(${QXMPPOMEMO_TARGET}
PUBLIC
${OMEMO_HEADER_DIR}
PRIVATE
@@ -39,21 +43,21 @@ target_include_directories(QXmppOmemo
${PROJECT_BINARY_DIR}/src
)
-generate_export_header(QXmppOmemo)
+generate_export_header(${QXMPPOMEMO_TARGET} BASE_NAME qxmppomemo)
install(
FILES ${OMEMO_INSTALL_HEADER_FILES} ${CMAKE_CURRENT_BINARY_DIR}/qxmppomemo_export.h
DESTINATION ${OMEMO_HEADER_DIR}
)
-set_target_properties(QXmppOmemo PROPERTIES
+set_target_properties(${QXMPPOMEMO_TARGET} PROPERTIES
VERSION ${PROJECT_VERSION}
SOVERSION ${SO_VERSION}
EXPORT_NAME Omemo
)
install(
- TARGETS QXmppOmemo
+ TARGETS ${QXMPPOMEMO_TARGET}
EXPORT QXmppOmemoTargets
RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
@@ -69,25 +73,25 @@ install(
)
export(
- TARGETS QXmppOmemo
+ TARGETS ${QXMPPOMEMO_TARGET}
FILE QXmppOmemo.cmake
)
configure_package_config_file(
QXmppOmemoConfig.cmake.in
- ${CMAKE_CURRENT_BINARY_DIR}/QXmppOmemoConfig.cmake
+ ${CMAKE_CURRENT_BINARY_DIR}/${QXMPPOMEMO_TARGET}Config.cmake
INSTALL_DESTINATION ${OMEMO_CMAKE_DIR}
)
write_basic_package_version_file(
- ${CMAKE_CURRENT_BINARY_DIR}/QXmppOmemoConfigVersion.cmake
+ ${CMAKE_CURRENT_BINARY_DIR}/${QXMPPOMEMO_TARGET}ConfigVersion.cmake
VERSION ${PROJECT_VERSION}
COMPATIBILITY SameMajorVersion
)
install(
- FILES ${CMAKE_CURRENT_BINARY_DIR}/QXmppOmemoConfig.cmake
- ${CMAKE_CURRENT_BINARY_DIR}/QXmppOmemoConfigVersion.cmake
+ FILES ${CMAKE_CURRENT_BINARY_DIR}/${QXMPPOMEMO_TARGET}Config.cmake
+ ${CMAKE_CURRENT_BINARY_DIR}/${QXMPPOMEMO_TARGET}ConfigVersion.cmake
DESTINATION ${OMEMO_CMAKE_DIR}
COMPONENT Devel
)
diff --git a/src/omemo/QXmppOmemoConfig.cmake.in b/src/omemo/QXmppOmemoConfig.cmake.in
index 5363c0f5..68596637 100644
--- a/src/omemo/QXmppOmemoConfig.cmake.in
+++ b/src/omemo/QXmppOmemoConfig.cmake.in
@@ -5,8 +5,8 @@
@PACKAGE_INIT@
include(CMakeFindDependencyMacro)
-find_dependency(QXmpp)
+find_dependency(QXmppQt@QT_VERSION_MAJOR@)
include("${CMAKE_CURRENT_LIST_DIR}/QXmppOmemo.cmake")
-check_required_components(QXmppOmemo)
+check_required_components(QXmppOmemoQt@QT_VERSION_MAJOR@)
diff --git a/src/omemo/QXmppOmemoData.cpp b/src/omemo/QXmppOmemoData.cpp
index 43e00c35..220e628f 100644
--- a/src/omemo/QXmppOmemoData.cpp
+++ b/src/omemo/QXmppOmemoData.cpp
@@ -13,7 +13,7 @@
#include <QDomElement>
#include <QHash>
-const char *ns_omemo_2 = "urn:xmpp:omemo:2";
+constexpr auto ns_omemo_2 = "urn:xmpp:omemo:2";
/// \cond
///
diff --git a/src/omemo/QXmppOmemoManager.cpp b/src/omemo/QXmppOmemoManager.cpp
index a3ad12bb..f9172d3b 100644
--- a/src/omemo/QXmppOmemoManager.cpp
+++ b/src/omemo/QXmppOmemoManager.cpp
@@ -675,11 +675,13 @@ QXmppOmemoOwnDevice Manager::ownDevice()
/// Returns all locally stored devices except the own device.
///
-/// Only devices that have been received after subscribing the corresponding
-/// device lists on the server are stored locally.
+/// Only devices that have been received after subscribing the corresponding device lists on the
+/// server are stored locally.
/// Thus, only those are returned.
-/// Call \c QXmppOmemoManager::subscribeToDeviceLists() for contacts without
-/// presence subscription before.
+/// Call \c QXmppOmemoManager::subscribeToDeviceLists() for contacts without presence subscription
+/// before.
+///
+/// You must build sessions before you can get devices with corresponding keys.
///
/// /\return all devices except the own device
///
@@ -691,11 +693,13 @@ QXmppTask<QVector<QXmppOmemoDevice>> Manager::devices()
///
/// Returns locally stored devices except the own device.
///
-/// Only devices that have been received after subscribing the corresponding
-/// device lists on the server are stored locally.
+/// Only devices that have been received after subscribing the corresponding device lists on the
+/// server are stored locally.
/// Thus, only those are returned.
-/// Call \c QXmppOmemoManager::subscribeToDeviceLists() for contacts without
-/// presence subscription before.
+/// Call \c QXmppOmemoManager::subscribeToDeviceLists() for contacts without presence subscription
+/// before.
+///
+/// You must build sessions before you can get devices with corresponding keys.
///
/// \param jids JIDs whose devices are being retrieved
///
@@ -835,16 +839,15 @@ bool Manager::isNewDeviceAutoSessionBuildingEnabled()
///
/// Builds sessions manually with devices for whom no sessions are available.
///
-/// Usually, sessions are built during sending a first message to a device or
-/// after a first message is received from a device.
+/// Usually, sessions are built during sending a first message to a device or after a first message
+/// is received from a device.
/// This can be called in order to speed up the sending of a message.
-/// If this method is called before sending the first message, all sessions can
-/// be built and when the first message is sent, the message has only be
-/// encrypted.
-/// Especially chats with multiple devices, that can decrease the noticeable
-/// time a user has to wait for sending a message.
-/// Additionally, the keys are automatically retrieved from the server which is
-/// helpful in order to get them when calling \c QXmppOmemoManager::devices().
+/// If this method is called before sending the first message, all sessions can be built and when
+/// the first message is being sent, the message only needs to be encrypted.
+/// Especially for chats with multiple devices, that can decrease the noticeable time a user has to
+/// wait for sending a message.
+/// Additionally, the keys are automatically retrieved from the server which is helpful in order to
+/// get them when calling \c QXmppOmemoManager::devices().
///
/// The user must be logged in while calling this.
///
@@ -1240,21 +1243,30 @@ void Manager::setClient(QXmppClient *client)
connect(d->trustManager, &QXmppTrustManager::trustLevelsChanged, this, [=](const QHash<QString, QMultiHash<QString, QByteArray>> &modifiedKeys) {
const auto &modifiedOmemoKeys = modifiedKeys.value(ns_omemo_2);
- Q_EMIT trustLevelsChanged(modifiedOmemoKeys);
+
+ if (!modifiedOmemoKeys.isEmpty()) {
+ Q_EMIT trustLevelsChanged(modifiedOmemoKeys);
+ }
+
+ QMultiHash<QString, uint32_t> modifiedDevices;
for (auto itr = modifiedOmemoKeys.cbegin(); itr != modifiedOmemoKeys.cend(); ++itr) {
const auto &keyOwnerJid = itr.key();
const auto &keyId = itr.value();
- // Emit 'deviceChanged()' only if there is a device with the key.
+ // Ensure to emit 'deviceChanged()' later only if there is a device with the key.
const auto &devices = d->devices.value(keyOwnerJid);
- for (auto itr = devices.cbegin(); itr != devices.cend(); ++itr) {
- if (itr->keyId == keyId) {
- Q_EMIT deviceChanged(keyOwnerJid, itr.key());
- return;
+ for (auto devicesItr = devices.cbegin(); devicesItr != devices.cend(); ++devicesItr) {
+ if (devicesItr->keyId == keyId) {
+ modifiedDevices.insert(keyOwnerJid, devicesItr.key());
+ break;
}
}
}
+
+ for (auto modifiedDevicesItr = modifiedDevices.cbegin(); modifiedDevicesItr != modifiedDevices.cend(); ++modifiedDevicesItr) {
+ Q_EMIT deviceChanged(modifiedDevicesItr.key(), modifiedDevicesItr.value());
+ }
});
}
diff --git a/src/omemo/QXmppOmemoManager_p.cpp b/src/omemo/QXmppOmemoManager_p.cpp
index bcfd8303..e8a209ee 100644
--- a/src/omemo/QXmppOmemoManager_p.cpp
+++ b/src/omemo/QXmppOmemoManager_p.cpp
@@ -35,14 +35,14 @@ 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";
+constexpr auto ns_client = "jabber:client";
+constexpr auto ns_pubsub_auto_create = "http://jabber.org/protocol/pubsub#auto-create";
+constexpr auto ns_pubsub_config_node = "http://jabber.org/protocol/pubsub#config-node";
+constexpr auto ns_pubsub_config_node_max = "http://jabber.org/protocol/pubsub#config-node-max";
+constexpr auto ns_pubsub_create_and_configure = "http://jabber.org/protocol/pubsub#create-and-configure";
+constexpr auto ns_pubsub_create_nodes = "http://jabber.org/protocol/pubsub#create-nodes";
+constexpr auto ns_pubsub_publish = "http://jabber.org/protocol/pubsub#publish";
+constexpr auto ns_pubsub_publish_options = "http://jabber.org/protocol/pubsub#publish-options";
namespace QXmpp::Omemo::Private {
@@ -754,7 +754,7 @@ void ManagerPrivate::renewSignedPreKeyPairs()
if (isSignedPreKeyPairRemoved) {
RefCountedPtr<ratchet_identity_key_pair> identityKeyPair;
- generateIdentityKeyPair(identityKeyPair.ptrRef());
+ deserializeIdentityKeyPair(identityKeyPair.ptrRef());
updateSignedPreKeyPair(identityKeyPair.get());
// Store the own device containing the new signed pre key ID.
@@ -960,54 +960,6 @@ void ManagerPrivate::removeDevicesRemovedFromServer()
}
//
-// Generates an identity key pair.
-//
-// The identity key pair is the pair of private and a public long-term key.
-//
-// \param identityKeyPair identity key pair location
-//
-// \return whether it succeeded
-//
-bool ManagerPrivate::generateIdentityKeyPair(ratchet_identity_key_pair **identityKeyPair) const
-{
- BufferSecurePtr privateIdentityKeyBuffer = BufferSecurePtr::fromByteArray(ownDevice.privateIdentityKey);
-
- if (!privateIdentityKeyBuffer) {
- warning("Buffer for serialized private identity key could not be created");
- return false;
- }
-
- RefCountedPtr<ec_private_key> privateIdentityKey;
-
- if (curve_decode_private_point(privateIdentityKey.ptrRef(), signal_buffer_data(privateIdentityKeyBuffer.get()), signal_buffer_len(privateIdentityKeyBuffer.get()), globalContext.get()) < 0) {
- warning("Private identity key could not be deserialized");
- return false;
- }
-
- const auto &serializedPublicIdentityKey = ownDevice.publicIdentityKey;
- BufferPtr publicIdentityKeyBuffer = BufferPtr::fromByteArray(serializedPublicIdentityKey);
-
- if (!publicIdentityKeyBuffer) {
- warning("Buffer for serialized public identity key could not be created");
- return false;
- }
-
- RefCountedPtr<ec_public_key> publicIdentityKey;
-
- 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;
- }
-
- if (ratchet_identity_key_pair_create(identityKeyPair, publicIdentityKey.get(), privateIdentityKey.get()) < 0) {
- warning("Identity key pair could not be deserialized");
- return false;
- }
-
- return true;
-}
-
-//
// Encrypts a message for specific recipients.
//
// \param message message to be encrypted
@@ -1428,15 +1380,14 @@ QByteArray ManagerPrivate::createOmemoEnvelopeData(const signal_protocol_address
//
QXmppTask<std::optional<QXmppMessage>> ManagerPrivate::decryptMessage(QXmppMessage stanza)
{
- QXmppPromise<std::optional<QXmppMessage>> interface;
-
// At this point, the stanza has always an OMEMO element.
const auto omemoElement = *stanza.omemoElement();
- if (auto optionalOmemoEnvelope = omemoElement.searchEnvelope(ownBareJid(), ownDevice.id)) {
+ if (const auto omemoEnvelope = omemoElement.searchEnvelope(ownBareJid(), ownDevice.id)) {
+ QXmppPromise<std::optional<QXmppMessage>> interface;
+
const auto senderJid = QXmppUtils::jidToBareJid(stanza.from());
const auto senderDeviceId = omemoElement.senderDeviceId();
- const auto omemoEnvelope = *optionalOmemoEnvelope;
const auto omemoPayload = omemoElement.payload();
subscribeToNewDeviceLists(senderJid, senderDeviceId);
@@ -1445,7 +1396,7 @@ QXmppTask<std::optional<QXmppMessage>> ManagerPrivate::decryptMessage(QXmppMessa
// for it after building the initial session or sent by devices to build a new session
// with this device.
if (omemoPayload.isEmpty()) {
- auto future = extractPayloadDecryptionData(senderJid, senderDeviceId, omemoEnvelope);
+ auto future = extractPayloadDecryptionData(senderJid, senderDeviceId, *omemoEnvelope);
future.then(q, [=](std::optional<QCA::SecureArray> payloadDecryptionData) mutable {
if (!payloadDecryptionData) {
warning("Empty OMEMO message could not be successfully processed");
@@ -1456,7 +1407,7 @@ QXmppTask<std::optional<QXmppMessage>> ManagerPrivate::decryptMessage(QXmppMessa
interface.finish(std::nullopt);
});
} else {
- auto future = decryptStanza(stanza, senderJid, senderDeviceId, omemoEnvelope, omemoPayload);
+ auto future = decryptStanza(stanza, senderJid, senderDeviceId, *omemoEnvelope, omemoPayload);
future.then(q, [=](std::optional<DecryptionResult> optionalDecryptionResult) mutable {
if (optionalDecryptionResult) {
const auto decryptionResult = std::move(*optionalDecryptionResult);
@@ -1474,9 +1425,11 @@ QXmppTask<std::optional<QXmppMessage>> ManagerPrivate::decryptMessage(QXmppMessa
}
});
}
- }
- return interface.task();
+ return interface.task();
+ } else {
+ return makeReadyTask<std::optional<QXmppMessage>>(std::nullopt);
+ }
}
//
@@ -1497,13 +1450,13 @@ QXmppTask<std::optional<IqDecryptionResult>> ManagerPrivate::decryptIq(const QDo
iq.parse(iqElement);
auto omemoElement = iq.omemoElement();
- if (const auto envelope = omemoElement.searchEnvelope(ownBareJid(), ownDevice.id)) {
+ if (const auto omemoEnvelope = omemoElement.searchEnvelope(ownBareJid(), ownDevice.id)) {
const auto senderJid = QXmppUtils::jidToBareJid(iq.from());
const auto senderDeviceId = omemoElement.senderDeviceId();
subscribeToNewDeviceLists(senderJid, senderDeviceId);
- auto future = decryptStanza(iq, senderJid, senderDeviceId, *envelope, omemoElement.payload(), false);
+ auto future = decryptStanza(iq, senderJid, senderDeviceId, *omemoEnvelope, omemoElement.payload(), false);
return chain<Result>(std::move(future), q, [iqElement](auto result) -> Result {
if (result) {
auto decryptedElement = iqElement.cloneNode(true).toElement();
@@ -2659,7 +2612,7 @@ std::optional<QXmppOmemoDeviceListItem> QXmppOmemoManagerPrivate::updateContactD
{
if (deviceListItems.size() > 1) {
const auto itr = std::find_if(deviceListItems.cbegin(), deviceListItems.cend(), [=](const QXmppOmemoDeviceListItem &item) {
- return item.id() == QXmppPubSubManager::Current;
+ return item.id() == QXmppPubSubManager::standardItemIdToString(QXmppPubSubManager::Current);
});
if (itr != deviceListItems.cend()) {
@@ -3495,6 +3448,56 @@ bool ManagerPrivate::createSessionBundle(session_pre_key_bundle **sessionBundle,
}
//
+// Deserializes the locally stored identity key pair.
+//
+// The identity key pair is the pair of private and a public long-term keys.
+//
+// \param identityKeyPair identity key pair location
+//
+// \return whether it succeeded
+//
+bool ManagerPrivate::deserializeIdentityKeyPair(ratchet_identity_key_pair **identityKeyPair) const
+{
+ RefCountedPtr<ec_private_key> privateIdentityKey;
+ deserializePrivateIdentityKey(privateIdentityKey.ptrRef(), ownDevice.privateIdentityKey);
+
+ RefCountedPtr<ec_public_key> publicIdentityKey;
+ deserializePublicIdentityKey(publicIdentityKey.ptrRef(), ownDevice.publicIdentityKey);
+
+ if (ratchet_identity_key_pair_create(identityKeyPair, publicIdentityKey.get(), privateIdentityKey.get()) < 0) {
+ warning("Identity key pair could not be deserialized");
+ return false;
+ }
+
+ return true;
+}
+
+//
+// Deserializes a private identity key.
+//
+// \param privateIdentityKey private identity key location
+// \param serializedPrivateIdentityKey serialized private identity key
+//
+// \return whether it succeeded
+//
+bool ManagerPrivate::deserializePrivateIdentityKey(ec_private_key **privateIdentityKey, const QByteArray &serializedPrivateIdentityKey) const
+{
+ BufferSecurePtr privateIdentityKeyBuffer = BufferSecurePtr::fromByteArray(serializedPrivateIdentityKey);
+
+ if (!privateIdentityKeyBuffer) {
+ warning("Buffer for serialized private identity key could not be created");
+ return false;
+ }
+
+ if (curve_decode_private_point(privateIdentityKey, signal_buffer_data(privateIdentityKeyBuffer.get()), signal_buffer_len(privateIdentityKeyBuffer.get()), globalContext.get()) < 0) {
+ warning("Private identity key could not be deserialized");
+ return false;
+ }
+
+ return true;
+}
+
+//
// Deserializes a public identity key.
//
// \param publicIdentityKey public identity key location
diff --git a/src/omemo/QXmppOmemoManager_p.h b/src/omemo/QXmppOmemoManager_p.h
index 0792bdf2..e1ba6ff1 100644
--- a/src/omemo/QXmppOmemoManager_p.h
+++ b/src/omemo/QXmppOmemoManager_p.h
@@ -194,7 +194,6 @@ public:
bool renewPreKeyPairs(uint32_t keyPairBeingRenewed);
bool updatePreKeyPairs(uint32_t count = 1);
void removeDevicesRemovedFromServer();
- bool generateIdentityKeyPair(ratchet_identity_key_pair **identityKeyPair) const;
QXmppTask<QXmppE2eeExtension::MessageEncryptResult> encryptMessageForRecipients(QXmppMessage &&message,
QVector<QString> recipientJids,
@@ -336,6 +335,9 @@ public:
const QByteArray &serializedSignedPublicPreKeySignature,
const QByteArray &serializedPublicPreKey,
uint32_t publicPreKeyId);
+
+ bool deserializeIdentityKeyPair(ratchet_identity_key_pair **identityKeyPair) const;
+ bool deserializePrivateIdentityKey(ec_private_key **privateIdentityKey, const QByteArray &serializedPrivateIdentityKey) const;
bool deserializePublicIdentityKey(ec_public_key **publicIdentityKey, const QByteArray &serializedPublicIdentityKey) const;
bool deserializeSignedPublicPreKey(ec_public_key **signedPublicPreKey, const QByteArray &serializedSignedPublicPreKey) const;
bool deserializePublicPreKey(ec_public_key **publicPreKey, const QByteArray &serializedPublicPreKey) const;