2016-05-19 9 views
1

Ich verwende den folgenden Code, um eine Verbindung zu einem Remote-Host herzustellen.QT 5.5 SSLHandshakeFailedError beim Versuch, sich mit einem selbstsignierten Zertifikat zu verbinden

Der Kunde muss mit einem selbstsignierten Zertifikat der Lage sein, eine gültige SSL-Verbindung authentifizieren zu erstellen:

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

Aber ich bekomme immer die Fehlermeldung:

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

Außerdem wird der Steckplatz errors nicht aufgerufen. Die Zeile QSslCertificate::importPkcs12(&certFile, &key, &certificate, &importedCerts, QByteArray::fromStdString("")); gibt true zurück.

Wenn ich die p12-Zertifikatsdatei im Chrome-Browser hinzufüge und versuche, den Host zu öffnen, funktioniert es einwandfrei.

Außerdem, wenn ich versuche, request.setUrl(QUrl("https://www.test.de")); aufrufen, wird das readyRead() Signal aufgerufen und ich kann den Inhalt der Antwort lesen.

Was ist falsch an meiner Implementierung?

Antwort

1

Das Problem war, dass die referenzierte Objekte, die als Argumente in importPkcs12 Funktion übergeben wurden (wie QSslKey) nicht explizit in dem QSslConfiguration Config-Objekt festgelegt wurden.

Nach dem Hinzufügen der fehlenden Zeilen wurde die Verbindung erfolgreich hergestellt.