diff options
Diffstat (limited to 'lib/events')
-rw-r--r-- | lib/events/encryptedevent.cpp | 7 | ||||
-rw-r--r-- | lib/events/encryptedevent.h | 2 | ||||
-rw-r--r-- | lib/events/encryptedfile.cpp | 30 | ||||
-rw-r--r-- | lib/events/encryptedfile.h | 1 | ||||
-rw-r--r-- | lib/events/roomkeyevent.cpp | 13 | ||||
-rw-r--r-- | lib/events/roomkeyevent.h | 1 |
6 files changed, 52 insertions, 2 deletions
diff --git a/lib/events/encryptedevent.cpp b/lib/events/encryptedevent.cpp index 9d07a35f..c97ccc16 100644 --- a/lib/events/encryptedevent.cpp +++ b/lib/events/encryptedevent.cpp @@ -61,3 +61,10 @@ RoomEventPtr EncryptedEvent::createDecrypted(const QString &decrypted) const } return loadEvent<RoomEvent>(eventObject); } + +void EncryptedEvent::setRelation(const QJsonObject& relation) +{ + auto content = contentJson(); + content["m.relates_to"] = relation; + editJson()["content"] = content; +} diff --git a/lib/events/encryptedevent.h b/lib/events/encryptedevent.h index 72efffd4..ddd5e415 100644 --- a/lib/events/encryptedevent.h +++ b/lib/events/encryptedevent.h @@ -56,6 +56,8 @@ public: QString deviceId() const { return contentPart<QString>(DeviceIdKeyL); } QString sessionId() const { return contentPart<QString>(SessionIdKeyL); } RoomEventPtr createDecrypted(const QString &decrypted) const; + + void setRelation(const QJsonObject& relation); }; REGISTER_EVENT_TYPE(EncryptedEvent) diff --git a/lib/events/encryptedfile.cpp b/lib/events/encryptedfile.cpp index d4a517bd..d35ee28f 100644 --- a/lib/events/encryptedfile.cpp +++ b/lib/events/encryptedfile.cpp @@ -8,6 +8,7 @@ #ifdef Quotient_E2EE_ENABLED #include <openssl/evp.h> #include <QtCore/QCryptographicHash> +#include "e2ee/qolmutils.h" #endif using namespace Quotient; @@ -27,7 +28,7 @@ QByteArray EncryptedFile::decryptFile(const QByteArray& ciphertext) const { int length; auto* ctx = EVP_CIPHER_CTX_new(); - QByteArray plaintext(ciphertext.size() + EVP_CIPHER_CTX_block_size(ctx) + QByteArray plaintext(ciphertext.size() + EVP_MAX_BLOCK_LENGTH - 1, '\0'); EVP_DecryptInit_ex(ctx, EVP_aes_256_ctr(), nullptr, @@ -44,7 +45,7 @@ QByteArray EncryptedFile::decryptFile(const QByteArray& ciphertext) const + length, &length); EVP_CIPHER_CTX_free(ctx); - return plaintext; + return plaintext.left(ciphertext.size()); } #else qWarning(MAIN) << "This build of libQuotient doesn't support E2EE, " @@ -53,6 +54,31 @@ QByteArray EncryptedFile::decryptFile(const QByteArray& ciphertext) const #endif } +std::pair<EncryptedFile, QByteArray> EncryptedFile::encryptFile(const QByteArray &plainText) +{ +#ifdef Quotient_E2EE_ENABLED + QByteArray k = getRandom(32); + auto kBase64 = k.toBase64(); + QByteArray iv = getRandom(16); + JWK key = {"oct"_ls, {"encrypt"_ls, "decrypt"_ls}, "A256CTR"_ls, QString(k.toBase64()).replace(u'/', u'_').replace(u'+', u'-').left(kBase64.indexOf('=')), true}; + + int length; + auto* ctx = EVP_CIPHER_CTX_new(); + QByteArray cipherText(plainText.size(), plainText.size() + EVP_MAX_BLOCK_LENGTH - 1); + EVP_EncryptInit_ex(ctx, EVP_aes_256_ctr(), nullptr, reinterpret_cast<const unsigned char*>(k.data()),reinterpret_cast<const unsigned char*>(iv.data())); + EVP_EncryptUpdate(ctx, reinterpret_cast<unsigned char*>(cipherText.data()), &length, reinterpret_cast<const unsigned char*>(plainText.data()), plainText.size()); + EVP_EncryptFinal_ex(ctx, reinterpret_cast<unsigned char*>(cipherText.data()) + length, &length); + EVP_CIPHER_CTX_free(ctx); + + auto hash = QCryptographicHash::hash(cipherText, QCryptographicHash::Sha256).toBase64(); + auto ivBase64 = iv.toBase64(); + EncryptedFile file = {{}, key, ivBase64.left(ivBase64.indexOf('=')), {{QStringLiteral("sha256"), hash.left(hash.indexOf('='))}}, "v2"_ls}; + return {file, cipherText}; +#else + return {}; +#endif +} + void JsonObjectConverter<EncryptedFile>::dumpTo(QJsonObject& jo, const EncryptedFile& pod) { diff --git a/lib/events/encryptedfile.h b/lib/events/encryptedfile.h index d0c4a030..022ac91e 100644 --- a/lib/events/encryptedfile.h +++ b/lib/events/encryptedfile.h @@ -46,6 +46,7 @@ public: QString v; QByteArray decryptFile(const QByteArray &ciphertext) const; + static std::pair<EncryptedFile, QByteArray> encryptFile(const QByteArray& plainText); }; template <> diff --git a/lib/events/roomkeyevent.cpp b/lib/events/roomkeyevent.cpp index 332be3f7..68962950 100644 --- a/lib/events/roomkeyevent.cpp +++ b/lib/events/roomkeyevent.cpp @@ -10,3 +10,16 @@ RoomKeyEvent::RoomKeyEvent(const QJsonObject &obj) : Event(typeId(), obj) if (roomId().isEmpty()) qCWarning(E2EE) << "Room key event has empty room id"; } + +RoomKeyEvent::RoomKeyEvent(const QString& algorithm, const QString& roomId, const QString& sessionId, const QString& sessionKey, const QString& senderId) + : Event(typeId(), { + {"content", QJsonObject{ + {"algorithm", algorithm}, + {"room_id", roomId}, + {"session_id", sessionId}, + {"session_key", sessionKey}, + }}, + {"sender", senderId}, + {"type", "m.room_key"}, + }) +{} diff --git a/lib/events/roomkeyevent.h b/lib/events/roomkeyevent.h index ed4c9440..2bda3086 100644 --- a/lib/events/roomkeyevent.h +++ b/lib/events/roomkeyevent.h @@ -12,6 +12,7 @@ public: DEFINE_EVENT_TYPEID("m.room_key", RoomKeyEvent) explicit RoomKeyEvent(const QJsonObject& obj); + explicit RoomKeyEvent(const QString& algorithm, const QString& roomId, const QString &sessionId, const QString& sessionKey, const QString& senderId); QString algorithm() const { return contentPart<QString>("algorithm"_ls); } QString roomId() const { return contentPart<QString>(RoomIdKeyL); } |