diff options
author | MÃ¥rten Nordheim <marten.nordheim@qt.io> | 2018-03-22 16:45:04 +0100 |
---|---|---|
committer | Timur Pocheptsov <timur.pocheptsov@qt.io> | 2018-03-23 18:14:59 +0000 |
commit | a7dda3e4b033f5ea48f1d0c24cf9b24c77ab7670 (patch) | |
tree | c82afc81d15318fa690bc822b60016b6e440ccfa /src/network/ssl/qsslsocket_openssl.cpp | |
parent | 89bf58b070ae9d5ef282ff205b7025ed0d453e38 (diff) |
Move QWindowsCaRootFetcher to its own file
In preparation for its usage in QDtls.
Change-Id: I7b28ac060e350228839461dc027c809af9ff73a4
Reviewed-by: Timur Pocheptsov <timur.pocheptsov@qt.io>
Diffstat (limited to 'src/network/ssl/qsslsocket_openssl.cpp')
-rw-r--r-- | src/network/ssl/qsslsocket_openssl.cpp | 117 |
1 files changed, 4 insertions, 113 deletions
diff --git a/src/network/ssl/qsslsocket_openssl.cpp b/src/network/ssl/qsslsocket_openssl.cpp index 396fe5e148..e269a1f8ea 100644 --- a/src/network/ssl/qsslsocket_openssl.cpp +++ b/src/network/ssl/qsslsocket_openssl.cpp @@ -66,6 +66,10 @@ #include "qsslpresharedkeyauthenticator.h" #include "qsslpresharedkeyauthenticator_p.h" +#ifdef Q_OS_WIN +#include "qwindowscarootfetcher_p.h" +#endif + #include <QtCore/qdatetime.h> #include <QtCore/qdebug.h> #include <QtCore/qdir.h> @@ -1173,119 +1177,6 @@ void QSslSocketBackendPrivate::_q_caRootLoaded(QSslCertificate cert, QSslCertifi } } -class QWindowsCaRootFetcherThread : public QThread -{ -public: - QWindowsCaRootFetcherThread() - { - qRegisterMetaType<QSslCertificate>(); - setObjectName(QStringLiteral("QWindowsCaRootFetcher")); - start(); - } - ~QWindowsCaRootFetcherThread() - { - quit(); - wait(15500); // worst case, a running request can block for 15 seconds - } -}; - -Q_GLOBAL_STATIC(QWindowsCaRootFetcherThread, windowsCaRootFetcherThread); - -QWindowsCaRootFetcher::QWindowsCaRootFetcher(const QSslCertificate &certificate, QSslSocket::SslMode sslMode) - : cert(certificate), mode(sslMode) -{ - moveToThread(windowsCaRootFetcherThread()); -} - -QWindowsCaRootFetcher::~QWindowsCaRootFetcher() -{ -} - -void QWindowsCaRootFetcher::start() -{ - QByteArray der = cert.toDer(); - PCCERT_CONTEXT wincert = CertCreateCertificateContext(X509_ASN_ENCODING, (const BYTE *)der.constData(), der.length()); - if (!wincert) { -#ifdef QSSLSOCKET_DEBUG - qCDebug(lcSsl, "QWindowsCaRootFetcher failed to convert certificate to windows form"); -#endif - emit finished(cert, QSslCertificate()); - deleteLater(); - return; - } - - CERT_CHAIN_PARA parameters; - memset(¶meters, 0, sizeof(parameters)); - parameters.cbSize = sizeof(parameters); - // set key usage constraint - parameters.RequestedUsage.dwType = USAGE_MATCH_TYPE_AND; - parameters.RequestedUsage.Usage.cUsageIdentifier = 1; - LPSTR oid = (LPSTR)(mode == QSslSocket::SslClientMode ? szOID_PKIX_KP_SERVER_AUTH : szOID_PKIX_KP_CLIENT_AUTH); - parameters.RequestedUsage.Usage.rgpszUsageIdentifier = &oid; - -#ifdef QSSLSOCKET_DEBUG - QElapsedTimer stopwatch; - stopwatch.start(); -#endif - PCCERT_CHAIN_CONTEXT chain; - BOOL result = CertGetCertificateChain( - 0, //default engine - wincert, - 0, //current date/time - 0, //default store - ¶meters, - 0, //default dwFlags - 0, //reserved - &chain); -#ifdef QSSLSOCKET_DEBUG - qCDebug(lcSsl) << "QWindowsCaRootFetcher" << stopwatch.elapsed() << "ms to get chain"; -#endif - - QSslCertificate trustedRoot; - if (result) { -#ifdef QSSLSOCKET_DEBUG - qCDebug(lcSsl) << "QWindowsCaRootFetcher - examining windows chains"; - if (chain->TrustStatus.dwErrorStatus == CERT_TRUST_NO_ERROR) - qCDebug(lcSsl) << " - TRUSTED"; - else - qCDebug(lcSsl) << " - NOT TRUSTED" << chain->TrustStatus.dwErrorStatus; - if (chain->TrustStatus.dwInfoStatus & CERT_TRUST_IS_SELF_SIGNED) - qCDebug(lcSsl) << " - SELF SIGNED"; - qCDebug(lcSsl) << "QSslSocketBackendPrivate::fetchCaRootForCert - dumping simple chains"; - for (unsigned int i = 0; i < chain->cChain; i++) { - if (chain->rgpChain[i]->TrustStatus.dwErrorStatus == CERT_TRUST_NO_ERROR) - qCDebug(lcSsl) << " - TRUSTED SIMPLE CHAIN" << i; - else - qCDebug(lcSsl) << " - UNTRUSTED SIMPLE CHAIN" << i << "reason:" << chain->rgpChain[i]->TrustStatus.dwErrorStatus; - for (unsigned int j = 0; j < chain->rgpChain[i]->cElement; j++) { - QSslCertificate foundCert(QByteArray((const char *)chain->rgpChain[i]->rgpElement[j]->pCertContext->pbCertEncoded - , chain->rgpChain[i]->rgpElement[j]->pCertContext->cbCertEncoded), QSsl::Der); - qCDebug(lcSsl) << " - " << foundCert; - } - } - qCDebug(lcSsl) << " - and" << chain->cLowerQualityChainContext << "low quality chains"; //expect 0, we haven't asked for them -#endif - - //based on http://msdn.microsoft.com/en-us/library/windows/desktop/aa377182%28v=vs.85%29.aspx - //about the final chain rgpChain[cChain-1] which must begin with a trusted root to be valid - if (chain->TrustStatus.dwErrorStatus == CERT_TRUST_NO_ERROR - && chain->cChain > 0) { - const PCERT_SIMPLE_CHAIN finalChain = chain->rgpChain[chain->cChain - 1]; - // http://msdn.microsoft.com/en-us/library/windows/desktop/aa377544%28v=vs.85%29.aspx - // rgpElement[0] is the end certificate chain element. rgpElement[cElement-1] is the self-signed "root" certificate element. - if (finalChain->TrustStatus.dwErrorStatus == CERT_TRUST_NO_ERROR - && finalChain->cElement > 0) { - trustedRoot = QSslCertificate(QByteArray((const char *)finalChain->rgpElement[finalChain->cElement - 1]->pCertContext->pbCertEncoded - , finalChain->rgpElement[finalChain->cElement - 1]->pCertContext->cbCertEncoded), QSsl::Der); - } - } - CertFreeCertificateChain(chain); - } - CertFreeCertificateContext(wincert); - - emit finished(cert, trustedRoot); - deleteLater(); -} #endif void QSslSocketBackendPrivate::disconnectFromHost() |