diff --git a/core/kdeconnectconfig.cpp b/core/kdeconnectconfig.cpp index 217e56192..405a3bf8f 100644 --- a/core/kdeconnectconfig.cpp +++ b/core/kdeconnectconfig.cpp @@ -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; } diff --git a/core/sslhelper.cpp b/core/sslhelper.cpp index a7d95a932..078918015 100644 --- a/core/sslhelper.cpp +++ b/core/sslhelper.cpp @@ -7,14 +7,40 @@ #include "sslhelper.h" #include +#include #include #include +#include #include 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 diff --git a/core/sslhelper.h b/core/sslhelper.h index 36e855988..40c6db918 100644 --- a/core/sslhelper.h +++ b/core/sslhelper.h @@ -7,26 +7,14 @@ #ifndef SSLHELPER_H #define SSLHELPER_H -#include -#include - -#include +#include +#include #include 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 \ No newline at end of file +#endif