¿Problema al hacer un almacén de certificados raíz personalizados para SSL usando QT?

StackOverflow https://stackoverflow.com/questions/4831739

  •  27-10-2019
  •  | 
  •  

Pregunta

Estoy desarrollando mi navegador personalizado en QT usando Qwebview y estoy tratando de hacer mi propia tienda de certificados de confianza de Root Cert que se toman del Proyecto Mozilla.

He usado qsslsocket :: setDefaultCacertificates () para anular los certificados predeterminados. Pero no puedo cargar https://www.gmail.com , donde en Mozilla funciona.

He establecido todos los certificados raíz requeridos para Gmail en mi tienda.

¿Alguien puede guiarme?

¿Fue útil?

Solución

La razón por la que no puede conectarse es porque el certificado SSL (con serial 2F:DF:BC:F6:AE:91:52:6D:0F:9A:A3:DF:40:34:3E:9A) se le presentó cuando se conecta a www.gmail.com se emite para un dominio diferente: www.google.com. Esto no tiene nada que ver con la tienda de certificados Root CA porque no se necesita un certificado de CA root para comparar el campo CN de sujeto de CERT con el host al que está intentando conectarse. Puede ignorar este y otros errores SSL llamando
void QNetworkReply::ignoreSslErrors () [virtual slot]
Para evitar este error, puede conectarse directamente https://mail.google.com ¿Cuál es el dominio al que te están redirigiendo cuando intentas conectarte https://www.gmail.com

A continuación se muestra un ejemplo de trabajo que le mostrará los errores SSL exactos y los errores de nivel QNAM. Ya sea la línea B1 o la línea B2, deben estar activas al mismo tiempo. Puede comentar la línea A si desea ver qué sucede con el almacén de certificado Root CA predeterminado (sistema). Hay dos certs utilizados por este código; CERTO DE CA CON SERIE 30:00:00:02 debe colocarse en un archivo llamado ThawteSGCCA.crt y el certificado de CA con serie 70:BA:E4:1D:10:D9:29:34:B6:38:CA:7B:03:CC:BA:BF debe colocarse en un archivo llamado 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"
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top