Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. General and Desktop
  4. QSSlSocket and Server tls errors
Forum Updated to NodeBB v4.3 + New Features

QSSlSocket and Server tls errors

Scheduled Pinned Locked Moved Unsolved General and Desktop
3 Posts 3 Posters 564 Views 1 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • S Offline
    S Offline
    silajim
    wrote on last edited by
    #1

    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"
    
    
    C 1 Reply Last reply
    0
    • hskoglundH Offline
      hskoglundH Offline
      hskoglund
      wrote on last edited by
      #2

      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..

      1 Reply Last reply
      0
      • S silajim

        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"
        
        
        C Offline
        C Offline
        ChrisW67
        wrote on last edited by
        #3

        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).

        1 Reply Last reply
        0

        • Login

        • Login or register to search.
        • First post
          Last post
        0
        • Categories
        • Recent
        • Tags
        • Popular
        • Users
        • Groups
        • Search
        • Get Qt Extensions
        • Unsolved