[cse] Request public key from server

This is the first step needed to properly communicate.
Next, get private key.
This commit is contained in:
Tomaz Canabrava 2017-09-12 11:21:53 +02:00 committed by Roeland Jago Douma
parent f4bbec1019
commit 17693a75e5
No known key found for this signature in database
GPG key ID: F941078878347C0C
6 changed files with 103 additions and 27 deletions

View file

@ -41,7 +41,6 @@ Q_LOGGING_CATEGORY(lcAccount, "sync.account", QtInfoMsg)
Account::Account(QObject *parent) Account::Account(QObject *parent)
: QObject(parent) : QObject(parent)
, _capabilities(QVariantMap()) , _capabilities(QVariantMap())
, _encryption(new ClientSideEncryption(this))
, _davPath(Theme::instance()->webDavPath()) , _davPath(Theme::instance()->webDavPath())
{ {
qRegisterMetaType<AccountPtr>("AccountPtr"); qRegisterMetaType<AccountPtr>("AccountPtr");
@ -485,9 +484,4 @@ void Account::setNonShib(bool nonShib)
} }
} }
ClientSideEncryption *Account::cse() const
{
return _encryption;
}
} // namespace OCC } // namespace OCC

View file

@ -226,7 +226,6 @@ public:
/// Called by network jobs on credential errors, emits invalidCredentials() /// Called by network jobs on credential errors, emits invalidCredentials()
void handleInvalidCredentials(); void handleInvalidCredentials();
ClientSideEncryption *cse() const;
public slots: public slots:
/// Used when forgetting credentials /// Used when forgetting credentials
void clearQNAMCache(); void clearQNAMCache();
@ -276,7 +275,6 @@ private:
QuotaInfo *_quotaInfo; QuotaInfo *_quotaInfo;
QSharedPointer<QNetworkAccessManager> _am; QSharedPointer<QNetworkAccessManager> _am;
QScopedPointer<AbstractCredentials> _credentials; QScopedPointer<AbstractCredentials> _credentials;
ClientSideEncryption *_encryption;
bool _http2Supported = false; bool _http2Supported = false;
/// Certificates that were explicitly rejected by the user /// Certificates that were explicitly rejected by the user

View file

@ -1,34 +1,104 @@
#include "clientsideencryption.h" #include "clientsideencryption.h"
#include "account.h" #include "account.h"
#include "capabilities.h" #include "capabilities.h"
#include "networkjobs.h"
#include <QDebug> #include <QDebug>
#include <QLoggingCategory> #include <QLoggingCategory>
#include <QFileInfo>
#include <QDir>
namespace OCC namespace OCC
{ {
Q_LOGGING_CATEGORY(lcCse, "sync.connectionvalidator", QtInfoMsg) Q_LOGGING_CATEGORY(lcCse, "sync.clientsideencryption", QtInfoMsg)
QString baseUrl = QStringLiteral("ocs/v2.php/apps/client_side_encryption/api/v1/"); QString baseUrl = QStringLiteral("ocs/v2.php/apps/client_side_encryption/api/v1/");
QString baseDirectory = QDir::homePath() + QStringLiteral("/.nextcloud-keys/");
ClientSideEncryption::ClientSideEncryption(Account *parent) : _account(parent) ClientSideEncryption::ClientSideEncryption()
{ {
} }
void OCC::ClientSideEncryption::initialize() void ClientSideEncryption::setAccount(AccountPtr account)
{ {
_account = account;
}
void ClientSideEncryption::initialize()
{
qCInfo(lcCse()) << "Initializing";
if (!_account->capabilities().clientSideEncryptionAvaliable()) { if (!_account->capabilities().clientSideEncryptionAvaliable()) {
qCInfo(lcCse()) << "No client side encryption, do not initialize anything."; qCInfo(lcCse()) << "No Client side encryption avaliable on server.";
emit initializationFinished(); emit initializationFinished();
} }
fetchPrivateKey(); if (hasPrivateKey() && hasPublicKey()) {
qCInfo(lcCse()) << "Public and private keys already downloaded";
emit initializationFinished();
}
getPublicKeyFromServer();
} }
void ClientSideEncryption::fetchPrivateKey() QString ClientSideEncryption::publicKeyPath() const
{ {
qCInfo(lcCse()) << "Client side encryption enabled, trying to retrieve the key."; return baseDirectory + _account->displayName() + ".pub";
}
QString ClientSideEncryption::privateKeyPath() const
{
return baseDirectory + _account->displayName() + ".rsa";
}
bool ClientSideEncryption::hasPrivateKey() const
{
return QFileInfo(privateKeyPath()).exists();
}
bool ClientSideEncryption::hasPublicKey() const
{
return QFileInfo(publicKeyPath()).exists();
}
void ClientSideEncryption::generateKeyPair()
{
}
QString ClientSideEncryption::generateSCR()
{
return {};
}
void ClientSideEncryption::getPrivateKeyFromServer()
{
}
void ClientSideEncryption::getPublicKeyFromServer()
{
qCInfo(lcCse()) << "Retrieving public key from server";
auto job = new JsonApiJob(_account, baseUrl + "public-key", this);
connect(job, &JsonApiJob::jsonReceived, [this](const QJsonDocument& doc, int retCode) {
switch(retCode) {
case 404: // no public key
qCInfo(lcCse()) << "No public key, generating a pair.";
break;
case 400: // internal error
qCInfo(lcCse()) << "Internal server error while requesting the public key, encryption aborted.";
break;
case 200: // ok
qCInfo(lcCse()) << "Found Public key, requesting Private Key.";
break;
}
});
job->start();
}
void ClientSideEncryption::signPublicKey()
{
} }
} }

