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?
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With