QSSlSocket and Server tls errors
-
Hi,
I've been trying to setup a QSSlServer server and a client using QSSlSocket, but I am getting this errors:qt.network.ssl: No functional TLS backend was found qt.network.ssl: No functional TLS backend was found qt.network.ssl: No TLS backend is available qt.network.ssl: No functional TLS backend was found qt.network.ssl: No functional TLS backend was found
What could it be? I am copying the openssl binaries into the exe dir (I am in windows), I tried different version but to no avail.
The full test file:
#include <QCoreApplication> #include <openssl/err.h> #include <openssl/pem.h> #include <openssl/x509.h> #include <openssl/evp.h> #include <openssl/core_names.h> #include <openssl/param_build.h> #include <QByteArray> #include <QSslCertificate> #include <QSslKey> // #include "ssllib.h" // #include "customqsslserver.h" #include <QSslSocket> #include <QtCore/QCoreApplication> #include <QtNetwork/QSslSocket> #include <QtNetwork/QSslServer> #include <QtNetwork/QSslConfiguration> #include <QtNetwork/QSslKey> #include <QtNetwork/QSslCertificate> #include <iostream> bool generateSelfSignedCertificate(QSslCertificate &outCert, QSslKey &outKey, int bits, int validityDays) { // Initialize OpenSSL algorithms and error strings (if not done elsewhere in your app) OpenSSL_add_all_algorithms(); ERR_load_crypto_strings(); // Generate key using new API EVP_PKEY_CTX *ctx = EVP_PKEY_CTX_new_id(EVP_PKEY_RSA, NULL); EVP_PKEY_keygen_init(ctx); EVP_PKEY_CTX_set_rsa_keygen_bits(ctx, bits); EVP_PKEY *pkey = NULL; EVP_PKEY_keygen(ctx, &pkey); // Generate certificate X509 *x509 = X509_new(); ASN1_INTEGER_set(X509_get_serialNumber(x509), 1); X509_gmtime_adj(X509_get_notBefore(x509), 0); X509_gmtime_adj(X509_get_notAfter(x509), 60 * 60 * 24 * validityDays); X509_set_pubkey(x509, pkey); // Set subject and issuer name X509_NAME *name = X509_get_subject_name(x509); X509_NAME_add_entry_by_txt(name, "C", MBSTRING_ASC, (unsigned char *)"CY", -1, -1, 0); X509_NAME_add_entry_by_txt(name, "O", MBSTRING_ASC, (unsigned char *)"BeardSoft", -1, -1, 0); X509_NAME_add_entry_by_txt(name, "CN", MBSTRING_ASC, (unsigned char *)"localhost", -1, -1, 0); X509_set_issuer_name(x509, name); // self-signed // Sign the certificate with its own key X509_sign(x509, pkey, EVP_sha256()); // Convert to QSslCertificate and QSslKey BIO *bioCert = BIO_new(BIO_s_mem()); PEM_write_bio_X509(bioCert, x509); char *certData; long certLen = BIO_get_mem_data(bioCert, &certData); outCert = QSslCertificate(QByteArray(certData, certLen), QSsl::Pem); BIO *bioKey = BIO_new(BIO_s_mem()); PEM_write_bio_PrivateKey(bioKey, pkey, NULL, NULL, 0, NULL, NULL); char *keyData; long keyLen = BIO_get_mem_data(bioKey, &keyData); outKey = QSslKey(QByteArray(keyData, keyLen), QSsl::Rsa, QSsl::Pem); // Clean up BIO_free_all(bioCert); BIO_free_all(bioKey); X509_free(x509); EVP_PKEY_free(pkey); EVP_PKEY_CTX_free(ctx); return true; } class MySslServer : public QSslServer { Q_OBJECT public: MySslServer(QObject* parent = nullptr) : QSslServer(parent) {} protected: void incomingConnection(qintptr socketDescriptor) override { QSslSocket* sslSocket = new QSslSocket(this); sslSocket->setSslConfiguration(sslConfiguration()); if (sslSocket->setSocketDescriptor(socketDescriptor)) { addPendingConnection(sslSocket); connect(sslSocket, &QSslSocket::encrypted, [sslSocket]() { std::cout << "Client connected: " << sslSocket->peerAddress().toString().toStdString() << std::endl; sslSocket->write("Hello from server"); }); sslSocket->startServerEncryption(); } else { delete sslSocket; } } }; class SslApp : public QObject { Q_OBJECT public: SslApp(QObject* parent = nullptr) : QObject(parent), server(nullptr), sslSocket(nullptr) {} void startServer() { server = new MySslServer(this); QSslConfiguration sslConfiguration; // SSLLib ssl; // auto keys = ssl.getKeys(); QSslCertificate cert; QSslKey pkey; generateSelfSignedCertificate(cert,pkey,1024,365); sslConfiguration.setPrivateKey(pkey); sslConfiguration.setLocalCertificate(cert); sslConfiguration.setProtocol(QSsl::TlsV1_2OrLater); sslConfiguration.setPeerVerifyMode(QSslSocket::VerifyNone); // For self-signed certs server->setSslConfiguration(sslConfiguration); if (!server->listen(QHostAddress::Any, 1234)) { std::cerr << "Failed to start server: " << server->errorString().toStdString() << std::endl; return; } std::cout << "Server listening on port 1234" << std::endl; } void connectToServer(const QString& ip, quint16 port) { sslSocket = new QSslSocket(this); sslSocket->connectToHostEncrypted(ip, port); connect(sslSocket, &QSslSocket::encrypted, [this]() { std::cout << "Connected to server." << std::endl; sslSocket->write("Hello from client"); }); connect(sslSocket, &QSslSocket::readyRead, [this]() { QByteArray data = sslSocket->readAll(); std::cout << "Received from server: " << data.toStdString() << std::endl; }); } private: MySslServer* server; QSslSocket* sslSocket; }; int main(int argc, char* argv[]) { QCoreApplication app(argc, argv); SslApp sslApp; std::string input; // while (true) { std::cout << "Enter 'server' to start server, 'client <ip> <port>' to connect to a server, or 'exit' to quit:" << std::endl; std::getline(std::cin, input); QStringList inputList = QString::fromStdString(input).split(" "); if (inputList[0] == "server") { sslApp.startServer(); } else if (inputList[0] == "client" && inputList.size() == 3) { QString ip = "192.168.1.254"; //inputList[1]; quint16 port = inputList[2].toUShort(); sslApp.connectToServer(ip, port); } else if (inputList[0] == "exit") { return 0; } else { std::cout << "Invalid input. Please try again." << std::endl; } // } return app.exec(); } #include "main.moc"
-
Hi, if you try the securesocketclient example in Qt and try connecting to your server, do you still get the same error?
Also, it could be that even though you copied all the openssl binaries, perhaps some MSVC runtime dll (that they need) is missing in System32.. -
What Qt version?
- OpenSSL 1.1.1 runtime libraries for Qt 5
- OpenSSL 1.1.1. or 3 for Qt 5.15.1+ or Qt 6
Exactly which openssl binaries are you placing with the executable?
Have you installed/deployed the Qt TLS plugins?
If you run your program (from a command prompt) with a non-zero QT_DEBUG_PLUGINS in the environment you should see diagnostic information about plugins loaded (or not).