View file

@ -3,23 +3,35 @@
#include <QString> #include <QString>
#include <QObject> #include <QObject>
#include <QJsonDocument>
#include "accountfwd.h"
namespace OCC { namespace OCC {
class Account;
class ClientSideEncryption : public QObject { class ClientSideEncryption : public QObject {
Q_OBJECT Q_OBJECT
public: public:
ClientSideEncryption(OCC::Account *parent); ClientSideEncryption();
void initialize(); void initialize();
void setAccount(AccountPtr account);
bool hasPrivateKey() const;
bool hasPublicKey() const;
void generateKeyPair();
QString generateSCR();
void getPrivateKeyFromServer();
void getPublicKeyFromServer();
void signPublicKey();
QString privateKeyPath() const;
QString publicKeyPath() const;
void fetchPrivateKey();
signals: signals:
void initializationFinished(); void initializationFinished();
private: private:
OCC::Account *_account; OCC::AccountPtr _account;
bool isInitialized = false; bool isInitialized = false;
}; };

View file

@ -326,8 +326,9 @@ void ConnectionValidator::slotUserFetched(const QJsonDocument &json)
void ConnectionValidator::slotAvatarImage(const QImage &img) void ConnectionValidator::slotAvatarImage(const QImage &img)
{ {
_account->setAvatar(img); _account->setAvatar(img);
connect(_account->cse(), &ClientSideEncryption::initializationFinished, this, &ConnectionValidator::reportConnected); cse.setAccount(_account);
_account->cse()->initialize(); connect(&cse, &ClientSideEncryption::initializationFinished, this, &ConnectionValidator::reportConnected);
cse.initialize();
} }
void ConnectionValidator::reportConnected() { void ConnectionValidator::reportConnected() {

View file

@ -21,6 +21,7 @@
#include <QVariantMap> #include <QVariantMap>
#include <QNetworkReply> #include <QNetworkReply>
#include "accountfwd.h" #include "accountfwd.h"
#include "clientsideencryption.h"
namespace OCC { namespace OCC {
@ -63,10 +64,6 @@ namespace OCC {
| |
+-> slotCapabilitiesRecieved -+ +-> slotCapabilitiesRecieved -+
| |
+-----------------------------------+
|
+-> Client Side Encryption Checks --+
|
+---------------------------------+ +---------------------------------+
| |
fetchUser fetchUser
@ -75,10 +72,13 @@ namespace OCC {
+-> slotUserFetched +-> slotUserFetched
AvatarJob AvatarJob
| |
+-> slotAvatarImage --> reportResult() +-> slotAvatarImage -->
+-----------------------------------+
|
+-> Client Side Encryption Checks --+ --reportResult()
\endcode \endcode
*/ */
class OWNCLOUDSYNC_EXPORT ConnectionValidator : public QObject class OWNCLOUDSYNC_EXPORT ConnectionValidator : public QObject
{ {
Q_OBJECT Q_OBJECT
@ -144,6 +144,7 @@ private:
QStringList _errors; QStringList _errors;
AccountPtr _account; AccountPtr _account;
bool _isCheckingServerAndAuth; bool _isCheckingServerAndAuth;
ClientSideEncryption cse;
}; };
} }