Topic: [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!

Share

Re: [C++] WolfSSL + Qt

Hi @Alexander79,

Unfortunately the method that you are currently employing will not work as you are mixing both Qt API’s and wolfSSL API’s at the application level instead of having them work together in the Qt library. However, we are currently porting the wolfSSL library to be compatible with Qt which will enable users to make calls to Qt’s API functions and have wolfSSL perform the SSL and cryptographic related tasks under the hood. The current development branch can be found here on github under the qtBranch: https://github.com/MJSPollard/wolfssl. The core functionality for the wolfSSL + Qt port is complete, we are just working on optimizing the code and handling edge case scenarios. If you would like further instruction on how to build wolfSSL with Qt to test in your application, please let us know and we can provide more information.

Best,

Michael Pollard

Share

Re: [C++] WolfSSL + Qt

Thank you for answer!
Now I study WolfSLL at home by myself and see it as a replacement for OpenSSL (in Qt).
I want to write some simple programs on my own to understand how to work with WolfSSL.

If you would like further instruction on how to build wolfSSL with Qt to test in your application, please let us know and we can provide more information.

Yes, provide more information, please.

Share

Re: [C++] WolfSSL + Qt

?

Share

Re: [C++] WolfSSL + Qt

Are there any live ones here?

Share

Re: [C++] WolfSSL + Qt

Hi Alexander76,

Sorry for the late reply. We are still in the process of finishing up building the Qt compatibility layer and merging it into wolfSSL’s master branch. It may be better to wait for when Qt support has been fully integrated and full documentation has been released. However, If you still want to get started now, we can list the build steps for the development version and post the patch file required for Qt. If you come across any issues, please let us know and we can get them sorted out.

Clone the qtBranch of wolfSSL: https://github.com/MJSPollard/wolfssl and build the library with the following commands.

$ cd wolfssl
$ ./autogen.sh
$ ./configure --enable-qt
$ make
$ sudo make install

Now follow the instructions here: https://wiki.qt.io/Building_Qt_5_from_Git to download Qt and any needed dependencies. Use the latest Qt version and apply the git generated patch file to your Qt repository. Note that this patch file is subject to change as wolfSSL integration into Qt progresses. Now execute the following commands.

$ export QT_CONFIGS="-openssl-linked -opensource -silent -confirm-license -developer-build -no-feature-dtls" 
$ export OPENSSL_PATH="-I/usr/local/include/wolfssl -I/usr/local/include"
$ export OPENSSL_LIBS="-L/usr/local/lib -lwolfssl"
$ cd qt5
$ ./configure $QT_CONFIGS $OPENSSL_PATH
$ make
$ make install

Note: if you have installed wolfSSL somewhere else, you will have to specify the location to that directory within OPENSSL_PATH and OPENSSL_LIBS

If you want to speed up the build time and exclude building the examples and tests, you can execute the following command and then reconfigure, including the EXCLUDE_TESTS environment variable in the ./configure line.

$ export EXCLUDE_TESTS="-nomake examples -nomake tests"

To clean up after building if there are errors or you just want to reconfigure, run the following commands.

$ git submodule foreach --recursive "git clean -dfx"
$ rm config.cache

Let us know if you have any further questions!

- Mike Pollard

Post's attachments

Qt_wolfSSL.patch 13.65 kb, 1 downloads since 2019-02-12 

You don't have the permssions to download the attachments of this post.

Share