Skip to content

Commit

Permalink
Refactoring, code-cleaning, etc.
Browse files Browse the repository at this point in the history
Signed-off-by: alex-z <[email protected]>
  • Loading branch information
allexzander committed Jan 15, 2024
1 parent b3249a1 commit 969612d
Show file tree
Hide file tree
Showing 6 changed files with 43 additions and 33 deletions.
1 change: 1 addition & 0 deletions src/libsync/encryptedfoldermetadatahandler.h
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
namespace OCC {
class FolderMetadata;
class SyncJournalDb;
// all metadata operations with server must be performed via this class
class OWNCLOUDSYNC_EXPORT EncryptedFolderMetadataHandler : public QObject
{
Q_OBJECT
Expand Down
17 changes: 5 additions & 12 deletions src/libsync/foldermetadata.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -535,19 +535,18 @@ const QSet<QByteArray>& FolderMetadata::keyChecksums() const
return _keyChecksums;
}

const QSet<QByteArray>& FolderMetadata::keyChecksumsRemoved() const
{
return _keyChecksumsRemoved;
}

void FolderMetadata::initEmptyMetadata()
{
if (_account->capabilities().clientSideEncryptionVersion() < 2.0) {
return initEmptyMetadataLegacy();
}
qCDebug(lcCseMetadata()) << "Setting up empty metadata v2";
if (_isRootEncryptedFolder) {
addUser(_account->davUser(), _account->e2e()->_certificate);
if (!addUser(_account->davUser(), _account->e2e()->_certificate)) {
qCDebug(lcCseMetadata) << "Empty metadata setup failed. Could not add first user.";
_account->reportClientStatus(OCC::ClientStatusReportingStatus::E2EeError_GeneralError);
return;
}
_metadataKeyForDecryption = _metadataKeyForEncryption;
}
_isMetadataValid = true;
Expand Down Expand Up @@ -1109,12 +1108,6 @@ void FolderMetadata::createNewMetadataKeyForEncryption()
if (!_isRootEncryptedFolder) {
return;
}
if (!metadataKeyForEncryption().isEmpty()) {
const auto checksumToRemove = calcSha256(metadataKeyForEncryption());
// TODO: since we are not supposed to remove checksums, we might as well get rid of _keyChecksumsRemoved
_keyChecksumsRemoved.insert(checksumToRemove);
//_keyChecksums.remove(checksumToRemove);
}
_metadataKeyForEncryption = EncryptionHelper::generateRandom(metadataKeySize);
if (!metadataKeyForEncryption().isEmpty()) {
_keyChecksums.insert(calcSha256(metadataKeyForEncryption()));
Expand Down
48 changes: 30 additions & 18 deletions src/libsync/foldermetadata.h
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
#pragma once
/*
* Copyright (C) 2023 by Oleksandr Zolotov <[email protected]>
* Copyright (C) 2024 by Oleksandr Zolotov <[email protected]>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
Expand Down Expand Up @@ -32,11 +32,13 @@ class TestClientSideEncryptionV2;
class TestSecureFileDrop;
namespace OCC
{
// Handles parsing and altering the metadata, encryption and decryption. Setup of the instance is always asynchronouse and emits void setupComplete()
class OWNCLOUDSYNC_EXPORT FolderMetadata : public QObject
{
friend class TestClientSideEncryptionV2;
friend class TestSecureFileDrop;
Q_OBJECT

// represents a user that has access to a folder for which metadata instance is created
struct FolderUser {
QString userId;
Expand All @@ -52,7 +54,7 @@ class OWNCLOUDSYNC_EXPORT FolderMetadata : public QObject
Version2_0,
};

// represents a user that has access to a specific filedrop entry
// represents a user that has access to a specific filedrop entry of the current folder
struct FileDropEntryUser {
QString userId;
QByteArray decryptedFiledropKey;
Expand Down Expand Up @@ -113,15 +115,16 @@ class OWNCLOUDSYNC_EXPORT FolderMetadata : public QObject

[[nodiscard]] bool moveFromFileDropToFiles();

bool addUser(const QString &userId, const QSslCertificate &certificate); //adds a user to have access to this folder (always generates new metadata key)
bool removeUser(const QString &userId); // removes a user from this folder and removes and generates a new metadata key
// adds a user to have access to this folder (always generates new metadata key)
[[nodiscard]] bool addUser(const QString &userId, const QSslCertificate &certificate);
// removes a user from this folder and removes and generates a new metadata key
[[nodiscard]] bool removeUser(const QString &userId);

[[nodiscard]] const QByteArray metadataKeyForEncryption() const;
[[nodiscard]] const QByteArray metadataKeyForDecryption() const;
[[nodiscard]] const QSet<QByteArray> &keyChecksums() const;
[[nodiscard]] const QSet<QByteArray> &keyChecksumsRemoved() const;

QByteArray encryptedMetadata();
[[nodiscard]] QByteArray encryptedMetadata();

[[nodiscard]] EncryptionStatusEnums::ItemEncryptionStatus existingMetadataEncryptionStatus() const;
[[nodiscard]] EncryptionStatusEnums::ItemEncryptionStatus encryptedMetadataEncryptionStatus() const;
Expand All @@ -135,8 +138,13 @@ class OWNCLOUDSYNC_EXPORT FolderMetadata : public QObject

[[nodiscard]] QByteArray initialMetadata() const;

public slots:
void addEncryptedFile(const EncryptedFile &f);
void removeEncryptedFile(const EncryptedFile &f);
void removeAllEncryptedFiles();

private:
QByteArray encryptedMetadataLegacy();
[[nodiscard]] QByteArray encryptedMetadataLegacy();

[[nodiscard]] bool verifyMetadataKey(const QByteArray &metadataKey) const;

Expand Down Expand Up @@ -165,11 +173,6 @@ class OWNCLOUDSYNC_EXPORT FolderMetadata : public QObject

static QByteArray prepareMetadataForSignature(const QJsonDocument &fullMetadata);

public slots:
void addEncryptedFile(const EncryptedFile &f);
void removeEncryptedFile(const EncryptedFile &f);
void removeAllEncryptedFiles();

private slots:
void initMetadata();
void initEmptyMetadata();
Expand All @@ -196,34 +199,43 @@ private slots:
QByteArray _initialMetadata;

bool _isRootEncryptedFolder = false;
// always contains the last generated metadata key (non-encrypted and non-base64)
QByteArray _metadataKeyForEncryption;
QByteArray _metadataKeyForDecryption; // used for storing initial metadataKey to use for decryption, especially in nested folders when changing the metadataKey and re-encrypting nested dirs
QSet<QByteArray> _keyChecksums;
QSet<QByteArray> _keyChecksumsRemoved;
// used for storing initial metadataKey to use for decryption, especially in nested folders when changing the metadataKey and re-encrypting nested dirs
QByteArray _metadataKeyForDecryption;
QByteArray _metadataNonce;
// metadatakey checksums for validation during setting up from existing metadata
QSet<QByteArray> _keyChecksums;

// filedrop part non-parsed, for upload in case parsing can not be done (due to not having access for the current user, etc.)
QJsonObject _fileDrop;
// used by unit tests, must get assigned simultaneously with _fileDrop and never erased
QJsonObject _fileDropFromServer;

QMap<int, QByteArray> _metadataKeys; //legacy, remove after migration is done
// legacy, remove after migration is done
QMap<int, QByteArray> _metadataKeys;

// users that have access to current folder's "ciphertext", except "filedrop" part
QHash<QString, FolderUser> _folderUsers;

// must increment on each metadata upload
quint64 _counter = 0;

MetadataVersion _existingMetadataVersion = MetadataVersion::VersionUndefined;
MetadataVersion _encryptedMetadataVersion = MetadataVersion::VersionUndefined;

// generated each time QByteArray encryptedMetadata() is called, and will later be used for validation if uploaded
QByteArray _metadataSignature;

// signature from server-side metadata
QByteArray _initialSignature;

// both files and folders info
QVector<EncryptedFile> _files;

// for parsed filedrop entries
// parsed filedrop entries ready for move
QVector<FileDropEntry> _fileDropEntries;

// sets to "true" on successful parse
bool _isMetadataValid = false;

QScopedPointer<EncryptedFolderMetadataHandler> _encryptedFolderMetadataHandler;
Expand Down
2 changes: 1 addition & 1 deletion src/libsync/updatee2eefolderusersmetadatajob.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -201,7 +201,7 @@ void UpdateE2eeFolderUsersMetadataJob::scheduleSubJobs()
const auto subJob = new UpdateE2eeFolderUsersMetadataJob(_account, _journalDb, _syncFolderRemotePath, UpdateE2eeFolderUsersMetadataJob::ReEncrypt, QString::fromUtf8(record._e2eMangledName));
subJob->setMetadataKeyForEncryption(folderMetadata->metadataKeyForEncryption());
subJob->setMetadataKeyForDecryption(folderMetadata->metadataKeyForDecryption());
subJob->setKeyChecksums(folderMetadata->keyChecksums() + folderMetadata->keyChecksumsRemoved());
subJob->setKeyChecksums(folderMetadata->keyChecksums());
subJob->setParent(this);
subJob->setFolderToken(_encryptedFolderMetadataHandler->folderToken());
_subJobs.insert(subJob);
Expand Down
6 changes: 5 additions & 1 deletion test/testclientsideencryptionv2.cpp
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (C) by Oleksandr Zolotov <[email protected]>
* Copyright (C) 2024 by Oleksandr Zolotov <[email protected]>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
Expand Down Expand Up @@ -214,6 +214,10 @@ private slots:

QVERIFY(metadata->addUser(_secondAccount->davUser(), _secondAccount->e2e()->_certificate));

QVERIFY(metadata->removeUser(_secondAccount->davUser()));

QVERIFY(metadata->addUser(_secondAccount->davUser(), _secondAccount->e2e()->_certificate));

const auto encryptedMetadata = metadata->encryptedMetadata();
QVERIFY(!encryptedMetadata.isEmpty());

Expand Down
2 changes: 1 addition & 1 deletion test/testsecurefiledrop.cpp
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (C) by Oleksandr Zolotov <[email protected]>
* Copyright (C) 2024 by Oleksandr Zolotov <[email protected]>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
Expand Down

0 comments on commit 969612d

Please sign in to comment.