aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--autotests/testgroupsession.cpp14
-rw-r--r--autotests/testolmaccount.cpp5
-rw-r--r--autotests/testolmsession.cpp14
-rw-r--r--autotests/testolmutility.cpp5
-rw-r--r--lib/connection.cpp136
-rw-r--r--lib/database.cpp32
-rw-r--r--lib/e2ee/e2ee.h8
-rw-r--r--lib/e2ee/qolmaccount.cpp20
-rw-r--r--lib/e2ee/qolmaccount.h21
-rw-r--r--lib/e2ee/qolminboundsession.cpp10
-rw-r--r--lib/e2ee/qolminboundsession.h14
-rw-r--r--lib/e2ee/qolmoutboundsession.cpp18
-rw-r--r--lib/e2ee/qolmoutboundsession.h19
-rw-r--r--lib/e2ee/qolmsession.cpp22
-rw-r--r--lib/e2ee/qolmsession.h35
-rw-r--r--lib/e2ee/qolmutility.cpp14
-rw-r--r--lib/e2ee/qolmutility.h7
-rw-r--r--lib/room.cpp17
18 files changed, 215 insertions, 196 deletions
diff --git a/autotests/testgroupsession.cpp b/autotests/testgroupsession.cpp
index 2566669e..3c329a8a 100644
--- a/autotests/testgroupsession.cpp
+++ b/autotests/testgroupsession.cpp
@@ -16,11 +16,11 @@ void TestGroupSession::groupSessionPicklingValid()
QVERIFY(QByteArray::fromBase64(ogsId).size() > 0);
QCOMPARE(0, ogs->sessionMessageIndex());
- auto ogsPickled = std::get<QByteArray>(ogs->pickle(Unencrypted {}));
- auto ogs2 = std::get<QOlmOutboundGroupSessionPtr>(QOlmOutboundGroupSession::unpickle(ogsPickled, Unencrypted {}));
+ auto ogsPickled = ogs->pickle(Unencrypted {}).value();
+ auto ogs2 = QOlmOutboundGroupSession::unpickle(ogsPickled, Unencrypted {}).value();
QCOMPARE(ogsId, ogs2->sessionId());
- auto igs = QOlmInboundGroupSession::create(std::get<QByteArray>(ogs->sessionKey()));
+ auto igs = QOlmInboundGroupSession::create(ogs->sessionKey().value());
const auto igsId = igs->sessionId();
// ID is valid base64?
QVERIFY(QByteArray::fromBase64(igsId).size() > 0);
@@ -29,22 +29,22 @@ void TestGroupSession::groupSessionPicklingValid()
QCOMPARE(0, igs->firstKnownIndex());
auto igsPickled = igs->pickle(Unencrypted {});
- igs = std::get<QOlmInboundGroupSessionPtr>(QOlmInboundGroupSession::unpickle(igsPickled, Unencrypted {}));
+ igs = QOlmInboundGroupSession::unpickle(igsPickled, Unencrypted {}).value();
QCOMPARE(igsId, igs->sessionId());
}
void TestGroupSession::groupSessionCryptoValid()
{
auto ogs = QOlmOutboundGroupSession::create();
- auto igs = QOlmInboundGroupSession::create(std::get<QByteArray>(ogs->sessionKey()));
+ auto igs = QOlmInboundGroupSession::create(ogs->sessionKey().value());
QCOMPARE(ogs->sessionId(), igs->sessionId());
const auto plainText = QStringLiteral("Hello world!");
- const auto ciphertext = std::get<QByteArray>(ogs->encrypt(plainText));
+ const auto ciphertext = ogs->encrypt(plainText).value();
// ciphertext valid base64?
QVERIFY(QByteArray::fromBase64(ciphertext).size() > 0);
- const auto decryptionResult = std::get<std::pair<QString, uint32_t>>(igs->decrypt(ciphertext));
+ const auto decryptionResult = igs->decrypt(ciphertext).value();
//// correct plaintext?
QCOMPARE(plainText, decryptionResult.first);
diff --git a/autotests/testolmaccount.cpp b/autotests/testolmaccount.cpp
index 9989665a..e31ff6d3 100644
--- a/autotests/testolmaccount.cpp
+++ b/autotests/testolmaccount.cpp
@@ -21,7 +21,7 @@ void TestOlmAccount::pickleUnpickledTest()
QOlmAccount olmAccount(QStringLiteral("@foo:bar.com"), QStringLiteral("QuotientTestDevice"));
olmAccount.createNewAccount();
auto identityKeys = olmAccount.identityKeys();
- auto pickled = std::get<QByteArray>(olmAccount.pickle(Unencrypted{}));
+ auto pickled = olmAccount.pickle(Unencrypted{}).value();
QOlmAccount olmAccount2(QStringLiteral("@foo:bar.com"), QStringLiteral("QuotientTestDevice"));
olmAccount2.unpickle(pickled, Unencrypted{});
auto identityKeys2 = olmAccount2.identityKeys();
@@ -57,8 +57,7 @@ void TestOlmAccount::signatureValid()
const auto identityKeys = olmAccount.identityKeys();
const auto ed25519Key = identityKeys.ed25519;
const auto verify = utility.ed25519Verify(ed25519Key, message, signature);
- QVERIFY(std::holds_alternative<bool>(verify));
- QVERIFY(std::get<bool>(verify) == true);
+ QVERIFY(verify.value_or(false));
}
void TestOlmAccount::oneTimeKeysValid()
diff --git a/autotests/testolmsession.cpp b/autotests/testolmsession.cpp
index 2674b60b..182659e7 100644
--- a/autotests/testolmsession.cpp
+++ b/autotests/testolmsession.cpp
@@ -20,8 +20,8 @@ std::pair<QOlmSessionPtr, QOlmSessionPtr> createSessionPair()
const QByteArray oneTimeKeyA("WzsbsjD85iB1R32iWxfJdwkgmdz29ClMbJSJziECYwk");
const QByteArray identityKeyB("q/YhJtog/5VHCAS9rM9uUf6AaFk1yPe4GYuyUOXyQCg");
const QByteArray oneTimeKeyB("oWvzryma+B2onYjo3hM6A3Mgo/Yepm8HvgSvwZMTnjQ");
- auto outbound = std::get<QOlmSessionPtr>(accountA
- .createOutboundSession(identityKeyB, oneTimeKeyB));
+ auto outbound =
+ accountA.createOutboundSession(identityKeyB, oneTimeKeyB).value();
const auto preKey = outbound->encrypt(""); // Payload does not matter for PreKey
@@ -29,7 +29,7 @@ std::pair<QOlmSessionPtr, QOlmSessionPtr> createSessionPair()
// We can't call QFail here because it's an helper function returning a value
throw "Wrong first message type received, can't create session";
}
- auto inbound = std::get<QOlmSessionPtr>(accountB.createInboundSession(preKey));
+ auto inbound = accountB.createInboundSession(preKey).value();
return { std::move(inbound), std::move(outbound) };
}
@@ -48,7 +48,7 @@ void TestOlmSession::olmEncryptDecrypt()
QVERIFY(inboundSession->matchesInboundSession(m));
}
- const auto decrypted = std::get<QString>(inboundSession->decrypt(encrypted));
+ const auto decrypted = inboundSession->decrypt(encrypted).value();
QCOMPARE(decrypted, "Hello world!");
}
@@ -56,11 +56,11 @@ void TestOlmSession::olmEncryptDecrypt()
void TestOlmSession::correctSessionOrdering()
{
// n0W5IJ2ZmaI9FxKRj/wohUQ6WEU0SfoKsgKKHsr4VbM
- auto session1 = std::get<QOlmSessionPtr>(QOlmSession::unpickle("7g5cfQRsDk2ROXf9S01n2leZiFRon+EbvXcMOADU0UGvlaV6t/0ihD2/0QGckDIvbmE1aV+PxB0zUtHXh99bI/60N+PWkCLA84jEY4sz3d45ui/TVoFGLDHlymKxvlj7XngXrbtlxSkVntsPzDiNpKEXCa26N2ubKpQ0fbjrV5gbBTYWfU04DXHPXFDTksxpNALYt/h0eVMVhf6hB0ZzpLBsOG0mpwkLufwub0CuDEDGGmRddz3TcNCLq5NnI8R9udDWvHAkTS1UTbHuIf/y6cZg875nJyXpAvd8/XhL8TOo8ot2sE1fElBa4vrH/m9rBQMC1GPkhLBIizmY44C+Sq9PQRnF+uCZ", Unencrypted{}));
+ auto session1 = QOlmSession::unpickle("7g5cfQRsDk2ROXf9S01n2leZiFRon+EbvXcMOADU0UGvlaV6t/0ihD2/0QGckDIvbmE1aV+PxB0zUtHXh99bI/60N+PWkCLA84jEY4sz3d45ui/TVoFGLDHlymKxvlj7XngXrbtlxSkVntsPzDiNpKEXCa26N2ubKpQ0fbjrV5gbBTYWfU04DXHPXFDTksxpNALYt/h0eVMVhf6hB0ZzpLBsOG0mpwkLufwub0CuDEDGGmRddz3TcNCLq5NnI8R9udDWvHAkTS1UTbHuIf/y6cZg875nJyXpAvd8/XhL8TOo8ot2sE1fElBa4vrH/m9rBQMC1GPkhLBIizmY44C+Sq9PQRnF+uCZ", Unencrypted{}).value();
// +9pHJhP3K4E5/2m8PYBPLh8pS9CJodwUOh8yz3mnmw0
- auto session2 = std::get<QOlmSessionPtr>(QOlmSession::unpickle("7g5cfQRsDk2ROXf9S01n2leZiFRon+EbvXcMOADU0UFD+q37/WlfTAzQsSjCdD07FcErZ4siEy5vpiB+pyO8i53ptZvb2qRvqNKFzPaXuu33PS2PBTmmnR+kJt+DgDNqWadyaj/WqEAejc7ALqSs5GuhbZtpoLe+lRSRK0rwVX3gzz4qrl8pm0pD5pSZAUWRXDRlieGWMclz68VUvnSaQH7ElTo4S634CJk+xQfFFCD26v0yONPSN6rwouS1cWPuG5jTlnV8vCFVTU2+lduKh54Ko6FUJ/ei4xR8Nk2duBGSc/TdllX9e2lDYHSUkWoD4ti5xsFioB8Blus7JK9BZfcmRmdlxIOD", Unencrypted {}));
+ auto session2 = QOlmSession::unpickle("7g5cfQRsDk2ROXf9S01n2leZiFRon+EbvXcMOADU0UFD+q37/WlfTAzQsSjCdD07FcErZ4siEy5vpiB+pyO8i53ptZvb2qRvqNKFzPaXuu33PS2PBTmmnR+kJt+DgDNqWadyaj/WqEAejc7ALqSs5GuhbZtpoLe+lRSRK0rwVX3gzz4qrl8pm0pD5pSZAUWRXDRlieGWMclz68VUvnSaQH7ElTo4S634CJk+xQfFFCD26v0yONPSN6rwouS1cWPuG5jTlnV8vCFVTU2+lduKh54Ko6FUJ/ei4xR8Nk2duBGSc/TdllX9e2lDYHSUkWoD4ti5xsFioB8Blus7JK9BZfcmRmdlxIOD", Unencrypted {}).value();
// MC7n8hX1l7WlC2/WJGHZinMocgiBZa4vwGAOredb/ME
- auto session3 = std::get<QOlmSessionPtr>(QOlmSession::unpickle("7g5cfQRsDk2ROXf9S01n2leZiFRon+EbvXcMOADU0UGNk2TmVDJ95K0Nywf24FNklNVtXtFDiFPHFwNSmCbHNCp3hsGtZlt0AHUkMmL48XklLqzwtVk5/v2RRmSKR5LqYdIakrtuK/fY0ENhBZIbI1sRetaJ2KMbY9l6rCJNfFg8VhpZ4KTVvEZVuP9g/eZkCnP5NxzXiBRF6nfY3O/zhcKxa3acIqs6BMhyLsfuJ80t+hQ1HvVyuhBerGujdSDzV9tJ9SPidOwfYATk81LVF9hTmnI0KaZa7qCtFzhG0dU/Z3hIWH9HOaw1aSB/IPmughbwdJOwERyhuo3YHoznlQnJ7X252BlI", Unencrypted{}));
+ auto session3 = QOlmSession::unpickle("7g5cfQRsDk2ROXf9S01n2leZiFRon+EbvXcMOADU0UGNk2TmVDJ95K0Nywf24FNklNVtXtFDiFPHFwNSmCbHNCp3hsGtZlt0AHUkMmL48XklLqzwtVk5/v2RRmSKR5LqYdIakrtuK/fY0ENhBZIbI1sRetaJ2KMbY9l6rCJNfFg8VhpZ4KTVvEZVuP9g/eZkCnP5NxzXiBRF6nfY3O/zhcKxa3acIqs6BMhyLsfuJ80t+hQ1HvVyuhBerGujdSDzV9tJ9SPidOwfYATk81LVF9hTmnI0KaZa7qCtFzhG0dU/Z3hIWH9HOaw1aSB/IPmughbwdJOwERyhuo3YHoznlQnJ7X252BlI", Unencrypted{}).value();
const auto session1Id = session1->sessionId();
const auto session2Id = session2->sessionId();
diff --git a/autotests/testolmutility.cpp b/autotests/testolmutility.cpp
index 92b8b5b2..c1323533 100644
--- a/autotests/testolmutility.cpp
+++ b/autotests/testolmutility.cpp
@@ -81,7 +81,10 @@ void TestOlmUtility::verifySignedOneTimeKey()
delete[](reinterpret_cast<uint8_t *>(utility));
QOlmUtility utility2;
- auto res2 = std::get<bool>(utility2.ed25519Verify(aliceOlm.identityKeys().ed25519, msg, signatureBuf1));
+ auto res2 =
+ utility2
+ .ed25519Verify(aliceOlm.identityKeys().ed25519, msg, signatureBuf1)
+ .value_or(false);
//QCOMPARE(std::string(olm_utility_last_error(utility)), "SUCCESS");
QCOMPARE(res2, true);
diff --git a/lib/connection.cpp b/lib/connection.cpp
index 955b5b1a..2528b70b 100644
--- a/lib/connection.cpp
+++ b/lib/connection.cpp
@@ -212,82 +212,83 @@ public:
void loadSessions() {
olmSessions = q->database()->loadOlmSessions(q->picklingMode());
}
- void saveSession(QOlmSessionPtr& session, const QString &senderKey) {
- auto pickleResult = session->pickle(q->picklingMode());
- if (std::holds_alternative<QOlmError>(pickleResult)) {
- qCWarning(E2EE) << "Failed to pickle olm session. Error" << std::get<QOlmError>(pickleResult);
- return;
- }
- q->database()->saveOlmSession(senderKey, session->sessionId(), std::get<QByteArray>(pickleResult), QDateTime::currentDateTime());
- }
-
- std::pair<QString, QString> sessionDecryptPrekey(const QOlmMessage& message,
- const QString& senderKey)
+ void saveSession(QOlmSession& session, const QString& senderKey)
{
- Q_ASSERT(message.type() == QOlmMessage::PreKey);
- for(auto& session : olmSessions[senderKey]) {
- if (session->matchesInboundSessionFrom(senderKey, message)) {
- qCDebug(E2EE) << "Found inbound session";
- const auto result = session->decrypt(message);
- if(std::holds_alternative<QString>(result)) {
- q->database()->setOlmSessionLastReceived(QString(session->sessionId()), QDateTime::currentDateTime());
- return { std::get<QString>(result), session->sessionId() };
- } else {
- qCDebug(E2EE) << "Failed to decrypt prekey message";
- return {};
- }
- }
- }
- qCDebug(E2EE) << "Creating new inbound session";
- auto newSessionResult = olmAccount->createInboundSessionFrom(senderKey.toUtf8(), message);
- if(std::holds_alternative<QOlmError>(newSessionResult)) {
- qCWarning(E2EE) << "Failed to create inbound session for" << senderKey << std::get<QOlmError>(newSessionResult);
- return {};
- }
- auto newSession = std::move(std::get<QOlmSessionPtr>(newSessionResult));
- auto error = olmAccount->removeOneTimeKeys(newSession);
- if (error) {
- qWarning(E2EE) << "Failed to remove one time key for session" << newSession->sessionId();
- }
- const auto result = newSession->decrypt(message);
- QString sessionId = newSession->sessionId();
- saveSession(newSession, senderKey);
- olmSessions[senderKey].push_back(std::move(newSession));
- if(std::holds_alternative<QString>(result)) {
- return { std::get<QString>(result), sessionId };
- } else {
- qCDebug(E2EE) << "Failed to decrypt prekey message with new session";
- return {};
- }
+ if (auto pickleResult = session.pickle(q->picklingMode()))
+ q->database()->saveOlmSession(senderKey, session.sessionId(),
+ *pickleResult,
+ QDateTime::currentDateTime());
+ else
+ qCWarning(E2EE) << "Failed to pickle olm session. Error"
+ << pickleResult.error();
}
- std::pair<QString, QString> sessionDecryptGeneral(const QOlmMessage& message, const QString &senderKey)
+
+ template <typename FnT>
+ std::pair<QString, QString> doDecryptMessage(const QOlmSession& session,
+ const QOlmMessage& message,
+ FnT&& andThen) const
{
- Q_ASSERT(message.type() == QOlmMessage::General);
- for(auto& session : olmSessions[senderKey]) {
- const auto result = session->decrypt(message);
- if(std::holds_alternative<QString>(result)) {
- q->database()->setOlmSessionLastReceived(QString(session->sessionId()), QDateTime::currentDateTime());
- return { std::get<QString>(result), session->sessionId() };
- }
+ const auto expectedMessage = session.decrypt(message);
+ if (expectedMessage) {
+ const auto result =
+ std::make_pair(*expectedMessage, session.sessionId());
+ andThen();
+ return result;
}
- qCWarning(E2EE) << "Failed to decrypt message";
+ const auto errorLine = message.type() == QOlmMessage::PreKey
+ ? "Failed to decrypt prekey message:"
+ : "Failed to decrypt message:";
+ qCDebug(E2EE) << errorLine << expectedMessage.error();
return {};
}
std::pair<QString, QString> sessionDecryptMessage(
const QJsonObject& personalCipherObject, const QByteArray& senderKey)
{
+ const auto msgType = static_cast<QOlmMessage::Type>(
+ personalCipherObject.value(TypeKeyL).toInt(-1));
+ if (msgType != QOlmMessage::General && msgType != QOlmMessage::PreKey) {
+ qCWarning(E2EE) << "Olm message has incorrect type" << msgType;
+ return {};
+ }
QOlmMessage message {
- personalCipherObject.value(BodyKeyL).toString().toLatin1(),
- static_cast<QOlmMessage::Type>(
- personalCipherObject.value(TypeKeyL).toInt(-1))
+ personalCipherObject.value(BodyKeyL).toString().toLatin1(), msgType
};
- if (message.type() == QOlmMessage::PreKey)
- return sessionDecryptPrekey(message, senderKey);
- if (message.type() == QOlmMessage::General)
- return sessionDecryptGeneral(message, senderKey);
- qCWarning(E2EE) << "Olm message has incorrect type" << message.type();
- return {};
+ for (const auto& session : olmSessions[senderKey])
+ if (msgType == QOlmMessage::General
+ || session->matchesInboundSessionFrom(senderKey, message)) {
+ return doDecryptMessage(*session, message, [this, &session] {
+ q->database()->setOlmSessionLastReceived(
+ session->sessionId(), QDateTime::currentDateTime());
+ });
+ }
+
+ if (msgType == QOlmMessage::General) {
+ qCWarning(E2EE) << "Failed to decrypt message";
+ return {};
+ }
+
+ qCDebug(E2EE) << "Creating new inbound session"; // Pre-key messages only
+ auto newSessionResult =
+ olmAccount->createInboundSessionFrom(senderKey, message);
+ if (!newSessionResult) {
+ qCWarning(E2EE)
+ << "Failed to create inbound session for" << senderKey
+ << "with error" << newSessionResult.error();
+ return {};
+ }
+ auto newSession = std::move(*newSessionResult);
+ auto error = olmAccount->removeOneTimeKeys(*newSession);
+ if (error) {
+ qWarning(E2EE) << "Failed to remove one time key for session"
+ << newSession->sessionId();
+ // Keep going though
+ }
+ return doDecryptMessage(
+ *newSession, message, [this, &senderKey, &newSession] {
+ saveSession(*newSession, senderKey);
+ olmSessions[senderKey].push_back(std::move(newSession));
+ });
}
#endif
@@ -2177,8 +2178,11 @@ void Connection::saveOlmAccount()
{
qCDebug(E2EE) << "Saving olm account";
#ifdef Quotient_E2EE_ENABLED
- auto pickle = d->olmAccount->pickle(d->picklingMode);
- d->database->setAccountPickle(std::get<QByteArray>(pickle));
+ if (const auto expectedPickle = d->olmAccount->pickle(d->picklingMode))
+ d->database->setAccountPickle(*expectedPickle);
+ else
+ qCWarning(E2EE) << "Couldn't save Olm account pickle:"
+ << expectedPickle.error();
#endif
}
diff --git a/lib/database.cpp b/lib/database.cpp
index 3189b3f1..e2e7acc9 100644
--- a/lib/database.cpp
+++ b/lib/database.cpp
@@ -184,12 +184,14 @@ UnorderedMap<QString, std::vector<QOlmSessionPtr>> Database::loadOlmSessions(con
commit();
UnorderedMap<QString, std::vector<QOlmSessionPtr>> sessions;
while (query.next()) {
- auto session = QOlmSession::unpickle(query.value("pickle").toByteArray(), picklingMode);
- if (std::holds_alternative<QOlmError>(session)) {
- qCWarning(E2EE) << "Failed to unpickle olm session";
- continue;
- }
- sessions[query.value("senderKey").toString()].push_back(std::move(std::get<QOlmSessionPtr>(session)));
+ if (auto expectedSession =
+ QOlmSession::unpickle(query.value("pickle").toByteArray(),
+ picklingMode)) {
+ sessions[query.value("senderKey").toString()].emplace_back(
+ std::move(*expectedSession));
+ } else
+ qCWarning(E2EE)
+ << "Failed to unpickle olm session:" << expectedSession.error();
}
return sessions;
}
@@ -203,15 +205,15 @@ UnorderedMap<QString, QOlmInboundGroupSessionPtr> Database::loadMegolmSessions(c
commit();
UnorderedMap<QString, QOlmInboundGroupSessionPtr> sessions;
while (query.next()) {
- auto session = QOlmInboundGroupSession::unpickle(query.value("pickle").toByteArray(), picklingMode);
- if (std::holds_alternative<QOlmError>(session)) {
- qCWarning(E2EE) << "Failed to unpickle megolm session";
- continue;
- }
-
- sessions[query.value("sessionId").toString()] = std::move(std::get<QOlmInboundGroupSessionPtr>(session));
- sessions[query.value("sessionId").toString()]->setOlmSessionId(query.value("olmSessionId").toString());
- sessions[query.value("sessionId").toString()]->setSenderId(query.value("senderId").toString());
+ if (auto expectedSession = QOlmInboundGroupSession::unpickle(
+ query.value("pickle").toByteArray(), picklingMode)) {
+ auto& sessionPtr = sessions[query.value("sessionId").toString()] =
+ std::move(*expectedSession);
+ sessionPtr->setOlmSessionId(query.value("olmSessionId").toString());
+ sessionPtr->setSenderId(query.value("senderId").toString());
+ } else
+ qCWarning(E2EE) << "Failed to unpickle megolm session:"
+ << expectedSession.error();
}
return sessions;
}
diff --git a/lib/e2ee/e2ee.h b/lib/e2ee/e2ee.h
index 268cb525..8e433d60 100644
--- a/lib/e2ee/e2ee.h
+++ b/lib/e2ee/e2ee.h
@@ -6,6 +6,8 @@
#pragma once
#include "converters.h"
+#include "expected.h"
+#include "qolmerrors.h"
#include "quotient_common.h"
#include <QtCore/QMetaType>
@@ -55,6 +57,12 @@ using QOlmSessionPtr = std::unique_ptr<QOlmSession>;
class QOlmInboundGroupSession;
using QOlmInboundGroupSessionPtr = std::unique_ptr<QOlmInboundGroupSession>;
+class QOlmOutboundGroupSession;
+using QOlmOutboundGroupSessionPtr = std::unique_ptr<QOlmOutboundGroupSession>;
+
+template <typename T>
+using QOlmExpected = Expected<T, QOlmError>;
+
struct IdentityKeys
{
QByteArray curve25519;
diff --git a/lib/e2ee/qolmaccount.cpp b/lib/e2ee/qolmaccount.cpp
index 3339ce46..72dddafb 100644
--- a/lib/e2ee/qolmaccount.cpp
+++ b/lib/e2ee/qolmaccount.cpp
@@ -73,7 +73,7 @@ void QOlmAccount::unpickle(QByteArray &pickled, const PicklingMode &mode)
}
}
-std::variant<QByteArray, QOlmError> QOlmAccount::pickle(const PicklingMode &mode)
+QOlmExpected<QByteArray> QOlmAccount::pickle(const PicklingMode &mode)
{
const QByteArray key = toKey(mode);
const size_t pickleLength = olm_pickle_account_length(m_account);
@@ -197,9 +197,9 @@ QByteArray QOlmAccount::signOneTimeKey(const QString &key) const
}
std::optional<QOlmError> QOlmAccount::removeOneTimeKeys(
- const QOlmSessionPtr& session)
+ const QOlmSession& session)
{
- const auto error = olm_remove_one_time_keys(m_account, session->raw());
+ const auto error = olm_remove_one_time_keys(m_account, session.raw());
if (error == olm_error()) {
return lastError(m_account);
@@ -245,19 +245,19 @@ UploadKeysJob *QOlmAccount::createUploadKeyRequest(const OneTimeKeys &oneTimeKey
return new UploadKeysJob(keys, oneTimeKeysSigned);
}
-std::variant<QOlmSessionPtr, QOlmError> QOlmAccount::createInboundSession(const QOlmMessage &preKeyMessage)
+QOlmExpected<QOlmSessionPtr> QOlmAccount::createInboundSession(const QOlmMessage &preKeyMessage)
{
Q_ASSERT(preKeyMessage.type() == QOlmMessage::PreKey);
return QOlmSession::createInboundSession(this, preKeyMessage);
}
-std::variant<QOlmSessionPtr, QOlmError> QOlmAccount::createInboundSessionFrom(const QByteArray &theirIdentityKey, const QOlmMessage &preKeyMessage)
+QOlmExpected<QOlmSessionPtr> QOlmAccount::createInboundSessionFrom(const QByteArray &theirIdentityKey, const QOlmMessage &preKeyMessage)
{
Q_ASSERT(preKeyMessage.type() == QOlmMessage::PreKey);
return QOlmSession::createInboundSessionFrom(this, theirIdentityKey, preKeyMessage);
}
-std::variant<QOlmSessionPtr, QOlmError> QOlmAccount::createOutboundSession(const QByteArray &theirIdentityKey, const QByteArray &theirOneTimeKey)
+QOlmExpected<QOlmSessionPtr> QOlmAccount::createOutboundSession(const QByteArray &theirIdentityKey, const QByteArray &theirOneTimeKey)
{
return QOlmSession::createOutboundSession(this, theirIdentityKey, theirOneTimeKey);
}
@@ -296,10 +296,6 @@ bool Quotient::ed25519VerifySignature(const QString& signingKey,
QByteArray signingKeyBuf = signingKey.toUtf8();
QOlmUtility utility;
auto signatureBuf = signature.toUtf8();
- auto result = utility.ed25519Verify(signingKeyBuf, canonicalJson, signatureBuf);
- if (std::holds_alternative<QOlmError>(result)) {
- return false;
- }
-
- return std::get<bool>(result);
+ return utility.ed25519Verify(signingKeyBuf, canonicalJson, signatureBuf)
+ .value_or(false);
}
diff --git a/lib/e2ee/qolmaccount.h b/lib/e2ee/qolmaccount.h
index 1f36919a..ee2aa69d 100644
--- a/lib/e2ee/qolmaccount.h
+++ b/lib/e2ee/qolmaccount.h
@@ -5,11 +5,12 @@
#pragma once
-#include "csapi/keys.h"
#include "e2ee/e2ee.h"
-#include "e2ee/qolmerrors.h"
#include "e2ee/qolmmessage.h"
-#include <QObject>
+
+#include "csapi/keys.h"
+
+#include <QtCore/QObject>
struct OlmAccount;
@@ -38,7 +39,7 @@ public:
void unpickle(QByteArray &pickled, const PicklingMode &mode);
//! Serialises an OlmAccount to encrypted Base64.
- std::variant<QByteArray, QOlmError> pickle(const PicklingMode &mode);
+ QOlmExpected<QByteArray> pickle(const PicklingMode &mode);
//! Returns the account's public identity keys already formatted as JSON
IdentityKeys identityKeys() const;
@@ -73,22 +74,26 @@ public:
DeviceKeys deviceKeys() const;
//! Remove the one time key used to create the supplied session.
- [[nodiscard]] std::optional<QOlmError> removeOneTimeKeys(const QOlmSessionPtr &session) const;
+ [[nodiscard]] std::optional<QOlmError> removeOneTimeKeys(
+ const QOlmSession& session);
//! 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.
- std::variant<QOlmSessionPtr, QOlmError> createInboundSession(const QOlmMessage &preKeyMessage);
+ QOlmExpected<QOlmSessionPtr> createInboundSession(
+ const QOlmMessage& preKeyMessage);
//! Creates an inbound session for sending/receiving messages from a received 'prekey' message.
//!
//! \param theirIdentityKey - The identity key of the Olm account that
//! encrypted this Olm message.
- std::variant<QOlmSessionPtr, QOlmError> createInboundSessionFrom(const QByteArray &theirIdentityKey, const QOlmMessage &preKeyMessage);
+ QOlmExpected<QOlmSessionPtr> createInboundSessionFrom(
+ const QByteArray& theirIdentityKey, const QOlmMessage& preKeyMessage);
//! Creates an outbound session for sending messages to a specific
/// identity and one time key.
- std::variant<QOlmSessionPtr, QOlmError> createOutboundSession(const QByteArray &theirIdentityKey, const QByteArray &theirOneTimeKey);
+ QOlmExpected<QOlmSessionPtr> createOutboundSession(
+ const QByteArray& theirIdentityKey, const QByteArray& theirOneTimeKey);
void markKeysAsPublished();
diff --git a/lib/e2ee/qolminboundsession.cpp b/lib/e2ee/qolminboundsession.cpp
index 62856831..17f06205 100644
--- a/lib/e2ee/qolminboundsession.cpp
+++ b/lib/e2ee/qolminboundsession.cpp
@@ -70,7 +70,8 @@ QByteArray QOlmInboundGroupSession::pickle(const PicklingMode &mode) const
return pickledBuf;
}
-std::variant<std::unique_ptr<QOlmInboundGroupSession>, QOlmError> QOlmInboundGroupSession::unpickle(const QByteArray &pickled, const PicklingMode &mode)
+QOlmExpected<QOlmInboundGroupSessionPtr> QOlmInboundGroupSession::unpickle(
+ const QByteArray& pickled, const PicklingMode& mode)
{
QByteArray pickledBuf = pickled;
const auto groupSession = olm_inbound_group_session(new uint8_t[olm_inbound_group_session_size()]);
@@ -85,7 +86,8 @@ std::variant<std::unique_ptr<QOlmInboundGroupSession>, QOlmError> QOlmInboundGro
return std::make_unique<QOlmInboundGroupSession>(groupSession);
}
-std::variant<std::pair<QString, uint32_t>, QOlmError> QOlmInboundGroupSession::decrypt(const QByteArray &message)
+QOlmExpected<std::pair<QByteArray, uint32_t>> QOlmInboundGroupSession::decrypt(
+ const QByteArray& message)
{
// This is for capturing the output of olm_group_decrypt
uint32_t messageIndex = 0;
@@ -114,10 +116,10 @@ std::variant<std::pair<QString, uint32_t>, QOlmError> QOlmInboundGroupSession::d
QByteArray output(plaintextLen, '0');
std::memcpy(output.data(), plaintextBuf.data(), plaintextLen);
- return std::make_pair<QString, qint32>(QString(output), messageIndex);
+ return std::make_pair(output, messageIndex);
}
-std::variant<QByteArray, QOlmError> 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');
diff --git a/lib/e2ee/qolminboundsession.h b/lib/e2ee/qolminboundsession.h
index 13515434..1a9b4415 100644
--- a/lib/e2ee/qolminboundsession.h
+++ b/lib/e2ee/qolminboundsession.h
@@ -5,11 +5,8 @@
#pragma once
#include "e2ee/e2ee.h"
-#include "e2ee/qolmerrors.h"
-#include "olm/olm.h"
-#include <memory>
-#include <variant>
+#include <olm/olm.h>
namespace Quotient {
@@ -27,14 +24,13 @@ public:
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 QOlmExpected<QOlmInboundGroupSessionPtr> unpickle(
+ const QByteArray& pickled, const PicklingMode& mode);
//! Decrypts ciphertext received for this group session.
- std::variant<std::pair<QString, uint32_t>, QOlmError> decrypt(
- const QByteArray& message);
+ QOlmExpected<std::pair<QByteArray, uint32_t> > 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);
+ QOlmExpected<QByteArray> exportSession(uint32_t messageIndex);
//! Get the first message index we know how to decrypt.
uint32_t firstKnownIndex() const;
//! Get a base64-encoded identifier for this session.
diff --git a/lib/e2ee/qolmoutboundsession.cpp b/lib/e2ee/qolmoutboundsession.cpp
index da32417b..96bad344 100644
--- a/lib/e2ee/qolmoutboundsession.cpp
+++ b/lib/e2ee/qolmoutboundsession.cpp
@@ -13,8 +13,7 @@ QOlmError lastError(OlmOutboundGroupSession *session) {
QOlmOutboundGroupSession::QOlmOutboundGroupSession(OlmOutboundGroupSession *session)
: m_groupSession(session)
-{
-}
+{}
QOlmOutboundGroupSession::~QOlmOutboundGroupSession()
{
@@ -22,7 +21,7 @@ QOlmOutboundGroupSession::~QOlmOutboundGroupSession()
delete[](reinterpret_cast<uint8_t *>(m_groupSession));
}
-std::unique_ptr<QOlmOutboundGroupSession> QOlmOutboundGroupSession::create()
+QOlmOutboundGroupSessionPtr QOlmOutboundGroupSession::create()
{
auto *olmOutboundGroupSession = olm_outbound_group_session(new uint8_t[olm_outbound_group_session_size()]);
const auto randomLength = olm_init_outbound_group_session_random_length(olmOutboundGroupSession);
@@ -45,7 +44,7 @@ std::unique_ptr<QOlmOutboundGroupSession> QOlmOutboundGroupSession::create()
return std::make_unique<QOlmOutboundGroupSession>(olmOutboundGroupSession);
}
-std::variant<QByteArray, QOlmError> QOlmOutboundGroupSession::pickle(const PicklingMode &mode)
+QOlmExpected<QByteArray> QOlmOutboundGroupSession::pickle(const PicklingMode &mode)
{
QByteArray pickledBuf(olm_pickle_outbound_group_session_length(m_groupSession), '0');
QByteArray key = toKey(mode);
@@ -61,7 +60,7 @@ std::variant<QByteArray, QOlmError> QOlmOutboundGroupSession::pickle(const Pickl
return pickledBuf;
}
-std::variant<std::unique_ptr<QOlmOutboundGroupSession>, QOlmError> QOlmOutboundGroupSession::unpickle(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()]);
@@ -80,7 +79,7 @@ std::variant<std::unique_ptr<QOlmOutboundGroupSession>, QOlmError> QOlmOutboundG
return std::make_unique<QOlmOutboundGroupSession>(olmOutboundGroupSession);
}
-std::variant<QByteArray, QOlmError> QOlmOutboundGroupSession::encrypt(const QString &plaintext)
+QOlmExpected<QByteArray> QOlmOutboundGroupSession::encrypt(const QString &plaintext)
{
QByteArray plaintextBuf = plaintext.toUtf8();
const auto messageMaxLength = olm_group_encrypt_message_length(m_groupSession, plaintextBuf.length());
@@ -112,12 +111,13 @@ QByteArray QOlmOutboundGroupSession::sessionId() const
return idBuffer;
}
-std::variant<QByteArray, QOlmError> QOlmOutboundGroupSession::sessionKey() const
+QOlmExpected<QByteArray> QOlmOutboundGroupSession::sessionKey() const
{
const auto keyMaxLength = olm_outbound_group_session_key_length(m_groupSession);
QByteArray keyBuffer(keyMaxLength, '0');
- const auto error = olm_outbound_group_session_key(m_groupSession, reinterpret_cast<uint8_t *>(keyBuffer.data()),
- keyMaxLength);
+ const auto error = olm_outbound_group_session_key(
+ m_groupSession, reinterpret_cast<uint8_t*>(keyBuffer.data()),
+ keyMaxLength);
if (error == olm_error()) {
return lastError(m_groupSession);
}
diff --git a/lib/e2ee/qolmoutboundsession.h b/lib/e2ee/qolmoutboundsession.h
index 32ba2b3b..8058bbb1 100644
--- a/lib/e2ee/qolmoutboundsession.h
+++ b/lib/e2ee/qolmoutboundsession.h
@@ -4,10 +4,10 @@
#pragma once
-#include "olm/olm.h"
-#include "e2ee/qolmerrors.h"
#include "e2ee/e2ee.h"
+
#include <memory>
+#include <olm/olm.h>
namespace Quotient {
@@ -19,15 +19,15 @@ public:
~QOlmOutboundGroupSession();
//! Creates a new instance of `QOlmOutboundGroupSession`.
//! Throw OlmError on errors
- static std::unique_ptr<QOlmOutboundGroupSession> create();
+ static QOlmOutboundGroupSessionPtr create();
//! Serialises a `QOlmOutboundGroupSession` to encrypted Base64.
- std::variant<QByteArray, QOlmError> pickle(const PicklingMode &mode);
+ QOlmExpected<QByteArray> 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 QOlmExpected<QOlmOutboundGroupSessionPtr> unpickle(
+ QByteArray& pickled, const PicklingMode& mode);
//! Encrypts a plaintext message using the session.
- std::variant<QByteArray, QOlmError> encrypt(const QString &plaintext);
+ QOlmExpected<QByteArray> encrypt(const QString& plaintext);
//! Get the current message index for this session.
//!
@@ -42,11 +42,10 @@ public:
//!
//! Each message is sent with a different ratchet key. This function returns the
//! ratchet key that will be used for the next message.
- std::variant<QByteArray, QOlmError> sessionKey() const;
+ QOlmExpected<QByteArray> sessionKey() const;
QOlmOutboundGroupSession(OlmOutboundGroupSession *groupSession);
private:
OlmOutboundGroupSession *m_groupSession;
};
-using QOlmOutboundGroupSessionPtr = std::unique_ptr<QOlmOutboundGroupSession>;
-}
+} // namespace Quotient
diff --git a/lib/e2ee/qolmsession.cpp b/lib/e2ee/qolmsession.cpp
index 5ccbfd40..2b149aac 100644
--- a/lib/e2ee/qolmsession.cpp
+++ b/lib/e2ee/qolmsession.cpp
@@ -27,7 +27,9 @@ OlmSession* QOlmSession::create()
return olm_session(new uint8_t[olm_session_size()]);
}
-std::variant<QOlmSessionPtr, QOlmError> QOlmSession::createInbound(QOlmAccount *account, const QOlmMessage &preKeyMessage, bool from, const QString &theirIdentityKey)
+QOlmExpected<QOlmSessionPtr> QOlmSession::createInbound(
+ QOlmAccount* account, const QOlmMessage& preKeyMessage, bool from,
+ const QString& theirIdentityKey)
{
if (preKeyMessage.type() != QOlmMessage::PreKey) {
qCCritical(E2EE) << "The message is not a pre-key in when creating inbound session" << BadMessageFormat;
@@ -53,17 +55,22 @@ std::variant<QOlmSessionPtr, QOlmError> QOlmSession::createInbound(QOlmAccount *
return std::make_unique<QOlmSession>(olmSession);
}
-std::variant<QOlmSessionPtr, QOlmError> QOlmSession::createInboundSession(QOlmAccount *account, const QOlmMessage &preKeyMessage)
+QOlmExpected<QOlmSessionPtr> QOlmSession::createInboundSession(
+ QOlmAccount* account, const QOlmMessage& preKeyMessage)
{
return createInbound(account, preKeyMessage);
}
-std::variant<QOlmSessionPtr, QOlmError> QOlmSession::createInboundSessionFrom(QOlmAccount *account, const QString &theirIdentityKey, const QOlmMessage &preKeyMessage)
+QOlmExpected<QOlmSessionPtr> QOlmSession::createInboundSessionFrom(
+ QOlmAccount* account, const QString& theirIdentityKey,
+ const QOlmMessage& preKeyMessage)
{
return createInbound(account, preKeyMessage, true, theirIdentityKey);
}
-std::variant<QOlmSessionPtr, QOlmError> QOlmSession::createOutboundSession(QOlmAccount *account, const QString &theirIdentityKey, const QString &theirOneTimeKey)
+QOlmExpected<QOlmSessionPtr> QOlmSession::createOutboundSession(
+ QOlmAccount* account, const QString& theirIdentityKey,
+ const QString& theirOneTimeKey)
{
auto *olmOutboundSession = create();
const auto randomLen = olm_create_outbound_session_random_length(olmOutboundSession);
@@ -89,7 +96,7 @@ std::variant<QOlmSessionPtr, QOlmError> QOlmSession::createOutboundSession(QOlmA
return std::make_unique<QOlmSession>(olmOutboundSession);
}
-std::variant<QByteArray, QOlmError> QOlmSession::pickle(const PicklingMode &mode)
+QOlmExpected<QByteArray> QOlmSession::pickle(const PicklingMode &mode)
{
QByteArray pickledBuf(olm_pickle_session_length(m_session), '0');
QByteArray key = toKey(mode);
@@ -105,7 +112,8 @@ std::variant<QByteArray, QOlmError> QOlmSession::pickle(const PicklingMode &mode
return pickledBuf;
}
-std::variant<QOlmSessionPtr, QOlmError> QOlmSession::unpickle(const QByteArray &pickled, const PicklingMode &mode)
+QOlmExpected<QOlmSessionPtr> QOlmSession::unpickle(const QByteArray& pickled,
+ const PicklingMode& mode)
{
QByteArray pickledBuf = pickled;
auto *olmSession = create();
@@ -140,7 +148,7 @@ QOlmMessage QOlmSession::encrypt(const QString &plaintext)
return QOlmMessage(messageBuf, messageType);
}
-std::variant<QString, QOlmError> QOlmSession::decrypt(const QOlmMessage &message) const
+QOlmExpected<QByteArray> QOlmSession::decrypt(const QOlmMessage &message) const
{
const auto messageType = message.type();
const auto ciphertext = message.toCiphertext();
diff --git a/lib/e2ee/qolmsession.h b/lib/e2ee/qolmsession.h
index 4eb151b6..faae16ef 100644
--- a/lib/e2ee/qolmsession.h
+++ b/lib/e2ee/qolmsession.h
@@ -19,32 +19,31 @@ 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 QOlmExpected<QOlmSessionPtr> createInboundSession(
+ QOlmAccount* account, const QOlmMessage& preKeyMessage);
- static std::variant<std::unique_ptr<QOlmSession>, QOlmError>
- createInboundSessionFrom(QOlmAccount* account,
- const QString& theirIdentityKey,
- const QOlmMessage& preKeyMessage);
+ static QOlmExpected<QOlmSessionPtr> 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 QOlmExpected<QOlmSessionPtr> createOutboundSession(
+ QOlmAccount* account, const QString& theirIdentityKey,
+ const QString& theirOneTimeKey);
//! Serialises an `QOlmSession` to encrypted Base64.
- std::variant<QByteArray, QOlmError> pickle(const PicklingMode &mode);
+ QOlmExpected<QByteArray> 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(
+ static QOlmExpected<QOlmSessionPtr> unpickle(
const QByteArray& pickled, const PicklingMode& mode);
//! Encrypts a plaintext message using the session.
QOlmMessage encrypt(const QString &plaintext);
- //! Decrypts a message using this session. Decoding is lossy, meaing if
+ //! Decrypts a message using this session. Decoding is lossy, meaning if
//! the decrypted plaintext contains invalid UTF-8 symbols, they will
//! be returned as `U+FFFD` (�).
- std::variant<QString, QOlmError> decrypt(const QOlmMessage &message) const;
+ QOlmExpected<QByteArray> decrypt(const QOlmMessage &message) const;
//! Get a base64-encoded identifier for this session.
QByteArray sessionId() const;
@@ -56,11 +55,10 @@ public:
bool hasReceivedMessage() const;
//! Checks if the 'prekey' message is for this in-bound session.
- std::variant<bool, QOlmError> matchesInboundSession(
- const QOlmMessage& preKeyMessage) const;
+ bool matchesInboundSession(const QOlmMessage& preKeyMessage) const;
//! Checks if the 'prekey' message is for this in-bound session.
- std::variant<bool, QOlmError> matchesInboundSessionFrom(
+ bool matchesInboundSessionFrom(
const QString& theirIdentityKey, const QOlmMessage& preKeyMessage) const;
friend bool operator<(const QOlmSession& lhs, const QOlmSession& rhs)
@@ -68,8 +66,7 @@ public:
return lhs.sessionId() < rhs.sessionId();
}
- friend bool operator<(const std::unique_ptr<QOlmSession>& lhs,
- const std::unique_ptr<QOlmSession>& rhs)
+ friend bool operator<(const QOlmSessionPtr& lhs, const QOlmSessionPtr& rhs)
{
return *lhs < *rhs;
}
@@ -80,7 +77,7 @@ public:
private:
//! Helper function for creating new sessions and handling errors.
static OlmSession* create();
- static std::variant<std::unique_ptr<QOlmSession>, QOlmError> createInbound(
+ static QOlmExpected<QOlmSessionPtr> createInbound(
QOlmAccount* account, const QOlmMessage& preKeyMessage,
bool from = false, const QString& theirIdentityKey = "");
OlmSession* m_session;
diff --git a/lib/e2ee/qolmutility.cpp b/lib/e2ee/qolmutility.cpp
index 9f09a37f..84559085 100644
--- a/lib/e2ee/qolmutility.cpp
+++ b/lib/e2ee/qolmutility.cpp
@@ -3,8 +3,8 @@
// SPDX-License-Identifier: LGPL-2.1-or-later
#include "e2ee/qolmutility.h"
-#include "olm/olm.h"
-#include <QDebug>
+
+#include <olm/olm.h>
using namespace Quotient;
@@ -40,8 +40,9 @@ QString QOlmUtility::sha256Utf8Msg(const QString &message) const
return sha256Bytes(message.toUtf8());
}
-std::variant<bool, QOlmError> QOlmUtility::ed25519Verify(const QByteArray &key,
- const QByteArray &message, const QByteArray &signature)
+QOlmExpected<bool> QOlmUtility::ed25519Verify(const QByteArray& key,
+ const QByteArray& message,
+ const QByteArray& signature)
{
QByteArray signatureBuf(signature.length(), '0');
std::copy(signature.begin(), signature.end(), signatureBuf.begin());
@@ -57,8 +58,5 @@ std::variant<bool, QOlmError> QOlmUtility::ed25519Verify(const QByteArray &key,
return error;
}
- if (ret != 0) {
- return false;
- }
- return true;
+ return !ret; // ret == 0 means success
}
diff --git a/lib/e2ee/qolmutility.h b/lib/e2ee/qolmutility.h
index a12af49a..5f6bcdc5 100644
--- a/lib/e2ee/qolmutility.h
+++ b/lib/e2ee/qolmutility.h
@@ -4,15 +4,12 @@
#pragma once
-#include <variant>
-#include "e2ee/qolmerrors.h"
+#include "e2ee/e2ee.h"
struct OlmUtility;
namespace Quotient {
-class QOlmSession;
-
//! Allows you to make use of crytographic hashing via SHA-2 and
//! verifying ed25519 signatures.
class QUOTIENT_API QOlmUtility
@@ -32,7 +29,7 @@ public:
//! \param key QByteArray The public part of the ed25519 key that signed the message.
//! \param message QByteArray The message that was signed.
//! \param signature QByteArray The signature of the message.
- std::variant<bool, QOlmError> ed25519Verify(const QByteArray &key,
+ QOlmExpected<bool> ed25519Verify(const QByteArray &key,
const QByteArray &message, const QByteArray &signature);
private:
diff --git a/lib/room.cpp b/lib/room.cpp
index db49e80f..1314803e 100644
--- a/lib/room.cpp
+++ b/lib/room.cpp
@@ -380,17 +380,22 @@ public:
return {};
}
auto decryptResult = senderSession->decrypt(cipher);
- if(std::holds_alternative<QOlmError>(decryptResult)) {
+ if(!decryptResult) {
qCWarning(E2EE) << "Unable to decrypt event" << eventId
- << "with matching megolm session:" << std::get<QOlmError>(decryptResult);
+ << "with matching megolm session:" << decryptResult.error();
return {};
}
- const auto& [content, index] = std::get<std::pair<QString, uint32_t>>(decryptResult);
- const auto& [recordEventId, ts] = q->connection()->database()->groupSessionIndexRecord(q->id(), senderSession->sessionId(), index);
+ const auto& [content, index] = *decryptResult;
+ const auto& [recordEventId, ts] =
+ q->connection()->database()->groupSessionIndexRecord(
+ q->id(), senderSession->sessionId(), index);
if (recordEventId.isEmpty()) {
- q->connection()->database()->addGroupSessionIndexRecord(q->id(), senderSession->sessionId(), index, eventId, timestamp.toMSecsSinceEpoch());
+ q->connection()->database()->addGroupSessionIndexRecord(
+ q->id(), senderSession->sessionId(), index, eventId,
+ timestamp.toMSecsSinceEpoch());
} else {
- if ((eventId != recordEventId) || (ts != timestamp.toMSecsSinceEpoch())) {
+ if ((eventId != recordEventId)
+ || (ts != timestamp.toMSecsSinceEpoch())) {
qCWarning(E2EE) << "Detected a replay attack on event" << eventId;
return {};
}