[network/ruqola] src/core: Prepare to extract session key
Laurent Montel <[email protected]>
| Newsgroups | gmane.comp.kde.cvs |
|---|---|
| Message-ID | <[email protected]> |
Git commit 3d6093840b42771fce72c47ece32e555a7ed6809 by Laurent Montel.
Committed on 05/08/2026 at 12:24.
Pushed by mlaurent into branch 'master'.
Prepare to extract session key
M +0 -27 src/core/encryption/encryptionutils.cpp
M +58 -9 src/core/roomencryptionkey.cpp
M +12 -1 src/core/roomencryptionkey.h
https://invent.kde.org/network/ruqola/-/commit/3d6093840b42771fce72c47ece32e555a7ed6809
diff --git a/src/core/encryption/encryptionutils.cpp b/src/core/encryption/encryptionutils.cpp
index ee9b87a354..c9595b3c57 100644
--- a/src/core/encryption/encryptionutils.cpp
+++ b/src/core/encryption/encryptionutils.cpp
@@ -268,33 +268,6 @@ QByteArray EncryptionUtils::getMasterKey(const QString &password, const QString
}
return masterKey;
-
-#if 0
- async getMasterKey(password: string): Promise<void | CryptoKey> {
- if (password == null) {
- alert('You should provide a password');
- }
-
- // First, create a PBKDF2 "key" containing the password
- let baseKey;
- try {
- baseKey = await importRawKey(toArrayBuffer(password));
- } catch (error) {
- this.setState(E2EEState.ERROR);
- return this.error('Error creating a key based on user password: ', error);
- }
-
- // Derive a key from the password
- try {
- return await deriveKey(toArrayBuffer(Meteor.userId()), baseKey);
- } catch (error) {
- this.setState(E2EEState.ERROR);
- return this.error('Error deriving baseKey: ', error);
- }
- }
- // TODO
- return {};
-#endif
}
/**
diff --git a/src/core/roomencryptionkey.cpp b/src/core/roomencryptionkey.cpp
index 3488e05122..85241162c2 100644
--- a/src/core/roomencryptionkey.cpp
+++ b/src/core/roomencryptionkey.cpp
@@ -6,6 +6,9 @@
#include "roomencryptionkey.h"
#include "ruqola_room_memory_debug.h"
+#if USE_E2E_SUPPORT
+#include "encryption/encryptionutils.h"
+#endif
RoomEncryptionKey::RoomEncryptionKey()
{
@@ -24,8 +27,10 @@ QString RoomEncryptionKey::e2EKey() const
void RoomEncryptionKey::setE2EKey(const QString &newE2EKey)
{
- mE2EKey = newE2EKey;
- parseSessionKey();
+ if (mE2EKey != newE2EKey) {
+ mE2EKey = newE2EKey;
+ parseSessionKey();
+ }
}
void RoomEncryptionKey::parseSessionKey()
@@ -45,12 +50,17 @@ void RoomEncryptionKey::parseSessionKey()
mE2eKeyId = mE2EKey.left(36); // ← UUID
- // Extraire encryptedKey
- const QString encryptedKeyBase64 = mE2EKey.mid(36); // ← base64
+ // Extraire encryptedKey (base64)
+ mEncryptedKeyBase64 = mE2EKey.mid(36);
- // Décoder le base64
- const QByteArray encryptedKey = QByteArray::fromBase64(encryptedKeyBase64.toLatin1());
+ if (mEncryptedKeyBase64.isEmpty()) {
+ qCWarning(RUQOLA_ROOM_MEMORY_LOG) << "E2EKey encryptedKey part is empty";
+ mSessionKey.clear();
+ return;
+ }
+ // Validate base64 can be decoded
+ const QByteArray encryptedKey = QByteArray::fromBase64(mEncryptedKeyBase64.toLatin1());
if (encryptedKey.isEmpty()) {
qCWarning(RUQOLA_ROOM_MEMORY_LOG) << "Failed to decode E2EKey from base64";
mSessionKey.clear();
@@ -64,9 +74,7 @@ void RoomEncryptionKey::parseSessionKey()
}
qDebug() << "E2EKey parsed - keyId:" << mE2eKeyId << "encryptedKey size:" << encryptedKey.size();
-
- // TODO: Decrypt with user's RSA private key
- // mSessionKey = EncryptionUtils::decryptSessionKey(encryptedKey, privateKey);
+ // Waiting for RSA private key to decrypt session key
}
QString RoomEncryptionKey::e2eKeyId() const
@@ -78,6 +86,47 @@ void RoomEncryptionKey::setE2eKeyId(const QString &newE2eKeyId)
{
mE2eKeyId = newE2eKeyId;
}
+#if USE_E2E_SUPPORT
+void RoomEncryptionKey::decryptWithPrivateKey(RSA *privateKey)
+{
+ if (!privateKey) {
+ qCWarning(RUQOLA_ROOM_MEMORY_LOG) << "Private key is null, cannot decrypt session key";
+ mSessionKey.clear();
+ return;
+ }
+
+ if (mEncryptedKeyBase64.isEmpty()) {
+ qCWarning(RUQOLA_ROOM_MEMORY_LOG) << "No encrypted key available for decryption";
+ mSessionKey.clear();
+ return;
+ }
+
+ // Decode base64 to binary
+ const QByteArray encryptedKey = QByteArray::fromBase64(mEncryptedKeyBase64.toLatin1());
+
+ if (encryptedKey.size() != 256) {
+ qCWarning(RUQOLA_ROOM_MEMORY_LOG) << "Invalid encryptedKey size for decryption:" << encryptedKey.size();
+ mSessionKey.clear();
+ return;
+ }
+
+ // Decrypt using RSA private key
+ mSessionKey = EncryptionUtils::decryptSessionKey(encryptedKey, privateKey);
+
+ if (mSessionKey.isEmpty()) {
+ qCWarning(RUQOLA_ROOM_MEMORY_LOG) << "Failed to decrypt session key with private key";
+ return;
+ }
+
+ if (mSessionKey.size() != 32) {
+ qCWarning(RUQOLA_ROOM_MEMORY_LOG) << "Invalid decrypted session key size:" << mSessionKey.size() << "(expected 32)";
+ mSessionKey.clear();
+ return;
+ }
+
+ qDebug() << "Session key successfully decrypted for keyId:" << mE2eKeyId;
+}
+#endif
bool RoomEncryptionKey::operator==(const RoomEncryptionKey &other) const
{
diff --git a/src/core/roomencryptionkey.h b/src/core/roomencryptionkey.h
index a6df609984..2d4b538370 100644
--- a/src/core/roomencryptionkey.h
+++ b/src/core/roomencryptionkey.h
@@ -4,9 +4,14 @@
SPDX-License-Identifier: LGPL-2.0-or-later
*/
#pragma once
+#include "config-ruqola.h"
#include "libruqolacore_export.h"
#include <QSharedData>
-
+#if USE_E2E_SUPPORT
+extern "C" {
+#include <openssl/rsa.h>
+}
+#endif
class LIBRUQOLACORE_EXPORT RoomEncryptionKey : public QSharedData
{
public:
@@ -22,10 +27,16 @@ public:
[[nodiscard]] QByteArray sessionKey() const;
+#if USE_E2E_SUPPORT
+ // Decrypt the session key using the provided RSA private key
+ // This is called after E2EKey is received from DDP
+ void decryptWithPrivateKey(RSA *privateKey);
+#endif
private:
LIBRUQOLACORE_NO_EXPORT void parseSessionKey();
// Encryption Key
QString mE2EKey;
QString mE2eKeyId;
+ QString mEncryptedKeyBase64; // Base64-encoded RSA-encrypted session key
QByteArray mSessionKey;
};