aboutsummaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
Diffstat (limited to 'lib')
-rw-r--r--lib/connection.cpp51
-rw-r--r--lib/converters.cpp13
-rw-r--r--lib/crypto/e2ee.h47
-rw-r--r--lib/crypto/qolmaccount.cpp36
-rw-r--r--lib/crypto/qolmaccount.h8
-rw-r--r--lib/encryptionmanager.cpp12
-rw-r--r--lib/networkaccessmanager.cpp6
7 files changed, 142 insertions, 31 deletions
diff --git a/lib/connection.cpp b/lib/connection.cpp
index f96eeb71..704bc1b4 100644
--- a/lib/connection.cpp
+++ b/lib/connection.cpp
@@ -108,7 +108,8 @@ public:
QVector<GetLoginFlowsJob::LoginFlow> loginFlows;
#ifdef Quotient_E2EE_ENABLED
- QScopedPointer<EncryptionManager> encryptionManager;
+ std::unique_ptr<QOlmAccount> olmAccount;
+ //QScopedPointer<EncryptionManager> encryptionManager;
#endif // Quotient_E2EE_ENABLED
QPointer<GetWellknownJob> resolverJob = nullptr;
@@ -183,6 +184,9 @@ public:
EventPtr sessionDecryptMessage(const EncryptedEvent& encryptedEvent)
{
+ qCWarning(E2EE) << "End-to-end encryption (E2EE) support is turned off.";
+ return {};
+ /*
#ifndef Quotient_E2EE_ENABLED
qCWarning(E2EE) << "End-to-end encryption (E2EE) support is turned off.";
return {};
@@ -242,6 +246,7 @@ public:
return std::move(decryptedEvent);
#endif // Quotient_E2EE_ENABLED
+*/
}
};
@@ -420,8 +425,8 @@ void Connection::Private::loginToServer(LoginArgTs&&... loginArgs)
#ifndef Quotient_E2EE_ENABLED
qCWarning(E2EE) << "End-to-end encryption (E2EE) support is turned off.";
#else // Quotient_E2EE_ENABLED
- encryptionManager->uploadIdentityKeys(q);
- encryptionManager->uploadOneTimeKeys(q);
+ //encryptionManager->uploadIdentityKeys(q);
+ //encryptionManager->uploadOneTimeKeys(q);
#endif // Quotient_E2EE_ENABLED
});
connect(loginJob, &BaseJob::failure, q, [this, loginJob] {
@@ -442,11 +447,19 @@ void Connection::Private::completeSetup(const QString& mxId)
qCWarning(E2EE) << "End-to-end encryption (E2EE) support is turned off.";
#else // Quotient_E2EE_ENABLED
AccountSettings accountSettings(data->userId());
- encryptionManager.reset(
- new EncryptionManager(accountSettings.encryptionAccountPickle()));
+
+ // init olmAccount
+ olmAccount = std::make_unique<QOlmAccount>(data->userId(), data->deviceId());
+
if (accountSettings.encryptionAccountPickle().isEmpty()) {
- accountSettings.setEncryptionAccountPickle(
- encryptionManager->olmAccountPickle());
+ // create new account and save unpickle data
+ olmAccount->createNewAccount();
+ accountSettings.setEncryptionAccountPickle(std::get<QByteArray>(olmAccount->pickle(Unencrypted{})));
+ // TODO handle pickle errors
+ } else {
+ // account already existing
+ auto pickle = accountSettings.encryptionAccountPickle();
+ olmAccount->unpickle(pickle, Unencrypted{});
}
#endif // Quotient_E2EE_ENABLED
emit q->stateChanged();
@@ -608,16 +621,16 @@ void Connection::onSyncSuccess(SyncData&& data, bool fromCache)
d->consumeToDeviceEvents(data.takeToDeviceEvents());
#ifdef Quotient_E2EE_ENABLED
// handling device_one_time_keys_count
- if (!d->encryptionManager)
- {
- qCDebug(E2EE) << "Encryption manager is not there yet, updating "
- "one-time key counts will be skipped";
- return;
- }
- if (const auto deviceOneTimeKeysCount = data.deviceOneTimeKeysCount();
- !deviceOneTimeKeysCount.isEmpty())
- d->encryptionManager->updateOneTimeKeyCounts(this,
- deviceOneTimeKeysCount);
+ //if (!d->encryptionManager)
+ //{
+ // qCDebug(E2EE) << "Encryption manager is not there yet, updating "
+ // "one-time key counts will be skipped";
+ // return;
+ //}
+ //if (const auto deviceOneTimeKeysCount = data.deviceOneTimeKeysCount();
+ // !deviceOneTimeKeysCount.isEmpty())
+ // d->encryptionManager->updateOneTimeKeyCounts(this,
+ // deviceOneTimeKeysCount);
#endif // Quotient_E2EE_ENABLED
}
@@ -745,6 +758,7 @@ void Connection::Private::consumePresenceData(Events&& presenceData)
void Connection::Private::consumeToDeviceEvents(Events&& toDeviceEvents)
{
+/*
#ifdef Quotient_E2EE_ENABLED
// handling m.room_key to-device encrypted event
visitEach(toDeviceEvents, [this](const EncryptedEvent& ee) {
@@ -775,6 +789,7 @@ void Connection::Private::consumeToDeviceEvents(Events&& toDeviceEvents)
});
});
#endif
+*/
}
void Connection::stopSync()
@@ -1228,7 +1243,7 @@ bool Connection::isLoggedIn() const { return !accessToken().isEmpty(); }
#ifdef Quotient_E2EE_ENABLED
QOlmAccount *Connection::olmAccount() const
{
- return d->encryptionManager->account();
+ return d->olmAccount.get(); //d->encryptionManager->account();
}
#endif // Quotient_E2EE_ENABLED
diff --git a/lib/converters.cpp b/lib/converters.cpp
index 444ca4f6..e6dcd854 100644
--- a/lib/converters.cpp
+++ b/lib/converters.cpp
@@ -3,15 +3,26 @@
#include "converters.h"
-#include <QtCore/QVariant>
+#include <QVariant>
+#include "crypto/e2ee.h"
QJsonValue Quotient::JsonConverter<QVariant>::dump(const QVariant& v)
{
+ if (v.canConvert<SignedOneTimeKey>()) {
+ return toJson(v.value<SignedOneTimeKey>());
+ }
return QJsonValue::fromVariant(v);
}
QVariant Quotient::JsonConverter<QVariant>::load(const QJsonValue& jv)
{
+ if (jv.isObject()) {
+ QJsonObject obj = jv.toObject();
+ if (obj.contains("key") && obj.contains("signatures")) {
+ SignedOneTimeKey signedOneTimeKeys;
+ signedOneTimeKeys.key = obj["key"].toString();
+ }
+ }
return jv.toVariant();
}
diff --git a/lib/crypto/e2ee.h b/lib/crypto/e2ee.h
index 73dd7f65..2d280185 100644
--- a/lib/crypto/e2ee.h
+++ b/lib/crypto/e2ee.h
@@ -7,10 +7,13 @@
#include <optional>
#include <string>
+#include "converters.h"
#include <variant>
#include <QMap>
+#include <QHash>
#include <QStringList>
+#include <QMetaType>
#include "util.h"
@@ -68,16 +71,56 @@ struct OneTimeKeys
};
//! Struct representing the signed one-time keys.
-struct SignedOneTimeKey
+class SignedOneTimeKey
{
+public:
+ SignedOneTimeKey() = default;
+ SignedOneTimeKey(const SignedOneTimeKey &) = default;
+ SignedOneTimeKey &operator=(const SignedOneTimeKey &) = default;
//! Required. The unpadded Base64-encoded 32-byte Curve25519 public key.
QString key;
//! Required. Signatures of the key object.
//! The signature is calculated using the process described at Signing JSON.
- QMap<QString, QMap<QString, QString>> signatures;
+ QHash<QString, QHash<QString, QString>> signatures;
+};
+
+
+template <>
+struct JsonObjectConverter<SignedOneTimeKey> {
+ static void fillFrom(const QJsonObject& jo,
+ SignedOneTimeKey& result)
+ {
+ fromJson(jo.value("key"_ls), result.key);
+ fromJson(jo.value("signatures"_ls), result.signatures);
+ }
+
+ static void dumpTo(QJsonObject &jo, const SignedOneTimeKey &result)
+ {
+ addParam<>(jo, QStringLiteral("key"), result.key);
+ addParam<>(jo, QStringLiteral("signatures"), result.signatures);
+ }
};
bool operator==(const IdentityKeys& lhs, const IdentityKeys& rhs);
+template <typename T>
+class asKeyValueRange
+{
+public:
+ asKeyValueRange(T &data)
+ : m_data{data}
+ {
+ }
+
+ auto begin() { return m_data.keyValueBegin(); }
+
+ auto end() { return m_data.keyValueEnd(); }
+
+private:
+ T &m_data;
+};
+
} // namespace Quotient
+
+Q_DECLARE_METATYPE(Quotient::SignedOneTimeKey)
diff --git a/lib/crypto/qolmaccount.cpp b/lib/crypto/qolmaccount.cpp
index 76b0a263..fb91c906 100644
--- a/lib/crypto/qolmaccount.cpp
+++ b/lib/crypto/qolmaccount.cpp
@@ -4,6 +4,8 @@
#ifdef Quotient_E2EE_ENABLED
#include "qolmaccount.h"
+#include "connection.h"
+#include "csapi/keys.h"
#include "crypto/qolmutils.h"
#include <QJsonObject>
#include <QJsonDocument>
@@ -138,7 +140,7 @@ size_t QOlmAccount::maxNumberOfOneTimeKeys() const
return olm_account_max_number_of_one_time_keys(m_account);
}
-void QOlmAccount::generateOneTimeKeys(size_t numberOfKeys) const
+size_t QOlmAccount::generateOneTimeKeys(size_t numberOfKeys) const
{
const size_t randomLen = olm_account_generate_one_time_keys_random_length(m_account, numberOfKeys);
QByteArray randomBuffer = getRandom(randomLen);
@@ -147,6 +149,7 @@ void QOlmAccount::generateOneTimeKeys(size_t numberOfKeys) const
if (error == olm_error()) {
throw lastError(m_account);
}
+ return error;
}
OneTimeKeys QOlmAccount::oneTimeKeys() const
@@ -212,6 +215,37 @@ OlmAccount *Quotient::QOlmAccount::data()
return m_account;
}
+UploadKeysJob *QOlmAccount::createUploadKeyRequest(const OneTimeKeys &oneTimeKeys)
+{
+
+ DeviceKeys deviceKeys;
+ deviceKeys.userId = m_userId;
+ deviceKeys.deviceId = m_deviceId;
+ deviceKeys.algorithms = QStringList {"m.olm.v1.curve25519-aes-sha2", "m.megolm.v1.aes-sha2"};
+
+ const auto idKeys = identityKeys();
+ deviceKeys.keys["curve25519:" + m_deviceId] = idKeys.curve25519;
+ deviceKeys.keys["ed25519:" + m_deviceId] = idKeys.ed25519;
+
+ const auto sign = signIdentityKeys();
+ deviceKeys.signatures[m_userId]["ed25519:" + m_deviceId] = sign;
+
+ if (oneTimeKeys.curve25519().isEmpty()) {
+ return new UploadKeysJob(deviceKeys);
+ }
+
+ // Sign & append the one time keys.
+ auto temp = signOneTimeKeys(oneTimeKeys);
+ QHash<QString, QVariant> oneTimeKeysSigned;
+ for (const auto &[keyId, key] : asKeyValueRange(temp)) {
+ QVariant keyVar;
+ keyVar.setValue(key);
+ oneTimeKeysSigned[keyId] = keyVar;
+ }
+
+ return new UploadKeysJob(deviceKeys, oneTimeKeysSigned);
+}
+
std::variant<std::unique_ptr<QOlmSession>, QOlmError> QOlmAccount::createInboundSession(const QOlmMessage &preKeyMessage)
{
Q_ASSERT(preKeyMessage.type() == QOlmMessage::PreKey);
diff --git a/lib/crypto/qolmaccount.h b/lib/crypto/qolmaccount.h
index 4398214a..d61c8748 100644
--- a/lib/crypto/qolmaccount.h
+++ b/lib/crypto/qolmaccount.h
@@ -4,6 +4,7 @@
#pragma once
#ifdef Quotient_E2EE_ENABLED
+#include "csapi/keys.h"
#include "crypto/e2ee.h"
#include "crypto/qolmerrors.h"
#include "crypto/qolmmessage.h"
@@ -15,6 +16,7 @@ struct OlmAccount;
namespace Quotient {
class QOlmSession;
+class Connection;
//! An olm account manages all cryptographic keys used on a device.
//! \code{.cpp}
@@ -55,7 +57,7 @@ public:
size_t maxNumberOfOneTimeKeys() const;
//! Generates the supplied number of one time keys.
- void generateOneTimeKeys(size_t numberOfKeys) const;
+ size_t generateOneTimeKeys(size_t numberOfKeys) const;
//! Gets the OlmAccount's one time keys formatted as JSON.
OneTimeKeys oneTimeKeys() const;
@@ -68,6 +70,8 @@ public:
SignedOneTimeKey signedOneTimeKey(const QByteArray &key, const QString &signature) const;
+ UploadKeysJob *createUploadKeyRequest(const OneTimeKeys &oneTimeKeys);
+
//! Remove the one time key used to create the supplied session.
[[nodiscard]] std::optional<QOlmError> removeOneTimeKeys(const std::unique_ptr<QOlmSession> &session) const;
@@ -90,7 +94,7 @@ public:
QOlmAccount(OlmAccount *account);
OlmAccount *data();
private:
- OlmAccount *m_account = nullptr;
+ OlmAccount *m_account = nullptr; // owning
QString m_userId;
QString m_deviceId;
};
diff --git a/lib/encryptionmanager.cpp b/lib/encryptionmanager.cpp
index 449eb2a3..c8dc6bdd 100644
--- a/lib/encryptionmanager.cpp
+++ b/lib/encryptionmanager.cpp
@@ -104,7 +104,7 @@ public:
{
// Try to decrypt message body using one of the known sessions for that
// device
- bool sessionsPassed = false;
+ /*bool sessionsPassed = false;
// new e2ee TODO:
for (auto &senderSession : sessions) {
if (senderSession == sessions.last()) {
@@ -152,7 +152,7 @@ public:
qCDebug(E2EE) << "try to establish new InboundSession with" << senderKey;
QOlmMessage preKeyMessage = QOlmMessage(message.toCiphertext(), QOlmMessage::PreKey);
// new e2ee TODO:
- const auto sessionResult = olmAccount->createInboundSessionFrom(senderKey.toUtf8(), preKeyMessage);
+ //const auto sessionResult = olmAccount->createInboundSessionFrom(senderKey.toUtf8(), preKeyMessage);
if (const auto error = std::get_if<QOlmError>(&sessionResult)) {
qCDebug(E2EE) << "Error decrypting pre-key message when trying "
@@ -161,7 +161,7 @@ public:
return QString();
}
- const auto newSession = std::get<std::unique_ptr<QOlmSession>>(sessionResult);
+ const auto newSession = std::get<std::unique_ptr<QOlmSession>>(olmAccount->createInboundSessionFrom(senderKey.toUtf8(), preKeyMessage));
qCDebug(E2EE) << "Created new Olm session" << newSession->sessionId();
@@ -178,9 +178,9 @@ public:
<< "Error removing one time keys"
<< error.value();
}
- sessions.insert(senderKey, std::move(newSession));
- return std::get<QString>(decryptedResult);
- }
+ //sessions.insert(senderKey, std::move(newSession)); TODO
+ //return std::get<QString>(decryptedResult);
+ }*/
return QString();
}
};
diff --git a/lib/networkaccessmanager.cpp b/lib/networkaccessmanager.cpp
index 57618329..293538ee 100644
--- a/lib/networkaccessmanager.cpp
+++ b/lib/networkaccessmanager.cpp
@@ -40,7 +40,11 @@ public:
NetworkAccessManager::NetworkAccessManager(QObject* parent)
: QNetworkAccessManager(parent), d(std::make_unique<Private>(this))
-{}
+{
+ connect(this, &QNetworkAccessManager::sslErrors, this, [](QNetworkReply *reply, const QList<QSslError> &errors) {
+ reply->ignoreSslErrors();
+ });
+}
QList<QSslError> NetworkAccessManager::ignoredSslErrors() const
{