]> dgit.raspbian.org Git - nextcloud-desktop.git/commitdiff
check checksum when getting e2ee metadata
authorMatthieu Gallien <matthieu.gallien@nextcloud.com>
Mon, 27 Mar 2023 22:45:28 +0000 (00:45 +0200)
committerMatthieu Gallien <matthieu.gallien@nextcloud.com>
Fri, 31 Mar 2023 15:18:28 +0000 (17:18 +0200)
Signed-off-by: Matthieu Gallien <matthieu.gallien@nextcloud.com>
src/libsync/clientsideencryption.cpp
src/libsync/clientsideencryption.h

index ef6d0982c1d0181ddeaae3d177c7fb4eac4b790d..38c819076d6cce46bf4880097cd349d8a787a884 100644 (file)
@@ -33,6 +33,7 @@
 #include <QUuid>
 #include <QScopeGuard>
 #include <QRandomGenerator>
+#include <QCryptographicHash>
 
 #include <qt5keychain/keychain.h>
 #include <common/utility.h>
@@ -1555,10 +1556,10 @@ void FolderMetadata::setupExistingMetadata(const QByteArray& metadata)
         }
     }
 
-    if (_metadataKey.isEmpty()) {
-        qCDebug(lcCse()) << "Could not setup existing metadata with missing metadataKeys!";
-        return;
-    }
+    const auto sharing = metadataObj["sharing"].toString().toLocal8Bit();
+    const auto files = metaDataDoc.object()["files"].toObject();
+    const auto metadataKey = metaDataDoc.object()["metadata"].toObject()["metadataKey"].toString().toUtf8();
+    const auto metadataKeyChecksum = metaDataDoc.object()["metadata"].toObject()["checksum"].toString().toUtf8();
 
     QByteArray sharing = metadataObj["sharing"].toString().toLocal8Bit();
     QJsonObject files = metaDataDoc.object()["files"].toObject();
@@ -1609,17 +1610,15 @@ void FolderMetadata::setupExistingMetadata(const QByteArray& metadata)
         file.encryptionKey = QByteArray::fromBase64(decryptedFileObj["key"].toString().toLocal8Bit());
         file.mimetype = decryptedFileObj["mimetype"].toString().toLocal8Bit();
 
-        // In case we wrongly stored "inode/directory" we try to recover from it
-        if (file.mimetype == QByteArrayLiteral("inode/directory")) {
-            file.mimetype = QByteArrayLiteral("httpd/unix-directory");
+        if (!checkMetadataKeyChecksum(metadataKey, metadataKeyChecksum)) {
+            _metadataKey.clear();
+            _files.clear();
+            return;
         }
 
-        _files.push_back(file);
-    }
-
-    // decryption finished, create new metadata key to be used for encryption
-    _metadataKey = EncryptionHelper::generateRandom(metadataKeySize);
-    _isMetadataSetup = true;
+        // decryption finished, create new metadata key to be used for encryption
+        _metadataKey = EncryptionHelper::generateRandom(metadataKeySize);
+        _isMetadataSetup = true;
 }
 
 // RSA/ECB/OAEPWithSHA-256AndMGF1Padding using private / public key.
@@ -1663,6 +1662,26 @@ QByteArray FolderMetadata::decryptJsonObject(const QByteArray& encryptedMetadata
     return EncryptionHelper::decryptStringSymmetric(pass, encryptedMetadata);
 }
 
+bool FolderMetadata::checkMetadataKeyChecksum(const QByteArray &metadataKey,
+                                              const QByteArray &metadataKeyChecksum) const
+{
+    const auto referenceMetadataKeyValue = computeMetadataKeyChecksum(metadataKey);
+    return referenceMetadataKeyValue == metadataKeyChecksum;
+}
+
+QByteArray FolderMetadata::computeMetadataKeyChecksum(const QByteArray &metadataKey) const
+{
+    auto checksumData = _account->e2e()->_mnemonic.remove(' ');
+    for (const auto &singleFile : _files) {
+        checksumData += singleFile.encryptedFilename;
+    }
+    checksumData += metadataKey;
+
+    auto hashAlgorithm = QCryptographicHash{QCryptographicHash::Sha256};
+    hashAlgorithm.addData(checksumData.toUtf8());
+    return hashAlgorithm.result().toHex();
+}
+
 bool FolderMetadata::isMetadataSetup() const
 {
     return _isMetadataSetup;
index a9a37e0cd88bb16356f829bb5f8fa54ebbf70c41..a180ef78f2ff9704524e3ff141aa6191ff855f25 100644 (file)
@@ -213,6 +213,10 @@ private:
     [[nodiscard]] QByteArray encryptJsonObject(const QByteArray& obj, const QByteArray pass) const;
     [[nodiscard]] QByteArray decryptJsonObject(const QByteArray& encryptedJsonBlob, const QByteArray& pass) const;
 
+    [[nodiscard]] bool checkMetadataKeyChecksum(const QByteArray &metadataKey, const QByteArray &metadataKeyChecksum) const;
+
+    [[nodiscard]] QByteArray computeMetadataKeyChecksum(const QByteArray &metadataKey) const;
+
     QByteArray _metadataKey;
 
     QVector<EncryptedFile> _files;