Simplify using QSslKey

This commit is contained in:
Albert Vaca Cintora 2023-07-12 19:27:05 +02:00
parent d948d882aa
commit d0786d1b62
3 changed files with 51 additions and 77 deletions

View file

@ -30,7 +30,7 @@
const QFile::Permissions strictPermissions = QFile::ReadOwner | QFile::WriteOwner | QFile::ReadUser | QFile::WriteUser;
struct KdeConnectConfigPrivate {
EVP_PKEY *m_privateKey;
QSslKey m_privateKey;
QSslCertificate m_certificate;
QSettings *m_config;
@ -250,23 +250,21 @@ bool KdeConnectConfig::loadPrivateKey(const QString &keyPath)
{
QFile privKey(keyPath);
if (privKey.exists() && privKey.open(QIODevice::ReadOnly)) {
d->m_privateKey = SslHelper::pemToRsaPrivateKey(privKey.readAll());
if (d->m_privateKey == nullptr) {
d->m_privateKey = QSslKey(privKey.readAll(), QSsl::KeyAlgorithm::Rsa);
if (d->m_privateKey.isNull()) {
qCWarning(KDECONNECT_CORE) << "Private key from" << keyPath << "is not valid!";
}
}
return (d->m_privateKey == nullptr);
return d->m_privateKey.isNull();
}
bool KdeConnectConfig::loadCertificate(const QString &certPath)
{
QFile cert(certPath);
if (cert.exists() && cert.open(QIODevice::ReadOnly)) {
auto loadedCerts = QSslCertificate::fromData(cert.readAll());
if (loadedCerts.empty()) {
d->m_certificate = QSslCertificate(cert.readAll());
if (d->m_certificate.isNull()) {
qCWarning(KDECONNECT_CORE) << "Certificate from" << certPath << "is not valid";
} else {
d->m_certificate = loadedCerts.at(0);
}
}
return d->m_certificate.isNull();
@ -298,7 +296,6 @@ void KdeConnectConfig::generatePrivateKey(const QString &keyPath)
qCDebug(KDECONNECT_CORE) << "Generating private key";
d->m_privateKey = SslHelper::generateRsaPrivateKey();
QByteArray keyPem = SslHelper::privateKeyToPEM(d->m_privateKey);
QFile privKey(keyPath);
bool error = false;
@ -306,7 +303,7 @@ void KdeConnectConfig::generatePrivateKey(const QString &keyPath)
error = true;
} else {
privKey.setPermissions(strictPermissions);
int written = privKey.write(keyPem);
int written = privKey.write(d->m_privateKey.toPem());
if (written <= 0) {
error = true;
}
@ -325,10 +322,7 @@ void KdeConnectConfig::generateCertificate(const QString &certPath)
DBusHelper::filterNonExportableCharacters(uuid);
qCDebug(KDECONNECT_CORE) << "My id:" << uuid;
X509 *certificate = SslHelper::generateSelfSignedCertificate(d->m_privateKey, uuid);
QByteArray pemCertificate = SslHelper::certificateToPEM(certificate);
X509_free(certificate);
d->m_certificate = QSslCertificate(pemCertificate);
d->m_certificate = SslHelper::generateSelfSignedCertificate(d->m_privateKey, uuid);
QFile cert(certPath);
bool error = false;
@ -336,7 +330,7 @@ void KdeConnectConfig::generateCertificate(const QString &certPath)
error = true;
} else {
cert.setPermissions(strictPermissions);
int written = cert.write(pemCertificate);
int written = cert.write(d->m_certificate.toPem());
if (written <= 0) {
error = true;
}

View file

@ -7,14 +7,40 @@
#include "sslhelper.h"
#include <openssl/bn.h>
#include <openssl/evp.h>
#include <openssl/pem.h>
#include <openssl/rsa.h>
#include <openssl/x509.h>
#include <openssl/x509v3.h>
namespace SslHelper
{
X509 *generateSelfSignedCertificate(EVP_PKEY *privateKey, const QString &commonName)
QSslKey generateRsaPrivateKey()
{
RSA *rsa = RSA_new();
BIGNUM *exponent = BN_new();
BN_set_word(exponent, RSA_F4);
RSA_generate_key_ex(rsa, 2048, exponent, nullptr);
BN_free(exponent);
EVP_PKEY *privateKey = EVP_PKEY_new();
EVP_PKEY_assign_RSA(privateKey, rsa);
// Convert to PEM which is the format needed for QSslKey
BIO *bio = BIO_new(BIO_s_mem());
PEM_write_bio_PrivateKey(bio, privateKey, nullptr, nullptr, 0, nullptr, nullptr);
BUF_MEM *mem = nullptr;
BIO_get_mem_ptr(bio, &mem);
QByteArray pemData(mem->data, mem->length);
BIO_free_all(bio);
EVP_PKEY_free(privateKey);
return QSslKey(pemData, QSsl::KeyAlgorithm::Rsa);
}
QSslCertificate generateSelfSignedCertificate(const QSslKey &qtPrivateKey, const QString &commonName)
{
X509 *x509 = X509_new();
X509_set_version(x509, 2);
@ -41,60 +67,26 @@ X509 *generateSelfSignedCertificate(EVP_PKEY *privateKey, const QString &commonN
ASN1_TIME_set(X509_get_notBefore(x509), now - a_year_in_seconds);
ASN1_TIME_set(X509_get_notAfter(x509), now + 10 * a_year_in_seconds);
// Set the public key for the certificate
// Convert the QSslKey to the OpenSSL private key format and sign the certificate
QByteArray keyPemData = qtPrivateKey.toPem();
BIO *keyBio = BIO_new_mem_buf(keyPemData.data(), -1);
EVP_PKEY *privateKey = PEM_read_bio_PrivateKey(keyBio, NULL, NULL, NULL);
X509_set_pubkey(x509, privateKey);
// Sign the certificate with the private key
X509_sign(x509, privateKey, EVP_sha256());
EVP_PKEY_free(privateKey);
BIO_free_all(keyBio);
return x509;
}
EVP_PKEY *generateRsaPrivateKey()
{
EVP_PKEY *privateKey = EVP_PKEY_new();
RSA *rsa = RSA_new();
BIGNUM *exponent = BN_new();
BN_set_word(exponent, RSA_F4);
RSA_generate_key_ex(rsa, 2048, exponent, nullptr);
EVP_PKEY_assign_RSA(privateKey, rsa);
BN_free(exponent);
return privateKey;
}
QByteArray certificateToPEM(X509 *certificate)
{
// Convert to PEM which is the format needed for QSslCertificate
BIO *bio = BIO_new(BIO_s_mem());
PEM_write_bio_X509(bio, certificate);
PEM_write_bio_X509(bio, x509);
BUF_MEM *mem = nullptr;
BIO_get_mem_ptr(bio, &mem);
QByteArray pemData(mem->data, mem->length);
BIO_free_all(bio);
return pemData;
}
QByteArray privateKeyToPEM(EVP_PKEY *privateKey)
{
BIO *bio = BIO_new(BIO_s_mem());
PEM_write_bio_PrivateKey(bio, privateKey, nullptr, nullptr, 0, nullptr, nullptr);
BUF_MEM *mem = nullptr;
BIO_get_mem_ptr(bio, &mem);
QByteArray pemData(mem->data, mem->length);
BIO_free_all(bio);
return pemData;
}
X509_free(x509);
EVP_PKEY *pemToRsaPrivateKey(const QByteArray &privateKeyPem)
{
const char *pemData = privateKeyPem.constData();
BIO *bio = BIO_new_mem_buf(pemData, -1);
EVP_PKEY *privateKey = PEM_read_bio_PrivateKey(bio, NULL, NULL, NULL);
BIO_free(bio);
return privateKey;
return QSslCertificate(pemData);
}
} // namespace SslHelper

View file

@ -7,26 +7,14 @@
#ifndef SSLHELPER_H
#define SSLHELPER_H
#include <openssl/evp.h>
#include <openssl/x509.h>
#include <QByteArray>
#include <QSslCertificate>
#include <QSslKey>
#include <QString>
namespace SslHelper
{
// Delete with X509_free(certificate);
X509 *generateSelfSignedCertificate(EVP_PKEY *privateKey, const QString &commonName);
// Delete with EVP_PKEY_free(privateKey);
EVP_PKEY *generateRsaPrivateKey();
QByteArray certificateToPEM(X509 *certificate);
QByteArray privateKeyToPEM(EVP_PKEY *privateKey);
EVP_PKEY *pemToRsaPrivateKey(const QByteArray &privateKeyPem);
QSslKey generateRsaPrivateKey();
QSslCertificate generateSelfSignedCertificate(const QSslKey &privateKey, const QString &commonName);
}
#endif
#endif