aboutsummaryrefslogtreecommitdiff
path: root/lib/events
diff options
context:
space:
mode:
Diffstat (limited to 'lib/events')
-rw-r--r--lib/events/encryptedevent.cpp7
-rw-r--r--lib/events/encryptedevent.h2
-rw-r--r--lib/events/encryptedfile.cpp30
-rw-r--r--lib/events/encryptedfile.h1
-rw-r--r--lib/events/roomkeyevent.cpp13
-rw-r--r--lib/events/roomkeyevent.h1
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); }