Skip to content

Commit

Permalink
Work
Browse files Browse the repository at this point in the history
  • Loading branch information
TobiasFella committed Sep 1, 2024
1 parent 4951a64 commit 615d663
Show file tree
Hide file tree
Showing 7 changed files with 24 additions and 79 deletions.
17 changes: 5 additions & 12 deletions Quotient/connectionencryptiondata_p.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -778,19 +778,12 @@ std::pair<QByteArray, QByteArray> ConnectionEncryptionData::sessionDecryptMessag
}
}

//TODO new session

qWarning() << "Creating new inbound session"; // Pre-key messages only
auto newSessionResult =
olmAccount->createInboundSession(senderKey, message);
auto&& newSession = std::move(newSessionResult);
auto result = newSession.tryDecrypt(message);
if (result.has_value()) {
saveSession(newSession, senderKey);
olmSessions[senderKey].push_back(std::move(newSession));
return std::make_pair(result.value(), newSession.sessionId());
}
return {};
auto newSessionResult = olmAccount->createInboundSession(senderKey, message);
auto&& newSession = std::move(newSessionResult.first);
saveSession(newSession, senderKey);
olmSessions[senderKey].push_back(std::move(newSession));
return std::make_pair(newSessionResult.second.toUtf8(), newSession.sessionId());
}

