Can't get QSslSocket working.



  • I can't seem to find a complete working client server sample code where each uses SSL (QSslSocket). The QT doc gives half of the equation for the SSL client when it starts an immediate SSL handshake

    @
    QSslSocket *socket = new QSslSocket(this);
    connect(socket, SIGNAL(encrypted()), this, SLOT(ready()));

    socket->connectToHostEncrypted("imap.example.com", 993);
    @

    but doesn't give corresponding server code that would go with that. The client part seems to be the easy part. But I don't quite understand what the server side is supposed to do once a connection has been established.

    Can somebody point me to something like that? Or if you know yourself explain to me how to properly establish an SSL handshake in QT.

    I would really appreciate this.

    Thanks.



  • Hello,

    A while ago I wrote an article about SMTP protocol which uses QSslSocket class.
    "SMTP example":http://morf.lv/modules.php?name=tutorials&lasit=20

    However, I'm only covering the client side of communication.
    So the question is, are you struggling with the server side? From the code, I can see the client side.



  • Yes definitely the server side. My QT ssl client seems to be working because I tested it against an SSL server I wrote in VS C++ and winsock library. So let me add the relevant code of my QT SSL server and client which cannot establish a handshake.

    QT SSL Client cpp:
    @
    MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
    {
    ...
    connect( connect_button, SIGNAL(clicked()), this, SLOT(connect_to_sslserver()) );
    ....
    }

    bool MainWindow::connect_to_sslserver()
    {
    if(connected_)
    return true;

    //Set the default destination port
    quint32 iport = 1111;
    
    tcpsocket_ = new QSslSocket;
    
    tcpsocket_->setPeerVerifyMode(QSslSocket::VerifyNone);
    QSslConfiguration sslConfig = tcpsocket_->sslConfiguration();
    sslConfig.setSslOption(QSsl::SslOptionDisableSessionTickets, true);
    sslConfig.setProtocol(QSsl::SslV3);
    tcpsocket_->setSslConfiguration(sslConfig);
    
    connect(tcpsocket_, SIGNAL(error(QAbstractSocket::SocketError)), this,
            SLOT(error_handler(QAbstractSocket::SocketError)));
    connect(tcpsocket_, SIGNAL(sslErrors(QList<QSslError>)), this,
            SLOT(ssl_error_handler(QList<QSslError>)));
    connect(tcpsocket_, SIGNAL(encrypted()), this, SLOT(sslsocket_ready()));
    
    tcpsocket_->connectToHostEncrypted("my-host", iport);
    if(!tcpsocket_->waitForEncrypted())
    {
        qDebug() << Q_FUNC_INFO << "failed to establish a SSL handshake with server";
        return false;
    }
    return true;
    

    }
    @

    QT SSL Server header:
    @
    class SSLServer : public QTcpServer
    {
    Q_OBJECT
    public:
    explicit SSLServer(QObject *parent = 0);
    void incomingConnection(int handle);
    signals:

    public slots:
    void ready();
    void error_handler(QAbstractSocket::SocketError);
    void ssl_error_handler(QList<QSslError> ssl_errors);
    void read_data_from_client();

    private:
    QSslSocket tcpCommandSocket_;
    QThread
    tcp_thread_;
    QObject * mainwin_;

    };
    @

    QT SSL Server cpp:

    @#include "secureserver.h"
    #include "mainwindow.h"

    SSLServer::SSLServer(QObject *parent) :
    QTcpServer(parent)
    {
    mainwin_ = parent;
    }

    void SSLServer::incomingConnection(int sd)
    {
    tcpCommandSocket_ = new QSslSocket;
    if( tcpCommandSocket_->setSocketDescriptor(sd))
    {
    QFile sslkeyfile("certs/server-priv-key.pem");
    if (!sslkeyfile.exists())
    {
    qDebug() << Q_FUNC_INFO << "file could not be found";
    return;
    }
    if (!sslkeyfile.open(QFile::ReadOnly| QFile::Text))
    {
    qDebug() << Q_FUNC_INFO << "file could not be opened";
    return;
    }
    QString private_key = sslkeyfile.readAll();
    tcpCommandSocket_->setPrivateKey(private_key);

        QFile sslServerCertfile&#40;"certs/server-cert.pem"&#41;;
        if (!sslServerCertfile.exists(&#41;&#41;
        {
            qDebug(&#41; << Q_FUNC_INFO << "file could not be found";
            return;
        }
    
        if (!sslServerCertfile.open(QFile::ReadOnly| QFile::Text))
        {
            qDebug() << Q_FUNC_INFO << "file could not be opened";
            return;
        }
        QString server_cert = sslServerCertfile.readAll();
        tcpCommandSocket_->setLocalCertificate(server_cert);
        tcpCommandSocket_->setPeerVerifyMode(QSslSocket::VerifyNone);
        tcpCommandSocket_->setProtocol(QSsl::SslV3);
    
        connect(tcpCommandSocket_, SIGNAL(error(QAbstractSocket::SocketError)), this,
                SLOT(error_handler(QAbstractSocket::SocketError)));
        connect(tcpCommandSocket_, SIGNAL(sslErrors(QList<QSslError>)), this,
                SLOT(ssl_error_handler(QList<QSslError>)));
    
        tcpCommandSocket_->startServerEncryption();
        if(!tcpCommandSocket_->waitForEncrypted())
        {
            qDebug() << Q_FUNC_INFO << "failed to perform SSL handshake with client";
            return;
        }
        connect(tcpCommandSocket_, SIGNAL(encrypted()), this, SLOT(ready()));
        connect(tcpCommandSocket_, SIGNAL(readyRead()), this, SLOT(read_data_from_client()));
    }
    else
    {
        qDebug() << Q_FUNC_INFO << "failed to set socket descriptor";
    }
    

    }

    void SSLServer::read_data_from_client()
    {
    QByteArray qstrbytes = tcpCommandSocket_->readAll();
    qDebug() << Q_FUNC_INFO << qstrbytes;
    }

    void SSLServer::ready()
    {
    qDebug() << Q_FUNC_INFO;

    }

    void SSLServer::error_handler(QAbstractSocket::SocketError in_error)
    {
    qDebug() << Q_FUNC_INFO << in_error;
    }

    void SSLServer::ssl_error_handler(QList<QSslError> ssl_errors)
    {
    foreach (QSslError err, ssl_errors)
    {
    qDebug() << Q_FUNC_INFO << err.errorString();
    }
    }
    @

    Errors messages on the Server:

    void SSLServer::error_handler(QAbstractSocket::SocketError) QAbstractSocket::SocketError( 13 )
    virtual void SSLServer::incomingConnection(int) failed to perform SSL handshake with client

    Errors messages on the client:

    void MainWindow::error_handler(QAbstractSocket::SocketError) QAbstractSocket::RemoteHostClosedError bool MainWindow::connect_to_sslserver() failed to establish a SSL handshake with server



  • A little more info that might help understand what is happening.

    I ran openssl client against my QT server like this:
    @openssl s_client -connect my-hostl:1111@

    here is the output
    @Loading 'screen' into random state - done
    CONNECTED(000001AC)
    4940:error:140790E5:SSL routines:SSL23_WRITE:ssl handshake failure:.\ssl\s23_lib.c:177:

    no peer certificate available

    No client certificate CA names sent

    SSL handshake has read 0 bytes and written 321 bytes

    New, (NONE), Cipher is (NONE)
    Secure Renegotiation IS NOT supported
    Compression: NONE
    Expansion: NONE@

    Hope this helps somebody out there understand what the problem is.

    Thanks


Log in to reply
 

Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.