summaryrefslogtreecommitdiffstats
path: root/src/network/ssl/qsslsocket_winrt.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/network/ssl/qsslsocket_winrt.cpp')
-rw-r--r--src/network/ssl/qsslsocket_winrt.cpp682
1 files changed, 0 insertions, 682 deletions
diff --git a/src/network/ssl/qsslsocket_winrt.cpp b/src/network/ssl/qsslsocket_winrt.cpp
deleted file mode 100644
index 5f5201fc82..0000000000
--- a/src/network/ssl/qsslsocket_winrt.cpp
+++ /dev/null
@@ -1,682 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtNetwork module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include "qssl_p.h"
-#include "qsslsocket_winrt_p.h"
-#include "qsslsocket.h"
-#include "qsslcertificate_p.h"
-#include "qsslcipher_p.h"
-
-#include <QtCore/QCoreApplication>
-#include <QtCore/QSysInfo>
-#include <QtCore/qfunctions_winrt.h>
-#include <private/qnativesocketengine_winrt_p.h>
-#include <private/qeventdispatcher_winrt_p.h>
-
-#include <windows.networking.h>
-#include <windows.networking.sockets.h>
-#include <windows.security.cryptography.certificates.h>
-#include <robuffer.h>
-
-using namespace Microsoft::WRL;
-using namespace Microsoft::WRL::Wrappers;
-using namespace ABI::Windows::Foundation;
-using namespace ABI::Windows::Foundation::Collections;
-using namespace ABI::Windows::Networking;
-using namespace ABI::Windows::Networking::Sockets;
-using namespace ABI::Windows::Security::Cryptography::Certificates;
-using namespace ABI::Windows::Storage::Streams;
-
-QT_BEGIN_NAMESPACE
-
-bool QSslSocketPrivate::s_libraryLoaded = true;
-bool QSslSocketPrivate::s_loadRootCertsOnDemand = true;
-bool QSslSocketPrivate::s_loadedCiphersAndCerts = false;
-
-struct SslSocketGlobal
-{
- SslSocketGlobal()
- {
- HRESULT hr;
- hr = GetActivationFactory(HString::MakeReference(RuntimeClass_Windows_Networking_HostName).Get(),
- &hostNameFactory);
- Q_ASSERT_SUCCEEDED(hr);
-
- ComPtr<ICertificateStoresStatics> certificateStores;
- hr = GetActivationFactory(HString::MakeReference(RuntimeClass_Windows_Security_Cryptography_Certificates_CertificateStores).Get(),
- &certificateStores);
- Q_ASSERT_SUCCEEDED(hr);
-
- hr = certificateStores->get_TrustedRootCertificationAuthorities(&rootStore);
- Q_ASSERT_SUCCEEDED(hr);
-
- ComPtr<IAsyncOperation<IVectorView<Certificate *> *>> op;
- hr = certificateStores->FindAllAsync(&op);
- Q_ASSERT_SUCCEEDED(hr);
- ComPtr<IVectorView<Certificate *>> certificates;
- hr = QWinRTFunctions::await(op, certificates.GetAddressOf());
- Q_ASSERT_SUCCEEDED(hr);
- quint32 size;
- hr = certificates->get_Size(&size);
- Q_ASSERT_SUCCEEDED(hr);
- for (quint32 i = 0; i < size; ++i) {
- ComPtr<ICertificate> certificate;
- hr = certificates->GetAt(i, &certificate);
- Q_ASSERT_SUCCEEDED(hr);
- systemCaCertificates.append(QSslCertificatePrivate::QSslCertificate_from_Certificate(certificate.Get()));
- }
- }
-
- void syncCaCertificates(const QSet<QSslCertificate> &add, const QSet<QSslCertificate> &remove)
- {
- QMutexLocker locker(&certificateMutex);
- for (const QSslCertificate &certificate : add) {
- QHash<QSslCertificate, QAtomicInt>::iterator it = additionalCertificates.find(certificate);
- if (it != additionalCertificates.end()) {
- it.value().ref(); // Add a reference
- } else {
- // install certificate
- HRESULT hr;
- hr = rootStore->Add(static_cast<ICertificate *>(certificate.handle()));
- Q_ASSERT_SUCCEEDED(hr);
- additionalCertificates.insert(certificate, 1);
- }
- }
- for (const QSslCertificate &certificate : remove) {
- QHash<QSslCertificate, QAtomicInt>::iterator it = additionalCertificates.find(certificate);
- if (it != additionalCertificates.end() && !it.value().deref()) {
- // no more references, remove certificate
- HRESULT hr;
- hr = rootStore->Delete(static_cast<ICertificate *>(certificate.handle()));
- Q_ASSERT_SUCCEEDED(hr);
- additionalCertificates.erase(it);
- }
- }
- }
-
- ComPtr<IHostNameFactory> hostNameFactory;
- QList<QSslCertificate> systemCaCertificates;
-
-private:
- QMutex certificateMutex;
- ComPtr<ICertificateStore> rootStore;
- QHash<QSslCertificate, QAtomicInt> additionalCertificates;
-};
-Q_GLOBAL_STATIC(SslSocketGlobal, g)
-
-// Called on the socket's thread to avoid cross-thread deletion
-void QSslSocketConnectionHelper::disconnectSocketFromHost()
-{
- if (d->plainSocket)
- d->plainSocket->disconnectFromHost();
-}
-
-QSslSocketBackendPrivate::QSslSocketBackendPrivate()
- : connectionHelper(new QSslSocketConnectionHelper(this))
-{
-}
-
-QSslSocketBackendPrivate::~QSslSocketBackendPrivate()
-{
- g->syncCaCertificates(QSet<QSslCertificate>(), previousCaCertificates);
-}
-
-bool QSslSocketPrivate::supportsSsl()
-{
- return true;
-}
-
-void QSslSocketPrivate::ensureInitialized()
-{
- if (s_loadedCiphersAndCerts)
- return;
- s_loadedCiphersAndCerts = true;
- resetDefaultCiphers();
-}
-
-long QSslSocketPrivate::sslLibraryVersionNumber()
-{
- // ### Qt 6: Find a proper replacement for the deprecated method below.
- return QSysInfo::windowsVersion();
-}
-
-QString QSslSocketPrivate::sslLibraryVersionString()
-{
- return QStringLiteral("Windows Runtime, ") + QSysInfo::prettyProductName();
-}
-
-long QSslSocketPrivate::sslLibraryBuildVersionNumber()
-{
- Q_UNIMPLEMENTED();
- return 0;
-}
-
-QString QSslSocketPrivate::sslLibraryBuildVersionString()
-{
- Q_UNIMPLEMENTED();
- return QString::number(sslLibraryBuildVersionNumber());
-}
-
-void QSslSocketPrivate::resetDefaultCiphers()
-{
- setDefaultSupportedCiphers(QSslSocketBackendPrivate::defaultCiphers());
- setDefaultCiphers(QSslSocketBackendPrivate::defaultCiphers());
-}
-
-
-QList<QSslCipher> QSslSocketBackendPrivate::defaultCiphers()
-{
- QList<QSslCipher> ciphers;
- const QString protocolStrings[] = { QStringLiteral("TLSv1"),
- QStringLiteral("TLSv1.1"), QStringLiteral("TLSv1.2") };
- const QSsl::SslProtocol protocols[] = { QSsl::TlsV1_0, QSsl::TlsV1_1, QSsl::TlsV1_2 };
- const int size = static_cast<int>(ARRAYSIZE(protocols));
- ciphers.reserve(size);
- for (int i = 0; i < size; ++i) {
- QSslCipher cipher;
- cipher.d->isNull = false;
- cipher.d->name = QStringLiteral("WINRT");
- cipher.d->protocol = protocols[i];
- cipher.d->protocolString = protocolStrings[i];
- ciphers.append(cipher);
- }
- return ciphers;
-}
-
-QList<QSslCertificate> QSslSocketPrivate::systemCaCertificates()
-{
- return g->systemCaCertificates;
-}
-
-void QSslSocketBackendPrivate::startClientEncryption()
-{
- Q_Q(QSslSocket);
-
- QSsl::SslProtocol protocol = q->protocol();
- switch (q->protocol()) {
- case QSsl::AnyProtocol:
- protectionLevel = SocketProtectionLevel_Tls10;
- break;
- case QSsl::TlsV1_0:
- protectionLevel = SocketProtectionLevel_Tls10;
- break;
- case QSsl::TlsV1_1:
- protectionLevel = SocketProtectionLevel_Tls11;
- break;
- case QSsl::TlsV1_2:
- protectionLevel = SocketProtectionLevel_Tls12;
- break;
- case QSsl::TlsV1_0OrLater:
- case QSsl::TlsV1_1OrLater:
- case QSsl::TlsV1_2OrLater:
- case QSsl::TlsV1_3:
- case QSsl::TlsV1_3OrLater:
- // TlsV1_0OrLater, TlsV1_1OrLater and TlsV1_2OrLater are disabled on WinRT
- // because there is no good way to map them to the native API.
- setErrorAndEmit(QAbstractSocket::SslInvalidUserDataError,
- QStringLiteral("unsupported protocol"));
- return;
- case QSsl::SecureProtocols:
- // SocketProtectionLevel_Tls12 actually means "use TLS1.0, 1.1 or 1.2"
- // https://docs.microsoft.com/en-us/uwp/api/windows.networking.sockets.socketprotectionlevel
- protectionLevel = SocketProtectionLevel_Tls12;
- break;
- default:
- protectionLevel = SocketProtectionLevel_Tls12; // default to highest
- protocol = QSsl::TlsV1_2;
- break;
- }
-
- // Sync custom certificates
- const QSet<QSslCertificate> caCertificates(configuration.caCertificates.constBegin(), configuration.caCertificates.constEnd());
- const QSet<QSslCertificate> newCertificates = caCertificates - previousCaCertificates;
- const QSet<QSslCertificate> oldCertificates = previousCaCertificates - caCertificates;
- g->syncCaCertificates(newCertificates, oldCertificates);
- previousCaCertificates = caCertificates;
-
- continueHandshake();
-}
-
-void QSslSocketBackendPrivate::startServerEncryption()
-{
- Q_UNIMPLEMENTED();
-}
-
-void QSslSocketBackendPrivate::transmit()
-{
- Q_Q(QSslSocket);
-
- if (connectionEncrypted && !writeBuffer.isEmpty()) {
- qint64 totalBytesWritten = 0;
- int nextDataBlockSize;
- while ((nextDataBlockSize = writeBuffer.nextDataBlockSize()) > 0) {
- int writtenBytes = plainSocket->write(writeBuffer.readPointer(), nextDataBlockSize);
- writtenBytes = nextDataBlockSize;
-
- writeBuffer.free(writtenBytes);
- totalBytesWritten += writtenBytes;
-
- if (writtenBytes < nextDataBlockSize)
- break;
- }
-
- if (totalBytesWritten > 0) {
- // Don't emit bytesWritten() recursively.
- if (!emittedBytesWritten) {
- emittedBytesWritten = true;
- emit q->bytesWritten(totalBytesWritten);
- emittedBytesWritten = false;
- }
- emit q->channelBytesWritten(0, totalBytesWritten);
- }
- }
-
- // Check if we've got any data to be read from the socket.
- int pendingBytes;
- bool bytesRead = false;
- while ((pendingBytes = plainSocket->bytesAvailable()) > 0) {
- char *ptr = buffer.reserve(pendingBytes);
- int readBytes = plainSocket->read(ptr, pendingBytes);
- buffer.chop(pendingBytes - readBytes);
- bytesRead = true;
- }
-
- if (bytesRead) {
- if (readyReadEmittedPointer)
- *readyReadEmittedPointer = true;
- emit q->readyRead();
- emit q->channelReadyRead(0);
- }
-
- if (pendingClose) {
- pendingClose = false;
- q->disconnectFromHost();
- }
-}
-
-void QSslSocketBackendPrivate::disconnectFromHost()
-{
- QMetaObject::invokeMethod(connectionHelper.data(), "disconnectSocketFromHost", Qt::QueuedConnection);
-}
-
-void QSslSocketBackendPrivate::disconnected()
-{
-}
-
-QSslCipher QSslSocketBackendPrivate::sessionCipher() const
-{
- return configuration.sessionCipher;
-}
-
-QSsl::SslProtocol QSslSocketBackendPrivate::sessionProtocol() const
-{
- return configuration.sessionCipher.protocol();
-}
-
-void QSslSocketBackendPrivate::continueHandshake()
-{
- IStreamSocket *socket = reinterpret_cast<IStreamSocket *>(plainSocket->socketDescriptor());
- if (qintptr(socket) == -1) {
- setErrorAndEmit(QAbstractSocket::SslInternalError,
- QStringLiteral("At attempt was made to continue the handshake on an invalid socket."));
- return;
- }
-
- HRESULT hr;
- ComPtr<IHostName> hostName;
- const QString host = verificationPeerName.isEmpty() ? plainSocket->peerName()
- : verificationPeerName;
- if (host.isEmpty()) {
- ComPtr<IStreamSocketInformation> info;
- hr = socket->get_Information(&info);
- Q_ASSERT_SUCCEEDED(hr);
- hr = info->get_RemoteAddress(&hostName);
- } else {
- HStringReference hostRef(reinterpret_cast<LPCWSTR>(host.utf16()), host.length());
- hr = g->hostNameFactory->CreateHostName(hostRef.Get(), &hostName);
- Q_ASSERT_SUCCEEDED(hr);
- }
- if (FAILED(hr)) {
- setErrorAndEmit(QAbstractSocket::SslInvalidUserDataError, qt_error_string(hr));
- return;
- }
-
- ComPtr<IStreamSocketControl> control;
- hr = socket->get_Control(&control);
- Q_ASSERT_SUCCEEDED(hr);
-
- ComPtr<IStreamSocketControl2> control2;
- hr = control.As(&control2);
- ComPtr<IVector<ChainValidationResult>> ignoreList;
- hr = control2->get_IgnorableServerCertificateErrors(&ignoreList);
- Q_ASSERT_SUCCEEDED(hr);
-
- QSet<QSslError> ignoreErrors(ignoreErrorsList.constBegin(), ignoreErrorsList.constEnd());
- for (int i = ChainValidationResult_Untrusted; i < ChainValidationResult_OtherErrors + 1; ++i) {
- // Populate the native ignore list - break to add, continue to skip
- switch (i) {
- case ChainValidationResult_Revoked:
- case ChainValidationResult_InvalidSignature:
- case ChainValidationResult_BasicConstraintsError:
- case ChainValidationResult_InvalidCertificateAuthorityPolicy:
- case ChainValidationResult_UnknownCriticalExtension:
- case ChainValidationResult_OtherErrors:
- continue; // The above errors can't be ignored in the handshake
- case ChainValidationResult_Untrusted:
- if (ignoreAllSslErrors || ignoreErrors.contains(QSslError::CertificateUntrusted))
- break;
- continue;
- case ChainValidationResult_Expired:
- if (ignoreAllSslErrors || ignoreErrors.contains(QSslError::CertificateExpired))
- break;
- continue;
- case ChainValidationResult_IncompleteChain:
- if (ignoreAllSslErrors
- || ignoreErrors.contains(QSslError::InvalidCaCertificate)
- || ignoreErrors.contains(QSslError::UnableToVerifyFirstCertificate)
- || ignoreErrors.contains(QSslError::UnableToGetIssuerCertificate)) {
- break;
- }
- continue;
- case ChainValidationResult_WrongUsage:
- if (ignoreAllSslErrors || ignoreErrors.contains(QSslError::InvalidPurpose))
- break;
- continue;
- case ChainValidationResult_InvalidName:
- if (ignoreAllSslErrors
- || ignoreErrors.contains(QSslError::HostNameMismatch)
- || ignoreErrors.contains(QSslError::SubjectIssuerMismatch)) {
- break;
- }
- continue;
- case ChainValidationResult_RevocationInformationMissing:
- case ChainValidationResult_RevocationFailure:
- default:
- if (ignoreAllSslErrors)
- break;
- continue;
- }
- hr = ignoreList->Append(static_cast<ChainValidationResult>(i));
- Q_ASSERT_SUCCEEDED(hr);
- }
-
- ComPtr<IAsyncAction> op;
- hr = socket->UpgradeToSslAsync(protectionLevel, hostName.Get(), &op);
- if (FAILED(hr)) {
- setErrorAndEmit(QAbstractSocket::SslInternalError,
- QSslSocket::tr("Error creating SSL session: %1").arg(qt_error_string(hr)));
- return;
- }
-
- hr = QEventDispatcherWinRT::runOnXamlThread([this, op]() {
- HRESULT hr = op->put_Completed(Callback<IAsyncActionCompletedHandler>(
- this, &QSslSocketBackendPrivate::onSslUpgrade).Get());
- return hr;
- });
- Q_ASSERT_SUCCEEDED(hr);
-}
-
-HRESULT QSslSocketBackendPrivate::onSslUpgrade(IAsyncAction *action, AsyncStatus)
-{
- Q_Q(QSslSocket);
-
- if (wasDeleted) {
- qCWarning(lcSsl,
- "SSL upgrade callback received after the delegate was deleted. "
- "This may be indicative of an internal bug in the WinRT SSL implementation.");
- return S_OK;
- }
-
- HRESULT hr = action->GetResults();
- QSet<QSslError> errors;
- switch (hr) {
- case SEC_E_INVALID_TOKEN: // Occurs when the server doesn't support the requested protocol
- setErrorAndEmit(QAbstractSocket::SslHandshakeFailedError, qt_error_string(hr));
- q->disconnectFromHost();
- return S_OK;
- default:
- if (FAILED(hr))
- qErrnoWarning(hr, "error"); // Unhandled error; let sslErrors take care of it
- break;
- }
-
- IStreamSocket *socket = reinterpret_cast<IStreamSocket *>(plainSocket->socketDescriptor());
- if (qintptr(socket) == -1) {
- qCWarning(lcSsl,
- "The underlying TCP socket used by the SSL socket is invalid. "
- "This may be indicative of an internal bug in the WinRT SSL implementation.");
- return S_OK;
- }
-
- ComPtr<IStreamSocketInformation> info;
- hr = socket->get_Information(&info);
- Q_ASSERT_SUCCEEDED(hr);
- ComPtr<IStreamSocketInformation2> info2;
- hr = info.As(&info2);
- Q_ASSERT_SUCCEEDED(hr);
-
- // Cipher
- QSsl::SslProtocol protocol;
- SocketProtectionLevel protectionLevel;
- hr = info->get_ProtectionLevel(&protectionLevel);
- switch (protectionLevel) {
- default:
- protocol = QSsl::UnknownProtocol;
- break;
- case SocketProtectionLevel_Ssl:
- protocol = QSsl::SslV3;
- break;
- case SocketProtectionLevel_Tls10:
- protocol = QSsl::TlsV1_0;
- break;
- case SocketProtectionLevel_Tls11:
- protocol = QSsl::TlsV1_1;
- break;
- case SocketProtectionLevel_Tls12:
- protocol = QSsl::TlsV1_2;
- break;
- }
- configuration.sessionCipher = QSslCipher(QStringLiteral("WINRT"), protocol); // The actual cipher name is not accessible
-
- // Certificate & chain
- ComPtr<ICertificate> certificate;
- hr = info2->get_ServerCertificate(&certificate);
- Q_ASSERT_SUCCEEDED(hr);
-
- QList<QSslCertificate> peerCertificateChain;
- if (certificate) {
- ComPtr<IAsyncOperation<CertificateChain *>> op;
- hr = certificate->BuildChainAsync(nullptr, &op);
- Q_ASSERT_SUCCEEDED(hr);
- ComPtr<ICertificateChain> certificateChain;
- hr = QWinRTFunctions::await(op, certificateChain.GetAddressOf());
- Q_ASSERT_SUCCEEDED(hr);
-
- ComPtr<IVectorView<Certificate *>> certificates;
- hr = certificateChain->GetCertificates(true, &certificates);
- Q_ASSERT_SUCCEEDED(hr);
- quint32 certificatesLength;
- hr = certificates->get_Size(&certificatesLength);
- Q_ASSERT_SUCCEEDED(hr);
- for (quint32 i = 0; i < certificatesLength; ++i) {
- ComPtr<ICertificate> chainCertificate;
- hr = certificates->GetAt(i, &chainCertificate);
- Q_ASSERT_SUCCEEDED(hr);
- peerCertificateChain.append(QSslCertificatePrivate::QSslCertificate_from_Certificate(chainCertificate.Get()));
- }
- }
-
- configuration.peerCertificate = certificate ? QSslCertificatePrivate::QSslCertificate_from_Certificate(certificate.Get())
- : QSslCertificate();
- configuration.peerCertificateChain = peerCertificateChain;
-
- // Errors
- ComPtr<IVectorView<ChainValidationResult>> chainValidationResults;
- hr = info2->get_ServerCertificateErrors(&chainValidationResults);
- Q_ASSERT_SUCCEEDED(hr);
- quint32 size;
- hr = chainValidationResults->get_Size(&size);
- Q_ASSERT_SUCCEEDED(hr);
- for (quint32 i = 0; i < size; ++i) {
- ChainValidationResult result;
- hr = chainValidationResults->GetAt(i, &result);
- Q_ASSERT_SUCCEEDED(hr);
- switch (result) {
- case ChainValidationResult_Success:
- break;
- case ChainValidationResult_Untrusted:
- errors.insert(QSslError::CertificateUntrusted);
- break;
- case ChainValidationResult_Revoked:
- errors.insert(QSslError::CertificateRevoked);
- break;
- case ChainValidationResult_Expired:
- errors.insert(QSslError::CertificateExpired);
- break;
- case ChainValidationResult_IncompleteChain:
- errors.insert(QSslError::UnableToGetIssuerCertificate);
- break;
- case ChainValidationResult_InvalidSignature:
- errors.insert(QSslError::CertificateSignatureFailed);
- break;
- case ChainValidationResult_WrongUsage:
- errors.insert(QSslError::InvalidPurpose);
- break;
- case ChainValidationResult_InvalidName:
- errors.insert(QSslError::HostNameMismatch);
- break;
- case ChainValidationResult_InvalidCertificateAuthorityPolicy:
- errors.insert(QSslError::InvalidCaCertificate);
- break;
- default:
- errors.insert(QSslError::UnspecifiedError);
- break;
- }
- }
-
- sslErrors = QList<QSslError>(errors.constBegin(), errors.constEnd());
-
- // Peer validation
- if (!configuration.peerCertificate.isNull()) {
- const QString peerName = verificationPeerName.isEmpty() ? q->peerName() : verificationPeerName;
- if (!isMatchingHostname(configuration.peerCertificate, peerName)) {
- // No matches in common names or alternate names.
- const QSslError error(QSslError::HostNameMismatch, configuration.peerCertificate);
- const int index = sslErrors.indexOf(QSslError::HostNameMismatch);
- if (index >= 0) // Replace the existing error
- sslErrors[index] = error;
- else
- sslErrors.append(error);
- emit q->peerVerifyError(error);
- }
-
- // Peer validation required, but no certificate is present
- } else if (configuration.peerVerifyMode == QSslSocket::VerifyPeer
- || configuration.peerVerifyMode == QSslSocket::AutoVerifyPeer) {
- QSslError error(QSslError::NoPeerCertificate);
- sslErrors.append(error);
- emit q->peerVerifyError(error);
- }
-
- // Peer chain validation
- for (const QSslCertificate &certificate : qAsConst(peerCertificateChain)) {
- if (!QSslCertificatePrivate::isBlacklisted(certificate))
- continue;
-
- QSslError error(QSslError::CertificateBlacklisted, certificate);
- sslErrors.append(error);
- emit q->peerVerifyError(error);
- }
-
- if (!sslErrors.isEmpty()) {
- emit q->sslErrors(sslErrors);
- setErrorAndEmit(QAbstractSocket::SslHandshakeFailedError, sslErrors.constFirst().errorString());
-
- // Disconnect if there are any non-ignorable errors
- for (const QSslError &error : qAsConst(sslErrors)) {
- if (ignoreErrorsList.contains(error))
- continue;
- q->disconnectFromHost();
- return S_OK;
- }
- }
-
- if (readBufferMaxSize)
- plainSocket->setReadBufferSize(readBufferMaxSize);
-
- connectionEncrypted = true;
- emit q->encrypted();
-
- // The write buffer may already have data written to it, so we need to call transmit.
- // This has to be done in 'q's thread, and not in the current thread (the XAML thread).
- QMetaObject::invokeMethod(q, [this](){ transmit(); });
-
- if (pendingClose) {
- pendingClose = false;
- q->disconnectFromHost();
- }
-
- return S_OK;
-}
-
-QList<QSslError> QSslSocketBackendPrivate::verify(const QList<QSslCertificate> &certificateChain, const QString &hostName)
-{
- Q_UNIMPLEMENTED();
- Q_UNUSED(certificateChain)
- Q_UNUSED(hostName)
- QList<QSslError> errors;
-
- return errors;
-}
-
-bool QSslSocketBackendPrivate::importPkcs12(QIODevice *device,
- QSslKey *key, QSslCertificate *cert,
- QList<QSslCertificate> *caCertificates,
- const QByteArray &passPhrase)
-{
- Q_UNIMPLEMENTED();
- Q_UNUSED(device)
- Q_UNUSED(key)
- Q_UNUSED(cert)
- Q_UNUSED(caCertificates)
- Q_UNUSED(passPhrase)
- return false;
-}
-
-QT_END_NAMESPACE