Important: Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

[C++] WolfSSL + Qt



  • Hello everyone!
    I was write a simple SSL-client/server in Visual Studio, using WolfSSL. It work fine.

    For now I try to write a simple SSL server, using Qt and based on QTcpServer.
    But I didn't find any information about WolfSSL + Qt.
    There is source code:
    SslServer.h

    #ifndef SSLSERVER_H
    #define SSLSERVER_H
    
    #include <QTcpServer>
    
    #define WC_NO_HARDEN
    #include <wolfssl/ssl.h>
    
    #define CERT_SERVER_CERT "Certs\\server-cert.pem"
    #define CERT_SERVER_KEY  "Certs\\server-key.pem"
    #define CERT_SERVER_DH   "Certs\\dh2048.pem"
    
    class SslServer : public QTcpServer
    {
        Q_OBJECT
    
    public:
        explicit SslServer(QObject* parent = nullptr);
        virtual ~SslServer() override;
    
    protected:
        virtual void incomingConnection(qintptr socketDescriptor) override final;
    
    private:
        WOLFSSL_CTX* m_CTX;
    };
    
    #endif // SSLSERVER_H
    

    SslServer.cpp

    #include "SslServer.h"
    #include "SslSocket.h"
    #include <QDebug>
    
    #pragma comment(lib, "ws2_32.lib")
    #pragma comment(lib, "AdvAPI32.lib")
    
    SslServer::SslServer(QObject* parent) :
        QTcpServer(parent),
        m_CTX(nullptr)
    {
        WSADATA wsa_data = { 0 };
        WSAStartup(MAKEWORD(2, 0), &wsa_data);
    
        wolfSSL_Init();
    
        m_CTX = wolfSSL_CTX_new(wolfTLSv1_2_server_method());
        if (m_CTX)
        {
            if (wolfSSL_CTX_use_certificate_file(m_CTX, CERT_SERVER_CERT, SSL_FILETYPE_PEM) == SSL_SUCCESS)
            {
                if (wolfSSL_CTX_use_PrivateKey_file(m_CTX, CERT_SERVER_KEY, SSL_FILETYPE_PEM) == SSL_SUCCESS)
                {
                    if (wolfSSL_CTX_SetTmpDH_file(m_CTX, CERT_SERVER_DH, SSL_FILETYPE_PEM) == SSL_SUCCESS)
                    {
                        qDebug() << "SslServer::SslServer -> init SSL is OK";
                    }
                }
            }
        }
    }
    
    SslServer::~SslServer()
    {
        if (m_CTX)
        {
            wolfSSL_CTX_free(m_CTX);
            m_CTX = nullptr;
        }
    
        wolfSSL_Cleanup();
        WSACleanup();
    }
    
    void SslServer::incomingConnection(qintptr socketDescriptor)
    {
        qDebug() << "SslServer::incomingConnection";
    
        SslSocket* sock = new SslSocket(this);
    
        WOLFSSL* ssl = wolfSSL_new(m_CTX);
        if (ssl)
        {
            wolfSSL_set_fd(ssl, socketDescriptor);
    
            for (;;)
            {
                // loop because accept didn't work immediately
                int r = wolfSSL_accept(ssl);
                if (r == -1)
                {
                    r = wolfSSL_get_error(ssl, r);
                    if (r == SSL_ERROR_WANT_READ)
                    {
                        Sleep(10);
                        continue;
                    }
                }
    
                break;
            }
    
            sock->setSocketDescriptor(socketDescriptor);
            sock->SetSSL(ssl);
            qDebug() << "SslServer::incomingConnection -> make SSL socket";
        }
    
        this->addPendingConnection(sock);
    }
    

    Then I was write SSLSocket
    There is source code:
    SslSocket.h

    #ifndef SslSocket_H
    #define SslSocket_H
    
    #include <QTcpSocket>
    
    #define WC_NO_HARDEN
    #include <wolfssl/ssl.h>
    
    class SslSocket : public QTcpSocket
    {
        Q_OBJECT
    
    public:
        explicit SslSocket(QObject* parent = nullptr);
        virtual ~SslSocket() override;
    
        void SetSSL(WOLFSSL* ssl);
    
        qint64     read(char* data, qint64 maxlen);
        QByteArray read(qint64 maxlen);
        qint64     write(const char* data, qint64 len);
        
    private:
        WOLFSSL* m_SSL;
    };
    
    #endif // SslSocket_H
    

    SslSocket.cpp

    #include "SslSocket.h"
    #include <QDebug>
    
    SslSocket::SslSocket(QObject* parent) :
        QTcpSocket(parent),
        m_SSL(nullptr)
    {
    }
    
    SslSocket::~SslSocket()
    {
        if (m_SSL)
        {
            wolfSSL_shutdown(m_SSL);
            wolfSSL_free(m_SSL);
            m_SSL = nullptr;
        }
    }
    
    void SslSocket::SetSSL(WOLFSSL* ssl)
    {
        m_SSL = ssl;
    }
    
    qint64 SslSocket::read(char* data, qint64 maxlen)
    {
        qDebug() << "SslSocket::read 1";
        if (m_SSL && data && maxlen > 0)
        {
            return wolfSSL_read(m_SSL, data, maxlen);
        }
    
        return 0;
    }
    
    QByteArray SslSocket::read(qint64 maxlen)
    {
        QByteArray data;
    
        qDebug() << "SslSocket::read 2, SSL = " << m_SSL;
        if (m_SSL && maxlen > 0)
        {
            data.resize(maxlen);
    
            maxlen = wolfSSL_read(m_SSL, (void*)data.data(), maxlen);
            if (maxlen > 0)
            {
                data.resize(maxlen);
            }
            else
            {
                data.clear();
            }
        }
    
        return std::move(data);
    }
    
    qint64 SslSocket::write(const char* data, qint64 len)
    {
        qDebug() << "SslSocket::write";
        if (m_SSL && data && len > 0)
        {
            return wolfSSL_write(m_SSL, data, len);
        }
    
        return 0;
    }
    

    Server listen port and accept connections is fine.
    But a have a problem to receive data from client at this line:

    maxlen = wolfSSL_read(m_SSL, (void*)data.data(), maxlen);
    

    Function wolfSSL_read return -1, but method bytesAvailable() in SSLSocket say to there is data to read in socket.

    What I do wrong?
    How a correct receive data over WolfSSL in Qt?
    Thank you!



  • Hello,

    Thank you for your interest in wolfSSL + Qt.

    wolfSSL has recently been expanded to support Qt's Network/SSL API.

    This would allow you to setup a wolfSSL client/server using Qt API.

    The changes to wolfSSL that enable Qt support are pending official release. In the meantime, you can email support@wolfssl.com to receive a copy of wolfSSL that supports Qt.

    For the fastest wolfSSL support, email support@wolfssl.com with your use case, questions, and requests.

    Thank you.


Log in to reply