aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlexey Rusakov <Kitsune-Ral@users.sf.net>2022-09-21 15:45:59 +0200
committerAlexey Rusakov <Kitsune-Ral@users.sf.net>2022-09-26 10:46:34 +0200
commitbcc05aa1d52cae2b6d8e70bb6cf04fa49904687a (patch)
tree7d005271303f9d96de10766cfab4a5b5e2dceafe
parent363a7e40e8aa12cb780b076cca8db4f47b70f4fa (diff)
downloadlibquotient-bcc05aa1d52cae2b6d8e70bb6cf04fa49904687a.tar.gz
libquotient-bcc05aa1d52cae2b6d8e70bb6cf04fa49904687a.zip
Cleanup across E2EE code
Notably: - simplified unnecessarily verbose constructs; - formally aligned (no re-numeration was necessary) QOlmMessage::Type with corresponding OLM_ constants; - dropped QOlmSession::encryptMessageType() because it's very sensitive to the order of calling with QOlmSession::encrypt() (and encrypt() itself already calls it and returns the message type); - simplify the return type of pickle() calls that can only fail due to an internal error; - replace const QString& with QStringView or const QByteArray& where appropriate; - use '\0' where it was meant to be instead of '0'.
-rw-r--r--autotests/testgroupsession.cpp9
-rw-r--r--autotests/testolmaccount.cpp3
-rw-r--r--autotests/testolmsession.cpp10
-rw-r--r--autotests/testolmutility.cpp15
-rw-r--r--lib/connection.cpp8
-rw-r--r--lib/e2ee/e2ee.h2
-rw-r--r--lib/e2ee/qolmaccount.cpp54
-rw-r--r--lib/e2ee/qolmaccount.h9
-rw-r--r--lib/e2ee/qolminboundsession.cpp57
-rw-r--r--lib/e2ee/qolminboundsession.h4
-rw-r--r--lib/e2ee/qolmmessage.cpp6
-rw-r--r--lib/e2ee/qolmmessage.h12
-rw-r--r--lib/e2ee/qolmoutboundsession.cpp44
-rw-r--r--lib/e2ee/qolmoutboundsession.h4
-rw-r--r--lib/e2ee/qolmsession.cpp96
-rw-r--r--lib/e2ee/qolmsession.h15
-rw-r--r--lib/e2ee/qolmutility.cpp24
-rw-r--r--lib/e2ee/qolmutils.h1
-rw-r--r--lib/events/filesourceinfo.cpp35
-rw-r--r--lib/keyverificationsession.cpp6
20 files changed, 186 insertions, 228 deletions
diff --git a/autotests/testgroupsession.cpp b/autotests/testgroupsession.cpp
index 3c329a8a..18ace73b 100644
--- a/autotests/testgroupsession.cpp
+++ b/autotests/testgroupsession.cpp
@@ -17,7 +17,9 @@ void TestGroupSession::groupSessionPicklingValid()
QCOMPARE(0, ogs->sessionMessageIndex());
auto ogsPickled = ogs->pickle(Unencrypted {}).value();
- auto ogs2 = QOlmOutboundGroupSession::unpickle(ogsPickled, Unencrypted {}).value();
+ auto ogs2 =
+ QOlmOutboundGroupSession::unpickle(std::move(ogsPickled), Unencrypted{})
+ .value();
QCOMPARE(ogsId, ogs2->sessionId());
auto igs = QOlmInboundGroupSession::create(ogs->sessionKey().value());
@@ -29,7 +31,8 @@ void TestGroupSession::groupSessionPicklingValid()
QCOMPARE(0, igs->firstKnownIndex());
auto igsPickled = igs->pickle(Unencrypted {});
- igs = QOlmInboundGroupSession::unpickle(igsPickled, Unencrypted {}).value();
+ igs = QOlmInboundGroupSession::unpickle(std::move(igsPickled), Unencrypted{})
+ .value();
QCOMPARE(igsId, igs->sessionId());
}
@@ -39,7 +42,7 @@ void TestGroupSession::groupSessionCryptoValid()
auto igs = QOlmInboundGroupSession::create(ogs->sessionKey().value());
QCOMPARE(ogs->sessionId(), igs->sessionId());
- const auto plainText = QStringLiteral("Hello world!");
+ const auto plainText = "Hello world!";
const auto ciphertext = ogs->encrypt(plainText).value();
// ciphertext valid base64?
QVERIFY(QByteArray::fromBase64(ciphertext).size() > 0);
diff --git a/autotests/testolmaccount.cpp b/autotests/testolmaccount.cpp
index eb428661..0e1eab84 100644
--- a/autotests/testolmaccount.cpp
+++ b/autotests/testolmaccount.cpp
@@ -25,7 +25,8 @@ void TestOlmAccount::pickleUnpickledTest()
auto identityKeys = olmAccount.identityKeys();
auto pickled = olmAccount.pickle(Unencrypted{}).value();
QOlmAccount olmAccount2(QStringLiteral("@foo:bar.com"), QStringLiteral("QuotientTestDevice"));
- auto unpickleResult = olmAccount2.unpickle(pickled, Unencrypted{});
+ auto unpickleResult = olmAccount2.unpickle(std::move(pickled),
+ Unencrypted{});
QCOMPARE(unpickleResult, 0);
auto identityKeys2 = olmAccount2.identityKeys();
QCOMPARE(identityKeys.curve25519, identityKeys2.curve25519);
diff --git a/autotests/testolmsession.cpp b/autotests/testolmsession.cpp
index 66a04241..18b0d5f2 100644
--- a/autotests/testolmsession.cpp
+++ b/autotests/testolmsession.cpp
@@ -11,12 +11,14 @@ std::pair<QOlmSessionPtr, QOlmSessionPtr> createSessionPair()
{
QByteArray pickledAccountA("eOBXIKivUT6YYowRH031BNv7zNmzqM5B7CpXdyeaPvala5mt7/OeqrG1qVA7vA1SYloFyvJPIy0QNkD3j1HiPl5vtZHN53rtfZ9exXDok03zjmssqn4IJsqcA7Fbo1FZeKafG0NFcWwCPTdmcV7REqxjqGm3I4K8MQFa45AdTGSUu2C12cWeOcbSMlcINiMral+Uyah1sgPmLJ18h1qcnskXUXQvpffZ5DiUw1Iz5zxnwOQF1GVyowPJD7Zdugvj75RQnDxAn6CzyvrY2k2CuedwqDC3fIXM2xdUNWttW4nC2g4InpBhCVvNwhZYxlUb5BUEjmPI2AB3dAL5ry6o9MFncmbN6x5x");
QByteArray pickledAccountB("eModTvoFi9oOIkax4j4nuxw9Tcl/J8mOmUctUWI68Q89HSaaPTqR+tdlKQ85v2GOs5NlZCp7EuycypN9GQ4fFbHUCrS7nspa3GFBWsR8PnM8+wez5PWmfFZLg3drOvT0jbMjpDx0MjGYClHBqcrEpKx9oFaIRGBaX6HXzT4lRaWSJkXxuX92q8iGNrLn96PuAWFNcD+2JXpPcNFntslwLUNgqzpZ04aIFYwL80GmzyOgq3Bz1GO6u3TgCQEAmTIYN2QkO0MQeuSfe7UoMumhlAJ6R8GPcdSSPtmXNk4tdyzzlgpVq1hm7ZLKto+g8/5Aq3PvnvA8wCqno2+Pi1duK1pZFTIlActr");
- auto accountA = QOlmAccount("accountA:foo.com", "Device1UserA");
- if (accountA.unpickle(pickledAccountA, Unencrypted{}) != OLM_SUCCESS)
+ auto accountA = QOlmAccount(u"accountA:foo.com", u"Device1UserA");
+ if (accountA.unpickle(std::move(pickledAccountA), Unencrypted{})
+ != OLM_SUCCESS)
qFatal("Failed to unpickle account A: %s", accountA.lastError());
- auto accountB = QOlmAccount("accountB:foo.com", "Device1UserB");
- if (accountB.unpickle(pickledAccountB, Unencrypted{}) != OLM_SUCCESS)
+ auto accountB = QOlmAccount(u"accountB:foo.com", u"Device1UserB");
+ if (accountB.unpickle(std::move(pickledAccountB), Unencrypted{})
+ != OLM_SUCCESS)
qFatal("Failed to unpickle account B: %s", accountB.lastError());
diff --git a/autotests/testolmutility.cpp b/autotests/testolmutility.cpp
index 5b67c805..64ceb3e7 100644
--- a/autotests/testolmutility.cpp
+++ b/autotests/testolmutility.cpp
@@ -49,7 +49,7 @@ void TestOlmUtility::canonicalJSON()
void TestOlmUtility::verifySignedOneTimeKey()
{
- QOlmAccount aliceOlm { "@alice:matrix.org", "aliceDevice" };
+ QOlmAccount aliceOlm { u"@alice:matrix.org", u"aliceDevice" };
aliceOlm.createNewAccount();
aliceOlm.generateOneTimeKeys(1);
auto keys = aliceOlm.oneTimeKeys();
@@ -64,16 +64,13 @@ void TestOlmUtility::verifySignedOneTimeKey()
auto utility = olm_utility(utilityBuf);
- QByteArray signatureBuf1(sig.length(), '0');
+ QByteArray signatureBuf1(sig.length(), '\0');
std::copy(sig.begin(), sig.end(), signatureBuf1.begin());
- auto res = olm_ed25519_verify(utility,
- aliceOlm.identityKeys().ed25519.data(),
- aliceOlm.identityKeys().ed25519.size(),
- msg.data(),
- msg.size(),
- (void *)sig.data(),
- sig.size());
+ auto res =
+ olm_ed25519_verify(utility, aliceOlm.identityKeys().ed25519.data(),
+ aliceOlm.identityKeys().ed25519.size(), msg.data(),
+ msg.size(), sig.data(), sig.size());
QCOMPARE(std::string(olm_utility_last_error(utility)), "SUCCESS");
QCOMPARE(res, 0);
diff --git a/lib/connection.cpp b/lib/connection.cpp
index 865dff79..f38bb751 100644
--- a/lib/connection.cpp
+++ b/lib/connection.cpp
@@ -652,8 +652,7 @@ void Connection::Private::completeSetup(const QString& mxId)
});
} else {
// account already existing
- auto pickle = database->accountPickle();
- olmAccount->unpickle(pickle, picklingMode);
+ olmAccount->unpickle(database->accountPickle(), picklingMode);
}
#endif // Quotient_E2EE_ENABLED
emit q->stateChanged();
@@ -2300,14 +2299,13 @@ std::pair<QOlmMessage::Type, QByteArray> Connection::Private::olmEncryptMessage(
{
const auto& curveKey = curveKeyForUserDevice(userId, device);
const auto& olmSession = olmSessions.at(curveKey).front();
- QOlmMessage::Type type = olmSession->encryptMessageType();
const auto result = olmSession->encrypt(message);
if (const auto pickle = olmSession->pickle(picklingMode)) {
database->updateOlmSession(curveKey, olmSession->sessionId(), *pickle);
} else {
qWarning(E2EE) << "Failed to pickle olm session: " << pickle.error();
}
- return { type, result.toCiphertext() };
+ return { result.type(), result.toCiphertext() };
}
bool Connection::Private::createOlmSession(const QString& targetUserId,
@@ -2343,7 +2341,7 @@ bool Connection::Private::createOlmSession(const QString& targetUserId,
return false;
}
const auto recipientCurveKey =
- curveKeyForUserDevice(targetUserId, targetDeviceId);
+ curveKeyForUserDevice(targetUserId, targetDeviceId).toLatin1();
auto session =
QOlmSession::createOutboundSession(olmAccount.get(), recipientCurveKey,
signedOneTimeKey->key());
diff --git a/lib/e2ee/e2ee.h b/lib/e2ee/e2ee.h
index 51ceff67..5999c0be 100644
--- a/lib/e2ee/e2ee.h
+++ b/lib/e2ee/e2ee.h
@@ -98,7 +98,7 @@ public:
{}
//! Unpadded Base64-encoded 32-byte Curve25519 public key
- QString key() const { return payload["key"_ls].toString(); }
+ QByteArray key() const { return payload["key"_ls].toString().toLatin1(); }
//! \brief Signatures of the key object
//!
diff --git a/lib/e2ee/qolmaccount.cpp b/lib/e2ee/qolmaccount.cpp
index d33db8e3..556a8274 100644
--- a/lib/e2ee/qolmaccount.cpp
+++ b/lib/e2ee/qolmaccount.cpp
@@ -27,11 +27,11 @@ const char* QOlmAccount::lastError() const
return olm_account_last_error(m_account);
}
-QOlmAccount::QOlmAccount(const QString& userId, const QString& deviceId,
+QOlmAccount::QOlmAccount(QStringView userId, QStringView deviceId,
QObject* parent)
: QObject(parent)
- , m_userId(userId)
- , m_deviceId(deviceId)
+ , m_userId(userId.toString())
+ , m_deviceId(deviceId.toString())
{}
QOlmAccount::~QOlmAccount()
@@ -43,20 +43,20 @@ QOlmAccount::~QOlmAccount()
void QOlmAccount::createNewAccount()
{
m_account = olm_account(new uint8_t[olm_account_size()]);
- size_t randomSize = olm_create_account_random_length(m_account);
- QByteArray randomData = getRandom(randomSize);
- if (olm_create_account(m_account, randomData.data(), randomSize)
+ const auto randomLength = olm_create_account_random_length(m_account);
+ QByteArray randomData = getRandom(randomLength);
+ if (olm_create_account(m_account, randomData.data(), randomLength)
== olm_error()) {
throw lastError();
}
emit needsSave();
}
-OlmErrorCode QOlmAccount::unpickle(QByteArray &pickled, const PicklingMode &mode)
+OlmErrorCode QOlmAccount::unpickle(QByteArray&& pickled, const PicklingMode &mode)
{
m_account = olm_account(new uint8_t[olm_account_size()]);
- const QByteArray key = toKey(mode);
- if (olm_unpickle_account(m_account, key.data(), key.length(),
+ if (const auto key = toKey(mode);
+ olm_unpickle_account(m_account, key.data(), key.length(),
pickled.data(), pickled.size())
== olm_error()) {
// Probably log the user out since we have no way of getting to the keys
@@ -69,7 +69,7 @@ QOlmExpected<QByteArray> QOlmAccount::pickle(const PicklingMode &mode)
{
const QByteArray key = toKey(mode);
const size_t pickleLength = olm_pickle_account_length(m_account);
- QByteArray pickleBuffer(pickleLength, '0');
+ QByteArray pickleBuffer(pickleLength, '\0');
if (olm_pickle_account(m_account, key.data(), key.length(),
pickleBuffer.data(), pickleLength)
== olm_error())
@@ -80,12 +80,12 @@ QOlmExpected<QByteArray> QOlmAccount::pickle(const PicklingMode &mode)
IdentityKeys QOlmAccount::identityKeys() const
{
const size_t keyLength = olm_account_identity_keys_length(m_account);
- QByteArray keyBuffer(keyLength, '0');
+ QByteArray keyBuffer(keyLength, '\0');
if (olm_account_identity_keys(m_account, keyBuffer.data(), keyLength)
== olm_error()) {
throw lastError();
}
- const QJsonObject key = QJsonDocument::fromJson(keyBuffer).object();
+ const auto key = QJsonDocument::fromJson(keyBuffer).object();
return IdentityKeys {
key.value(QStringLiteral("curve25519")).toString().toUtf8(),
key.value(QStringLiteral("ed25519")).toString().toUtf8()
@@ -94,7 +94,7 @@ IdentityKeys QOlmAccount::identityKeys() const
QByteArray QOlmAccount::sign(const QByteArray &message) const
{
- QByteArray signatureBuffer(olm_account_signature_length(m_account), '0');
+ QByteArray signatureBuffer(olm_account_signature_length(m_account), '\0');
if (olm_account_sign(m_account, message.data(), message.length(),
signatureBuffer.data(), signatureBuffer.length())
@@ -112,15 +112,15 @@ QByteArray QOlmAccount::sign(const QJsonObject &message) const
QByteArray QOlmAccount::signIdentityKeys() const
{
const auto keys = identityKeys();
- return sign(QJsonObject {
- { "algorithms", QJsonArray { "m.olm.v1.curve25519-aes-sha2",
- "m.megolm.v1.aes-sha2" } },
+ return sign(QJsonObject{
+ { "algorithms", QJsonArray{ "m.olm.v1.curve25519-aes-sha2",
+ "m.megolm.v1.aes-sha2" } },
{ "user_id", m_userId },
{ "device_id", m_deviceId },
- { "keys", QJsonObject { { QStringLiteral("curve25519:") + m_deviceId,
- QString::fromUtf8(keys.curve25519) },
- { QStringLiteral("ed25519:") + m_deviceId,
- QString::fromUtf8(keys.ed25519) } } } });
+ { "keys", QJsonObject{ { QStringLiteral("curve25519:") + m_deviceId,
+ QString::fromUtf8(keys.curve25519) },
+ { QStringLiteral("ed25519:") + m_deviceId,
+ QString::fromUtf8(keys.ed25519) } } } });
}
size_t QOlmAccount::maxNumberOfOneTimeKeys() const
@@ -130,7 +130,7 @@ size_t QOlmAccount::maxNumberOfOneTimeKeys() const
size_t QOlmAccount::generateOneTimeKeys(size_t numberOfKeys)
{
- const size_t randomLength =
+ const auto randomLength =
olm_account_generate_one_time_keys_random_length(m_account,
numberOfKeys);
QByteArray randomBuffer = getRandom(randomLength);
@@ -147,8 +147,8 @@ size_t QOlmAccount::generateOneTimeKeys(size_t numberOfKeys)
UnsignedOneTimeKeys QOlmAccount::oneTimeKeys() const
{
- const size_t oneTimeKeyLength = olm_account_one_time_keys_length(m_account);
- QByteArray oneTimeKeysBuffer(static_cast<int>(oneTimeKeyLength), '0');
+ const auto oneTimeKeyLength = olm_account_one_time_keys_length(m_account);
+ QByteArray oneTimeKeysBuffer(static_cast<int>(oneTimeKeyLength), '\0');
if (olm_account_one_time_keys(m_account, oneTimeKeysBuffer.data(),
oneTimeKeyLength)
@@ -193,13 +193,13 @@ DeviceKeys QOlmAccount::deviceKeys() const
SupportedAlgorithms.cend());
const auto idKeys = identityKeys();
- return DeviceKeys {
+ return DeviceKeys{
.userId = m_userId,
.deviceId = m_deviceId,
.algorithms = Algorithms,
- .keys { { "curve25519:" + m_deviceId, idKeys.curve25519 },
- { "ed25519:" + m_deviceId, idKeys.ed25519 } },
- .signatures {
+ .keys{ { "curve25519:" + m_deviceId, idKeys.curve25519 },
+ { "ed25519:" + m_deviceId, idKeys.ed25519 } },
+ .signatures{
{ m_userId, { { "ed25519:" + m_deviceId, signIdentityKeys() } } } }
};
}
diff --git a/lib/e2ee/qolmaccount.h b/lib/e2ee/qolmaccount.h
index 5ad98e47..0fb9803f 100644
--- a/lib/e2ee/qolmaccount.h
+++ b/lib/e2ee/qolmaccount.h
@@ -24,7 +24,8 @@ class QUOTIENT_API QOlmAccount : public QObject
{
Q_OBJECT
public:
- QOlmAccount(const QString &userId, const QString &deviceId, QObject *parent = nullptr);
+ QOlmAccount(QStringView userId, QStringView deviceId,
+ QObject* parent = nullptr);
~QOlmAccount() override;
//! Creates a new instance of OlmAccount. During the instantiation
@@ -36,7 +37,7 @@ public:
//! Deserialises from encrypted Base64 that was previously obtained by pickling a `QOlmAccount`.
//! This needs to be called before any other action or use createNewAccount() instead.
- [[nodiscard]] OlmErrorCode unpickle(QByteArray& pickled,
+ [[nodiscard]] OlmErrorCode unpickle(QByteArray&& pickled,
const PicklingMode& mode);
//! Serialises an OlmAccount to encrypted Base64.
@@ -74,7 +75,7 @@ public:
//! Creates an inbound session for sending/receiving messages from a received 'prekey' message.
//!
- //! \param message An Olm pre-key message that was encrypted for this account.
+ //! \param preKeyMessage An Olm pre-key message that was encrypted for this account.
QOlmExpected<QOlmSessionPtr> createInboundSession(
const QOlmMessage& preKeyMessage);
@@ -93,7 +94,7 @@ public:
void markKeysAsPublished();
OlmErrorCode lastErrorCode() const;
- const char *lastError() const;
+ const char* lastError() const;
// HACK do not use directly
QOlmAccount(OlmAccount *account);
diff --git a/lib/e2ee/qolminboundsession.cpp b/lib/e2ee/qolminboundsession.cpp
index 870070c2..a05ddf62 100644
--- a/lib/e2ee/qolminboundsession.cpp
+++ b/lib/e2ee/qolminboundsession.cpp
@@ -2,8 +2,9 @@
//
// SPDX-License-Identifier: LGPL-2.1-or-later
-#include "e2ee/qolminboundsession.h"
-#include "logging.h"
+#include "qolminboundsession.h"
+#include "qolmutils.h"
+#include "../logging.h"
#include <cstring>
#include <iostream>
@@ -37,7 +38,7 @@ std::unique_ptr<QOlmInboundGroupSession> QOlmInboundGroupSession::create(const Q
olmInboundGroupSession,
reinterpret_cast<const uint8_t*>(key.constData()), key.size())
== olm_error()) {
- // FIXME: create QOlmInboundGroupSession earlier and use lastError()
+ // FIXME: create QOlmInboundGroupSession earlier and use lastErrorCode()
throw olm_inbound_group_session_last_error_code(olmInboundGroupSession);
}
@@ -47,11 +48,10 @@ std::unique_ptr<QOlmInboundGroupSession> QOlmInboundGroupSession::create(const Q
std::unique_ptr<QOlmInboundGroupSession> QOlmInboundGroupSession::import(const QByteArray &key)
{
const auto olmInboundGroupSession = olm_inbound_group_session(new uint8_t[olm_inbound_group_session_size()]);
- QByteArray keyBuf = key;
if (olm_import_inbound_group_session(
olmInboundGroupSession,
- reinterpret_cast<const uint8_t*>(keyBuf.data()), keyBuf.size())
+ reinterpret_cast<const uint8_t*>(key.data()), key.size())
== olm_error()) {
// FIXME: create QOlmInboundGroupSession earlier and use lastError()
throw olm_inbound_group_session_last_error_code(olmInboundGroupSession);
@@ -60,19 +60,12 @@ std::unique_ptr<QOlmInboundGroupSession> QOlmInboundGroupSession::import(const Q
return std::make_unique<QOlmInboundGroupSession>(olmInboundGroupSession);
}
-QByteArray toKey(const PicklingMode &mode)
-{
- if (std::holds_alternative<Unencrypted>(mode)) {
- return "";
- }
- return std::get<Encrypted>(mode).key;
-}
-
-QByteArray QOlmInboundGroupSession::pickle(const PicklingMode &mode) const
+QByteArray QOlmInboundGroupSession::pickle(const PicklingMode& mode) const
{
- QByteArray pickledBuf(olm_pickle_inbound_group_session_length(m_groupSession), '0');
- const QByteArray key = toKey(mode);
- if (olm_pickle_inbound_group_session(m_groupSession, key.data(),
+ QByteArray pickledBuf(
+ olm_pickle_inbound_group_session_length(m_groupSession), '\0');
+ if (const auto key = toKey(mode);
+ olm_pickle_inbound_group_session(m_groupSession, key.data(),
key.length(), pickledBuf.data(),
pickledBuf.length())
== olm_error()) {
@@ -82,14 +75,13 @@ QByteArray QOlmInboundGroupSession::pickle(const PicklingMode &mode) const
}
QOlmExpected<QOlmInboundGroupSessionPtr> QOlmInboundGroupSession::unpickle(
- const QByteArray& pickled, const PicklingMode& mode)
+ QByteArray&& pickled, const PicklingMode& mode)
{
- QByteArray pickledBuf = pickled;
const auto groupSession = olm_inbound_group_session(new uint8_t[olm_inbound_group_session_size()]);
- QByteArray key = toKey(mode);
+ auto key = toKey(mode);
if (olm_unpickle_inbound_group_session(groupSession, key.data(),
- key.length(), pickledBuf.data(),
- pickledBuf.size())
+ key.length(), pickled.data(),
+ pickled.size())
== olm_error()) {
// FIXME: create QOlmInboundGroupSession earlier and use lastError()
return olm_inbound_group_session_last_error_code(groupSession);
@@ -107,13 +99,16 @@ QOlmExpected<std::pair<QByteArray, uint32_t>> QOlmInboundGroupSession::decrypt(
// We need to clone the message because
// olm_decrypt_max_plaintext_length destroys the input buffer
- QByteArray messageBuf(message.length(), '0');
+ QByteArray messageBuf(message.length(), '\0');
std::copy(message.begin(), message.end(), messageBuf.begin());
- QByteArray plaintextBuf(olm_group_decrypt_max_plaintext_length(m_groupSession,
- reinterpret_cast<uint8_t *>(messageBuf.data()), messageBuf.length()), '0');
+ QByteArray plaintextBuf(olm_group_decrypt_max_plaintext_length(
+ m_groupSession,
+ reinterpret_cast<uint8_t*>(messageBuf.data()),
+ messageBuf.length()),
+ '\0');
- messageBuf = QByteArray(message.length(), '0');
+ messageBuf = QByteArray(message.length(), '\0');
std::copy(message.begin(), message.end(), messageBuf.begin());
const auto plaintextLen = olm_group_decrypt(m_groupSession, reinterpret_cast<uint8_t *>(messageBuf.data()),
@@ -123,16 +118,17 @@ QOlmExpected<std::pair<QByteArray, uint32_t>> QOlmInboundGroupSession::decrypt(
return lastErrorCode();
}
- QByteArray output(plaintextLen, '0');
+ QByteArray output(plaintextLen, '\0');
std::memcpy(output.data(), plaintextBuf.data(), plaintextLen);
return std::make_pair(output, messageIndex);
}
-QOlmExpected<QByteArray> QOlmInboundGroupSession::exportSession(uint32_t messageIndex)
+QOlmExpected<QByteArray> QOlmInboundGroupSession::exportSession(
+ uint32_t messageIndex)
{
const auto keyLength = olm_export_inbound_group_session_length(m_groupSession);
- QByteArray keyBuf(keyLength, '0');
+ QByteArray keyBuf(keyLength, '\0');
if (olm_export_inbound_group_session(
m_groupSession, reinterpret_cast<uint8_t*>(keyBuf.data()),
keyLength, messageIndex)
@@ -149,7 +145,8 @@ uint32_t QOlmInboundGroupSession::firstKnownIndex() const
QByteArray QOlmInboundGroupSession::sessionId() const
{
- QByteArray sessionIdBuf(olm_inbound_group_session_id_length(m_groupSession), '0');
+ QByteArray sessionIdBuf(olm_inbound_group_session_id_length(m_groupSession),
+ '\0');
if (olm_inbound_group_session_id(
m_groupSession, reinterpret_cast<uint8_t*>(sessionIdBuf.data()),
sessionIdBuf.length())
diff --git a/lib/e2ee/qolminboundsession.h b/lib/e2ee/qolminboundsession.h
index e8da6355..0b89349a 100644
--- a/lib/e2ee/qolminboundsession.h
+++ b/lib/e2ee/qolminboundsession.h
@@ -21,11 +21,11 @@ public:
//! Import an inbound group session, from a previous export.
static std::unique_ptr<QOlmInboundGroupSession> import(const QByteArray& key);
//! Serialises an `OlmInboundGroupSession` to encrypted Base64.
- QByteArray pickle(const PicklingMode &mode) const;
+ QByteArray pickle(const PicklingMode& mode) const;
//! Deserialises from encrypted Base64 that was previously obtained by pickling
//! an `OlmInboundGroupSession`.
static QOlmExpected<QOlmInboundGroupSessionPtr> unpickle(
- const QByteArray& pickled, const PicklingMode& mode);
+ QByteArray&& pickled, const PicklingMode& mode);
//! Decrypts ciphertext received for this group session.
QOlmExpected<std::pair<QByteArray, uint32_t> > decrypt(const QByteArray& message);
//! Export the base64-encoded ratchet key for this session, at the given index,
diff --git a/lib/e2ee/qolmmessage.cpp b/lib/e2ee/qolmmessage.cpp
index f9b4a5c2..b9cb8bd2 100644
--- a/lib/e2ee/qolmmessage.cpp
+++ b/lib/e2ee/qolmmessage.cpp
@@ -15,12 +15,6 @@ QOlmMessage::QOlmMessage(QByteArray ciphertext, QOlmMessage::Type type)
Q_ASSERT_X(!isEmpty(), "olm message", "Ciphertext is empty");
}
-QOlmMessage::QOlmMessage(const QOlmMessage &message)
- : QByteArray(message)
- , m_messageType(message.type())
-{
-}
-
QOlmMessage::Type QOlmMessage::type() const
{
return m_messageType;
diff --git a/lib/e2ee/qolmmessage.h b/lib/e2ee/qolmmessage.h
index b4285a93..ea73b3e3 100644
--- a/lib/e2ee/qolmmessage.h
+++ b/lib/e2ee/qolmmessage.h
@@ -6,8 +6,9 @@
#include "quotient_export.h"
-#include <QObject>
-#include <QByteArray>
+#include <QtCore/QByteArray>
+#include <qobjectdefs.h>
+#include <olm/olm.h>
namespace Quotient {
@@ -22,15 +23,12 @@ class QUOTIENT_API QOlmMessage : public QByteArray {
Q_GADGET
public:
enum Type {
- PreKey = 0,
- General,
+ PreKey = OLM_MESSAGE_TYPE_PRE_KEY,
+ General = OLM_MESSAGE_TYPE_MESSAGE,
};
Q_ENUM(Type)
- QOlmMessage() = default;
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.cpp b/lib/e2ee/qolmoutboundsession.cpp
index 79c16e01..22107a21 100644
--- a/lib/e2ee/qolmoutboundsession.cpp
+++ b/lib/e2ee/qolmoutboundsession.cpp
@@ -2,9 +2,10 @@
//
// SPDX-License-Identifier: LGPL-2.1-or-later
-#include "e2ee/qolmoutboundsession.h"
+#include "qolmoutboundsession.h"
-#include "e2ee/qolmutils.h"
+#include "logging.h"
+#include "qolmutils.h"
#include <olm/olm.h>
@@ -43,8 +44,9 @@ QOlmOutboundGroupSessionPtr QOlmOutboundGroupSession::create()
throw olm_outbound_group_session_last_error_code(olmOutboundGroupSession);
}
+ // FIXME: is it used anywhere?
const auto keyMaxLength = olm_outbound_group_session_key_length(olmOutboundGroupSession);
- QByteArray keyBuffer(keyMaxLength, '0');
+ QByteArray keyBuffer(keyMaxLength, '\0');
olm_outbound_group_session_key(olmOutboundGroupSession, reinterpret_cast<uint8_t *>(keyBuffer.data()),
keyMaxLength);
@@ -55,8 +57,9 @@ QOlmOutboundGroupSessionPtr QOlmOutboundGroupSession::create()
QOlmExpected<QByteArray> QOlmOutboundGroupSession::pickle(const PicklingMode &mode) const
{
- QByteArray pickledBuf(olm_pickle_outbound_group_session_length(m_groupSession), '0');
- QByteArray key = toKey(mode);
+ QByteArray pickledBuf(
+ olm_pickle_outbound_group_session_length(m_groupSession), '\0');
+ auto key = toKey(mode);
if (olm_pickle_outbound_group_session(m_groupSession, key.data(),
key.length(), pickledBuf.data(),
pickledBuf.length())
@@ -64,40 +67,41 @@ QOlmExpected<QByteArray> QOlmOutboundGroupSession::pickle(const PicklingMode &mo
return lastErrorCode();
key.clear();
-
return pickledBuf;
}
-QOlmExpected<QOlmOutboundGroupSessionPtr> QOlmOutboundGroupSession::unpickle(const QByteArray &pickled, const PicklingMode &mode)
+QOlmExpected<QOlmOutboundGroupSessionPtr> QOlmOutboundGroupSession::unpickle(
+ QByteArray&& pickled, const PicklingMode& mode)
{
- QByteArray pickledBuf = pickled;
auto *olmOutboundGroupSession = olm_outbound_group_session(new uint8_t[olm_outbound_group_session_size()]);
- QByteArray key = toKey(mode);
+ auto key = toKey(mode);
if (olm_unpickle_outbound_group_session(olmOutboundGroupSession, key.data(),
- key.length(), pickledBuf.data(),
- pickledBuf.length())
+ key.length(), pickled.data(),
+ pickled.length())
== olm_error()) {
// FIXME: create the session object earlier and use lastError()
return olm_outbound_group_session_last_error_code(
olmOutboundGroupSession);
}
const auto idMaxLength = olm_outbound_group_session_id_length(olmOutboundGroupSession);
- QByteArray idBuffer(idMaxLength, '0');
+ QByteArray idBuffer(idMaxLength, '\0');
olm_outbound_group_session_id(olmOutboundGroupSession, reinterpret_cast<uint8_t *>(idBuffer.data()),
idBuffer.length());
+ // FIXME: idBuffer doesn't seem to be used, is it needed here?
key.clear();
return std::make_unique<QOlmOutboundGroupSession>(olmOutboundGroupSession);
}
-QOlmExpected<QByteArray> QOlmOutboundGroupSession::encrypt(const QString &plaintext) const
+QOlmExpected<QByteArray> QOlmOutboundGroupSession::encrypt(
+ const QByteArray& plaintext) const
{
- QByteArray plaintextBuf = plaintext.toUtf8();
- const auto messageMaxLength = olm_group_encrypt_message_length(m_groupSession, plaintextBuf.length());
- QByteArray messageBuf(messageMaxLength, '0');
+ const auto messageMaxLength =
+ olm_group_encrypt_message_length(m_groupSession, plaintext.length());
+ QByteArray messageBuf(messageMaxLength, '\0');
if (olm_group_encrypt(m_groupSession,
- reinterpret_cast<uint8_t*>(plaintextBuf.data()),
- plaintextBuf.length(),
+ reinterpret_cast<const uint8_t*>(plaintext.data()),
+ plaintext.length(),
reinterpret_cast<uint8_t*>(messageBuf.data()),
messageBuf.length())
== olm_error())
@@ -114,7 +118,7 @@ uint32_t QOlmOutboundGroupSession::sessionMessageIndex() const
QByteArray QOlmOutboundGroupSession::sessionId() const
{
const auto idMaxLength = olm_outbound_group_session_id_length(m_groupSession);
- QByteArray idBuffer(idMaxLength, '0');
+ QByteArray idBuffer(idMaxLength, '\0');
if (olm_outbound_group_session_id(
m_groupSession, reinterpret_cast<uint8_t*>(idBuffer.data()),
idBuffer.length())
@@ -127,7 +131,7 @@ QByteArray QOlmOutboundGroupSession::sessionId() const
QOlmExpected<QByteArray> QOlmOutboundGroupSession::sessionKey() const
{
const auto keyMaxLength = olm_outbound_group_session_key_length(m_groupSession);
- QByteArray keyBuffer(keyMaxLength, '0');
+ QByteArray keyBuffer(keyMaxLength, '\0');
if (olm_outbound_group_session_key(
m_groupSession, reinterpret_cast<uint8_t*>(keyBuffer.data()),
keyMaxLength)
diff --git a/lib/e2ee/qolmoutboundsession.h b/lib/e2ee/qolmoutboundsession.h
index cd26fc67..e5e73ddf 100644
--- a/lib/e2ee/qolmoutboundsession.h
+++ b/lib/e2ee/qolmoutboundsession.h
@@ -24,10 +24,10 @@ public:
//! Deserialises from encrypted Base64 that was previously obtained by
//! pickling a `QOlmOutboundGroupSession`.
static QOlmExpected<QOlmOutboundGroupSessionPtr> unpickle(
- const QByteArray& pickled, const PicklingMode& mode);
+ QByteArray&& pickled, const PicklingMode& mode);
//! Encrypts a plaintext message using the session.
- QOlmExpected<QByteArray> encrypt(const QString& plaintext) const;
+ QOlmExpected<QByteArray> encrypt(const QByteArray& plaintext) const;
//! Get the current message index for this session.
//!
diff --git a/lib/e2ee/qolmsession.cpp b/lib/e2ee/qolmsession.cpp
index 771d310d..e252c37f 100644
--- a/lib/e2ee/qolmsession.cpp
+++ b/lib/e2ee/qolmsession.cpp
@@ -76,22 +76,17 @@ QOlmExpected<QOlmSessionPtr> QOlmSession::createInboundSessionFrom(
}
QOlmExpected<QOlmSessionPtr> QOlmSession::createOutboundSession(
- QOlmAccount* account, const QString& theirIdentityKey,
- const QString& theirOneTimeKey)
+ QOlmAccount* account, const QByteArray& theirIdentityKey,
+ const QByteArray& theirOneTimeKey)
{
- auto *olmOutboundSession = create();
- const auto randomLen = olm_create_outbound_session_random_length(olmOutboundSession);
- QByteArray randomBuf = getRandom(randomLen);
+ auto* olmOutboundSession = create();
+ auto randomBuf = getRandom(
+ olm_create_outbound_session_random_length(olmOutboundSession));
- QByteArray theirIdentityKeyBuf = theirIdentityKey.toUtf8();
- QByteArray theirOneTimeKeyBuf = theirOneTimeKey.toUtf8();
if (olm_create_outbound_session(
- olmOutboundSession, account->data(),
- reinterpret_cast<uint8_t*>(theirIdentityKeyBuf.data()),
- theirIdentityKeyBuf.length(),
- reinterpret_cast<uint8_t*>(theirOneTimeKeyBuf.data()),
- theirOneTimeKeyBuf.length(),
- reinterpret_cast<uint8_t*>(randomBuf.data()), randomBuf.length())
+ olmOutboundSession, account->data(), theirIdentityKey.data(),
+ theirIdentityKey.length(), theirOneTimeKey.data(),
+ theirOneTimeKey.length(), randomBuf.data(), randomBuf.length())
== olm_error()) {
// FIXME: the QOlmSession object should be created earlier
const auto lastErr = olm_session_last_error_code(olmOutboundSession);
@@ -107,7 +102,7 @@ QOlmExpected<QOlmSessionPtr> QOlmSession::createOutboundSession(
QOlmExpected<QByteArray> QOlmSession::pickle(const PicklingMode &mode) const
{
- QByteArray pickledBuf(olm_pickle_session_length(m_session), '0');
+ QByteArray pickledBuf(olm_pickle_session_length(m_session), '\0');
QByteArray key = toKey(mode);
if (olm_pickle_session(m_session, key.data(), key.length(),
pickledBuf.data(), pickledBuf.length())
@@ -118,14 +113,13 @@ QOlmExpected<QByteArray> QOlmSession::pickle(const PicklingMode &mode) const
return pickledBuf;
}
-QOlmExpected<QOlmSessionPtr> QOlmSession::unpickle(const QByteArray& pickled,
+QOlmExpected<QOlmSessionPtr> QOlmSession::unpickle(QByteArray&& pickled,
const PicklingMode& mode)
{
- QByteArray pickledBuf = pickled;
auto *olmSession = create();
- QByteArray key = toKey(mode);
+ auto key = toKey(mode);
if (olm_unpickle_session(olmSession, key.data(), key.length(),
- pickledBuf.data(), pickledBuf.length())
+ pickled.data(), pickled.length())
== olm_error()) {
// FIXME: the QOlmSession object should be created earlier
return olm_session_last_error_code(olmSession);
@@ -135,52 +129,48 @@ QOlmExpected<QOlmSessionPtr> QOlmSession::unpickle(const QByteArray& pickled,
return std::make_unique<QOlmSession>(olmSession);
}
-QOlmMessage QOlmSession::encrypt(const QString &plaintext)
+QOlmMessage QOlmSession::encrypt(const QByteArray& plaintext)
{
- QByteArray plaintextBuf = plaintext.toUtf8();
- const auto messageMaxLen = olm_encrypt_message_length(m_session, plaintextBuf.length());
- QByteArray messageBuf(messageMaxLen, '0');
- const auto messageType = encryptMessageType();
- const auto randomLen = olm_encrypt_random_length(m_session);
- QByteArray randomBuf = getRandom(randomLen);
- if (olm_encrypt(m_session, reinterpret_cast<uint8_t*>(plaintextBuf.data()),
- plaintextBuf.length(),
- reinterpret_cast<uint8_t*>(randomBuf.data()),
- randomBuf.length(),
- reinterpret_cast<uint8_t*>(messageBuf.data()),
+ const auto messageMaxLength =
+ olm_encrypt_message_length(m_session, plaintext.length());
+ QByteArray messageBuf(messageMaxLength, '0');
+ // NB: The type has to be calculated before calling olm_encrypt()
+ const auto messageType = olm_encrypt_message_type(m_session);
+ auto randomBuf = getRandom(olm_encrypt_random_length(m_session));
+ if (olm_encrypt(m_session, plaintext.data(), plaintext.length(),
+ randomBuf.data(), randomBuf.length(), messageBuf.data(),
messageBuf.length())
== olm_error()) {
throw lastError();
}
- return QOlmMessage(messageBuf, messageType);
+ randomBuf.clear();
+ return QOlmMessage(messageBuf, QOlmMessage::Type(messageType));
}
QOlmExpected<QByteArray> QOlmSession::decrypt(const QOlmMessage &message) const
{
- const auto messageType = message.type();
const auto ciphertext = message.toCiphertext();
- const auto messageTypeValue = messageType == QOlmMessage::Type::General
- ? OLM_MESSAGE_TYPE_MESSAGE : OLM_MESSAGE_TYPE_PRE_KEY;
+ const auto messageTypeValue = message.type();
// We need to clone the message because
// olm_decrypt_max_plaintext_length destroys the input buffer
- QByteArray messageBuf(ciphertext.length(), '0');
+ QByteArray messageBuf(ciphertext.length(), '\0');
std::copy(message.begin(), message.end(), messageBuf.begin());
- const auto plaintextMaxLen = olm_decrypt_max_plaintext_length(m_session, messageTypeValue,
- reinterpret_cast<uint8_t *>(messageBuf.data()), messageBuf.length());
+ const auto plaintextMaxLen = olm_decrypt_max_plaintext_length(
+ m_session, messageTypeValue, messageBuf.data(), messageBuf.length());
if (plaintextMaxLen == olm_error()) {
return lastError();
}
- QByteArray plaintextBuf(plaintextMaxLen, '0');
- QByteArray messageBuf2(ciphertext.length(), '0');
+ QByteArray plaintextBuf(plaintextMaxLen, '\0');
+ QByteArray messageBuf2(ciphertext.length(), '\0');
std::copy(message.begin(), message.end(), messageBuf2.begin());
- const auto plaintextResultLen = olm_decrypt(m_session, messageTypeValue,
- reinterpret_cast<uint8_t *>(messageBuf2.data()), messageBuf2.length(),
- reinterpret_cast<uint8_t *>(plaintextBuf.data()), plaintextMaxLen);
+ const auto plaintextResultLen =
+ olm_decrypt(m_session, messageTypeValue, messageBuf2.data(),
+ messageBuf2.length(), plaintextBuf.data(), plaintextMaxLen);
if (plaintextResultLen == olm_error()) {
const auto lastErr = lastErrorCode();
if (lastErr == OLM_OUTPUT_BUFFER_TOO_SMALL) {
@@ -188,31 +178,15 @@ QOlmExpected<QByteArray> QOlmSession::decrypt(const QOlmMessage &message) const
}
return lastErr;
}
- QByteArray output(plaintextResultLen, '0');
- std::memcpy(output.data(), plaintextBuf.data(), plaintextResultLen);
- plaintextBuf.clear();
- return output;
-}
-
-QOlmMessage::Type QOlmSession::encryptMessageType()
-{
- const auto messageTypeResult = olm_encrypt_message_type(m_session);
- if (messageTypeResult == olm_error()) {
- throw lastError();
- }
- if (messageTypeResult == OLM_MESSAGE_TYPE_PRE_KEY) {
- return QOlmMessage::PreKey;
- }
- return QOlmMessage::General;
+ plaintextBuf.truncate(plaintextResultLen);
+ return plaintextBuf;
}
QByteArray QOlmSession::sessionId() const
{
const auto idMaxLength = olm_session_id_length(m_session);
QByteArray idBuffer(idMaxLength, '0');
- if (olm_session_id(m_session, reinterpret_cast<uint8_t*>(idBuffer.data()),
- idBuffer.length())
- == olm_error()) {
+ if (olm_session_id(m_session, idBuffer.data(), idMaxLength) == olm_error()) {
throw lastError();
}
return idBuffer;
diff --git a/lib/e2ee/qolmsession.h b/lib/e2ee/qolmsession.h
index cc988a03..174e98ef 100644
--- a/lib/e2ee/qolmsession.h
+++ b/lib/e2ee/qolmsession.h
@@ -26,18 +26,18 @@ public:
const QOlmMessage& preKeyMessage);
static QOlmExpected<QOlmSessionPtr> createOutboundSession(
- QOlmAccount* account, const QString& theirIdentityKey,
- const QString& theirOneTimeKey);
+ QOlmAccount* account, const QByteArray& theirIdentityKey,
+ const QByteArray& theirOneTimeKey);
//! Serialises an `QOlmSession` to encrypted Base64.
QOlmExpected<QByteArray> pickle(const PicklingMode &mode) const;
- //! Deserialises from encrypted Base64 that was previously obtained by pickling a `QOlmSession`.
- static QOlmExpected<QOlmSessionPtr> unpickle(
- const QByteArray& pickled, const PicklingMode& mode);
+ //! Deserialises from encrypted Base64 previously made with pickle()
+ static QOlmExpected<QOlmSessionPtr> unpickle(QByteArray&& pickled,
+ const PicklingMode& mode);
//! Encrypts a plaintext message using the session.
- QOlmMessage encrypt(const QString &plaintext);
+ QOlmMessage encrypt(const QByteArray& plaintext);
//! Decrypts a message using this session. Decoding is lossy, meaning if
//! the decrypted plaintext contains invalid UTF-8 symbols, they will
@@ -47,9 +47,6 @@ public:
//! Get a base64-encoded identifier for this session.
QByteArray sessionId() const;
- //! The type of the next message that will be returned from encryption.
- QOlmMessage::Type encryptMessageType();
-
//! Checker for any received messages for this session.
bool hasReceivedMessage() const;
diff --git a/lib/e2ee/qolmutility.cpp b/lib/e2ee/qolmutility.cpp
index 15c875c0..08c2b699 100644
--- a/lib/e2ee/qolmutility.cpp
+++ b/lib/e2ee/qolmutility.cpp
@@ -32,7 +32,7 @@ QOlmUtility::~QOlmUtility()
QString QOlmUtility::sha256Bytes(const QByteArray &inputBuf) const
{
const auto outputLen = olm_sha256_length(m_utility);
- QByteArray outputBuf(outputLen, '0');
+ QByteArray outputBuf(outputLen, '\0');
olm_sha256(m_utility, inputBuf.data(), inputBuf.length(),
outputBuf.data(), outputBuf.length());
@@ -48,19 +48,17 @@ QOlmExpected<bool> QOlmUtility::ed25519Verify(const QByteArray& key,
const QByteArray& message,
const QByteArray& signature)
{
- QByteArray signatureBuf(signature.length(), '0');
+ QByteArray signatureBuf(signature.length(), '\0');
std::copy(signature.begin(), signature.end(), signatureBuf.begin());
- const auto ret = olm_ed25519_verify(m_utility, key.data(), key.size(),
- message.data(), message.size(),
- (void*)signatureBuf.data(),
- signatureBuf.size());
- if (ret == olm_error()) {
- auto error = lastErrorCode();
- if (error == OLM_BAD_MESSAGE_MAC)
- return false;
- return error;
- }
+ if (olm_ed25519_verify(m_utility, key.data(), key.size(), message.data(),
+ message.size(), signatureBuf.data(),
+ signatureBuf.size())
+ == 0)
+ return true;
- return ret == 0;
+ auto error = lastErrorCode();
+ if (error == OLM_BAD_MESSAGE_MAC)
+ return false;
+ return error;
}
diff --git a/lib/e2ee/qolmutils.h b/lib/e2ee/qolmutils.h
index f218e628..7a8511c3 100644
--- a/lib/e2ee/qolmutils.h
+++ b/lib/e2ee/qolmutils.h
@@ -9,6 +9,7 @@
#include "e2ee/e2ee.h"
namespace Quotient {
+
// Convert PicklingMode to key
QUOTIENT_API QByteArray toKey(const PicklingMode &mode);
QUOTIENT_API QByteArray getRandom(size_t bufferSize);
diff --git a/lib/events/filesourceinfo.cpp b/lib/events/filesourceinfo.cpp
index e8b6794b..6abe6a08 100644
--- a/lib/events/filesourceinfo.cpp
+++ b/lib/events/filesourceinfo.cpp
@@ -59,19 +59,15 @@ std::pair<EncryptedFileMetadata, QByteArray> Quotient::encryptFile(
const QByteArray& plainText)
{
#ifdef Quotient_E2EE_ENABLED
- QByteArray k = getRandom(32);
- auto kBase64 = k.toBase64();
- QByteArray iv = getRandom(16);
- JWK key = { "oct"_ls,
- { "encrypt"_ls, "decrypt"_ls },
- "A256CTR"_ls,
- QString(k.toBase64())
- .replace(u'/', u'_')
- .replace(u'+', u'-')
- .left(kBase64.indexOf('=')),
- true };
-
- int length;
+ auto k = getRandom(32);
+ auto kBase64 = k.toBase64(QByteArray::Base64UrlEncoding
+ | QByteArray::OmitTrailingEquals);
+ auto iv = getRandom(16);
+ JWK key = {
+ "oct"_ls, { "encrypt"_ls, "decrypt"_ls }, "A256CTR"_ls, kBase64, true
+ };
+
+ int length = -1;
auto* ctx = EVP_CIPHER_CTX_new();
EVP_EncryptInit_ex(ctx, EVP_aes_256_ctr(), nullptr,
reinterpret_cast<const unsigned char*>(k.data()),
@@ -89,14 +85,11 @@ std::pair<EncryptedFileMetadata, QByteArray> Quotient::encryptFile(
EVP_CIPHER_CTX_free(ctx);
auto hash = QCryptographicHash::hash(cipherText, QCryptographicHash::Sha256)
- .toBase64();
- auto ivBase64 = iv.toBase64();
- EncryptedFileMetadata efm = { {},
- key,
- ivBase64.left(ivBase64.indexOf('=')),
- { { QStringLiteral("sha256"),
- hash.left(hash.indexOf('=')) } },
- "v2"_ls };
+ .toBase64(QByteArray::OmitTrailingEquals);
+ auto ivBase64 = iv.toBase64(QByteArray::OmitTrailingEquals);
+ EncryptedFileMetadata efm = {
+ {}, key, ivBase64, { { QStringLiteral("sha256"), hash } }, "v2"_ls
+ };
return { efm, cipherText };
#else
return {};
diff --git a/lib/keyverificationsession.cpp b/lib/keyverificationsession.cpp
index 3f76eac1..0f24c743 100644
--- a/lib/keyverificationsession.cpp
+++ b/lib/keyverificationsession.cpp
@@ -71,9 +71,9 @@ void KeyVerificationSession::init(milliseconds timeout)
QTimer::singleShot(timeout, this, [this] { cancelVerification(TIMEOUT); });
m_sas = olm_sas(new std::byte[olm_sas_size()]);
- auto randomSize = olm_create_sas_random_length(m_sas);
- auto random = getRandom(randomSize);
- olm_create_sas(m_sas, random.data(), randomSize);
+ const auto randomLength = olm_create_sas_random_length(m_sas);
+ auto random = getRandom(randomLength);
+ olm_create_sas(m_sas, random.data(), randomLength);
}
KeyVerificationSession::~KeyVerificationSession()