diff options
-rw-r--r-- | autotests/testgroupsession.cpp | 14 | ||||
-rw-r--r-- | autotests/testolmaccount.cpp | 5 | ||||
-rw-r--r-- | autotests/testolmsession.cpp | 14 | ||||
-rw-r--r-- | autotests/testolmutility.cpp | 5 | ||||
-rw-r--r-- | lib/connection.cpp | 136 | ||||
-rw-r--r-- | lib/database.cpp | 32 | ||||
-rw-r--r-- | lib/e2ee/e2ee.h | 8 | ||||
-rw-r--r-- | lib/e2ee/qolmaccount.cpp | 20 | ||||
-rw-r--r-- | lib/e2ee/qolmaccount.h | 21 | ||||
-rw-r--r-- | lib/e2ee/qolminboundsession.cpp | 10 | ||||
-rw-r--r-- | lib/e2ee/qolminboundsession.h | 14 | ||||
-rw-r--r-- | lib/e2ee/qolmoutboundsession.cpp | 18 | ||||
-rw-r--r-- | lib/e2ee/qolmoutboundsession.h | 19 | ||||
-rw-r--r-- | lib/e2ee/qolmsession.cpp | 22 | ||||
-rw-r--r-- | lib/e2ee/qolmsession.h | 35 | ||||
-rw-r--r-- | lib/e2ee/qolmutility.cpp | 14 | ||||
-rw-r--r-- | lib/e2ee/qolmutility.h | 7 | ||||
-rw-r--r-- | lib/room.cpp | 17 |
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 {}; } |