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 Server Side SNI Support
Forum Updated to NodeBB v4.3 + New Features

QSslSocket Server Side SNI Support

Scheduled Pinned Locked Moved Solved General and Desktop
11 Posts 3 Posters 3.7k Views 3 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.
  • M Offline
    M Offline
    Mythiclese
    wrote on last edited by
    #1

    I'm trying to write an SSL server program that can support SNI. I first set startTransaction(), and then read the incoming client handshake request, and pull the SNI. Then set rollbackTransaction(), and set setPrivateKey, setLocalCertificate, and startServerEncryption. However, the connection never gets encryption enabled. When I check bytesAvailable() after rollbackTransaction() for my QSslSocket, it comes back with the right amount of bytes. However, when I check in void QSslSocket::startServerEncryption() for d->plainSocket->bytesAvailable(), it says zero bytes available. Also, checking in void QSslSocketBackendPrivate::startServerEncryption() for plainSocket->bytesAvailable(), gives zero bytes available as well. Why the difference in bytesAvailable()?

    1 Reply Last reply
    0
    • SGaistS Offline
      SGaistS Offline
      SGaist
      Lifetime Qt Champion
      wrote on last edited by
      #2

      Hi and welcome to devnet,

      You should add which version of Qt your are using as well as platform and OpenSSL version.

      Can you also show the code that you are currently using ?

      Interested in AI ? www.idiap.ch
      Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

      1 Reply Last reply
      0
      • M Offline
        M Offline
        Mythiclese
        wrote on last edited by
        #3

        Sorry about that.
        Qt: 5.8.0
        Platform: Arch Linux (latest updates)
        OpenSSL: 1.0.2.k

        Code:
        main.cpp

        #include <QCoreApplication>
        #include "sniserver.h"
        
        int main(int argc, char *argv[])
        {
        	QCoreApplication app(argc, argv);
        	app.setObjectName("CoreApp");
        
                SniServer *sniServer(new SniServer);
                sniServer->setObjectName("sniserverd");
                sniServer->moveToThread(sniServer);
                sniServer->start();
        
        	return app.exec();
        }
        

        sslserver.h

        #ifndef SSLSERVER_H
        #define SSLSERVER_H
        
        #include <QTcpServer>
        
        class SslServer : public QTcpServer
        {
        	Q_OBJECT
        
        public:
        	explicit SslServer(QObject *parent = 0);
        	virtual ~SslServer();
        
        protected:
        	virtual void incomingConnection(qintptr socketDescriptor);
        
        private slots:
        	void sslSocketReady();
        };
        
        #endif // SSLSERVER_H
        

        sslserver.cpp

        #include <QSslSocket>
        #include "sslserver.h"
        
        SslServer::SslServer(QObject *parent) : QTcpServer(parent)
        {
        }
        
        SslServer::~SslServer()
        {
        }
        
        void SslServer::incomingConnection(qintptr socketDescriptor)
        {
        	QSslSocket *sslSocket = new QSslSocket;
        
        	sslSocket->setSocketDescriptor(socketDescriptor);
        	sslSocket->setProtocol(QSsl::TlsV1_2OrLater);
        
        	QObject::connect(sslSocket, &QSslSocket::encrypted, this, &SslServer::sslSocketReady);
        
        	addPendingConnection(sslSocket);
        }
        
        void SslServer::sslSocketReady()
        {
        	qDebug("Ssl Socket is encrypted");
        }
        

        sniserver.h

        #ifndef SNISERVER_H
        #define SNISERVER_H
        
        #include <QThread>
        
        class SslServer;
        
        class SniServer : public QThread
        {
        	Q_OBJECT
        
        public:
        	explicit SniServer(QObject *parent = 0);
        	virtual ~SniServer();
        
        protected:
        	void run();
        
        private:
        	SniServer(const SniServer&);
        	SniServer& operator=(const SniServer&);
        
        	SslServer *m_sslServer;
        
        private slots:
        	void disconnectedHttpsClient();
        	void newSslConnection();
        	void readClientHello();
        	void readInputHttps();
        };
        
        #endif // SNISERVER_H
        

        sniserver.cpp

        #include <QSslSocket>
        #include <QSslCertificate>
        
        #include "utils.h"
        #include "sslserver.h"
        #include "httpsclient.h"
        #include "sniserver.h"
        
        SniServer::SniServer(QObject *parent) : QThread(parent),
        		m_sslServer(new SslServer(this))
        {
        }
        
        SniServer::~SniServer()
        {
        	m_sslServer->close();
        }
        
        void SniServer::run()
        {
        	m_sslServer->setObjectName("SNIServer::m_sslServer");
        
        	QObject::connect(m_sslServer, &SslServer::newConnection, this, &SniServer::newSslConnection);
        
        	if(m_sslServer->listen(QHostAddress::Any, 443)){
        		qWarning(" Notice:;\tThe SNI Https server is running on port 443");
        	}else{
        		qCritical() << "Unable to start the Http server:" << m_sslServer->errorString();
        	}
        
        	exec();
        }
        
        void SniServer::newSslConnection()
        {
        	HttpsClient *httpsClient = new HttpsClient(qobject_cast<QSslSocket *>(m_sslServer->nextPendingConnection()), this);
        	httpsClient->setObjectName("SniServer::httpsClient");
        
        	QObject::connect(httpsClient, &HttpsClient::readyRead, this, &SniServer::readClientHello);
        	QObject::connect(httpsClient, &HttpsClient::disconnected, this, &SniServer::disconnectedHttpsClient);
        }
        
        void SniServer::disconnectedHttpsClient()
        {
        	HttpsClient *tmpClient(qobject_cast<HttpsClient *>(sender()));
        
        	tmpClient->deleteLater();
        	tmpClient = 0;
        }
        
        void SniServer::readClientHello()
        {
        	HttpsClient *tmpClient(qobject_cast<HttpsClient *>(sender()));
        	tmpClient->resetInactivityTimer();
        
        	QObject::disconnect(tmpClient, &HttpsClient::readyRead, this, &SniServer::readClientHello);
        
        	tmpClient->m_sslSocket->startTransaction();
        	QByteArray incomingRequest(tmpClient->m_sslSocket->readAll());
        	tmpClient->m_sslSocket->rollbackTransaction();
        	qDebug() << "SniServer::readInputHttps:" << incomingRequest.toHex();
        
        	tmpClient->m_sslSocket->setPrivateKey("/opt/server/server.domainname.org.key.pem");
        	tmpClient->m_sslSocket->setLocalCertificate(QSslCertificate(Utils().readFile("/opt/server/server.domainname.org.cert.pem")));
        	tmpClient->m_sslSocket->startServerEncryption();
        
        	QObject::connect(tmpClient, &HttpsClient::readyRead, this, &SniServer::readInputHttps);
        
        	tmpClient = 0;
        }
        
        void SniServer::readInputHttps()
        {
        	HttpsClient *tmpClient(qobject_cast<HttpsClient *>(sender()));
        	tmpClient->resetInactivityTimer();
        
        	QByteArray incomingRequest(tmpClient->m_sslSocket->readAll());
        	qDebug() << "SniServer::readInputHttps:" << incomingRequest.toHex();
        
        	tmpClient = 0;
        }
        

        As you can see, a pretty straight forward implementation.

        1 Reply Last reply
        0
        • M Offline
          M Offline
          Mythiclese
          wrote on last edited by Mythiclese
          #4

          I decided to add Server Side SNI support to QSslSocket.

          mrjjM 1 Reply Last reply
          0
          • SGaistS Offline
            SGaistS Offline
            SGaist
            Lifetime Qt Champion
            wrote on last edited by
            #5

            Nice ! Thank you :)

            Interested in AI ? www.idiap.ch
            Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

            1 Reply Last reply
            0
            • M Mythiclese

              I decided to add Server Side SNI support to QSslSocket.

              mrjjM Offline
              mrjjM Offline
              mrjj
              Lifetime Qt Champion
              wrote on last edited by
              #6

              @Mythiclese
              Thank you for making Qt better!

              1 Reply Last reply
              0
              • M Offline
                M Offline
                Mythiclese
                wrote on last edited by
                #7

                Well, it is self-serving after all, lol. I need this feature, so might as well share it.

                mrjjM 1 Reply Last reply
                0
                • M Mythiclese

                  Well, it is self-serving after all, lol. I need this feature, so might as well share it.

                  mrjjM Offline
                  mrjjM Offline
                  mrjj
                  Lifetime Qt Champion
                  wrote on last edited by
                  #8

                  @Mythiclese
                  Well that really is the good spirit :)

                  1 Reply Last reply
                  1
                  • M Offline
                    M Offline
                    Mythiclese
                    wrote on last edited by
                    #9

                    That's why I love open source. You can always roll your own.

                    mrjjM 1 Reply Last reply
                    0
                    • M Mythiclese

                      That's why I love open source. You can always roll your own.

                      mrjjM Offline
                      mrjjM Offline
                      mrjj
                      Lifetime Qt Champion
                      wrote on last edited by
                      #10

                      @Mythiclese
                      Indeed. The freedom is real. So its also great you give something back. Helping to keep this freedom.

                      1 Reply Last reply
                      0
                      • M Offline
                        M Offline
                        Mythiclese
                        wrote on last edited by
                        #11

                        Aye, I try to give back when I can.

                        1 Reply Last reply
                        1

                        • Login

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