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

Creating secure channel with not mutual authentication



  • Hi all,

    I have an application in which a secure channel must be established between a client and a server (both Qt). I do not have any certificate to set on both. The only thing I need is encryption on the channel. How can I do it? I followed many examples using QSslSocket and set PeerVerifyMode to QSslSocket::VerifyNone. on both sides. However, when I invoke the connectToHostEncrypted on client side, this blocksuntil timeout expires and the connection is lost.

    This is the client test file that I'm writing to the test the connection (socket_ is QSslSocket).

    @
    TestSecureSocketClient::TestSecureSocketClient()
    {
    connect(&socket_, SIGNAL(connected()), SLOT(onConnected()));
    connect(&socket_, SIGNAL(readyRead()), SLOT(onReadyRead()));
    connect(&socket_, SIGNAL(aboutToClose()), SLOT(onClosed()));
    connect(&socket_, SIGNAL(encrypted()), SLOT(onEncrypted()));
    connect(&socket_, SIGNAL(sslErrors(QList<QSslError>)), SLOT(onSslErrors(QList<QSslError>)));
    }

    void TestSecureSocketClient::start()
    {
    socket_.setPeerVerifyMode(QSslSocket::VerifyNone);

    socket_.connectToHostEncrypted("127.0.0.1", 52000);
    qDebug() << "encrypted = " << socket_.waitForEncrypted(5000); // This gives false after the timeout expires
    

    }

    void TestSecureSocketClient::onConnected()
    {
    qDebug() << "Connected";

    QTimer* timer = new QTimer(this);
    connect(timer, SIGNAL(timeout()), SLOT(onTimeout()));
    timer->start(1000);
    

    }

    void TestSecureSocketClient::onReadyRead()
    {
    QByteArray rxBuffer = socket_.readAll();
    HexString::print("Rx", rxBuffer);
    }

    void TestSecureSocketClient::onClosed()
    {
    qDebug() << "Client close";
    }

    void TestSecureSocketClient::onTimeout()
    {
    QString str = "Hello";
    socket_.write(str.toLatin1());
    }

    void TestSecureSocketClient::onEncrypted()
    {
    qDebug() << "client encrypted";
    }

    void TestSecureSocketClient::onSslErrors(const QList<QSslError> &errors)
    {
    qDebug() << "errors = " << errors.size();
    }
    @

    While this is the server .cpp file

    @
    void TestSecureSocketServer::incomingConnection(int socket)
    {
    qDebug() << "incoming connection sd = " << socket; // This happens. The connection is established
    QSslSocket *serverSocket = new QSslSocket;
    if (serverSocket->setSocketDescriptor(socket))
    {
    serverSocket->setPeerVerifyMode(QSslSocket::VerifyNone);
    connect(serverSocket, SIGNAL(encrypted()), this, SLOT(onEncrypted()));
    serverSocket->startServerEncryption();
    }
    else
    {
    delete serverSocket;
    }
    }

    void TestSecureSocketServer::onEncrypted()
    {
    qDebug() << "Encrypted"; // This never happens
    }

    void TestSecureSocketServer::onReadyRead()
    {
    QTcpSocket* socket = qobject_cast<QTcpSocket*>(sender());
    HexString::print("received", socket->readAll());
    }

    void TestSecureSocketServer::onSslErrors(const QList<QSslError> &errors)
    {
    for (QList<QSslError>::const_iterator it = errors.begin(); it != errors.end(); ++it )
    {
    QSslError error = *it;
    qDebug() << "Error = " << error.errorString();
    }
    }
    @

    The strange thing is that no ssl errors are emitted on both sides. More, after the invocation of waitForEncrypted on the client side, the socket state becomes QAbstractSocket::Unconnected on client, while remains QAbstractSocket::Connected on the server (anyway this may be due to lack of synchronization).

    Thanks for any help.

    Fabio


Log in to reply