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 QSslConfiguration
config 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