Simplify using QSslKey
This commit is contained in:
parent
d948d882aa
commit
d0786d1b62
3 changed files with 51 additions and 77 deletions
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
Loading…
Reference in a new issue