Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/nextcloud/desktop.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorMatthieu Gallien <matthieu.gallien@nextcloud.com>2022-09-16 19:20:41 +0300
committerMatthieu Gallien <matthieu_gallien@yahoo.fr>2022-10-24 11:25:41 +0300
commit1ec7774e2f814cdd8e1b0529cf17619a96701b14 (patch)
tree201ded8654c58909565a66af16551fca64d1b4dc /src
parenteb92426cc2cf9e86db394ca6b4621ea270b7dc99 (diff)
validate certificate for E2EE against private key
Signed-off-by: Matthieu Gallien <matthieu.gallien@nextcloud.com>
Diffstat (limited to 'src')
-rw-r--r--src/libsync/clientsideencryption.cpp33
-rw-r--r--src/libsync/clientsideencryption.h6
2 files changed, 35 insertions, 4 deletions
diff --git a/src/libsync/clientsideencryption.cpp b/src/libsync/clientsideencryption.cpp
index a9a81b1a2..29b56c4b8 100644
--- a/src/libsync/clientsideencryption.cpp
+++ b/src/libsync/clientsideencryption.cpp
@@ -1123,10 +1123,10 @@ void ClientSideEncryption::generateKeyPair(const AccountPtr &account)
_privateKey = key;
qCInfo(lcCse()) << "Keys generated correctly, sending to server.";
- generateCSR(account, localKeyPair);
+ generateCSR(account, std::move(localKeyPair));
}
-void ClientSideEncryption::generateCSR(const AccountPtr &account, EVP_PKEY *keyPair)
+void ClientSideEncryption::generateCSR(const AccountPtr &account, PKey keyPair)
{
// OpenSSL expects const char.
auto cnArray = account->davUser().toLocal8Bit();
@@ -1184,11 +1184,38 @@ void ClientSideEncryption::generateCSR(const AccountPtr &account, EVP_PKEY *keyP
auto job = new SignPublicKeyApiJob(account, e2eeBaseUrl() + "public-key", this);
job->setCsr(output);
- connect(job, &SignPublicKeyApiJob::jsonReceived, [this, account](const QJsonDocument& json, int retCode) {
+ connect(job, &SignPublicKeyApiJob::jsonReceived, [this, account, keyPair = std::move(keyPair)](const QJsonDocument& json, int retCode) {
if (retCode == 200) {
QString cert = json.object().value("ocs").toObject().value("data").toObject().value("public-key").toString();
_certificate = QSslCertificate(cert.toLocal8Bit(), QSsl::Pem);
_publicKey = _certificate.publicKey();
+
+ const auto publicKeyString = cert.toLocal8Bit();
+ Bio serverPublicKeyBio;
+ BIO_write(serverPublicKeyBio, publicKeyString.constData(), publicKeyString.size());
+ const auto serverPublicKey = PKey::readPrivateKey(serverPublicKeyBio);
+
+ Bio certificateBio;
+ const auto certificatePem = _certificate.toPem();
+ BIO_write(certificateBio, certificatePem.constData(), certificatePem.size());
+ const auto x509Certificate = X509Certificate::readCertificate(certificateBio);
+
+ if (auto certificateCheckResult = X509_check_private_key(x509Certificate, keyPair) ; !certificateCheckResult) {
+ std::array<char, 512> buffer;
+ qCInfo(lcCse()) << "X509_check_private_key" << certificateCheckResult;
+
+ unsigned long lastError = 1;
+ while (lastError) {
+ lastError = ERR_get_error();
+ qCInfo(lcCse()) << ERR_error_string(lastError, buffer.data());
+ }
+
+ forgetSensitiveData(account);
+ return;
+ }
+
+ qCInfo(lcCse()) << "received a valid certificate";
+
fetchAndValidatePublicKeyFromServer(account);
}
qCInfo(lcCse()) << retCode;
diff --git a/src/libsync/clientsideencryption.h b/src/libsync/clientsideencryption.h
index b628492b8..b3f6079fe 100644
--- a/src/libsync/clientsideencryption.h
+++ b/src/libsync/clientsideencryption.h
@@ -113,6 +113,10 @@ private:
};
}
+namespace {
+class PKey;
+}
+
class OWNCLOUDSYNC_EXPORT ClientSideEncryption : public QObject {
Q_OBJECT
public:
@@ -121,7 +125,7 @@ public:
private:
void generateKeyPair(const AccountPtr &account);
- void generateCSR(const AccountPtr &account, EVP_PKEY *keyPair);
+ void generateCSR(const AccountPtr &account, PKey keyPair);
void encryptPrivateKey(const AccountPtr &account);
public: