проблема в создании пользовательского хранилища корневых сертификатов для SSL с использованием QT?

Я разрабатываю свой собственный браузер в Qt, используя QWebView, и я пытаюсь создать собственное хранилище корневых сертификатов доверенных сертификатов, взятых из проекта Mozilla.

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

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

может ли кто-нибудь направить меня?


person Ashish    schedule 28.01.2011    source источник


Ответы (1)


Причина, по которой вы не можете подключиться, заключается в том, что сертификат 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 сертификата с хостом, к которому вы пытаетесь подключиться, не требуется сертификат корневого ЦС. Вы можете игнорировать эту и другие ошибки SSL, вызвав
void QNetworkReply::ignoreSslErrors () [virtual slot]
Чтобы избежать этой ошибки, вы можете напрямую подключиться к https://mail.google.com, который является домен, на который вы перенаправляетесь при попытке подключения к https://www.gmail.com

Ниже приведен рабочий пример, который покажет вам точные ошибки SSL и ошибки уровня QNAM. Либо линия B1, либо линия B2 должны быть активны одновременно. Вы можете прокомментировать строку A, если хотите увидеть, что происходит с хранилищем сертификатов корневого ЦС по умолчанию (системным). В этом коде используются два сертификата; Сертификат ЦС с серийным номером 30:00:00:02 следует поместить в файл с именем ThawteSGCCA.crt, а сертификат ЦС с серийным номером 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"
person Piotr Dobrogost    schedule 18.02.2011
comment
Я использовал корневые сертификаты органов власти, которые выдают сертификаты для Gmail. и включен в мой магазин корневых сертификатов. каким-то образом я могу подключиться к google.com, но gmail.com выдает ошибки SSL. так будет ли это проблема, связанная с корневым сертификатом ?? - person Ashish; 19.02.2011
comment
@Ashish Смотрите новую версию моего ответа. - person Piotr Dobrogost; 20.02.2011
comment
@Ashish В моем ответе чего-то не хватает? - person Piotr Dobrogost; 22.02.2011
comment
Итак, каков обходной путь такой проблемы (документ перемещен) и как именно Mozilla это делает? - person Ashish; 22.02.2011
comment
@Ashish Документ перемещен, и другие перенаправления HTTP (коды состояния HTTP 3xx) обрабатываются для вас QNetworkAccessManger, используемым QtWebKit (QWebPage, QWebFrame). QNAM следует всем этим редиректам, и вы получаете содержимое последней страницы. - person Piotr Dobrogost; 22.02.2011
comment
Это по умолчанию с QNAM? Если да, то почему QNAM не может получить содержимое перенаправленной страницы? - person Ashish; 23.02.2011
comment
@Ashish Да, это по умолчанию. Я не могу понять, по какой причине QNAM не может получить страницу; запустите мой код и опубликуйте вывод в какой-нибудь pastebin. - person Piotr Dobrogost; 23.02.2011
comment
Если я игнорирую ошибки SSL, то только тогда это работает. например ответить-›игнорироватьSslErrors(); в слоте slotSslErrors. - person Ashish; 23.02.2011