├── Sample
├── certs
│ ├── ca.xdb
│ ├── server.p12
│ └── root.crt
├── sample.qrc
├── Sample.pro
├── server.h
├── mainwindow.h
├── main.cpp
├── mainwindow.cpp
├── server.cpp
└── mainwindow.ui
├── qsslserver.pri
├── .gitignore
├── LICENSE
├── README.md
├── qsslserver.h
└── qsslserver.cpp
/Sample/certs/ca.xdb:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Skycoder42/QSslServer/master/Sample/certs/ca.xdb
--------------------------------------------------------------------------------
/Sample/certs/server.p12:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Skycoder42/QSslServer/master/Sample/certs/server.p12
--------------------------------------------------------------------------------
/Sample/sample.qrc:
--------------------------------------------------------------------------------
1 |
2 |
3 | certs/server.p12
4 | certs/root.crt
5 |
6 |
7 |
--------------------------------------------------------------------------------
/qsslserver.pri:
--------------------------------------------------------------------------------
1 | INCLUDEPATH += $$PWD
2 |
3 | HEADERS += \
4 | $$PWD/qsslserver.h
5 |
6 | SOURCES += \
7 | $$PWD/qsslserver.cpp
8 |
9 | QDEP_PACKAGE_EXPORTS += Q_SSL_SERVER_EXPORT
10 | !qdep_build: DEFINES += "Q_SSL_SERVER_EXPORT="
11 |
--------------------------------------------------------------------------------
/Sample/Sample.pro:
--------------------------------------------------------------------------------
1 | QT += core gui widgets network
2 |
3 | TARGET = Sample
4 | TEMPLATE = app
5 |
6 | include(../qsslserver.pri)
7 |
8 | HEADERS += \
9 | mainwindow.h \
10 | server.h
11 |
12 | SOURCES += \
13 | main.cpp \
14 | mainwindow.cpp \
15 | server.cpp
16 |
17 | FORMS += \
18 | mainwindow.ui
19 |
20 | RESOURCES += \
21 | sample.qrc
22 |
--------------------------------------------------------------------------------
/Sample/server.h:
--------------------------------------------------------------------------------
1 | #ifndef SERVER_H
2 | #define SERVER_H
3 |
4 | #include
5 | #include
6 |
7 | class Server : public QObject
8 | {
9 | Q_OBJECT
10 |
11 | public:
12 | explicit Server(QObject *parent = nullptr);
13 |
14 | public slots:
15 | void start();
16 | void stop();
17 |
18 | signals:
19 | void connected(quint16 port);
20 |
21 | private slots:
22 | void newConnection();
23 | void error();
24 |
25 | private:
26 | QSslServer *server;
27 | };
28 |
29 | #endif // SERVER_H
30 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # C++ objects and libs
2 |
3 | *.slo
4 | *.lo
5 | *.o
6 | *.a
7 | *.la
8 | *.lai
9 | *.so
10 | *.dll
11 | *.dylib
12 |
13 | # Qt-es
14 |
15 | /.qmake.cache
16 | /.qmake.stash
17 | *.pro.user
18 | *.pro.user.*
19 | *.qbs.user
20 | *.qbs.user.*
21 | *.moc
22 | moc_*.cpp
23 | moc_*.h
24 | qrc_*.cpp
25 | ui_*.h
26 | Makefile*
27 | *build-*
28 |
29 | # QtCreator
30 |
31 | *.autosave
32 |
33 | # QtCtreator Qml
34 | *.qmlproject.user
35 | *.qmlproject.user.*
36 |
37 | # QtCtreator CMake
38 | CMakeLists.txt.user*
39 |
40 |
--------------------------------------------------------------------------------
/Sample/mainwindow.h:
--------------------------------------------------------------------------------
1 | #ifndef MAINWINDOW_H
2 | #define MAINWINDOW_H
3 |
4 | #include
5 | #include
6 |
7 | namespace Ui {
8 | class MainWindow;
9 | }
10 |
11 | class MainWindow : public QMainWindow
12 | {
13 | Q_OBJECT
14 |
15 | public:
16 | explicit MainWindow(QWidget *parent = nullptr);
17 | ~MainWindow() override;
18 |
19 | public slots:
20 | void connectTo(quint16 port);
21 |
22 | private slots:
23 | void on_sendButton_clicked();
24 |
25 | void readyRead();
26 | void error();
27 | void sslErrors(const QList &errors);
28 |
29 | private:
30 | Ui::MainWindow *ui;
31 | QSslSocket *socket;
32 | };
33 |
34 | #endif // MAINWINDOW_H
35 |
--------------------------------------------------------------------------------
/Sample/main.cpp:
--------------------------------------------------------------------------------
1 | #include
2 | #include
3 | #include "mainwindow.h"
4 | #include "server.h"
5 |
6 | int main(int argc, char *argv[])
7 | {
8 | QApplication a(argc, argv);
9 |
10 | QThread serverThread;
11 | QObject::connect(qApp, &QApplication::aboutToQuit, &serverThread, [&](){
12 | serverThread.quit();
13 | serverThread.wait();
14 | });
15 |
16 | auto svr = new Server{};
17 | svr->moveToThread(&serverThread);
18 | QObject::connect(&serverThread, &QThread::finished,
19 | svr, &Server::stop);
20 | QObject::connect(&serverThread, &QThread::started,
21 | svr, &Server::start);
22 |
23 | MainWindow w;
24 | QObject::connect(svr, &Server::connected,
25 | &w, &MainWindow::connectTo,
26 | Qt::QueuedConnection);
27 |
28 | serverThread.start();
29 | w.show();
30 | return a.exec();
31 | }
32 |
--------------------------------------------------------------------------------
/Sample/mainwindow.cpp:
--------------------------------------------------------------------------------
1 | #include "mainwindow.h"
2 | #include "ui_mainwindow.h"
3 |
4 | #include
5 |
6 | MainWindow::MainWindow(QWidget *parent) :
7 | QMainWindow{parent},
8 | ui{new Ui::MainWindow},
9 | socket{new QSslSocket{this}}
10 | {
11 | ui->setupUi(this);
12 |
13 | socket->addCaCertificates(QSslCertificate::fromPath(QStringLiteral(":/certs/root.crt")));
14 |
15 | connect(socket, &QSslSocket::readyRead,
16 | this, &MainWindow::readyRead);
17 | connect(socket, QOverload::of(&QSslSocket::error),
18 | this, &MainWindow::error);
19 | connect(socket, QOverload &>::of(&QSslSocket::sslErrors),
20 | this, &MainWindow::sslErrors);
21 | }
22 |
23 | MainWindow::~MainWindow()
24 | {
25 | delete ui;
26 | }
27 |
28 | void MainWindow::connectTo(quint16 port)
29 | {
30 | socket->connectToHostEncrypted(QStringLiteral("127.0.0.1"), port);
31 | }
32 |
33 | void MainWindow::on_sendButton_clicked()
34 | {
35 | socket->write(ui->lineEdit->text().toUtf8());
36 | ui->lineEdit->clear();
37 | }
38 |
39 | void MainWindow::readyRead()
40 | {
41 | ui->plainTextEdit->appendPlainText(QString::fromUtf8(socket->readAll()));
42 | }
43 |
44 | void MainWindow::error()
45 | {
46 | ui->plainTextEdit->appendPlainText(QStringLiteral(" >>> ERROR: %1").arg(socket->errorString()));
47 | }
48 |
49 | void MainWindow::sslErrors(const QList &errors)
50 | {
51 | for(const auto &error : errors)
52 | ui->plainTextEdit->appendPlainText(QStringLiteral(" >>> SSL-ERROR: %1").arg(error.errorString()));
53 | }
54 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | BSD 3-Clause License
2 |
3 | Copyright (c) 2018, Felix Barz
4 | All rights reserved.
5 |
6 | Redistribution and use in source and binary forms, with or without
7 | modification, are permitted provided that the following conditions are met:
8 |
9 | * Redistributions of source code must retain the above copyright notice, this
10 | list of conditions and the following disclaimer.
11 |
12 | * Redistributions in binary form must reproduce the above copyright notice,
13 | this list of conditions and the following disclaimer in the documentation
14 | and/or other materials provided with the distribution.
15 |
16 | * Neither the name of the copyright holder nor the names of its
17 | contributors may be used to endorse or promote products derived from
18 | this software without specific prior written permission.
19 |
20 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
21 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
23 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
24 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
25 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
26 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
27 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
28 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
29 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30 |
--------------------------------------------------------------------------------
/Sample/server.cpp:
--------------------------------------------------------------------------------
1 | #include "server.h"
2 |
3 | Server::Server(QObject *parent) :
4 | QObject{parent},
5 | server{new QSslServer{this}}
6 | {
7 | if(!server->importPkcs12(QStringLiteral(":/certs/server.p12")))
8 | qCritical() << " >>> SERVER ERROR: Failed to import certificates";
9 |
10 | connect(server, &QSslServer::newConnection,
11 | this, &Server::newConnection);
12 | connect(server, &QSslServer::acceptError,
13 | this, &Server::error);
14 | }
15 |
16 | void Server::start()
17 | {
18 | if(server->listen(QHostAddress::LocalHost))
19 | emit connected(server->serverPort());
20 | else
21 | error();
22 | }
23 |
24 | void Server::stop()
25 | {
26 | server->close();
27 | }
28 |
29 | void Server::newConnection()
30 | {
31 | while(server->hasPendingConnections()) {
32 | auto socket = server->nextPendingConnection();
33 |
34 | connect(socket, &QSslSocket::readyRead, socket, [socket]{
35 | socket->write(socket->readAll());
36 | });
37 | connect(socket, &QSslSocket::disconnected,
38 | socket, &QSslSocket::deleteLater);
39 | connect(socket, QOverload::of(&QSslSocket::error),
40 | socket, [socket](){
41 | qCritical() << " >>> SERVER SOCKET ERROR:" << socket->errorString();
42 | });
43 | connect(socket, QOverload &>::of(&QSslSocket::sslErrors),
44 | this, [](const QList &errors){
45 | for(const auto &error : errors)
46 | qCritical() << " >>> SERVER SOCKET SSL ERROR:" << error.errorString();
47 | });
48 | }
49 | }
50 |
51 | void Server::error()
52 | {
53 | qCritical() << " >>> SERVER ERROR:" << server->errorString();
54 | }
55 |
--------------------------------------------------------------------------------
/Sample/certs/root.crt:
--------------------------------------------------------------------------------
1 | -----BEGIN CERTIFICATE-----
2 | MIIE7zCCAtegAwIBAgIBATANBgkqhkiG9w0BAQsFADAAMCAXDTE4MDMyMDE2MjQw
3 | MFoYDzk5OTkxMjMxMjM1OTU5WjAAMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIIC
4 | CgKCAgEAr10vlCdxehbgNBLAnd/sgi6LPonlWMFGBaCsyIo1hBp6K8I9xfCruBWO
5 | al8QXpVYLvEIl0aggUwOcj18b+6KMjm5CvrDTMOhz1LGpwEPYmv4D5M3+zDLrZQe
6 | sH+gwiLltxP5n/d+S+zIsJUrSRK1BmoEbaES+0TeSpe/1pSwrvL7zHbl+HetRbXF
7 | 26tTP+ghF59VyyPjQLY3biWOEK2xoLmW7hQJWR5t5h6IB7fvMYQ97QpF8Kndo5tl
8 | LqZpKkx09cEMKVvm2cMqUO/qQPncB8xSJ7UVBAevLjfIKd195oyNN+fVZ0Y/Z5V+
9 | Hlmn6qWUUawJ43NzyLjR3L4lywq005T1tN/6Fi0TWgKQzz5ESFxpmTacQ+BSgPNS
10 | jJW22ieo/Gu0mPUjw27OgNAKV9q3TBZaXYWGb0ABcdnGFb9hKjzNJ4KXJK7xcg+1
11 | HFDz6SZ/7EuY1su9ZyDqykLF8sRKTGJE7Jzy31AfP4CwRdXMKKzPiP+5Pt/v9Q1V
12 | 4Q4zKsACl5R8VZJatubQXLYg/BRpgWwq5ttFqwFdKxzDFUVngzlX6eoEc7JdDhvr
13 | Y01lsnVk9XW8qNKnKbjXtfJ5raT/3+7jq56pgCkyXB7aGu60xpAztYUypg1eYEsm
14 | dxdPyrg/YJO/KUPxetv4WYxAJ3TX5uVKuhKNFUfHhIJddp38QisCAwEAAaNyMHAw
15 | DwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQU4l3P5Iuodml1jjMwaCZKBpDzJ1Iw
16 | CwYDVR0PBAQDAgEGMBEGCWCGSAGG+EIBAQQEAwIABzAeBglghkgBhvhCAQ0EERYP
17 | eGNhIGNlcnRpZmljYXRlMA0GCSqGSIb3DQEBCwUAA4ICAQBg+JJ0mIBwG34W4xt4
18 | /TJyK2rs+oBDccmDuPtOldw5CyRtOv3QD9e2kWhndNlaWmMW0LbO+BpAfwg1BuGO
19 | Z8E8DR4vhxp12eZOHGo6VsqI2Wp8tDXFHEdhBRgZyG32Awa2J1bf/rz1QmHbC/14
20 | TKOqjCzSBH+gQyj8rg67vVnHXBR/banWXcTyS/q3wgcJMjzKKZj11K5JjKXLj9D7
21 | TrEF+pbcusE1k/vEdQyMLqCVx7O+SXfJ557SEj/Hn/lItar7FW2nSg2rkAroug3s
22 | /y3cR75GSWLsGRkFqgGKzhLr+S7Z+4HIW3Rv45ARGy3086oOFkQbfdtjvNwU1els
23 | v/bmvg0vOfmgIL5ymYjEy4aR2b3oOrxRfv3oTLsjvYa2JLcg8vmnH3NiR03LVbcC
24 | qYz0qlF1++/j+e8cP143LZjSvPQex1oTcbV0WhG3i4ZvSCHIbnYBlCGRQdKE2lUD
25 | GFr5VBpukgWHmAaq4gyjsAL8/8sRxHDJ5Kb0F1MP+C6BJ2Fhr2jmygg2WcdDfsr6
26 | 8bIbLhgG+TOzxogQGWIVBPP19EyWA7z46+1uWfv6ibjzqMF3r/W2mRqFUz6dJPjJ
27 | 1iDxfY/tMu7UYNuOc0AM4O8mCG/d+YOvEh+I90eoQtXQqxEq5oub5gi4QK7wJBHy
28 | 3xXGpUwxp5Whsyg44IZytAFbzg==
29 | -----END CERTIFICATE-----
30 |
--------------------------------------------------------------------------------
/Sample/mainwindow.ui:
--------------------------------------------------------------------------------
1 |
2 |
3 | MainWindow
4 |
5 |
6 |
7 | 0
8 | 0
9 | 520
10 | 381
11 |
12 |
13 |
14 | MainWindow
15 |
16 |
17 |
18 | -
19 |
20 |
21 | true
22 |
23 |
24 |
25 | -
26 |
27 |
28 | Ping:
29 |
30 |
31 |
32 | -
33 |
34 |
35 | Send
36 |
37 |
38 |
39 | -
40 |
41 |
42 | Pong:
43 |
44 |
45 |
46 | -
47 |
48 |
49 |
50 |
51 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # QSslServer
2 | An extension of QTcpServer to support ssl. The counterpart to QSslSocket.
3 |
4 | ## Features
5 | - Works like a normal `QTcpServer`, but with `QSslSocket` instead of `QTcpSocket`
6 | - Adds a variety of useful method to setup the server. Mainly loading certificates and keys.
7 | - You can configure the server as deeply as you want by directly using `QSslConfiguration`
8 |
9 | ## Installation
10 | The package is provided via qdep, as `Skycoder42/QSslServer`. To use it simply:
11 |
12 | 1. Install and enable qdep (See [qdep - Installing](https://github.com/Skycoder42/qdep#installation))
13 | 2. Add the following to your pro file:
14 | ```qmake
15 | QDEP_DEPENDS += Skycoder42/QSslServer
16 | !load(qdep):error("Failed to load qdep feature! Run 'qdep prfgen --qmake $$QMAKE_QMAKE' to create it.")
17 | ```
18 |
19 | ## Usage
20 | It works exactly like the TCP server. The only difference: you need to set a certificate before connecting:
21 | ```cpp
22 | auto server = new QSslServer(this);
23 |
24 | //emits newConnection just like the tcp variant
25 | connect(server, &QSslServer::newConnection, this, [this](){
26 | while(server->hasPendingConnections()) {
27 | auto socket = server->nextPendingConnection();
28 |
29 | //work with the new socket
30 | }
31 | });
32 |
33 | //load a certificate and private key, then start listening
34 | if(!server->importPkcs12(QStringLiteral("/path/to/cert.p12")))
35 | qCritical() << "Failed to import certificates";
36 | else
37 | server->listen(QHostAddress::Any, 4711);
38 | ```
39 |
40 | This code sample is basically it. For a more advanced example, check the project in the
41 | Sample subfolder. It's a widgets application with an SSL based echo server. Certificates are included to emulate a real life situation:
42 |
43 | - `Sample/certs/root.crt` is a PEM encoded CA certificate that is added as CA cert to the client
44 | - `Sample/certs/server.p12` is a PKCS#12 container with the root CA certificate, the server certificate (signed by the CA cert) and the servers private key. It is loaded by the server.
45 |
46 | Note: For this example the p12 file is unencrypted. Typically a password should be used to protect it.
47 |
--------------------------------------------------------------------------------
/qsslserver.h:
--------------------------------------------------------------------------------
1 | #ifndef QSSLSERVER_H
2 | #define QSSLSERVER_H
3 |
4 | #include
5 | #include
6 | #include
7 |
8 | class Q_SSL_SERVER_EXPORT QSslServer : public QTcpServer
9 | {
10 | Q_OBJECT
11 |
12 | public:
13 | explicit QSslServer(QObject *parent = nullptr);
14 |
15 | QSslSocket *nextPendingConnection();
16 |
17 | // SSL configuration
18 | QSslConfiguration sslConfiguration() const;
19 | void setSslConfiguration(QSslConfiguration configuration);
20 |
21 | // Certificate
22 | void setLocalCertificateChain(const QList &localChain);
23 | void setLocalCertificateChain(const QString &fileName,
24 | QSsl::EncodingFormat format = QSsl::Pem,
25 | QSslCertificate::PatternSyntax syntax = QSslCertificate::PatternSyntax::FixedString);
26 | QList localCertificateChain() const;
27 |
28 | void setLocalCertificate(const QSslCertificate &certificate);
29 | void setLocalCertificate(const QString &fileName,
30 | QSsl::EncodingFormat format = QSsl::Pem);
31 | QSslCertificate localCertificate() const;
32 |
33 | // Private keys
34 | void setPrivateKey(const QSslKey &key);
35 | void setPrivateKey(const QString &fileName,
36 | QSsl::KeyAlgorithm algorithm = QSsl::Rsa,
37 | QSsl::EncodingFormat format = QSsl::Pem,
38 | const QByteArray &passPhrase = QByteArray{});
39 | QSslKey privateKey() const;
40 |
41 | // CA settings
42 | bool addCaCertificates(const QString &path,
43 | QSsl::EncodingFormat format = QSsl::Pem,
44 | QSslCertificate::PatternSyntax syntax = QSslCertificate::PatternSyntax::FixedString);
45 | void addCaCertificate(const QSslCertificate &certificate);
46 | void addCaCertificates(const QList &certificates);
47 |
48 | // PKCS#12
49 | bool importPkcs12(const QString &path,
50 | const QByteArray &passPhrase = QByteArray(),
51 | bool replaceCaCerts = false);
52 |
53 | QSsl::SslProtocol protocol() const;
54 | void setProtocol(QSsl::SslProtocol protocol);
55 |
56 | protected:
57 | void incomingConnection(qintptr handle) override;
58 |
59 | private:
60 | QSslConfiguration _configuration;
61 | };
62 |
63 | #endif // QSSLSERVER_H
64 |
--------------------------------------------------------------------------------
/qsslserver.cpp:
--------------------------------------------------------------------------------
1 | #include "qsslserver.h"
2 | #include
3 | #include
4 | #include
5 | #include
6 | #include
7 |
8 | QSslServer::QSslServer(QObject *parent) :
9 | QTcpServer{parent},
10 | _configuration{QSslConfiguration::defaultConfiguration()}
11 | {}
12 |
13 | QSslSocket *QSslServer::nextPendingConnection()
14 | {
15 | return qobject_cast(QTcpServer::nextPendingConnection());
16 | }
17 |
18 | QSslConfiguration QSslServer::sslConfiguration() const
19 | {
20 | return _configuration;
21 | }
22 |
23 | void QSslServer::setSslConfiguration(QSslConfiguration configuration)
24 | {
25 | _configuration = std::move(configuration);
26 | }
27 |
28 | void QSslServer::setLocalCertificateChain(const QList &localChain)
29 | {
30 | _configuration.setLocalCertificateChain(localChain);
31 | }
32 |
33 | void QSslServer::setLocalCertificateChain(const QString &fileName, QSsl::EncodingFormat format, QSslCertificate::PatternSyntax syntax)
34 | {
35 | _configuration.setLocalCertificateChain(QSslCertificate::fromPath(fileName, format, syntax));
36 | }
37 |
38 | QList QSslServer::localCertificateChain() const
39 | {
40 | return _configuration.localCertificateChain();
41 | }
42 |
43 | void QSslServer::setLocalCertificate(const QSslCertificate &certificate)
44 | {
45 | _configuration.setLocalCertificate(certificate);
46 | }
47 |
48 | void QSslServer::setLocalCertificate(const QString &fileName, QSsl::EncodingFormat format)
49 | {
50 | QFile file{fileName};
51 | if(file.open(QIODevice::ReadOnly)) {
52 | QSslCertificate certificate{&file, format};
53 | if(!certificate.isNull())
54 | _configuration.setLocalCertificate(certificate);
55 | file.close();
56 | }
57 | }
58 |
59 | QSslCertificate QSslServer::localCertificate() const
60 | {
61 | return _configuration.localCertificate();
62 | }
63 |
64 | void QSslServer::setPrivateKey(const QSslKey &key)
65 | {
66 | _configuration.setPrivateKey(key);
67 | }
68 |
69 | void QSslServer::setPrivateKey(const QString &fileName, QSsl::KeyAlgorithm algorithm, QSsl::EncodingFormat format, const QByteArray &passPhrase)
70 | {
71 | QFile file{fileName};
72 | if(file.open(QIODevice::ReadOnly)) {
73 | QSslKey newKey{&file, algorithm, format, QSsl::PrivateKey, passPhrase};
74 | if(!newKey.isNull())
75 | _configuration.setPrivateKey(newKey);
76 | file.close();
77 | }
78 | }
79 |
80 | QSslKey QSslServer::privateKey() const
81 | {
82 | return _configuration.privateKey();
83 | }
84 |
85 | bool QSslServer::addCaCertificates(const QString &path, QSsl::EncodingFormat format, QSslCertificate::PatternSyntax syntax)
86 | {
87 | auto certs = QSslCertificate::fromPath(path, format, syntax);
88 | if (!certs.isEmpty()) {
89 | addCaCertificates(certs);
90 | return true;
91 | } else
92 | return false;
93 | }
94 |
95 | void QSslServer::addCaCertificate(const QSslCertificate &certificate)
96 | {
97 | auto certs = _configuration.caCertificates();
98 | certs.append(certificate);
99 | _configuration.setCaCertificates(certs);
100 | }
101 |
102 | void QSslServer::addCaCertificates(const QList &certificates)
103 | {
104 | auto certs = _configuration.caCertificates();
105 | certs.append(certificates);
106 | _configuration.setCaCertificates(certs);
107 | }
108 |
109 | bool QSslServer::importPkcs12(const QString &path, const QByteArray &passPhrase, bool replaceCaCerts)
110 | {
111 | QFile file{path};
112 | if(file.open(QIODevice::ReadOnly)) {
113 | QSslKey key;
114 | QSslCertificate cert;
115 | QList caCerts;
116 | if (QSslCertificate::importPkcs12(&file, &key, &cert, &caCerts, passPhrase)) {
117 | file.close();
118 | if(!caCerts.isEmpty()) {
119 | if(replaceCaCerts)
120 | _configuration.setCaCertificates(caCerts);
121 | else
122 | addCaCertificates(caCerts);
123 | }
124 | if(!cert.isNull())
125 | _configuration.setLocalCertificate(cert);
126 | if(!key.isNull())
127 | _configuration.setPrivateKey(key);
128 | return true;
129 | } else
130 | file.close();
131 | }
132 |
133 | return false;
134 | }
135 |
136 | QSsl::SslProtocol QSslServer::protocol() const
137 | {
138 | return _configuration.protocol();
139 | }
140 |
141 | void QSslServer::setProtocol(QSsl::SslProtocol protocol)
142 | {
143 | _configuration.setProtocol(protocol);
144 | }
145 |
146 | void QSslServer::incomingConnection(qintptr handle)
147 | {
148 | //Create Socket
149 | auto socket = new QSslSocket{};
150 | if (!socket->setSocketDescriptor(handle)) {
151 | emit acceptError(socket->error());
152 | delete socket;
153 | return;
154 | }
155 |
156 | //set ssl data
157 | socket->setSslConfiguration(_configuration);
158 | socket->startServerEncryption();
159 | addPendingConnection(socket);
160 | }
161 |
--------------------------------------------------------------------------------