mirror of
https://github.com/nextcloud/desktop.git
synced 2024-11-28 19:58:56 +03:00
validate certificate for E2EE against private key
Signed-off-by: Matthieu Gallien <matthieu.gallien@nextcloud.com>
This commit is contained in:
parent
eb92426cc2
commit
1ec7774e2f
2 changed files with 35 additions and 4 deletions
|
@ -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;
|
||||
|
|
|
@ -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:
|
||||
|
|
Loading…
Reference in a new issue