aboutsummaryrefslogtreecommitdiff
path: root/lib/e2ee
diff options
context:
space:
mode:
authorAlexey Rusakov <Kitsune-Ral@users.sf.net>2022-02-15 20:51:32 +0100
committerAlexey Rusakov <Kitsune-Ral@users.sf.net>2022-02-16 17:58:17 +0100
commit53dfa70601b2d27a6be12d52e86af123d0b26b79 (patch)
treea8629e4a229edfeec7c5f32ab72db7d63dc1ed06 /lib/e2ee
parent52a787eefb3fb3d147648d08fc439a4b8a966fd3 (diff)
downloadlibquotient-53dfa70601b2d27a6be12d52e86af123d0b26b79.tar.gz
libquotient-53dfa70601b2d27a6be12d52e86af123d0b26b79.zip
Cleanup
A note on switching to QLatin1String for JSON key constants - this is more concise and barely affects (if at all) runtime performance (padding each QChar with zeros is trivial for assignment; and comparison can be done directly with the same performance as for two QStrings).
Diffstat (limited to 'lib/e2ee')
-rw-r--r--lib/e2ee/e2ee.h76
-rw-r--r--lib/e2ee/qolmaccount.cpp79
-rw-r--r--lib/e2ee/qolminboundsession.h26
-rw-r--r--lib/e2ee/qolmmessage.cpp4
-rw-r--r--lib/e2ee/qolmmessage.h3
-rw-r--r--lib/e2ee/qolmoutboundsession.h4
-rw-r--r--lib/e2ee/qolmsession.h41
-rw-r--r--lib/e2ee/qolmutility.h3
8 files changed, 107 insertions, 129 deletions
diff --git a/lib/e2ee/e2ee.h b/lib/e2ee/e2ee.h
index 4c825376..e21aa87b 100644
--- a/lib/e2ee/e2ee.h
+++ b/lib/e2ee/e2ee.h
@@ -5,43 +5,34 @@
#pragma once
-#include <optional>
-#include <string>
#include "converters.h"
+#include "quotient_common.h"
+
+#include <QtCore/QMetaType>
#include <variant>
-#include <QMap>
-#include <QHash>
-#include <QStringList>
-#include <QMetaType>
+namespace Quotient {
-#include "util.h"
+constexpr auto CiphertextKeyL = "ciphertext"_ls;
+constexpr auto SenderKeyKeyL = "sender_key"_ls;
+constexpr auto DeviceIdKeyL = "device_id"_ls;
+constexpr auto SessionIdKeyL = "session_id"_ls;
-namespace Quotient {
+constexpr auto AlgorithmKeyL = "algorithm"_ls;
+constexpr auto RotationPeriodMsKeyL = "rotation_period_ms"_ls;
+constexpr auto RotationPeriodMsgsKeyL = "rotation_period_msgs"_ls;
+
+constexpr auto AlgorithmKey = "algorithm"_ls;
+constexpr auto RotationPeriodMsKey = "rotation_period_ms"_ls;
+constexpr auto RotationPeriodMsgsKey = "rotation_period_msgs"_ls;
+
+constexpr auto Ed25519Key = "ed25519"_ls;
+constexpr auto Curve25519Key = "curve25519"_ls;
+constexpr auto SignedCurve25519Key = "signed_curve25519"_ls;
+
+constexpr auto OlmV1Curve25519AesSha2AlgoKey = "m.olm.v1.curve25519-aes-sha2"_ls;
+constexpr auto MegolmV1AesSha2AlgoKey = "m.megolm.v1.aes-sha2"_ls;
-inline const auto CiphertextKeyL = "ciphertext"_ls;
-inline const auto SenderKeyKeyL = "sender_key"_ls;
-inline const auto DeviceIdKeyL = "device_id"_ls;
-inline const auto SessionIdKeyL = "session_id"_ls;
-
-inline const auto AlgorithmKeyL = "algorithm"_ls;
-inline const auto RotationPeriodMsKeyL = "rotation_period_ms"_ls;
-inline const auto RotationPeriodMsgsKeyL = "rotation_period_msgs"_ls;
-
-inline const auto AlgorithmKey = QStringLiteral("algorithm");
-inline const auto RotationPeriodMsKey = QStringLiteral("rotation_period_ms");
-inline const auto RotationPeriodMsgsKey =
- QStringLiteral("rotation_period_msgs");
-
-inline const auto Ed25519Key = QStringLiteral("ed25519");
-inline const auto Curve25519Key = QStringLiteral("curve25519");
-inline const auto SignedCurve25519Key = QStringLiteral("signed_curve25519");
-inline const auto OlmV1Curve25519AesSha2AlgoKey =
- QStringLiteral("m.olm.v1.curve25519-aes-sha2");
-inline const auto MegolmV1AesSha2AlgoKey =
- QStringLiteral("m.megolm.v1.aes-sha2");
-inline const QStringList SupportedAlgorithms = { OlmV1Curve25519AesSha2AlgoKey,
- MegolmV1AesSha2AlgoKey };
struct Unencrypted {};
struct Encrypted {
QByteArray key;
@@ -55,9 +46,6 @@ using QOlmSessionPtr = std::unique_ptr<QOlmSession>;
class QOlmInboundGroupSession;
using QOlmInboundGroupSessionPtr = std::unique_ptr<QOlmInboundGroupSession>;
-template<class... Ts> struct overloaded : Ts... { using Ts::operator()...; };
-template<class... Ts> overloaded(Ts...) -> overloaded<Ts...>;
-
struct IdentityKeys
{
QByteArray curve25519;
@@ -73,16 +61,13 @@ struct QUOTIENT_API OneTimeKeys
QMap<QString, QString> curve25519() const;
//! Get a reference to the hashmap corresponding to given key type.
- std::optional<QMap<QString, QString>> get(QString keyType) const;
+// std::optional<QHash<QString, QString>> get(QString keyType) const;
};
//! Struct representing the signed one-time keys.
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;
@@ -94,8 +79,7 @@ public:
template <>
struct JsonObjectConverter<SignedOneTimeKey> {
- static void fillFrom(const QJsonObject& jo,
- SignedOneTimeKey& result)
+ static void fillFrom(const QJsonObject& jo, SignedOneTimeKey& result)
{
fromJson(jo.value("key"_ls), result.key);
fromJson(jo.value("signatures"_ls), result.signatures);
@@ -108,24 +92,22 @@ struct JsonObjectConverter<SignedOneTimeKey> {
}
};
-bool operator==(const IdentityKeys& lhs, const IdentityKeys& rhs);
-
template <typename T>
class asKeyValueRange
{
public:
- asKeyValueRange(T &data)
- : m_data{data}
- {
- }
+ asKeyValueRange(T& data)
+ : m_data { data }
+ {}
auto begin() { return m_data.keyValueBegin(); }
-
auto end() { return m_data.keyValueEnd(); }
private:
T &m_data;
};
+template <typename T>
+asKeyValueRange(T&) -> asKeyValueRange<T>;
} // namespace Quotient
diff --git a/lib/e2ee/qolmaccount.cpp b/lib/e2ee/qolmaccount.cpp
index 34ee7ea0..9cbb14f5 100644
--- a/lib/e2ee/qolmaccount.cpp
+++ b/lib/e2ee/qolmaccount.cpp
@@ -3,53 +3,41 @@
// SPDX-License-Identifier: LGPL-2.1-or-later
#include "qolmaccount.h"
+
#include "connection.h"
-#include "csapi/keys.h"
-#include "e2ee/qolmutils.h"
#include "e2ee/qolmutility.h"
-#include <QJsonObject>
-#include <QJsonDocument>
-#include <QDebug>
-#include <iostream>
+#include "e2ee/qolmutils.h"
+
+#include "csapi/keys.h"
+
+#include <QtCore/QRandomGenerator>
using namespace Quotient;
QMap<QString, QString> OneTimeKeys::curve25519() const
{
- return keys[QStringLiteral("curve25519")];
+ return keys[Curve25519Key];
}
-std::optional<QMap<QString, QString>> OneTimeKeys::get(QString keyType) const
-{
- if (!keys.contains(keyType)) {
- return std::nullopt;
- }
- return keys[keyType];
-}
-
-bool operator==(const IdentityKeys& lhs, const IdentityKeys& rhs)
-{
- return lhs.curve25519 == rhs.curve25519 && lhs.ed25519 == rhs.ed25519;
-}
+//std::optional<QHash<QString, QString>> OneTimeKeys::get(QString keyType) const
+//{
+// if (!keys.contains(keyType)) {
+// return std::nullopt;
+// }
+// return keys[keyType];
+//}
// Convert olm error to enum
QOlmError lastError(OlmAccount *account) {
return fromString(olm_account_last_error(account));
}
-QByteArray getRandom(size_t bufferSize)
-{
- QByteArray buffer(bufferSize, '0');
- std::generate(buffer.begin(), buffer.end(), std::rand);
- return buffer;
-}
-
-QOlmAccount::QOlmAccount(const QString &userId, const QString &deviceId, QObject *parent)
+QOlmAccount::QOlmAccount(const QString& userId, const QString& deviceId,
+ QObject* parent)
: QObject(parent)
, m_userId(userId)
, m_deviceId(deviceId)
-{
-}
+{}
QOlmAccount::~QOlmAccount()
{
@@ -66,7 +54,7 @@ void QOlmAccount::createNewAccount()
if (error == olm_error()) {
throw lastError(m_account);
}
- Q_EMIT needsSave();
+ emit needsSave();
}
void QOlmAccount::unpickle(QByteArray &pickled, const PicklingMode &mode)
@@ -161,7 +149,7 @@ size_t QOlmAccount::generateOneTimeKeys(size_t numberOfKeys) const
if (error == olm_error()) {
throw lastError(m_account);
}
- Q_EMIT needsSave();
+ emit needsSave();
return error;
}
@@ -220,14 +208,11 @@ std::optional<QOlmError> QOlmAccount::removeOneTimeKeys(const QOlmSessionPtr &se
if (error == olm_error()) {
return lastError(m_account);
}
- Q_EMIT needsSave();
+ emit needsSave();
return std::nullopt;
}
-OlmAccount *QOlmAccount::data()
-{
- return m_account;
-}
+OlmAccount* QOlmAccount::data() { return m_account; }
DeviceKeys QOlmAccount::deviceKeys() const
{
@@ -284,31 +269,27 @@ std::variant<QOlmSessionPtr, QOlmError> QOlmAccount::createOutboundSession(const
void QOlmAccount::markKeysAsPublished()
{
olm_account_mark_keys_as_published(m_account);
- Q_EMIT needsSave();
+ emit needsSave();
}
-bool Quotient::verifyIdentitySignature(const DeviceKeys &deviceKeys,
- const QString &deviceId,
- const QString &userId)
+bool Quotient::verifyIdentitySignature(const DeviceKeys& deviceKeys,
+ const QString& deviceId,
+ const QString& userId)
{
const auto signKeyId = "ed25519:" + deviceId;
const auto signingKey = deviceKeys.keys[signKeyId];
const auto signature = deviceKeys.signatures[userId][signKeyId];
- if (signature.isEmpty()) {
- return false;
- }
-
return ed25519VerifySignature(signingKey, toJson(deviceKeys), signature);
}
-bool Quotient::ed25519VerifySignature(const QString &signingKey,
- const QJsonObject &obj,
- const QString &signature)
+bool Quotient::ed25519VerifySignature(const QString& signingKey,
+ const QJsonObject& obj,
+ const QString& signature)
{
- if (signature.isEmpty()) {
+ if (signature.isEmpty())
return false;
- }
+
QJsonObject obj1 = obj;
obj1.remove("unsigned");
diff --git a/lib/e2ee/qolminboundsession.h b/lib/e2ee/qolminboundsession.h
index 1f5dadd3..437f753d 100644
--- a/lib/e2ee/qolminboundsession.h
+++ b/lib/e2ee/qolminboundsession.h
@@ -4,12 +4,12 @@
#pragma once
-#include <QByteArray>
-#include <variant>
-#include <memory>
-#include "olm/olm.h"
-#include "e2ee/qolmerrors.h"
#include "e2ee/e2ee.h"
+#include "e2ee/qolmerrors.h"
+#include "olm/olm.h"
+
+#include <memory>
+#include <variant>
namespace Quotient {
@@ -20,16 +20,18 @@ class QUOTIENT_API QOlmInboundGroupSession
public:
~QOlmInboundGroupSession();
//! Creates a new instance of `OlmInboundGroupSession`.
- static std::unique_ptr<QOlmInboundGroupSession> create(const QByteArray &key);
+ static std::unique_ptr<QOlmInboundGroupSession> create(const QByteArray& key);
//! Import an inbound group session, from a previous export.
- static std::unique_ptr<QOlmInboundGroupSession> import(const QByteArray &key);
+ static std::unique_ptr<QOlmInboundGroupSession> import(const QByteArray& key);
//! Serialises an `OlmInboundGroupSession` to encrypted Base64.
QByteArray pickle(const PicklingMode &mode) const;
//! Deserialises from encrypted Base64 that was previously obtained by pickling
//! an `OlmInboundGroupSession`.
- static std::variant<std::unique_ptr<QOlmInboundGroupSession>, QOlmError> unpickle(const QByteArray &picked, const PicklingMode &mode);
+ static std::variant<std::unique_ptr<QOlmInboundGroupSession>, QOlmError>
+ unpickle(const QByteArray& picked, const PicklingMode& mode);
//! Decrypts ciphertext received for this group session.
- std::variant<std::pair<QString, uint32_t>, QOlmError> decrypt(const QByteArray &message);
+ std::variant<std::pair<QString, uint32_t>, QOlmError> decrypt(
+ const QByteArray& message);
//! Export the base64-encoded ratchet key for this session, at the given index,
//! in a format which can be used by import.
std::variant<QByteArray, QOlmError> exportSession(uint32_t messageIndex);
@@ -38,11 +40,11 @@ public:
//! Get a base64-encoded identifier for this session.
QByteArray sessionId() const;
bool isVerified() const;
- QOlmInboundGroupSession(OlmInboundGroupSession *session);
+
+ QOlmInboundGroupSession(OlmInboundGroupSession* session);
private:
- OlmInboundGroupSession *m_groupSession;
+ OlmInboundGroupSession* m_groupSession;
};
using QOlmInboundGroupSessionPtr = std::unique_ptr<QOlmInboundGroupSession>;
-using OlmInboundGroupSessionPtr = std::unique_ptr<OlmInboundGroupSession>;
} // namespace Quotient
diff --git a/lib/e2ee/qolmmessage.cpp b/lib/e2ee/qolmmessage.cpp
index 15008b75..81b166b0 100644
--- a/lib/e2ee/qolmmessage.cpp
+++ b/lib/e2ee/qolmmessage.cpp
@@ -6,11 +6,11 @@
using namespace Quotient;
-QOlmMessage::QOlmMessage(const QByteArray &ciphertext, QOlmMessage::Type type)
+QOlmMessage::QOlmMessage(QByteArray ciphertext, QOlmMessage::Type type)
: QByteArray(std::move(ciphertext))
, m_messageType(type)
{
- Q_ASSERT_X(!ciphertext.isEmpty(), "olm message", "Ciphertext is empty");
+ Q_ASSERT_X(!isEmpty(), "olm message", "Ciphertext is empty");
}
QOlmMessage::QOlmMessage(const QOlmMessage &message)
diff --git a/lib/e2ee/qolmmessage.h b/lib/e2ee/qolmmessage.h
index 557c02b1..5d5db636 100644
--- a/lib/e2ee/qolmmessage.h
+++ b/lib/e2ee/qolmmessage.h
@@ -28,8 +28,9 @@ public:
Q_ENUM(Type)
QOlmMessage() = default;
- explicit QOlmMessage(const QByteArray &ciphertext, Type type = General);
+ explicit QOlmMessage(QByteArray ciphertext, Type type = General);
explicit QOlmMessage(const QOlmMessage &message);
+ ~QOlmMessage() = default;
static QOlmMessage fromCiphertext(const QByteArray &ciphertext);
diff --git a/lib/e2ee/qolmoutboundsession.h b/lib/e2ee/qolmoutboundsession.h
index 0122bbfd..32ba2b3b 100644
--- a/lib/e2ee/qolmoutboundsession.h
+++ b/lib/e2ee/qolmoutboundsession.h
@@ -24,7 +24,8 @@ public:
std::variant<QByteArray, QOlmError> pickle(const PicklingMode &mode);
//! Deserialises from encrypted Base64 that was previously obtained by
//! pickling a `QOlmOutboundGroupSession`.
- static std::variant<std::unique_ptr<QOlmOutboundGroupSession>, QOlmError> unpickle(QByteArray &pickled, const PicklingMode &mode);
+ static std::variant<std::unique_ptr<QOlmOutboundGroupSession>, QOlmError>
+ unpickle(QByteArray& pickled, const PicklingMode& mode);
//! Encrypts a plaintext message using the session.
std::variant<QByteArray, QOlmError> encrypt(const QString &plaintext);
@@ -48,5 +49,4 @@ private:
};
using QOlmOutboundGroupSessionPtr = std::unique_ptr<QOlmOutboundGroupSession>;
-using OlmOutboundGroupSessionPtr = std::unique_ptr<OlmOutboundGroupSession>;
}
diff --git a/lib/e2ee/qolmsession.h b/lib/e2ee/qolmsession.h
index 889a606d..f20c9837 100644
--- a/lib/e2ee/qolmsession.h
+++ b/lib/e2ee/qolmsession.h
@@ -16,20 +16,31 @@ namespace Quotient {
class QOlmAccount;
class QOlmSession;
-
//! Either an outbound or inbound session for secure communication.
class QUOTIENT_API QOlmSession
{
public:
~QOlmSession();
//! Creates an inbound session for sending/receiving messages from a received 'prekey' message.
- static std::variant<std::unique_ptr<QOlmSession>, QOlmError> createInboundSession(QOlmAccount *account, const QOlmMessage &preKeyMessage);
- static std::variant<std::unique_ptr<QOlmSession>, QOlmError> createInboundSessionFrom(QOlmAccount *account, const QString &theirIdentityKey, const QOlmMessage &preKeyMessage);
- static std::variant<std::unique_ptr<QOlmSession>, QOlmError> createOutboundSession(QOlmAccount *account, const QString &theirIdentityKey, const QString &theirOneTimeKey);
+ static std::variant<std::unique_ptr<QOlmSession>, QOlmError>
+ createInboundSession(QOlmAccount* account, const QOlmMessage& preKeyMessage);
+
+ static std::variant<std::unique_ptr<QOlmSession>, QOlmError>
+ createInboundSessionFrom(QOlmAccount* account,
+ const QString& theirIdentityKey,
+ const QOlmMessage& preKeyMessage);
+
+ static std::variant<std::unique_ptr<QOlmSession>, QOlmError>
+ createOutboundSession(QOlmAccount* account, const QString& theirIdentityKey,
+ const QString& theirOneTimeKey);
+
//! Serialises an `QOlmSession` to encrypted Base64.
std::variant<QByteArray, QOlmError> pickle(const PicklingMode &mode);
+
//! Deserialises from encrypted Base64 that was previously obtained by pickling a `QOlmSession`.
- static std::variant<std::unique_ptr<QOlmSession>, QOlmError> unpickle(const QByteArray &pickled, const PicklingMode &mode);
+ static std::variant<std::unique_ptr<QOlmSession>, QOlmError> unpickle(
+ const QByteArray& pickled, const PicklingMode& mode);
+
//! Encrypts a plaintext message using the session.
QOlmMessage encrypt(const QString &plaintext);
@@ -48,29 +59,33 @@ public:
bool hasReceivedMessage() const;
//! Checks if the 'prekey' message is for this in-bound session.
- std::variant<bool, QOlmError> matchesInboundSession(const QOlmMessage &preKeyMessage) const;
+ std::variant<bool, QOlmError> matchesInboundSession(
+ const QOlmMessage& preKeyMessage) const;
//! Checks if the 'prekey' message is for this in-bound session.
- std::variant<bool, QOlmError> matchesInboundSessionFrom(const QString &theirIdentityKey, const QOlmMessage &preKeyMessage) const;
+ std::variant<bool, QOlmError> matchesInboundSessionFrom(
+ const QString& theirIdentityKey, const QOlmMessage& preKeyMessage) const;
friend bool operator<(const QOlmSession& lhs, const QOlmSession& rhs)
{
return lhs.sessionId() < rhs.sessionId();
}
- friend bool operator<(const std::unique_ptr<QOlmSession> &lhs, const std::unique_ptr<QOlmSession> &rhs) {
+ friend bool operator<(const std::unique_ptr<QOlmSession>& lhs,
+ const std::unique_ptr<QOlmSession>& rhs)
+ {
return *lhs < *rhs;
}
- OlmSession *raw() const
- {
- return m_session;
- }
+ OlmSession* raw() const { return m_session; }
+
QOlmSession(OlmSession* session);
private:
//! Helper function for creating new sessions and handling errors.
static OlmSession* create();
- static std::variant<std::unique_ptr<QOlmSession>, QOlmError> createInbound(QOlmAccount *account, const QOlmMessage& preKeyMessage, bool from = false, const QString& theirIdentityKey = "");
+ static std::variant<std::unique_ptr<QOlmSession>, QOlmError> createInbound(
+ QOlmAccount* account, const QOlmMessage& preKeyMessage,
+ bool from = false, const QString& theirIdentityKey = "");
OlmSession* m_session;
};
} //namespace Quotient
diff --git a/lib/e2ee/qolmutility.h b/lib/e2ee/qolmutility.h
index b2e79e29..a12af49a 100644
--- a/lib/e2ee/qolmutility.h
+++ b/lib/e2ee/qolmutility.h
@@ -4,7 +4,6 @@
#pragma once
-#include <QObject>
#include <variant>
#include "e2ee/qolmerrors.h"
@@ -13,7 +12,6 @@ struct OlmUtility;
namespace Quotient {
class QOlmSession;
-class Connection;
//! Allows you to make use of crytographic hashing via SHA-2 and
//! verifying ed25519 signatures.
@@ -37,7 +35,6 @@ public:
std::variant<bool, QOlmError> ed25519Verify(const QByteArray &key,
const QByteArray &message, const QByteArray &signature);
-
private:
OlmUtility *m_utility;