Skip to content

Commit

Permalink
split hardware token encryption init process to enable it when needed
Browse files Browse the repository at this point in the history
if the account is configured to use encryption based on hardware token,
the account will have a non empty path to the specific driver switching
triggering the initialization process

Signed-off-by: Matthieu Gallien <[email protected]>
  • Loading branch information
mgallien committed Aug 17, 2023
1 parent 2e5e305 commit e8e4198
Show file tree
Hide file tree
Showing 4 changed files with 91 additions and 66 deletions.
10 changes: 10 additions & 0 deletions src/libsync/account.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -990,6 +990,16 @@ bool Account::askUserForMnemonic() const
return _e2eAskUserForMnemonic;
}

bool Account::useHardwareTokenEncryption() const
{
return !encryptionHardwareTokenDriverPath().isEmpty();
}

QString Account::encryptionHardwareTokenDriverPath() const
{
return {};
}

void Account::setAskUserForMnemonic(const bool ask)
{
_e2eAskUserForMnemonic = ask;
Expand Down
8 changes: 8 additions & 0 deletions src/libsync/account.h
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,8 @@ class OWNCLOUDSYNC_EXPORT Account : public QObject
Q_PROPERTY(QUrl url MEMBER _url)
Q_PROPERTY(bool e2eEncryptionKeysGenerationAllowed MEMBER _e2eEncryptionKeysGenerationAllowed)
Q_PROPERTY(bool askUserForMnemonic READ askUserForMnemonic WRITE setAskUserForMnemonic NOTIFY askUserForMnemonicChanged)
Q_PROPERTY(bool useHardwareTokenEncryption READ useHardwareTokenEncryption NOTIFY useHardwareTokenEncryptionChanged)
Q_PROPERTY(QString encryptionHardwareTokenDriverPath READ encryptionHardwareTokenDriverPath NOTIFY encryptionHardwareTokenDriverPathChanged)

public:
static AccountPtr create();
Expand Down Expand Up @@ -323,6 +325,10 @@ class OWNCLOUDSYNC_EXPORT Account : public QObject

[[nodiscard]] bool askUserForMnemonic() const;

[[nodiscard]] bool useHardwareTokenEncryption() const;

[[nodiscard]] QString encryptionHardwareTokenDriverPath() const;

public slots:
/// Used when forgetting credentials
void clearQNAMCache();
Expand Down Expand Up @@ -351,6 +357,8 @@ public slots:
void accountChangedDisplayName();
void prettyNameChanged();
void askUserForMnemonicChanged();
void useHardwareTokenEncryptionChanged();
void encryptionHardwareTokenDriverPathChanged();

/// Used in RemoteWipe
void appPasswordRetrieved(QString);
Expand Down
138 changes: 72 additions & 66 deletions src/libsync/clientsideencryption.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -961,11 +961,81 @@ std::optional<QByteArray> decryptStringAsymmetricWithToken(ENGINE *sslEngine, PK
}


ClientSideEncryption::ClientSideEncryption()
ClientSideEncryption::ClientSideEncryption() = default;

const QSslKey &ClientSideEncryption::getPublicKey() const
{
return _publicKey;
}

void ClientSideEncryption::setPublicKey(const QSslKey &publicKey)
{
_publicKey = publicKey;
}

const QByteArray &ClientSideEncryption::getPrivateKey() const
{
return _privateKey;
}

void ClientSideEncryption::setPrivateKey(const QByteArray &privateKey)
{
_privateKey = privateKey;
}

PKCS11_KEY* ClientSideEncryption::getTokenPublicKey() const
{
return _tokenPublicKey;
}

PKCS11_KEY* ClientSideEncryption::getTokenPrivateKey() const
{
return _tokenPrivateKey;
}

bool ClientSideEncryption::useTokenBasedEncryption() const
{
return _tokenPublicKey && _tokenPrivateKey;
}

const QString &ClientSideEncryption::getMnemonic() const
{
return _mnemonic;
}

void ClientSideEncryption::setCertificate(const QSslCertificate &certificate)
{
_certificate = certificate;
}

ENGINE* ClientSideEncryption::sslEngine() const
{
return ENGINE_get_default_RSA();
}

void ClientSideEncryption::initialize(const AccountPtr &account)
{
Q_ASSERT(account);

if (account->useHardwareTokenEncryption()) {
initializeHardwareTokenEncryption(account);
}

qCInfo(lcCse()) << "Initializing";
if (!account->capabilities().clientSideEncryptionAvailable()) {
qCInfo(lcCse()) << "No Client side encryption available on server.";
emit initializationFinished();
return;
}

fetchCertificateFromKeyChain(account);
}

void ClientSideEncryption::initializeHardwareTokenEncryption(const AccountPtr &account)
{
auto ctx = PKCS11_CTX_new();

auto rc = PKCS11_CTX_load(ctx, "");
auto rc = PKCS11_CTX_load(ctx, account->encryptionHardwareTokenDriverPath().toLatin1().constData());
if (rc) {
qCWarning(lcCse()) << "loading pkcs11 engine failed:" << ERR_reason_error_string(ERR_get_error());
rc = 1;
Expand Down Expand Up @@ -1071,70 +1141,6 @@ ClientSideEncryption::ClientSideEncryption()
<< "need login:" << (_tokenPublicKey->needLogin ? "true" : "false");
}

const QSslKey &ClientSideEncryption::getPublicKey() const
{
return _publicKey;
}

void ClientSideEncryption::setPublicKey(const QSslKey &publicKey)
{
_publicKey = publicKey;
}

const QByteArray &ClientSideEncryption::getPrivateKey() const
{
return _privateKey;
}

void ClientSideEncryption::setPrivateKey(const QByteArray &privateKey)
{
_privateKey = privateKey;
}

PKCS11_KEY* ClientSideEncryption::getTokenPublicKey() const
{
return _tokenPublicKey;
}

PKCS11_KEY* ClientSideEncryption::getTokenPrivateKey() const
{
return _tokenPrivateKey;
}

bool ClientSideEncryption::useTokenBasedEncryption() const
{
return _tokenPublicKey && _tokenPrivateKey;
}

const QString &ClientSideEncryption::getMnemonic() const
{
return _mnemonic;
}

void ClientSideEncryption::setCertificate(const QSslCertificate &certificate)
{
_certificate = certificate;
}

ENGINE* ClientSideEncryption::sslEngine() const
{
return ENGINE_get_default_RSA();
}

void ClientSideEncryption::initialize(const AccountPtr &account)
{
Q_ASSERT(account);

qCInfo(lcCse()) << "Initializing";
if (!account->capabilities().clientSideEncryptionAvailable()) {
qCInfo(lcCse()) << "No Client side encryption available on server.";
emit initializationFinished();
return;
}

fetchCertificateFromKeyChain(account);
}

void ClientSideEncryption::fetchCertificateFromKeyChain(const AccountPtr &account)
{
const QString kck = AbstractCredentials::keychainKey(
Expand Down
1 change: 1 addition & 0 deletions src/libsync/clientsideencryption.h
Original file line number Diff line number Diff line change
Expand Up @@ -167,6 +167,7 @@ class OWNCLOUDSYNC_EXPORT ClientSideEncryption : public QObject {

public slots:
void initialize(const OCC::AccountPtr &account);
void initializeHardwareTokenEncryption(const AccountPtr &account);
void forgetSensitiveData(const OCC::AccountPtr &account);

private slots:
Expand Down

0 comments on commit e8e4198

Please sign in to comment.