BITTE, ich wiederhole, BITTE rufen Sie ignoreSslErrors()
NICHT auf. Dies widerspricht vollständig dem Zweck von SSL/TLS. Es gibt sehr spezielle Fälle, in denen es sicher aufgerufen werden kann, aber dies (selbstsigniertes Zertifikat) ist kein spezieller Fall.
Der folgende minimale Code, bereit zum Ausführen, zeigt, wie man ein Server-Selbstsigniertes Zertifikat sicher akzeptiert. Verkürzen Sie es nicht.
Der Treiber:
int main(int argc, char** argv) {
QCoreApplication app(argc, argv);
QTextStream log(stdout);
DummyClient dummy(log);
QObject::connect(&dummy, SIGNAL(done()), &app, SLOT(quit()));
return app.exec();
}
Die DummyClient
Klasse:
/*
* Zeigen Sie, wie man sicher einen TLS-Server authentifiziert, der ein selbstsigniertes Zertifikat verwendet.
* Warnung: Keine Fehlerbehandlung, um den Code kurz zu halten.
*/
class DummyClient : public QObject {
Q_OBJECT
public:
DummyClient(QTextStream& log)
: _log(log),
_sock(new QSslSocket(this)) {
connect(_sock, SIGNAL(encrypted()), this, SLOT(onEncrypted()));
connect(_sock, SIGNAL(sslErrors(QList)),
this, SLOT(onSslErrors(QList)));
connect(_sock, SIGNAL(error(QAbstractSocket::SocketError)),
this, SLOT(onErrors(QAbstractSocket::SocketError)));
// Trust store: welche CAs oder selbstsignierte Zertifikate vertrauen wir.
//
// Wir verwenden setCaCertificates() anstatt QSslSocket::addCaCertificates()
// da wir die ~200 Standard-CAs nicht vertrauen wollen.
QList trustedCas = QSslCertificate::fromPath("server-cert.pem");
if (trustedCas.empty()) {
qFatal("Fehler: keine vertrauenswürdigen Cas gefunden");
}
_sock->setCaCertificates(trustedCas);
bool mutualAuth = false;
if (mutualAuth) {
// Unsere Identität
_sock->setPrivateKey("client-key.pem");
_sock->setLocalCertificate("client-cert.pem");
}
_log << "Verbindung wird hergestellt" << endl;
// Hinweis: serverName muss mit dem Zertifikat CN oder Alternativnamen übereinstimmen.
Qstring serverName = "meinserver.beispiel.org";
_sock->connectToHostEncrypted(serverName, 995);
}
signals:
void done();
private slots:
void onEncrypted() {
_log << "onEncrypted" << endl;
/* Alles ist gut. Kommunikation starten. */
emit done();
}
void onSslErrors(QList errors) {
QSslError first = errors.takeFirst();
_log << "onSslErrors: " << first.errorString() << endl;
/* Etwas ist schiefgelaufen im TLS-Handshake. Benutzer informieren und beenden! */
emit done();
}
void onErrors(QAbstractSocket::SocketError) {
_log << "onErrors: " << _sock->errorString() << endl;
emit done();
}
private:
QTextStream& _log;
QSslSocket* _sock;
};