fix(encryption): detect if the secure token needs reset

we detect that the secure storage USB token has been removed and we
initialize again the token and certificates to dynamically recover

Signed-off-by: Matthieu Gallien <matthieu.gallien@nextcloud.com>
This commit is contained in:
Matthieu Gallien 2025-06-18 09:23:07 +02:00
parent 9612cbb806
commit ab9abf1772
3 changed files with 18 additions and 5 deletions

View File

@ -68,6 +68,7 @@ Account::Account(QObject *parent)
: QObject(parent)
, _capabilities(QVariantMap())
, _serverColor(Theme::defaultColor())
, _e2e(sharedFromThis())
{
qRegisterMetaType<AccountPtr>("AccountPtr");
qRegisterMetaType<Account *>("Account*");

View File

@ -768,7 +768,11 @@ std::optional<QByteArray> decryptStringAsymmetric(ENGINE *sslEngine,
if (EVP_PKEY_decrypt(ctx, unsignedData(out), &outlen, (unsigned char *)binaryData.constData(), binaryData.size()) <= 0) {
const auto error = handleErrors();
qCCritical(lcCseDecryption()) << "Could not decrypt the data." << error;
if (error.contains("Device removed")) {
qCWarning(lcCseDecryption()) << "USB secure token needs reset" << error;
} else {
qCCritical(lcCseDecryption()) << "Could not decrypt the data." << error;
}
return {};
}
@ -843,7 +847,9 @@ void debugOpenssl()
}
ClientSideEncryption::ClientSideEncryption()
ClientSideEncryption::ClientSideEncryption(const OCC::AccountPtr &account, QObject *parent)
: QObject(parent)
, _account(account)
{
}
@ -1306,7 +1312,7 @@ void ClientSideEncryption::fetchPublicKeyFromKeyChain(const AccountPtr &account)
job->start();
}
bool ClientSideEncryption::checkEncryptionIsWorking() const
bool ClientSideEncryption::checkEncryptionIsWorking()
{
qCInfo(lcCse) << "check encryption is working before enabling end-to-end encryption feature";
QByteArray data = EncryptionHelper::generateRandom(64);
@ -1321,6 +1327,10 @@ bool ClientSideEncryption::checkEncryptionIsWorking() const
const auto decryptionResult = EncryptionHelper::decryptStringAsymmetric(getCertificateInformation(), paddingMode(), *this, *encryptedData);
if (!decryptionResult) {
if (useTokenBasedEncryption()) {
initializeHardwareTokenEncryption(nullptr,
_account);
}
qCWarning(lcCse()) << "encryption error";
return false;
}

View File

@ -238,7 +238,7 @@ class OWNCLOUDSYNC_EXPORT ClientSideEncryption : public QObject {
Q_PROPERTY(bool canDecrypt READ canDecrypt NOTIFY canDecryptChanged FINAL)
Q_PROPERTY(bool userCertificateNeedsMigration READ userCertificateNeedsMigration NOTIFY userCertificateNeedsMigrationChanged FINAL)
public:
ClientSideEncryption();
explicit ClientSideEncryption(const OCC::AccountPtr &account, QObject *parent = nullptr);
[[nodiscard]] bool isInitialized() const;
@ -388,13 +388,15 @@ private:
[[nodiscard]] bool checkServerPublicKeyValidity(const QByteArray &serverPublicKeyString) const;
[[nodiscard]] bool sensitiveDataRemaining() const;
[[nodiscard]] bool checkEncryptionIsWorking() const;
[[nodiscard]] bool checkEncryptionIsWorking();
void failedToInitialize(const AccountPtr &account);
void saveCertificateIdentification(const AccountPtr &account) const;
void cacheTokenPin(const QString pin);
OCC::AccountPtr _account;
QString _mnemonic;
bool _newMnemonicGenerated = false;