Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

QT 5.5 SSLHandshakeFailedError when trying connect with a self signed certificate

I use following code to try to establish a connection to a remote host.

The client must authenticate with a self signed certificate to be able to create a valid SSL connection:

QRemoteProxyCommunication::QRemoteProxyCommunication(QObject *parent) : QObject(parent) {
    QNetworkAccessManager *manager = new QNetworkAccessManager(this);

    QNetworkRequest request;

    QFile certFile("/path/to/file/clientcert.p12");
    certFile.open(QFile::ReadOnly);
    QSslCertificate certificate;
    QSslKey key;
    QList<QSslCertificate> importedCerts;

    bool imported = QSslCertificate::importPkcs12(&certFile, &key, &certificate, &importedCerts, QByteArray::fromStdString(""));
    qDebug() << "Imported: " << imported;

    QSslConfiguration config = request.sslConfiguration();

    config.setCaCertificates(importedCerts);
    config.setProtocol(QSsl::AnyProtocol);
    config.setPeerVerifyMode(QSslSocket::VerifyNone);
    request.setSslConfiguration(config);
    request.setUrl(QUrl("https://www.url.com"));
    reply = manager->get(request);;

    qDebug() << " Certs: " << certificate;

    qDebug() << reply->error();
    qDebug() << reply->errorString();

    connect(reply, SIGNAL(readyRead()), this, SLOT(replyReadyRead()));
    connect(reply, SIGNAL(finished()), this, SLOT(replyFinished()));
    connect(reply, SIGNAL(error(QNetworkReply::NetworkError)), this, SLOT(replyNetworkError(QNetworkReply::NetworkError)));
    connect(manager, SIGNAL(sslErrors(QNetworkReply*, const QList<QSslError>)),
            this, SLOT(errors(QNetworkReply*, const QList<QSslError>)));
    connect(manager, SIGNAL(sslErrors(QNetworkReply*, const QList<QSslError>)),
            this, SLOT(errors(QNetworkReply*, const QList<QSslError>)));

}

void QRemoteProxyCommunication::replyNetworkError(QNetworkReply::NetworkError code) {

    qDebug() << "Network error => " << code;
}

But I always get the error message:

Network error => QNetworkReply::NetworkError(SslHandshakeFailedError) in replyNetworkError SLOT.

Furthermore the slot errors is not invoked.

The line QSslCertificate::importPkcs12(&certFile, &key, &certificate, &importedCerts, QByteArray::fromStdString("")); returns true.

If I add the p12 certificate file within Chrome Browser and try to open the host it is working fine.

Furthermore if I try to call request.setUrl(QUrl("https://www.test.de")); the readyRead() signal is invoked and I can read the response content.

What`s wrong with my implementation?

like image 829
sk2212 Avatar asked Oct 16 '25 19:10

sk2212


1 Answers

The problem was that the referenced objects which were passed as arguments in importPkcs12 function (like QSslKey) were not explicitly set in the QSslConfigurationconfig object.

QFile certFile("/path/to/file/clientcert.p12");
certFile.open(QFile::ReadOnly);
QSslCertificate certificate;
QSslKey key;
QList<QSslCertificate> importedCerts;

bool imported = QSslCertificate::importPkcs12(&certFile, &key, &certificate, &importedCerts, QByteArray::fromStdString("xxxx"));

QSslConfiguration config = request.sslConfiguration();

config.setCaCertificates(importedCerts);
config.setLocalCertificate(certificate);
config.setPrivateKey(key);
config.setProtocol(QSsl::AnyProtocol);
config.setPeerVerifyMode(QSslSocket::VerifyNone);

After adding the missing lines the connection was established successfully.

like image 95
sk2212 Avatar answered Oct 18 '25 10:10

sk2212



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!