2011-01-28 4 views
1

Я разрабатываю свой пользовательский браузер в Qt с помощью QWebView и Я пытаюсь создать собственный корневой сертификат cert доверенных сертификатов, взятых из проекта mozilla.Проблема создания пользовательского корневого хранилища сертификатов для SSL с использованием QT?

Я использовал QSslSocket :: setDefaultCaCertificates(), чтобы переопределить сертификаты по умолчанию. Но я не могу загрузить https://www.gmail.com, где, как и в mozilla, он работает.

Я установил все необходимые корневые сертификаты для gmail в мой магазин.

Может ли кто-нибудь мне навестить?

ответ

4

Причина, по которой вы не можете подключиться, заключается в том, что сертификат SSL (с серийным номером 2F:DF:BC:F6:AE:91:52:6D:0F:9A:A3:DF:40:34:3E:9A), представленный вам при подключении к www.gmail.com, выдается для другого домена - www.google.com. Это не имеет никакого отношения к корневому хранилищу сертификатов ЦС, потому что для сопоставления поля Subject объекта CN с узлом, к которому вы пытаетесь подключиться, не требуется корневой сертификат CA. Вы можете игнорировать это и другие ошибки SSL, вызвав
void QNetworkReply::ignoreSslErrors() [virtual slot]
Чтобы избежать этой ошибки можно подключить непосредственно к https://mail.google.com, который является домен, который вы будете перенаправлены при попытке подключиться к https://www.gmail.com

Ниже приведен рабочий пример который покажет вам точные ошибки SSL и ошибки уровня QNAM. Любая строка B1 или строка B2 должна быть активна одновременно. Вы можете прокомментировать строку A, если хотите узнать, что происходит с хранилищем сертификатов корневого центра сертификации по умолчанию (system). Для этого кода используются два сертификата. Сертификат CA с серийным номером 30:00:00:02 следует поместить в файл с именем ThawteSGCCA.crt, а сертификат CA с серийным номером 70:BA:E4:1D:10:D9:29:34:B6:38:CA:7B:03:CC:BA:BF должен быть помещен в файл с именем BuiltinObjectToken-VerisignClass3PublicPrimaryCertificationAuthority.crt.

#include <QtGui/QApplication> 
#include <QtCore/QDebug> 
#include <QtCore/QList> 
#include <QtNetwork/QNetworkAccessManager> 
#include <QtNetwork/QNetworkRequest> 
#include <QtNetwork/QNetworkReply> 
#include <QtNetwork/QSslConfiguration> 
#include <QtNetwork/QSslSocket> 
#include <QtNetwork/QSslError> 
#include <QtWebKit/QWebFrame> 
#include <QtWebKit/QWebPage> 



class Handler : public QObject{ 
    Q_OBJECT 

public slots: 

    void slotLoadFinished(bool ok) { 
     if (ok) { 
      qDebug() << "Page size: " << static_cast<QWebPage*>(sender())->mainFrame()->toHtml().size(); 
     } 
    } 

    void slotFinished(QNetworkReply * reply) { 
     if (reply->error() == QNetworkReply::NoError) { 
      qDebug() << "connected to " << reply->url(); 
      qDebug() << "HTTP status: " << reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt(); 

     } else { 
      qDebug() << "error while connecting to " << reply->url(); 
      qDebug() << "error code: " << reply->error(); 
      qDebug() << "error string: " << reply->errorString(); 
     } 
    } 

    void slotSslErrors(QNetworkReply * reply, QList<QSslError> const & errors) { 
     qDebug() << "SSL errors: " << errors; 
     qDebug() << "peer's certificate: " 
       << reply->sslConfiguration().peerCertificate(); 
    } 

}; 


int main(int argc, char *argv[]) 
{ 
    QApplication app(argc, argv); 
    Handler handler; 

    // CA certs for: 
    // 1. cert with Subject.CN == mail.google.com cert with serial 1f:19:f6:de:35:dd:63:a1:42:91:8a:d5:2c:c0:ab:12 
    // 2. cert with Subject.CN == www.google.com cert with serial 2F:DF:BC:F6:AE:91:52:6D:0F:9A:A3:DF:40:34:3E:9A 
    QList<QSslCertificate> CAcerts = 
      // serial 30:00:00:02 
      QSslCertificate::fromPath("ThawteSGCCA.crt") + 
      // serial 70:BA:E4:1D:10:D9:29:34:B6:38:CA:7B:03:CC:BA:BF 
      QSslCertificate::fromPath("BuiltinObjectToken-VerisignClass3PublicPrimaryCertificationAuthority.crt"); 

    qDebug() << "root CA certificates:\n" 
      << CAcerts 
      << "\n"; 
    QSslSocket::setDefaultCaCertificates(CAcerts); // line A 

    QWebPage page; 
    // OK because cert with serial 1f:19:f6:de:35:dd:63:a1:42:91:8a:d5:2c:c0:ab:12 is for host mail.google.com 
// page.mainFrame()->load(QUrl("https://mail.google.com")); // line B1 
    // SSL ERROR "The host name did not match any of the valid hosts for this certificate" 
    // because cert with serial 1f:19:f6:de:35:dd:63:a1:42:91:8a:d5:2c:c0:ab:12 is NOT for www.gmail.com 
    page.mainFrame()->load(QUrl("https://www.gmail.com")); // line B2 

    QObject::connect(page.networkAccessManager(), SIGNAL(finished(QNetworkReply*)), &handler, SLOT(slotFinished(QNetworkReply*))); 
    QObject::connect(page.networkAccessManager(), SIGNAL(sslErrors(QNetworkReply*,QList<QSslError>)), &handler, SLOT(slotSslErrors(QNetworkReply*,QList<QSslError>))); 
    QObject::connect(&page, SIGNAL(loadFinished(bool)), &handler, SLOT(slotLoadFinished(bool))); 

    return app.exec(); 
} 

#include "main.moc" 
+0

Я использовал корневые сертификаты властей, у которых есть проблемы с сертификатами gmail. и включен в мой корневой магазин сертификатов. каким-то образом я могу подключиться к https://www.google.com, но https://gmail.com дает ошибки ssl. так будет ли это проблемой, связанной с корневым сертификатом? – Ashish

+1

@Ashish См. Новую версию моего ответа. –

+1

@Ashish В моем ответе чего-то не хватает? –