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.8k 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.
  • 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