std::pair<EventPtr, QByteArray> ConnectionEncryptionData::sessionDecryptMessage(
Expand Down
10 changes: 4 additions & 6 deletions Quotient/database.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -283,17 +283,15 @@ void Database::migrateTo11()
{
qCDebug(DATABASE) << "Migrating database to version 11";
//TODO: This is terrible :(
std::array<std::uint8_t, 128> _key;
std::array<std::uint8_t, 32> vodoKey;
std::copy(m_picklingKey.data(), m_picklingKey.data() + 128, _key.begin());
std::copy(m_picklingKey.data(), m_picklingKey.data() + 32, vodoKey.begin());

transaction();
auto query = prepareQuery(u"SELECT pickle FROM accounts;"_s);
execute(query);
if (query.next()) {
auto olmAccountPickle = query.value(u"pickle"_s).toString();
auto account = olm::account_from_olm_pickle(rust::String((const char *) olmAccountPickle.toLatin1().data(), olmAccountPickle.size()), _key);
auto account = olm::account_from_olm_pickle(rust::String((const char *) olmAccountPickle.toLatin1().data(), olmAccountPickle.size()), rust::Slice((const unsigned char*) m_picklingKey.data(), m_picklingKey.size()));
auto pickle = account->pickle(vodoKey);
execute(u"DELETE FROM accounts;"_s);
query = prepareQuery(u"INSERT INTO accounts(pickle) VALUES(:pickle);"_s);
Expand All @@ -308,7 +306,7 @@ void Database::migrateTo11()
inboundPickles += query.value(0).toString();
}
for (const auto &olmPickle : inboundPickles) {
auto session = megolm::inbound_group_session_from_olm_pickle((rust::String((const char *) olmPickle.toLatin1().data(), olmPickle.size())), _key);
auto session = megolm::inbound_group_session_from_olm_pickle((rust::String((const char *) olmPickle.toLatin1().data(), olmPickle.size())), rust::Slice((const unsigned char*) m_picklingKey.data(), m_picklingKey.size()));
auto pickle = session->pickle(vodoKey);
auto replaceQuery = prepareQuery(u"UPDATE inbound_megolm_sessions SET pickle=:pickle WHERE pickle=:olmPickle;"_s);
replaceQuery.bindValue(u":pickle"_s, QString::fromLatin1({pickle.data(), (qsizetype) pickle.size()}));
Expand All @@ -325,7 +323,7 @@ void Database::migrateTo11()
}

for (const auto &olmPickle : outboundPickles) {
auto session = megolm::group_session_from_olm_pickle((rust::String((const char *) olmPickle.toLatin1().data(), olmPickle.size())), _key);
auto session = megolm::group_session_from_olm_pickle((rust::String((const char *) olmPickle.toLatin1().data(), olmPickle.size())), rust::Slice((const unsigned char*) m_picklingKey.data(), m_picklingKey.size()));
auto pickle = session->pickle(vodoKey);
auto replaceQuery = prepareQuery(u"UPDATE outbound_megolm_sessions SET pickle=:pickle WHERE pickle=:olmPickle;"_s);
replaceQuery.bindValue(u":pickle"_s, QString::fromLatin1({pickle.data(), (qsizetype) pickle.size()}));
Expand All @@ -341,7 +339,7 @@ void Database::migrateTo11()
olmPickles += query.value(0).toString();
}
for (const auto &olmPickle : olmPickles) {
auto session = olm::session_from_olm_pickle((rust::String((const char *) olmPickle.toLatin1().data(), olmPickle.size())), _key);
auto session = olm::session_from_olm_pickle((rust::String((const char *) olmPickle.toLatin1().data(), olmPickle.size())), rust::Slice((const unsigned char*) m_picklingKey.data(), m_picklingKey.size()));
auto pickle = session->pickle(vodoKey);
auto replaceQuery = prepareQuery(u"UPDATE olm_sessions SET pickle=:pickle WHERE pickle=:olmPickle;"_s);
replaceQuery.bindValue(u":pickle"_s, QString::fromLatin1({pickle.data(), (qsizetype) pickle.size()}));
Expand Down
4 changes: 2 additions & 2 deletions Quotient/e2ee/qolmaccount.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -155,7 +155,7 @@ UploadKeysJob* QOlmAccount::createUploadKeyRequest(
return new UploadKeysJob(deviceKeys(), signOneTimeKeys(oneTimeKeys));
}

QOlmSession QOlmAccount::createInboundSession(
std::pair<QOlmSession, QString> QOlmAccount::createInboundSession(
const QByteArray& theirIdentityKey, const QOlmMessage& preKeyMessage)
{
rust::Str theirIdentityKeyRS(theirIdentityKey.data(), theirIdentityKey.length());
Expand All @@ -165,7 +165,7 @@ QOlmSession QOlmAccount::createInboundSession(
qWarning() << "Creating inbound session";
auto result = olmData->create_inbound_session(*types::curve25519_public_key_from_base64_result_value(std::move(theirIdentityKeyResult)), *olm_message_from_parts(parts));

return QOlmSession(std::move(result.session));
return {QOlmSession(std::move(result.session)), QString::fromUtf8({result.plaintext.data(), (int) result.plaintext.size()})};
}


Expand Down
4 changes: 2 additions & 2 deletions Quotient/e2ee/qolmaccount.h
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ class QUOTIENT_API QOlmAccount : public QObject

//! Deserialises from encrypted Base64 that was previously obtained by pickling a `QOlmAccount`.
[[nodiscard]] static QOlmAccount *unpickle(QByteArray&& pickled,
const PicklingKey& key, const QString& userId, const QString& deviceId, QObject *parent);
const PicklingKey& key, const QString& userId, const QString& deviceId, QObject* parent);

//! Serialises an OlmAccount to encrypted Base64.
QByteArray pickle(const PicklingKey& key) const;
Expand Down Expand Up @@ -80,7 +80,7 @@ class QUOTIENT_API QOlmAccount : public QObject
//!
//! \param theirIdentityKey - The identity key of the Olm account that
//! encrypted this Olm message.
QOlmSession createInboundSession(
std::pair<QOlmSession, QString> createInboundSession(
const QByteArray& theirIdentityKey,
const QOlmMessage& preKeyMessage);

Expand Down
2 changes: 1 addition & 1 deletion Quotient/e2ee/qolmsession.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ QOlmExpected<QByteArray> QOlmSession::tryDecrypt(const QOlmMessage& message)
});
auto decryptedResult = m_session->decrypt(*olmMessage.into_raw());
if (decryptedResult->has_error()) {
return 1; //TODO return correct error
return decryptedResult->error_code();
}
auto decrypted = olm::session_decrypt_result_value(std::move(decryptedResult));
return QByteArray(decrypted.data(), decrypted.size());
Expand Down
65 changes: 10 additions & 55 deletions autotests/testolmsession.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -7,64 +7,19 @@
#include "testolmsession.h"

using namespace Quotient;

std::pair<QOlmSession, QOlmSession> createSessionPair()
{
QByteArray pickledAccountA("eOBXIKivUT6YYowRH031BNv7zNmzqM5B7CpXdyeaPvala5mt7/OeqrG1qVA7vA1SYloFyvJPIy0QNkD3j1HiPl5vtZHN53rtfZ9exXDok03zjmssqn4IJsqcA7Fbo1FZeKafG0NFcWwCPTdmcV7REqxjqGm3I4K8MQFa45AdTGSUu2C12cWeOcbSMlcINiMral+Uyah1sgPmLJ18h1qcnskXUXQvpffZ5DiUw1Iz5zxnwOQF1GVyowPJD7Zdugvj75RQnDxAn6CzyvrY2k2CuedwqDC3fIXM2xdUNWttW4nC2g4InpBhCVvNwhZYxlUb5BUEjmPI2AB3dAL5ry6o9MFncmbN6x5x");
QByteArray pickledAccountB("eModTvoFi9oOIkax4j4nuxw9Tcl/J8mOmUctUWI68Q89HSaaPTqR+tdlKQ85v2GOs5NlZCp7EuycypN9GQ4fFbHUCrS7nspa3GFBWsR8PnM8+wez5PWmfFZLg3drOvT0jbMjpDx0MjGYClHBqcrEpKx9oFaIRGBaX6HXzT4lRaWSJkXxuX92q8iGNrLn96PuAWFNcD+2JXpPcNFntslwLUNgqzpZ04aIFYwL80GmzyOgq3Bz1GO6u3TgCQEAmTIYN2QkO0MQeuSfe7UoMumhlAJ6R8GPcdSSPtmXNk4tdyzzlgpVq1hm7ZLKto+g8/5Aq3PvnvA8wCqno2+Pi1duK1pZFTIlActr");
auto accountA = QOlmAccount::newAccount(nullptr, QStringLiteral("RESTORE"), QStringLiteral("RESTORE"));
auto accountB = QOlmAccount::newAccount(nullptr, QStringLiteral("RESTORE"), QStringLiteral("RESTORE"));

const QByteArray identityKeyA("qIEr3TWcJQt4CP8QoKKJcCaukByIOpgh6erBkhLEa2o");
const QByteArray oneTimeKeyA("WzsbsjD85iB1R32iWxfJdwkgmdz29ClMbJSJziECYwk");
const QByteArray identityKeyB("q/YhJtog/5VHCAS9rM9uUf6AaFk1yPe4GYuyUOXyQCg");
const QByteArray oneTimeKeyB("oWvzryma+B2onYjo3hM6A3Mgo/Yepm8HvgSvwZMTnjQ");
auto outbound =
accountA->createOutboundSession(identityKeyB, oneTimeKeyB);

const auto preKey = outbound.encrypt(""); // Payload does not matter for PreKey

if (preKey.type() != QOlmMessage::PreKey) {
// 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 = accountB->createInboundSession(accountA->identityKeys().curve25519.toLatin1(), preKey);
return { std::move(inbound), std::move(outbound) };
}
using namespace Qt::Literals::StringLiterals;

void TestOlmSession::olmEncryptDecrypt()
{
auto [inboundSession, outboundSession] = createSessionPair();
const auto encrypted = outboundSession.encrypt("Hello world!");

//TODO
// const auto decrypted = inboundSession.decrypt(encrypted).value();
//
// QCOMPARE(decrypted, "Hello world!");
}

void TestOlmSession::correctSessionOrdering()
{
// n0W5IJ2ZmaI9FxKRj/wohUQ6WEU0SfoKsgKKHsr4VbM
auto session1 = QOlmSession::unpickle("7g5cfQRsDk2ROXf9S01n2leZiFRon+EbvXcMOADU0UGvlaV6t/0ihD2/0QGckDIvbmE1aV+PxB0zUtHXh99bI/60N+PWkCLA84jEY4sz3d45ui/TVoFGLDHlymKxvlj7XngXrbtlxSkVntsPzDiNpKEXCa26N2ubKpQ0fbjrV5gbBTYWfU04DXHPXFDTksxpNALYt/h0eVMVhf6hB0ZzpLBsOG0mpwkLufwub0CuDEDGGmRddz3TcNCLq5NnI8R9udDWvHAkTS1UTbHuIf/y6cZg875nJyXpAvd8/XhL8TOo8ot2sE1fElBa4vrH/m9rBQMC1GPkhLBIizmY44C+Sq9PQRnF+uCZ", PicklingKey::mock()).value();
// +9pHJhP3K4E5/2m8PYBPLh8pS9CJodwUOh8yz3mnmw0
auto session2 = QOlmSession::unpickle("7g5cfQRsDk2ROXf9S01n2leZiFRon+EbvXcMOADU0UFD+q37/WlfTAzQsSjCdD07FcErZ4siEy5vpiB+pyO8i53ptZvb2qRvqNKFzPaXuu33PS2PBTmmnR+kJt+DgDNqWadyaj/WqEAejc7ALqSs5GuhbZtpoLe+lRSRK0rwVX3gzz4qrl8pm0pD5pSZAUWRXDRlieGWMclz68VUvnSaQH7ElTo4S634CJk+xQfFFCD26v0yONPSN6rwouS1cWPuG5jTlnV8vCFVTU2+lduKh54Ko6FUJ/ei4xR8Nk2duBGSc/TdllX9e2lDYHSUkWoD4ti5xsFioB8Blus7JK9BZfcmRmdlxIOD", PicklingKey::mock()).value();
// MC7n8hX1l7WlC2/WJGHZinMocgiBZa4vwGAOredb/ME
auto session3 = QOlmSession::unpickle("7g5cfQRsDk2ROXf9S01n2leZiFRon+EbvXcMOADU0UGNk2TmVDJ95K0Nywf24FNklNVtXtFDiFPHFwNSmCbHNCp3hsGtZlt0AHUkMmL48XklLqzwtVk5/v2RRmSKR5LqYdIakrtuK/fY0ENhBZIbI1sRetaJ2KMbY9l6rCJNfFg8VhpZ4KTVvEZVuP9g/eZkCnP5NxzXiBRF6nfY3O/zhcKxa3acIqs6BMhyLsfuJ80t+hQ1HvVyuhBerGujdSDzV9tJ9SPidOwfYATk81LVF9hTmnI0KaZa7qCtFzhG0dU/Z3hIWH9HOaw1aSB/IPmughbwdJOwERyhuo3YHoznlQnJ7X252BlI", PicklingKey::mock()).value();

const auto session1Id = session1.sessionId();
const auto session2Id = session2.sessionId();
const auto session3Id = session3.sessionId();

std::vector<QOlmSession> sessionList;
sessionList.push_back(std::move(session1));
sessionList.push_back(std::move(session2));
sessionList.push_back(std::move(session3));

std::sort(sessionList.begin(), sessionList.end());
QCOMPARE(sessionList[0].sessionId(), session2Id);
QCOMPARE(sessionList[1].sessionId(), session3Id);
QCOMPARE(sessionList[2].sessionId(), session1Id);
auto alice = QOlmAccount::newAccount(nullptr, u"@alice:foo.bar"_s, u"ABCDEF"_s);
auto bob = QOlmAccount::newAccount(nullptr, u"@bob:foo.bar"_s, u"ABCDEF"_s);

bob->generateOneTimeKeys(1);
auto otk = bob->oneTimeKeys().keys.values()[0];
auto outboundSession = alice->createOutboundSession(bob->identityKeys().curve25519.toLatin1(), otk.toLatin1());
auto message = outboundSession.encrypt("Hello World!"_ba);
auto [inboundSession, plaintext] = bob->createInboundSession(alice->identityKeys().curve25519.toLatin1(), message);
QCOMPARE(plaintext.toLatin1(), "Hello World!"_ba);
}

QTEST_GUILESS_MAIN(TestOlmSession)
1 change: 0 additions & 1 deletion autotests/testolmsession.h
Original file line number Diff line number Diff line change
Expand Up @@ -9,5 +9,4 @@ class TestOlmSession : public QObject
Q_OBJECT
private Q_SLOTS:
void olmEncryptDecrypt();
void correctSessionOrdering();
};

0 comments on commit 615d663

Please sign in to comment.