Skip to content

Commit

Permalink
try different permutation to try to recover the broken checksum
Browse files Browse the repository at this point in the history
will only accept a checksum that can be computed from proper data

should still be safe

Signed-off-by: Matthieu Gallien <matthieu.gallien@nextcloud.com>
  • Loading branch information
mgallien committed Apr 4, 2023
1 parent 27f46eb commit b0c6948
Show file tree
Hide file tree
Showing 2 changed files with 35 additions and 0 deletions.
33 changes: 33 additions & 0 deletions src/libsync/clientsideencryption.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}

Expand All @@ -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;
Expand Down
2 changes: 2 additions & 0 deletions src/libsync/clientsideencryption.h
Original file line number Diff line number Diff line change
Expand Up @@ -233,6 +233,8 @@ class OWNCLOUDSYNC_EXPORT FolderMetadata {
[[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;

Expand Down

0 comments on commit b0c6948

Please sign in to comment.