From b0c69481f2f457d88389b70ad511ba356f03b9bb Mon Sep 17 00:00:00 2001 From: Matthieu Gallien Date: Tue, 4 Apr 2023 17:27:24 +0200 Subject: [PATCH] try different permutation to try to recover the broken checksum will only accept a checksum that can be computed from proper data should still be safe Signed-off-by: Matthieu Gallien --- src/libsync/clientsideencryption.cpp | 33 ++++++++++++++++++++++++++++ src/libsync/clientsideencryption.h | 2 ++ 2 files changed, 35 insertions(+) diff --git a/src/libsync/clientsideencryption.cpp b/src/libsync/clientsideencryption.cpp index 4dfc3c6d3..5e5633b28 100644 --- a/src/libsync/clientsideencryption.cpp +++ b/src/libsync/clientsideencryption.cpp @@ -1714,6 +1714,14 @@ bool FolderMetadata::checkMetadataKeyChecksum(const QByteArray &metadataKey, const QByteArray &metadataKeyChecksum) const { const auto referenceMetadataKeyValue = computeMetadataKeyChecksum(metadataKey); + + if (referenceMetadataKeyValue != metadataKeyChecksum) { + if (recoverMetadataKeyChecksum(metadataKeyChecksum, metadataKey)) { + qCInfo(lcCseMetadata) << "Checksum recovery done"; + return true; + } + } + return referenceMetadataKeyValue == metadataKeyChecksum; } @@ -1734,6 +1742,31 @@ QByteArray FolderMetadata::computeMetadataKeyChecksum(const QByteArray &metadata return hashAlgorithm.result().toHex(); } +bool FolderMetadata::recoverMetadataKeyChecksum(const QByteArray &expectedChecksum, + const QByteArray &metadataKey) const +{ + const auto sortLambda = [] (const auto &first, const auto &second) { + return first.encryptedFilename < second.encryptedFilename; + }; + auto sortedFiles = _files; + + std::sort(sortedFiles.begin(), sortedFiles.end(), sortLambda); + + do { + auto hashAlgorithm = QCryptographicHash{QCryptographicHash::Sha256}; + hashAlgorithm.addData(_account->e2e()->_mnemonic.remove(' ').toUtf8()); + for (const auto &singleFile : sortedFiles) { + hashAlgorithm.addData(singleFile.encryptedFilename.toUtf8()); + } + hashAlgorithm.addData(metadataKey); + if (hashAlgorithm.result().toHex() == expectedChecksum) { + break; + } + } while (std::next_permutation(sortedFiles.begin(), sortedFiles.end(), sortLambda)); + + return expectedChecksum; +} + bool FolderMetadata::isMetadataSetup() const { return _isMetadataSetup; diff --git a/src/libsync/clientsideencryption.h b/src/libsync/clientsideencryption.h index c4517379d..1f9504d6f 100644 --- a/src/libsync/clientsideencryption.h +++ b/src/libsync/clientsideencryption.h @@ -233,6 +233,8 @@ private: [[nodiscard]] bool checkMetadataKeyChecksum(const QByteArray &metadataKey, const QByteArray &metadataKeyChecksum) const; [[nodiscard]] QByteArray computeMetadataKeyChecksum(const QByteArray &metadataKey) const; + [[nodiscard]] bool recoverMetadataKeyChecksum(const QByteArray &expectedChecksum, + const QByteArray &metadataKey) const; QByteArray _metadataKey;