How a client app connect to an SSL server with a self-signed certificate in Qt?

时间秒杀一切 提交于 2019-12-12 09:05:09

问题


I want to communicate with a POP3 server with ssl and port 995 with my client app the certificate of server is self-signed and while running the app the error that received is:

The certificate is self-signed, and untrusted

A part of code is:

socket = new QSslSocket(this);
QFile certfile("D:\\hani\\cert\\localhost.localdomain.pem");
Q_ASSERT(certfile.open(QIODevice::ReadOnly));
QList<QSslCertificate> certList;
QSslCertificate cert(&certfile,QSsl::Pem);
certList.append(cert);
socket->addCaCertificate(cert);
socket->setCaCertificates(certList);
QList<QSslCertificate> serverCert = socket->caCertificates();

What can I do?


回答1:


DO NOT, let me repeat, DO NOT call ignoreSslErrors(). It completely defeats the purpose of SSL/TLS. There are very special cases where it can be called safely, but this (self-signed certificate) is not a special case.

The following minimal code, ready to run, shows how to securely accept a server self-signed certificate. Do not shortcut it.

The driver:

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();
}

The DummyClient class:

/*
 * Show how to safely authenticate a TLS server which uses a self-signed certificate.
 * Warning: No error handling to keep the code short.
 */
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<QSslError>)),
                this, SLOT(onSslErrors(QList<QSslError>)));
        connect(_sock, SIGNAL(error(QAbstractSocket::SocketError)),
                this, SLOT(onErrors(QAbstractSocket::SocketError)));

        // Trust store: which CAs or self-signed certs we are going to trust.
        //
        // We use setCaCertificates() instead than QSslSocket::addCaCertificates()
        // because we don't want to trust the ~200 default CAs.
        QList<QSslCertificate> trustedCas = QSslCertificate::fromPath("server-cert.pem");
        if (trustedCas.empty()) {
            qFatal("Error: no trusted Cas");
        }
        _sock->setCaCertificates(trustedCas);

        bool mutualAuth = false;
        if (mutualAuth) {
            // Our identity
            _sock->setPrivateKey("client-key.pem");
            _sock->setLocalCertificate("client-cert.pem");
        }

        _log << "Connecting" << endl;
        // Note: serverName must match the cert CN or alternative name.
        Qstring serverName = "myserver.example.org";
        _sock->connectToHostEncrypted(serverName, 995);
    }

signals:
    void done();

private slots:
    void onEncrypted() {
        _log << "onEncrypted" << endl;

        /* Everything is good. Start communicating. */

        emit done();
    }

    void onSslErrors(QList<QSslError> errors) {
        QSslError first = errors.takeFirst();
        _log << "onSslErrors: " << first.errorString() << endl;

        /* Something went wrong in the TLS handshake. Inform the user and quit! */

        emit done();
    }

    void onErrors(QAbstractSocket::SocketError) {
        _log << "onErrors: " << _sock->errorString() << endl;
        emit done();
    }

private:
    QTextStream& _log;
    QSslSocket* _sock;
};



回答2:


http://qt-project.org/doc/qt-5.1/qtnetwork/qsslsocket.html

Look at the description of QSslSocket::sslErrors:

If you want to continue connecting despite the errors that have occurred,
you must call QSslSocket::ignoreSslErrors() from inside a slot connected 
to this signal.

DISCLAIMER: This is very ill-advised, as it leaves the server "wide open" to man-in-the-middle attacks



来源:https://stackoverflow.com/questions/18810788/how-a-client-app-connect-to-an-ssl-server-with-a-self-signed-certificate-in-qt

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!