96 const QList<QSslCertificate> &caCertificates,
const QString &hostName)
97 : cert(certificate), mode(sslMode), explicitlyTrustedCAs(caCertificates), peerVerifyName(hostName)
99 moveToThread(windowsCaRootFetcherThread());
108 QByteArray der = cert.toDer();
109 PCCERT_CONTEXT wincert = CertCreateCertificateContext(X509_ASN_ENCODING, (
const BYTE *)der.constData(), der.length());
111#ifdef QSSLSOCKET_DEBUG
112 qCDebug(lcTlsBackend,
"QWindowsCaRootFetcher failed to convert certificate to windows form");
114 emit finished(cert, QSslCertificate());
119 CERT_CHAIN_PARA parameters;
120 memset(¶meters, 0,
sizeof(parameters));
121 parameters.cbSize =
sizeof(parameters);
123 parameters.RequestedUsage.dwType = USAGE_MATCH_TYPE_AND;
124 parameters.RequestedUsage.Usage.cUsageIdentifier = 1;
125 LPSTR oid = (LPSTR)(mode == QSslSocket::SslClientMode ? szOID_PKIX_KP_SERVER_AUTH : szOID_PKIX_KP_CLIENT_AUTH);
126 parameters.RequestedUsage.Usage.rgpszUsageIdentifier = &oid;
128#ifdef QSSLSOCKET_DEBUG
129 QElapsedTimer stopwatch;
132 PCCERT_CHAIN_CONTEXT chain;
133 auto additionalStore = createAdditionalStore();
134 BOOL result = CertGetCertificateChain(
138 additionalStore.get(),
143#ifdef QSSLSOCKET_DEBUG
144 qCDebug(lcSsl) <<
"QWindowsCaRootFetcher" << stopwatch.elapsed() <<
"ms to get chain";
147 QSslCertificate trustedRoot;
149#ifdef QSSLSOCKET_DEBUG
150 qCDebug(lcSsl) <<
"QWindowsCaRootFetcher - examining windows chains";
151 if (chain->TrustStatus.dwErrorStatus == CERT_TRUST_NO_ERROR)
152 qCDebug(lcSsl) <<
" - TRUSTED";
154 qCDebug(lcSsl) <<
" - NOT TRUSTED" << chain->TrustStatus.dwErrorStatus;
155 if (chain->TrustStatus.dwInfoStatus & CERT_TRUST_IS_SELF_SIGNED)
156 qCDebug(lcSsl) <<
" - SELF SIGNED";
157 qCDebug(lcSsl) <<
"QWindowsCaRootFetcher - dumping simple chains";
158 for (
unsigned int i = 0; i < chain->cChain; i++) {
159 if (chain->rgpChain[i]->TrustStatus.dwErrorStatus == CERT_TRUST_NO_ERROR)
160 qCDebug(lcSsl) <<
" - TRUSTED SIMPLE CHAIN" << i;
162 qCDebug(lcSsl) <<
" - UNTRUSTED SIMPLE CHAIN" << i <<
"reason:" << chain->rgpChain[i]->TrustStatus.dwErrorStatus;
163 for (
unsigned int j = 0; j < chain->rgpChain[i]->cElement; j++) {
164 QSslCertificate foundCert(QByteArray((
const char *)chain->rgpChain[i]->rgpElement[j]->pCertContext->pbCertEncoded
165 , chain->rgpChain[i]->rgpElement[j]->pCertContext->cbCertEncoded), QSsl::Der);
166 qCDebug(lcSsl) <<
" - " << foundCert;
169 qCDebug(lcSsl) <<
" - and" << chain->cLowerQualityChainContext <<
"low quality chains";
174 if (chain->TrustStatus.dwErrorStatus == CERT_TRUST_NO_ERROR
175 && chain->cChain > 0) {
176 const PCERT_SIMPLE_CHAIN finalChain = chain->rgpChain[chain->cChain - 1];
179 if (finalChain->TrustStatus.dwErrorStatus == CERT_TRUST_NO_ERROR
180 && finalChain->cElement > 0) {
181 trustedRoot = QSslCertificate(QByteArray((
const char *)finalChain->rgpElement[finalChain->cElement - 1]->pCertContext->pbCertEncoded
182 , finalChain->rgpElement[finalChain->cElement - 1]->pCertContext->cbCertEncoded), QSsl::Der);
184 }
else if (explicitlyTrustedCAs.size()) {
186#if QT_CONFIG(openssl)
187 const auto verifiedChain = buildVerifiedChain(explicitlyTrustedCAs, chain, peerVerifyName);
188 if (verifiedChain.size())
189 trustedRoot = verifiedChain.last();
195 CertFreeCertificateChain(chain);
197 CertFreeCertificateContext(wincert);
199 emit finished(cert, trustedRoot);
209 if (HCERTSTORE rawPtr = CertOpenStore(CERT_STORE_PROV_MEMORY, 0, 0, 0,
nullptr)) {