diff options
Diffstat (limited to 'src/network/ssl/qsslsocket_winrt.cpp')
-rw-r--r-- | src/network/ssl/qsslsocket_winrt.cpp | 682 |
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 |