/****************************************************************************
**
** Copyright (C) 2018 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$
**
****************************************************************************/

// #define QSSLSOCKET_DEBUG

#include "qssl_p.h"
#include "qsslsocket.h"
#include "qsslsocket_schannel_p.h"
#include "qsslcertificate.h"
#include "qsslcertificateextension.h"
#include "qsslcertificate_p.h"
#include "qsslcipher_p.h"

#include <QtCore/qscopeguard.h>
#include <QtCore/qoperatingsystemversion.h>
#include <QtCore/qregularexpression.h>
#include <QtCore/qdatastream.h>
#include <QtCore/qmutex.h>

#define SECURITY_WIN32
#include <security.h>
#include <schnlsp.h>

#if NTDDI_VERSION >= NTDDI_WINBLUE && !defined(Q_CC_MINGW)
// ALPN = Application Layer Protocol Negotiation
#define SUPPORTS_ALPN 1
#endif

// Not defined in MinGW
#ifndef SECBUFFER_ALERT
#define SECBUFFER_ALERT 17
#endif
#ifndef SECPKG_ATTR_APPLICATION_PROTOCOL
#define SECPKG_ATTR_APPLICATION_PROTOCOL 35
#endif

// Another missing MinGW define
#ifndef SEC_E_APPLICATION_PROTOCOL_MISMATCH
#define SEC_E_APPLICATION_PROTOCOL_MISMATCH _HRESULT_TYPEDEF_(0x80090367L)
#endif

// Also not defined in MinGW.......
#ifndef SP_PROT_TLS1_SERVER
#define SP_PROT_TLS1_SERVER 0x00000040
#endif
#ifndef SP_PROT_TLS1_CLIENT
#define SP_PROT_TLS1_CLIENT 0x00000080
#endif
#ifndef SP_PROT_TLS1_0_SERVER
#define SP_PROT_TLS1_0_SERVER SP_PROT_TLS1_SERVER
#endif
#ifndef SP_PROT_TLS1_0_CLIENT
#define SP_PROT_TLS1_0_CLIENT SP_PROT_TLS1_CLIENT
#endif
#ifndef SP_PROT_TLS1_0
#define SP_PROT_TLS1_0 (SP_PROT_TLS1_0_CLIENT | SP_PROT_TLS1_0_SERVER)
#endif
#ifndef SP_PROT_TLS1_1_SERVER
#define SP_PROT_TLS1_1_SERVER 0x00000100
#endif
#ifndef SP_PROT_TLS1_1_CLIENT
#define SP_PROT_TLS1_1_CLIENT 0x00000200
#endif
#ifndef SP_PROT_TLS1_1
#define SP_PROT_TLS1_1 (SP_PROT_TLS1_1_CLIENT | SP_PROT_TLS1_1_SERVER)
#endif
#ifndef SP_PROT_TLS1_2_SERVER
#define SP_PROT_TLS1_2_SERVER 0x00000400
#endif
#ifndef SP_PROT_TLS1_2_CLIENT
#define SP_PROT_TLS1_2_CLIENT 0x00000800
#endif
#ifndef SP_PROT_TLS1_2
#define SP_PROT_TLS1_2 (SP_PROT_TLS1_2_CLIENT | SP_PROT_TLS1_2_SERVER)
#endif
#ifndef SP_PROT_TLS1_3_SERVER
#define SP_PROT_TLS1_3_SERVER 0x00001000
#endif
#ifndef SP_PROT_TLS1_3_CLIENT
#define SP_PROT_TLS1_3_CLIENT 0x00002000
#endif
#ifndef SP_PROT_TLS1_3
#define SP_PROT_TLS1_3 (SP_PROT_TLS1_3_CLIENT | SP_PROT_TLS1_3_SERVER)
#endif

/*
    @future!:

    - Transmitting intermediate certificates
        - Look for a way to avoid putting intermediate certificates in the certificate store
        - No documentation on how to send the chain
        - A stackoverflow question on this from 3 years ago implies schannel only sends intermediate
            certificates if it's "in the system or user certificate store".
                - https://stackoverflow.com/q/30156584/2493610
                - This can be done by users, but we shouldn't add any and all local intermediate
                    certs to the stores automatically.
    - PSK support
        - Was added in Windows 10 (it seems), documentation at time of writing is sparse/non-existent.
            - Specifically about how to supply credentials when they're requested.
            - Or how to recognize that they're requested in the first place.
        - Skip certificate verification.
        - Check if "PSK-only" is still required to do PSK _at all_ (all-around bad solution).
        - Check if SEC_I_INCOMPLETE_CREDENTIALS is still returned for both "missing certificate" and
            "missing PSK" when calling InitializeSecurityContext in "performHandshake".

    Medium priority:
    - Setting cipher-suites (or ALG_ID)
        - People have survived without it in WinRT

    Low priority:
    - Possibly make RAII wrappers for SecBuffer (which I commonly create QScopeGuards for)

*/

QT_BEGIN_NAMESPACE

namespace {
SecBuffer createSecBuffer(void *ptr, unsigned long length, unsigned long bufferType)
{
    return SecBuffer{ length, bufferType, ptr };
}

SecBuffer createSecBuffer(QByteArray &buffer, unsigned long bufferType)
{
    return createSecBuffer(buffer.data(), static_cast<unsigned long>(buffer.length()), bufferType);
}

QString schannelErrorToString(qint32 status)
{
    switch (status) {
    case SEC_E_INSUFFICIENT_MEMORY:
        return QSslSocket::tr("Insufficient memory");
    case SEC_E_INTERNAL_ERROR:
        return QSslSocket::tr("Internal error");
    case SEC_E_INVALID_HANDLE:
        return QSslSocket::tr("An internal handle was invalid");
    case SEC_E_INVALID_TOKEN:
        return QSslSocket::tr("An internal token was invalid");
    case SEC_E_LOGON_DENIED:
        // According to the link below we get this error when Schannel receives TLS1_ALERT_ACCESS_DENIED
        // https://docs.microsoft.com/en-us/windows/desktop/secauthn/schannel-error-codes-for-tls-and-ssl-alerts
        return QSslSocket::tr("Access denied");
    case SEC_E_NO_AUTHENTICATING_AUTHORITY:
        return QSslSocket::tr("No authority could be contacted for authorization");
    case SEC_E_NO_CREDENTIALS:
        return QSslSocket::tr("No credentials");
    case SEC_E_TARGET_UNKNOWN:
        return QSslSocket::tr("The target is unknown or unreachable");
    case SEC_E_UNSUPPORTED_FUNCTION:
        return QSslSocket::tr("An unsupported function was requested");
    case SEC_E_WRONG_PRINCIPAL:
        // SNI error
        return QSslSocket::tr("The hostname provided does not match the one received from the peer");
    case SEC_E_APPLICATION_PROTOCOL_MISMATCH:
        return QSslSocket::tr("No common protocol exists between the client and the server");
    case SEC_E_ILLEGAL_MESSAGE:
        return QSslSocket::tr("Unexpected or badly-formatted message received");
    case SEC_E_ENCRYPT_FAILURE:
        return QSslSocket::tr("The data could not be encrypted");
    case SEC_E_ALGORITHM_MISMATCH:
        return QSslSocket::tr("No cipher suites in common");
    case SEC_E_UNKNOWN_CREDENTIALS:
        // This can mean "invalid argument" in some cases...
        return QSslSocket::tr("The credentials were not recognized / Invalid argument");
    case SEC_E_MESSAGE_ALTERED:
        // According to the Internet it also triggers for messages that are out of order.
        // https://microsoft.public.platformsdk.security.narkive.com/4JAvlMvD/help-please-schannel-security-contexts-and-decryptmessage
        return QSslSocket::tr("The message was tampered with, damaged or out of sequence.");
    case SEC_E_OUT_OF_SEQUENCE:
        return QSslSocket::tr("A message was received out of sequence.");
    case SEC_E_CONTEXT_EXPIRED:
        return QSslSocket::tr("The TLS/SSL connection has been closed");
    default:
        return QSslSocket::tr("Unknown error occurred: %1").arg(status);
    }
}

DWORD toSchannelProtocol(QSsl::SslProtocol protocol)
{
    DWORD protocols = SP_PROT_NONE;
    switch (protocol) {
    case QSsl::UnknownProtocol:
        return DWORD(-1);
    case QSsl::DtlsV1_0:
    case QSsl::DtlsV1_2:
    case QSsl::DtlsV1_0OrLater:
    case QSsl::DtlsV1_2OrLater:
        return DWORD(-1); // Not supported at the moment (@future)
    case QSsl::AnyProtocol:
        protocols = SP_PROT_TLS1_0 | SP_PROT_TLS1_1 | SP_PROT_TLS1_2;
        // @future Add TLS 1.3 when supported by Windows!
        break;
    case QSsl::SslV2:
    case QSsl::SslV3:
        return DWORD(-1); // Not supported
    case QSsl::TlsV1SslV3:
        protocols = SP_PROT_TLS1_0;
        break;
    case QSsl::TlsV1_0:
        protocols = SP_PROT_TLS1_0;
        break;
    case QSsl::TlsV1_1:
        protocols = SP_PROT_TLS1_1;
        break;
    case QSsl::TlsV1_2:
        protocols = SP_PROT_TLS1_2;
        break;
    case QSsl::TlsV1_3:
        if ((false)) // @future[0/1] Replace with version check once it's supported in Windows
            protocols = SP_PROT_TLS1_3;
        else
            protocols = DWORD(-1);
        break;
    case QSsl::SecureProtocols: // TLS v1.0 and later is currently considered secure
    case QSsl::TlsV1_0OrLater:
        // For the "OrLater" protocols we fall through from one to the next, adding all of them
        // in ascending order
        protocols = SP_PROT_TLS1_0;
        Q_FALLTHROUGH();
    case QSsl::TlsV1_1OrLater:
        protocols |= SP_PROT_TLS1_1;
        Q_FALLTHROUGH();
    case QSsl::TlsV1_2OrLater:
        protocols |= SP_PROT_TLS1_2;
        Q_FALLTHROUGH();
    case QSsl::TlsV1_3OrLater:
        if ((false)) // @future[1/1] Also replace this with a version check
            protocols |= SP_PROT_TLS1_3;
        else if (protocol == QSsl::TlsV1_3OrLater)
            protocols = DWORD(-1); // if TlsV1_3OrLater was specifically chosen we should fail
        break;
    }
    return protocols;
}

/*!
    \internal
    Used when converting the established session's \a protocol back to
    Qt's own SslProtocol type.

    Only one protocol should be passed in at a time.
*/
QSsl::SslProtocol toQtSslProtocol(DWORD protocol)
{
#define MAP_PROTOCOL(sp_protocol, q_protocol) \
    if (protocol & sp_protocol) {             \
        Q_ASSERT(!(protocol & ~sp_protocol)); \
        return q_protocol;                    \
    }

    MAP_PROTOCOL(SP_PROT_TLS1_0, QSsl::TlsV1_0)
    MAP_PROTOCOL(SP_PROT_TLS1_1, QSsl::TlsV1_1)
    MAP_PROTOCOL(SP_PROT_TLS1_2, QSsl::TlsV1_2)
    MAP_PROTOCOL(SP_PROT_TLS1_3, QSsl::TlsV1_3)
#undef MAP_PROTOCOL
    Q_UNREACHABLE();
    return QSsl::UnknownProtocol;
}

/*!
    \internal
    Used by verifyCertContext to check if a client cert is used by a server or vice versa.
*/
bool netscapeWrongCertType(const QList<QSslCertificateExtension> &extensions, bool isClient)
{
    const auto netscapeIt = std::find_if(
            extensions.cbegin(), extensions.cend(),
            [](const QSslCertificateExtension &extension) {
                const auto netscapeCertType = QStringLiteral("2.16.840.1.113730.1.1");
                return extension.oid() == netscapeCertType;
            });
    if (netscapeIt != extensions.cend()) {
        const QByteArray netscapeCertTypeByte = netscapeIt->value().toByteArray();
        int netscapeCertType = 0;
        QDataStream dataStream(netscapeCertTypeByte);
        dataStream >> netscapeCertType;
        if (dataStream.status() != QDataStream::Status::Ok)
            return true;
        const int expectedPeerCertType = isClient ? NETSCAPE_SSL_SERVER_AUTH_CERT_TYPE
                                                  : NETSCAPE_SSL_CLIENT_AUTH_CERT_TYPE;
        if ((netscapeCertType & expectedPeerCertType) == 0)
            return true;
    }
    return false;
}

/*!
    \internal
    Used by verifyCertContext to check the basicConstraints certificate
    extension to see if the certificate is a certificate authority.
    Returns false if the certificate does not have the basicConstraints
    extension or if it is not a certificate authority.
*/
bool isCertificateAuthority(const QList<QSslCertificateExtension> &extensions)
{
    auto it = std::find_if(extensions.cbegin(), extensions.cend(),
                           [](const QSslCertificateExtension &extension) {
                               return extension.name() == QLatin1String("basicConstraints");
                           });
    if (it != extensions.cend()) {
        QVariantMap basicConstraints = it->value().toMap();
        return basicConstraints.value(QLatin1String("ca"), false).toBool();
    }
    return false;
}

/*!
    \internal
    Returns true if the attributes we requested from the context/handshake have
    been given.
*/
bool matchesContextRequirements(DWORD attributes, DWORD requirements,
                                QSslSocket::PeerVerifyMode verifyMode,
                                bool isClient)
{
#ifdef QSSLSOCKET_DEBUG
#define DEBUG_WARN(message) qCWarning(lcSsl, message)
#else
#define DEBUG_WARN(message)
#endif

#define CHECK_ATTRIBUTE(attributeName)                                                                 \
    do {                                                                                               \
        const DWORD req##attributeName = isClient ? ISC_REQ_##attributeName : ASC_REQ_##attributeName; \
        const DWORD ret##attributeName = isClient ? ISC_RET_##attributeName : ASC_RET_##attributeName; \
        if (!(requirements & req##attributeName) != !(attributes & ret##attributeName)) {              \
            DEBUG_WARN("Missing attribute \"" #attributeName "\"");                                    \
            return false;                                                                              \
        }                                                                                              \
    } while (false)

    CHECK_ATTRIBUTE(CONFIDENTIALITY);
    CHECK_ATTRIBUTE(REPLAY_DETECT);
    CHECK_ATTRIBUTE(SEQUENCE_DETECT);
    CHECK_ATTRIBUTE(STREAM);
    if (verifyMode == QSslSocket::PeerVerifyMode::VerifyPeer)
        CHECK_ATTRIBUTE(MUTUAL_AUTH);

    // This one is manual because there is no server / ASC_ version
    if (isClient) {
        const auto reqManualCredValidation = ISC_REQ_MANUAL_CRED_VALIDATION;
        const auto retManualCredValidation = ISC_RET_MANUAL_CRED_VALIDATION;
        if (!(requirements & reqManualCredValidation) != !(attributes & retManualCredValidation)) {
            DEBUG_WARN("Missing attribute \"MANUAL_CRED_VALIDATION\"");
            return false;
        }
    }

    return true;
#undef CHECK_ATTRIBUTE
#undef DEBUG_WARN
}

template<typename Required, typename Actual>
Required const_reinterpret_cast(Actual *p)
{
    return Required(p);
}

#ifdef SUPPORTS_ALPN
bool supportsAlpn()
{
    return QOperatingSystemVersion::current() >= QOperatingSystemVersion::Windows8_1;
}

QByteArray createAlpnString(const QByteArrayList &nextAllowedProtocols)
{
    QByteArray alpnString;
    if (!nextAllowedProtocols.isEmpty() && supportsAlpn()) {
        const QByteArray names = [&nextAllowedProtocols]() {
            QByteArray protocolString;
            for (QByteArray proto : nextAllowedProtocols) {
                if (proto.size() > 255) {
                    qCWarning(lcSsl) << "TLS ALPN extension" << proto
                                     << "is too long and will be ignored.";
                    continue;
                } else if (proto.isEmpty()) {
                    continue;
                }
                protocolString += char(proto.length()) + proto;
            }
            return protocolString;
        }();
        if (names.isEmpty())
            return alpnString;

        const quint16 namesSize = names.size();
        const quint32 alpnId = SecApplicationProtocolNegotiationExt_ALPN;
        const quint32 totalSize = sizeof(alpnId) + sizeof(namesSize) + namesSize;
        alpnString = QByteArray::fromRawData(reinterpret_cast<const char *>(&totalSize), sizeof(totalSize))
                + QByteArray::fromRawData(reinterpret_cast<const char *>(&alpnId), sizeof(alpnId))
                + QByteArray::fromRawData(reinterpret_cast<const char *>(&namesSize), sizeof(namesSize))
                + names;
    }
    return alpnString;
}
#endif // SUPPORTS_ALPN
} // anonymous namespace

bool QSslSocketPrivate::s_loadRootCertsOnDemand = true;
bool QSslSocketPrivate::s_loadedCiphersAndCerts = false;
Q_GLOBAL_STATIC(QRecursiveMutex, qt_schannel_mutex)

void QSslSocketPrivate::ensureInitialized()
{
    const QMutexLocker locker(qt_schannel_mutex);
    if (s_loadedCiphersAndCerts)
        return;
    s_loadedCiphersAndCerts = true;

    setDefaultCaCertificates(systemCaCertificates());
    s_loadRootCertsOnDemand = true; // setDefaultCaCertificates sets it to false, re-enable it.

    resetDefaultCiphers();
}

void QSslSocketPrivate::resetDefaultCiphers()
{
    setDefaultSupportedCiphers(QSslSocketBackendPrivate::defaultCiphers());
    setDefaultCiphers(QSslSocketBackendPrivate::defaultCiphers());
}

void QSslSocketPrivate::resetDefaultEllipticCurves()
{
    Q_UNIMPLEMENTED();
}

bool QSslSocketPrivate::supportsSsl()
{
    return true;
}

QList<QSslCertificate> QSslSocketPrivate::systemCaCertificates()
{
    // Copied from qsslsocket_openssl.cpp's systemCaCertificates function.
    QList<QSslCertificate> systemCerts;
    auto hSystemStore = QHCertStorePointer(CertOpenSystemStore(0, L"ROOT"));
    if (hSystemStore) {
        PCCERT_CONTEXT pc = nullptr;
        while ((pc = CertFindCertificateInStore(hSystemStore.get(), X509_ASN_ENCODING, 0,
                                                CERT_FIND_ANY, nullptr, pc))) {
            systemCerts.append(QSslCertificatePrivate::QSslCertificate_from_CERT_CONTEXT(pc));
        }
    }
    return systemCerts;
}

long QSslSocketPrivate::sslLibraryVersionNumber()
{
    const auto os = QOperatingSystemVersion::current();
    return (os.majorVersion() << 24) | ((os.minorVersion() & 0xFF) << 16) | (os.microVersion() & 0xFFFF);
}

QString QSslSocketPrivate::sslLibraryVersionString()
{
    const auto os = QOperatingSystemVersion::current();
    return QString::fromLatin1("Secure Channel, %1 %2.%3.%4")
            .arg(os.name(),
                 QString::number(os.majorVersion()),
                 QString::number(os.minorVersion()),
                 QString::number(os.microVersion()));
}

long QSslSocketPrivate::sslLibraryBuildVersionNumber()
{
    // There is no separate build version
    return sslLibraryVersionNumber();
}

QString QSslSocketPrivate::sslLibraryBuildVersionString()
{
    const auto os = QOperatingSystemVersion::current();
    return QString::fromLatin1("%1.%2.%3")
            .arg(QString::number(os.majorVersion()),
                 QString::number(os.minorVersion()),
                 QString::number(os.microVersion()));
}

QSslSocketBackendPrivate::QSslSocketBackendPrivate()
{
    SecInvalidateHandle(&credentialHandle);
    SecInvalidateHandle(&contextHandle);
    ensureInitialized();
}

QSslSocketBackendPrivate::~QSslSocketBackendPrivate()
{
    closeCertificateStores();
    deallocateContext();
    freeCredentialsHandle();
    CertFreeCertificateContext(localCertContext);
}

bool QSslSocketBackendPrivate::sendToken(void *token, unsigned long tokenLength, bool emitError)
{
    if (tokenLength == 0)
        return true;
    const qint64 written = plainSocket->write(static_cast<const char *>(token), tokenLength);
    if (written != qint64(tokenLength)) {
        // Failed to write/buffer everything or an error occurred
        if (emitError)
            setErrorAndEmit(plainSocket->error(), plainSocket->errorString());
        return false;
    }
    return true;
}

QString QSslSocketBackendPrivate::targetName() const
{
    // Used for SNI extension
    return verificationPeerName.isEmpty() ? q_func()->peerName() : verificationPeerName;
}

ULONG QSslSocketBackendPrivate::getContextRequirements()
{
    const bool isClient = mode == QSslSocket::SslClientMode;
    ULONG req = 0;

    req |= ISC_REQ_ALLOCATE_MEMORY; // Allocate memory for buffers automatically
    req |= ISC_REQ_CONFIDENTIALITY; // Encrypt messages
    req |= ISC_REQ_REPLAY_DETECT; // Detect replayed messages
    req |= ISC_REQ_SEQUENCE_DETECT; // Detect out of sequence messages
    req |= ISC_REQ_STREAM; // Support a stream-oriented connection

    if (isClient) {
        req |= ISC_REQ_MANUAL_CRED_VALIDATION; // Manually validate certificate
    } else {
        switch (configuration.peerVerifyMode) {
        case QSslSocket::PeerVerifyMode::VerifyNone:
        // There doesn't seem to be a way to ask for an optional client cert :-(
        case QSslSocket::PeerVerifyMode::AutoVerifyPeer:
        case QSslSocket::PeerVerifyMode::QueryPeer:
            break;
        case QSslSocket::PeerVerifyMode::VerifyPeer:
            req |= ISC_REQ_MUTUAL_AUTH;
            break;
        }
    }

    return req;
}

bool QSslSocketBackendPrivate::acquireCredentialsHandle()
{
    Q_ASSERT(schannelState == SchannelState::InitializeHandshake);

    const bool isClient = mode == QSslSocket::SslClientMode;
    const DWORD protocols = toSchannelProtocol(configuration.protocol);
    if (protocols == DWORD(-1)) {
        setErrorAndEmit(QAbstractSocket::SslInvalidUserDataError,
                        QSslSocket::tr("Invalid protocol chosen"));
        return false;
    }

    const CERT_CHAIN_CONTEXT *chainContext = nullptr;
    auto freeCertChain = qScopeGuard([&chainContext]() {
        if (chainContext)
            CertFreeCertificateChain(chainContext);
    });

    DWORD certsCount = 0;
    // Set up our certificate stores before trying to use one...
    initializeCertificateStores();

    // Check if user has specified a certificate chain but it could not be loaded.
    // This happens if there was something wrong with the certificate chain or there was no private
    // key.
    if (!configuration.localCertificateChain.isEmpty() && !localCertificateStore)
        return true; // 'true' because "tst_QSslSocket::setEmptyKey" expects us to not disconnect

    if (localCertificateStore != nullptr) {
        CERT_CHAIN_FIND_BY_ISSUER_PARA findParam;
        ZeroMemory(&findParam, sizeof(findParam));
        findParam.cbSize = sizeof(findParam);
        findParam.pszUsageIdentifier = isClient ? szOID_PKIX_KP_CLIENT_AUTH : szOID_PKIX_KP_SERVER_AUTH;

        // There should only be one chain in our store, so.. we grab that one.
        chainContext = CertFindChainInStore(localCertificateStore.get(),
                                            X509_ASN_ENCODING,
                                            0,
                                            CERT_CHAIN_FIND_BY_ISSUER,
                                            &findParam,
                                            nullptr);
        if (!chainContext) {
            const QString message = isClient
                ? QSslSocket::tr("The certificate provided cannot be used for a client.")
                : QSslSocket::tr("The certificate provided cannot be used for a server.");
            setErrorAndEmit(QAbstractSocket::SocketError::SslInvalidUserDataError, message);
            return false;
        }
        Q_ASSERT(chainContext->cChain == 1);
        Q_ASSERT(chainContext->rgpChain[0]);
        Q_ASSERT(chainContext->rgpChain[0]->cbSize >= 1);
        Q_ASSERT(chainContext->rgpChain[0]->rgpElement[0]);
        Q_ASSERT(!localCertContext);
        localCertContext = CertDuplicateCertificateContext(chainContext->rgpChain[0]
                                                                   ->rgpElement[0]
                                                                   ->pCertContext);
        certsCount = 1;
        Q_ASSERT(localCertContext);
    }

    SCHANNEL_CRED cred{
        SCHANNEL_CRED_VERSION, // dwVersion
        certsCount, // cCreds
        &localCertContext, // paCred (certificate(s) containing a private key for authentication)
        nullptr, // hRootStore

        0, // cMappers (reserved)
        nullptr, // aphMappers (reserved)

        0, // cSupportedAlgs
        nullptr, // palgSupportedAlgs (nullptr = system default) @future: QSslCipher-related

        protocols, // grbitEnabledProtocols
        0, // dwMinimumCipherStrength (0 = system default)
        0, // dwMaximumCipherStrength (0 = system default)
        0, // dwSessionLifespan (0 = schannel default, 10 hours)
        SCH_CRED_REVOCATION_CHECK_CHAIN_EXCLUDE_ROOT
                | SCH_CRED_NO_DEFAULT_CREDS, // dwFlags
        0 // dwCredFormat (must be 0)
    };

    TimeStamp expiration{};
    auto status = AcquireCredentialsHandle(nullptr, // pszPrincipal (unused)
                                           const_cast<wchar_t *>(UNISP_NAME), // pszPackage
                                           isClient ? SECPKG_CRED_OUTBOUND : SECPKG_CRED_INBOUND, // fCredentialUse
                                           nullptr, // pvLogonID (unused)
                                           &cred, // pAuthData
                                           nullptr, // pGetKeyFn (unused)
                                           nullptr, // pvGetKeyArgument (unused)
                                           &credentialHandle, // phCredential
                                           &expiration // ptsExpir
    );

    if (status != SEC_E_OK) {
        setErrorAndEmit(QAbstractSocket::SslInternalError, schannelErrorToString(status));
        return false;
    }
    return true;
}

void QSslSocketBackendPrivate::deallocateContext()
{
    if (SecIsValidHandle(&contextHandle)) {
        DeleteSecurityContext(&contextHandle);
        SecInvalidateHandle(&contextHandle);
    }
}

void QSslSocketBackendPrivate::freeCredentialsHandle()
{
    if (SecIsValidHandle(&credentialHandle)) {
        FreeCredentialsHandle(&credentialHandle);
        SecInvalidateHandle(&credentialHandle);
    }
}

void QSslSocketBackendPrivate::closeCertificateStores()
{
    localCertificateStore.reset();
    peerCertificateStore.reset();
    caCertificateStore.reset();
}

bool QSslSocketBackendPrivate::createContext()
{
    Q_ASSERT(SecIsValidHandle(&credentialHandle));
    Q_ASSERT(schannelState == SchannelState::InitializeHandshake);
    Q_ASSERT(mode == QSslSocket::SslClientMode);
    ULONG contextReq = getContextRequirements();

    SecBuffer outBuffers[3];
    outBuffers[0] = createSecBuffer(nullptr, 0, SECBUFFER_TOKEN);
    outBuffers[1] = createSecBuffer(nullptr, 0, SECBUFFER_ALERT);
    outBuffers[2] = createSecBuffer(nullptr, 0, SECBUFFER_EMPTY);
    auto freeBuffers = qScopeGuard([&outBuffers]() {
        for (auto i = 0ull; i < ARRAYSIZE(outBuffers); i++) {
            if (outBuffers[i].pvBuffer)
                FreeContextBuffer(outBuffers[i].pvBuffer);
        }
    });
    SecBufferDesc outputBufferDesc{
        SECBUFFER_VERSION,
        ARRAYSIZE(outBuffers),
        outBuffers
    };

    TimeStamp expiry;

    SecBufferDesc alpnBufferDesc;
    bool useAlpn = false;
#ifdef SUPPORTS_ALPN
    configuration.nextProtocolNegotiationStatus = QSslConfiguration::NextProtocolNegotiationNone;
    QByteArray alpnString = createAlpnString(configuration.nextAllowedProtocols);
    useAlpn = !alpnString.isEmpty();
    SecBuffer alpnBuffers[1];
    alpnBuffers[0] = createSecBuffer(alpnString, SECBUFFER_APPLICATION_PROTOCOLS);
    alpnBufferDesc = {
        SECBUFFER_VERSION,
        ARRAYSIZE(alpnBuffers),
        alpnBuffers
    };
#endif

    auto status = InitializeSecurityContext(&credentialHandle, // phCredential
                                            nullptr, // phContext
                                            const_reinterpret_cast<SEC_WCHAR *>(targetName().utf16()), // pszTargetName
                                            contextReq, // fContextReq
                                            0, // Reserved1
                                            0, // TargetDataRep (unused)
                                            useAlpn ? &alpnBufferDesc : nullptr, // pInput
                                            0, // Reserved2
                                            &contextHandle, // phNewContext
                                            &outputBufferDesc, // pOutput
                                            &contextAttributes, // pfContextAttr
                                            &expiry // ptsExpiry
    );

    // This is the first call to InitializeSecurityContext, so theoretically "CONTINUE_NEEDED"
    // should be the only non-error return-code here.
    if (status != SEC_I_CONTINUE_NEEDED) {
        setErrorAndEmit(QAbstractSocket::SslInternalError,
                        QSslSocket::tr("Error creating SSL context (%1)").arg(schannelErrorToString(status)));
        return false;
    }

    if (!sendToken(outBuffers[0].pvBuffer, outBuffers[0].cbBuffer))
        return false;
    schannelState = SchannelState::PerformHandshake;
    return true;
}

bool QSslSocketBackendPrivate::acceptContext()
{
    Q_ASSERT(SecIsValidHandle(&credentialHandle));
    Q_ASSERT(schannelState == SchannelState::InitializeHandshake);
    Q_ASSERT(mode == QSslSocket::SslServerMode);
    ULONG contextReq = getContextRequirements();

    intermediateBuffer += plainSocket->read(16384);
    if (intermediateBuffer.isEmpty())
        return true; // definitely need more data..

    SecBuffer inBuffers[2];
    inBuffers[0] = createSecBuffer(intermediateBuffer, SECBUFFER_TOKEN);

#ifdef SUPPORTS_ALPN
    configuration.nextProtocolNegotiationStatus = QSslConfiguration::NextProtocolNegotiationNone;
    // The string must be alive when we call AcceptSecurityContext
    QByteArray alpnString = createAlpnString(configuration.nextAllowedProtocols);
    if (!alpnString.isEmpty()) {
        inBuffers[1] = createSecBuffer(alpnString, SECBUFFER_APPLICATION_PROTOCOLS);
    } else
#endif
    {
        inBuffers[1] = createSecBuffer(nullptr, 0, SECBUFFER_EMPTY);
    }

    SecBufferDesc inputBufferDesc{
        SECBUFFER_VERSION,
        ARRAYSIZE(inBuffers),
        inBuffers
    };

    SecBuffer outBuffers[3];
    outBuffers[0] = createSecBuffer(nullptr, 0, SECBUFFER_TOKEN);
    outBuffers[1] = createSecBuffer(nullptr, 0, SECBUFFER_ALERT);
    outBuffers[2] = createSecBuffer(nullptr, 0, SECBUFFER_EMPTY);
    auto freeBuffers = qScopeGuard([&outBuffers]() {
        for (auto i = 0ull; i < ARRAYSIZE(outBuffers); i++) {
            if (outBuffers[i].pvBuffer)
                FreeContextBuffer(outBuffers[i].pvBuffer);
        }
    });
    SecBufferDesc outputBufferDesc{
        SECBUFFER_VERSION,
        ARRAYSIZE(outBuffers),
        outBuffers
    };

    TimeStamp expiry;
    auto status = AcceptSecurityContext(
            &credentialHandle, // phCredential
            nullptr, // phContext
            &inputBufferDesc, // pInput
            contextReq, // fContextReq
            0, // TargetDataRep (unused)
            &contextHandle, // phNewContext
            &outputBufferDesc, // pOutput
            &contextAttributes, // pfContextAttr
            &expiry // ptsTimeStamp
    );

    if (status == SEC_E_INCOMPLETE_MESSAGE) {
        // Need more data
        return true;
    }

    if (inBuffers[1].BufferType == SECBUFFER_EXTRA) {
        // https://docs.microsoft.com/en-us/windows/desktop/secauthn/extra-buffers-returned-by-schannel
        // inBuffers[1].cbBuffer indicates the amount of bytes _NOT_ processed, the rest need to
        // be stored.
        intermediateBuffer = intermediateBuffer.right(int(inBuffers[1].cbBuffer));
    } else { /* No 'extra' data, message not incomplete */
        intermediateBuffer.clear();
    }

    if (status != SEC_I_CONTINUE_NEEDED) {
        setErrorAndEmit(QAbstractSocket::SslHandshakeFailedError,
                        QSslSocket::tr("Error creating SSL context (%1)").arg(schannelErrorToString(status)));
        return false;
    }
    if (!sendToken(outBuffers[0].pvBuffer, outBuffers[0].cbBuffer))
        return false;
    schannelState = SchannelState::PerformHandshake;
    return true;
}

bool QSslSocketBackendPrivate::performHandshake()
{
    if (plainSocket->state() == QAbstractSocket::UnconnectedState) {
        setErrorAndEmit(QAbstractSocket::RemoteHostClosedError,
                        QSslSocket::tr("The TLS/SSL connection has been closed"));
        return false;
    }
    Q_ASSERT(SecIsValidHandle(&credentialHandle));
    Q_ASSERT(SecIsValidHandle(&contextHandle));
    Q_ASSERT(schannelState == SchannelState::PerformHandshake);

#ifdef QSSLSOCKET_DEBUG
    qCDebug(lcSsl) << "Bytes available from socket:" << plainSocket->bytesAvailable();
    qCDebug(lcSsl) << "intermediateBuffer size:" << intermediateBuffer.size();
#endif

    intermediateBuffer += plainSocket->read(16384);
    if (intermediateBuffer.isEmpty())
        return true; // no data, will fail

    SecBuffer inputBuffers[2];
    inputBuffers[0] = createSecBuffer(intermediateBuffer, SECBUFFER_TOKEN);
    inputBuffers[1] = createSecBuffer(nullptr, 0, SECBUFFER_EMPTY);
    SecBufferDesc inputBufferDesc{
        SECBUFFER_VERSION,
        ARRAYSIZE(inputBuffers),
        inputBuffers
    };

    SecBuffer outBuffers[3];
    outBuffers[0] = createSecBuffer(nullptr, 0, SECBUFFER_TOKEN);
    outBuffers[1] = createSecBuffer(nullptr, 0, SECBUFFER_ALERT);
    outBuffers[2] = createSecBuffer(nullptr, 0, SECBUFFER_EMPTY);
    auto freeBuffers = qScopeGuard([&outBuffers]() {
        for (auto i = 0ull; i < ARRAYSIZE(outBuffers); i++) {
            if (outBuffers[i].pvBuffer)
                FreeContextBuffer(outBuffers[i].pvBuffer);
        }
    });
    SecBufferDesc outputBufferDesc{
        SECBUFFER_VERSION,
        ARRAYSIZE(outBuffers),
        outBuffers
    };

    ULONG contextReq = getContextRequirements();
    TimeStamp expiry;
    auto status = InitializeSecurityContext(&credentialHandle, // phCredential
                                            &contextHandle, // phContext
                                            const_reinterpret_cast<SEC_WCHAR *>(targetName().utf16()), // pszTargetName
                                            contextReq, // fContextReq
                                            0, // Reserved1
                                            0, // TargetDataRep (unused)
                                            &inputBufferDesc, // pInput
                                            0, // Reserved2
                                            nullptr, // phNewContext (we already have one)
                                            &outputBufferDesc, // pOutput
                                            &contextAttributes, // pfContextAttr
                                            &expiry // ptsExpiry
    );

    if (inputBuffers[1].BufferType == SECBUFFER_EXTRA) {
        // https://docs.microsoft.com/en-us/windows/desktop/secauthn/extra-buffers-returned-by-schannel
        // inputBuffers[1].cbBuffer indicates the amount of bytes _NOT_ processed, the rest need to
        // be stored.
        intermediateBuffer = intermediateBuffer.right(int(inputBuffers[1].cbBuffer));
    } else {
        // Clear the buffer if we weren't asked for more data
        if (status != SEC_E_INCOMPLETE_MESSAGE)
            intermediateBuffer.clear();
    }
    switch (status) {
    case SEC_E_OK:
        // Need to transmit a final token in the handshake if 'cbBuffer' is non-zero.
        if (!sendToken(outBuffers[0].pvBuffer, outBuffers[0].cbBuffer))
            return false;
        schannelState = SchannelState::VerifyHandshake;
        return true;
    case SEC_I_CONTINUE_NEEDED:
        if (!sendToken(outBuffers[0].pvBuffer, outBuffers[0].cbBuffer))
            return false;
        // Must call InitializeSecurityContext again later (done through continueHandshake)
        return true;
    case SEC_I_INCOMPLETE_CREDENTIALS:
        // Schannel takes care of picking certificate to send (other than the one we can specify),
        // so if we get here then that means we don't have a certificate the server accepts.
        setErrorAndEmit(QAbstractSocket::SslHandshakeFailedError,
                        QSslSocket::tr("Server did not accept any certificate we could present."));
        return false;
    case SEC_I_CONTEXT_EXPIRED:
        // "The message sender has finished using the connection and has initiated a shutdown."
        if (outBuffers[0].BufferType == SECBUFFER_TOKEN) {
            if (!sendToken(outBuffers[0].pvBuffer, outBuffers[0].cbBuffer))
                return false;
        }
        if (!shutdown) { // we did not initiate this
            setErrorAndEmit(QAbstractSocket::RemoteHostClosedError,
                            QSslSocket::tr("The TLS/SSL connection has been closed"));
        }
        return true;
    case SEC_E_INCOMPLETE_MESSAGE:
        // Simply incomplete, wait for more data
        return true;
    case SEC_E_ALGORITHM_MISMATCH:
        setErrorAndEmit(QAbstractSocket::SslHandshakeFailedError,
                        QSslSocket::tr("Algorithm mismatch"));
        shutdown = true; // skip sending the "Shutdown" alert
        return false;
    }

    // Note: We can get here if the connection is using TLS 1.2 and the server certificate uses
    // MD5, which is not allowed in Schannel. This causes an "invalid token" error during handshake.
    // (If you came here investigating an error: md5 is insecure, update your certificate)
    setErrorAndEmit(QAbstractSocket::SslHandshakeFailedError,
                    QSslSocket::tr("Handshake failed: %1").arg(schannelErrorToString(status)));
    return false;
}

bool QSslSocketBackendPrivate::verifyHandshake()
{
    Q_Q(QSslSocket);
    sslErrors.clear();

    const bool isClient = mode == QSslSocket::SslClientMode;
#define CHECK_STATUS(status)                                                  \
    if (status != SEC_E_OK) {                                                 \
        setErrorAndEmit(QAbstractSocket::SslInternalError,                    \
                        QSslSocket::tr("Failed to query the TLS context: %1") \
                                .arg(schannelErrorToString(status)));         \
        return false;                                                         \
    }

    // Everything is set up, now make sure there's nothing wrong and query some attributes...
    if (!matchesContextRequirements(contextAttributes, getContextRequirements(),
                                    configuration.peerVerifyMode, isClient)) {
        setErrorAndEmit(QAbstractSocket::SslHandshakeFailedError,
                        QSslSocket::tr("Did not get the required attributes for the connection."));
        return false;
    }

    // Get stream sizes (to know the max size of a message and the size of the header and trailer)
    auto status = QueryContextAttributes(&contextHandle,
                                         SECPKG_ATTR_STREAM_SIZES,
                                         &streamSizes);
    CHECK_STATUS(status);

    // Get session cipher info
    status = QueryContextAttributes(&contextHandle,
                                    SECPKG_ATTR_CONNECTION_INFO,
                                    &connectionInfo);
    CHECK_STATUS(status);

#ifdef SUPPORTS_ALPN
    if (!configuration.nextAllowedProtocols.isEmpty() && supportsAlpn()) {
        SecPkgContext_ApplicationProtocol alpn;
        status = QueryContextAttributes(&contextHandle,
                                        SECPKG_ATTR_APPLICATION_PROTOCOL,
                                        &alpn);
        CHECK_STATUS(status);
        if (alpn.ProtoNegoStatus == SecApplicationProtocolNegotiationStatus_Success) {
            QByteArray negotiatedProto = QByteArray((const char *)alpn.ProtocolId,
                                                    alpn.ProtocolIdSize);
            if (!configuration.nextAllowedProtocols.contains(negotiatedProto)) {
                setErrorAndEmit(QAbstractSocket::SslHandshakeFailedError,
                                QSslSocket::tr("Unwanted protocol was negotiated"));
                return false;
            }
            configuration.nextNegotiatedProtocol = negotiatedProto;
            configuration.nextProtocolNegotiationStatus = QSslConfiguration::NextProtocolNegotiationNegotiated;
        } else {
            configuration.nextNegotiatedProtocol = "";
            configuration.nextProtocolNegotiationStatus = QSslConfiguration::NextProtocolNegotiationUnsupported;
        }
    }
#endif // supports ALPN

#undef CHECK_STATUS

    // Verify certificate
    CERT_CONTEXT *certificateContext = nullptr;
    auto freeCertificate = qScopeGuard([&certificateContext]() {
        if (certificateContext)
            CertFreeCertificateContext(certificateContext);
    });
    status = QueryContextAttributes(&contextHandle,
                                    SECPKG_ATTR_REMOTE_CERT_CONTEXT,
                                    &certificateContext);

    // QueryPeer can (currently) not work in Schannel since Schannel itself doesn't have a way to
    // ask for a certificate and then still be OK if it's not received.
    // To work around this we don't request a certificate at all for QueryPeer.
    // For servers AutoVerifyPeer is supposed to be treated the same as QueryPeer.
    // This means that servers using Schannel will only request client certificate for "VerifyPeer".
    if ((!isClient && configuration.peerVerifyMode == QSslSocket::PeerVerifyMode::VerifyPeer)
        || (isClient && configuration.peerVerifyMode != QSslSocket::PeerVerifyMode::VerifyNone
            && configuration.peerVerifyMode != QSslSocket::PeerVerifyMode::QueryPeer)) {
        if (status != SEC_E_OK) {
#ifdef QSSLSOCKET_DEBUG
            qCDebug(lcSsl) << "Couldn't retrieve peer certificate, status:"
                           << schannelErrorToString(status);
#endif
            const QSslError error{ QSslError::NoPeerCertificate };
            sslErrors += error;
            emit q->peerVerifyError(error);
            if (q->state() != QAbstractSocket::ConnectedState)
                return false;
        }
    }

    // verifyCertContext returns false if the user disconnected while it was checking errors.
    if (certificateContext && !verifyCertContext(certificateContext))
        return false;

    if (!checkSslErrors() || state != QAbstractSocket::ConnectedState) {
#ifdef QSSLSOCKET_DEBUG
        qCDebug(lcSsl) << __func__ << "was unsuccessful. Paused:" << paused;
#endif
        // If we're paused then checkSslErrors returned false, but it's not an error
        return paused && state == QAbstractSocket::ConnectedState;
    }

    schannelState = SchannelState::Done;
    return true;
}

bool QSslSocketBackendPrivate::renegotiate()
{
    SecBuffer outBuffers[3];
    outBuffers[0] = createSecBuffer(nullptr, 0, SECBUFFER_TOKEN);
    outBuffers[1] = createSecBuffer(nullptr, 0, SECBUFFER_ALERT);
    outBuffers[2] = createSecBuffer(nullptr, 0, SECBUFFER_EMPTY);
    auto freeBuffers = qScopeGuard([&outBuffers]() {
        for (auto i = 0ull; i < ARRAYSIZE(outBuffers); i++) {
            if (outBuffers[i].pvBuffer)
                FreeContextBuffer(outBuffers[i].pvBuffer);
        }
    });
    SecBufferDesc outputBufferDesc{
        SECBUFFER_VERSION,
        ARRAYSIZE(outBuffers),
        outBuffers
    };

    ULONG contextReq = getContextRequirements();
    TimeStamp expiry;
    SECURITY_STATUS status;
    if (mode == QSslSocket::SslClientMode) {
        status = InitializeSecurityContext(&credentialHandle, // phCredential
                                           &contextHandle, // phContext
                                           const_reinterpret_cast<SEC_WCHAR *>(targetName().utf16()), // pszTargetName
                                           contextReq, // fContextReq
                                           0, // Reserved1
                                           0, // TargetDataRep (unused)
                                           nullptr, // pInput (nullptr for renegotiate)
                                           0, // Reserved2
                                           nullptr, // phNewContext (we already have one)
                                           &outputBufferDesc, // pOutput
                                           &contextAttributes, // pfContextAttr
                                           &expiry // ptsExpiry
        );
    } else {
        status = AcceptSecurityContext(
                &credentialHandle, // phCredential
                &contextHandle, // phContext
                nullptr, // pInput
                contextReq, // fContextReq
                0, // TargetDataRep (unused)
                nullptr, // phNewContext
                &outputBufferDesc, // pOutput
                &contextAttributes, // pfContextAttr,
                &expiry // ptsTimeStamp
        );
    }
    if (status == SEC_I_CONTINUE_NEEDED) {
        schannelState = SchannelState::PerformHandshake;
        return sendToken(outBuffers[0].pvBuffer, outBuffers[0].cbBuffer);
    }
    setErrorAndEmit(QAbstractSocket::SslHandshakeFailedError,
                    QSslSocket::tr("Renegotiation was unsuccessful: %1").arg(schannelErrorToString(status)));
    return false;
}

/*!
    \internal
    reset the state in preparation for reuse of socket
*/
void QSslSocketBackendPrivate::reset()
{
    closeCertificateStores(); // certificate stores could've changed
    deallocateContext();
    freeCredentialsHandle(); // in case we already had one (@future: session resumption requires re-use)

    connectionInfo = {};
    streamSizes = {};

    CertFreeCertificateContext(localCertContext);
    localCertContext = nullptr;

    contextAttributes = 0;
    intermediateBuffer.clear();
    schannelState = SchannelState::InitializeHandshake;

    connectionEncrypted = false;
    shutdown = false;
    renegotiating = false;
}

void QSslSocketBackendPrivate::startClientEncryption()
{
    if (connectionEncrypted)
        return; // let's not mess up the connection...
    reset();
    continueHandshake();
}

void QSslSocketBackendPrivate::startServerEncryption()
{
    if (connectionEncrypted)
        return; // let's not mess up the connection...
    reset();
    continueHandshake();
}

void QSslSocketBackendPrivate::transmit()
{
    Q_Q(QSslSocket);

    // Can happen if called through QSslSocket::abort->QSslSocket::close->QSslSocket::flush->here
    if (plainSocket->state() == QAbstractSocket::SocketState::UnconnectedState)
        return;

    if (schannelState != SchannelState::Done) {
        continueHandshake();
        return;
    }

    if (connectionEncrypted) { // encrypt data in writeBuffer and write it to plainSocket
        qint64 totalBytesWritten = 0;
        qint64 writeBufferSize;
        while ((writeBufferSize = writeBuffer.size()) > 0) {
            const int headerSize = int(streamSizes.cbHeader);
            const int trailerSize = int(streamSizes.cbTrailer);
            // Try to read 'cbMaximumMessage' bytes from buffer before encrypting.
            const int size = int(std::min(writeBufferSize, qint64(streamSizes.cbMaximumMessage)));
            QByteArray fullMessage(headerSize + trailerSize + size, Qt::Uninitialized);
            {
                // Use peek() here instead of read() so we don't lose data if encryption fails.
                qint64 copied = writeBuffer.peek(fullMessage.data() + headerSize, size);
                Q_ASSERT(copied == size);
            }

            SecBuffer inputBuffers[4]{
                createSecBuffer(fullMessage.data(), headerSize, SECBUFFER_STREAM_HEADER),
                createSecBuffer(fullMessage.data() + headerSize, size, SECBUFFER_DATA),
                createSecBuffer(fullMessage.data() + headerSize + size, trailerSize, SECBUFFER_STREAM_TRAILER),
                createSecBuffer(nullptr, 0, SECBUFFER_EMPTY)
            };
            SecBufferDesc message{
                SECBUFFER_VERSION,
                ARRAYSIZE(inputBuffers),
                inputBuffers
            };
            auto status = EncryptMessage(&contextHandle, 0, &message, 0);
            if (status != SEC_E_OK) {
                setErrorAndEmit(QAbstractSocket::SslInternalError,
                                QSslSocket::tr("Schannel failed to encrypt data: %1")
                                        .arg(schannelErrorToString(status)));
                return;
            }
            // Data was encrypted successfully, so we free() what we peek()ed earlier
            writeBuffer.free(size);

            // The trailer's size is not final, so resize fullMessage to not send trailing junk
            fullMessage.resize(inputBuffers[0].cbBuffer + inputBuffers[1].cbBuffer + inputBuffers[2].cbBuffer);
            const qint64 bytesWritten = plainSocket->write(fullMessage);
#ifdef QSSLSOCKET_DEBUG
            qCDebug(lcSsl) << "Wrote" << bytesWritten << "of total"
                           << fullMessage.length() << "bytes";
#endif
            if (bytesWritten >= 0) {
                totalBytesWritten += bytesWritten;
            } else {
                setErrorAndEmit(plainSocket->error(), plainSocket->errorString());
                return;
            }
        }

        if (totalBytesWritten > 0) {
            // Don't emit bytesWritten() recursively.
            if (!emittedBytesWritten) {
                emittedBytesWritten = true;
                emit q->bytesWritten(totalBytesWritten);
                emittedBytesWritten = false;
            }
            emit q->channelBytesWritten(0, totalBytesWritten);
        }
    }

    if (connectionEncrypted) { // Decrypt data from remote
        int totalRead = 0;
        bool hadIncompleteData = false;
        while (!readBufferMaxSize || buffer.size() < readBufferMaxSize) {
            QByteArray ciphertext;
            if (intermediateBuffer.length()) {
#ifdef QSSLSOCKET_DEBUG
                qCDebug(lcSsl) << "Restoring data from intermediateBuffer:"
                               << intermediateBuffer.length() << "bytes";
#endif
                ciphertext.swap(intermediateBuffer);
            }
            int initialLength = ciphertext.length();
            ciphertext += plainSocket->read(16384);
#ifdef QSSLSOCKET_DEBUG
            qCDebug(lcSsl) << "Read" << ciphertext.length() - initialLength
                           << "encrypted bytes from the socket";
#endif
            if (ciphertext.length() == 0 || (hadIncompleteData && initialLength == ciphertext.length())) {
#ifdef QSSLSOCKET_DEBUG
                qCDebug(lcSsl) << (hadIncompleteData ? "No new data received, leaving loop!"
                                                     : "Nothing to decrypt, leaving loop!");
#endif
                if (ciphertext.length()) // We have data, it came from intermediateBuffer, swap back
                    intermediateBuffer.swap(ciphertext);
                break;
            }
            hadIncompleteData = false;
#ifdef QSSLSOCKET_DEBUG
            qCDebug(lcSsl) << "Total amount of bytes to decrypt:" << ciphertext.length();
#endif

            SecBuffer dataBuffer[4]{
                createSecBuffer(ciphertext, SECBUFFER_DATA),
                createSecBuffer(nullptr, 0, SECBUFFER_EMPTY),
                createSecBuffer(nullptr, 0, SECBUFFER_EMPTY),
                createSecBuffer(nullptr, 0, SECBUFFER_EMPTY)
            };
            SecBufferDesc message{
                SECBUFFER_VERSION,
                ARRAYSIZE(dataBuffer),
                dataBuffer
            };
            auto status = DecryptMessage(&contextHandle, &message, 0, nullptr);
            if (status == SEC_E_OK || status == SEC_I_RENEGOTIATE || status == SEC_I_CONTEXT_EXPIRED) {
                // There can still be 0 output even if it succeeds, this is fine
                if (dataBuffer[1].cbBuffer > 0) {
                    // It is always decrypted in-place.
                    // But [0] is the STREAM_HEADER, [1] is the DATA and [2] is the STREAM_TRAILER.
                    // The pointers in all of those still point into the 'ciphertext' byte array.
                    buffer.append(static_cast<char *>(dataBuffer[1].pvBuffer),
                                  dataBuffer[1].cbBuffer);
                    totalRead += dataBuffer[1].cbBuffer;
#ifdef QSSLSOCKET_DEBUG
                    qCDebug(lcSsl) << "Decrypted" << dataBuffer[1].cbBuffer
                                   << "bytes. New read buffer size:" << buffer.size();
#endif
                }
                if (dataBuffer[3].BufferType == SECBUFFER_EXTRA) {
                    // https://docs.microsoft.com/en-us/windows/desktop/secauthn/extra-buffers-returned-by-schannel
                    // dataBuffer[3].cbBuffer indicates the amount of bytes _NOT_ processed,
                    // the rest need to be stored.
#ifdef QSSLSOCKET_DEBUG
                    qCDebug(lcSsl) << "We've got excess data, moving it to the intermediate buffer:"
                                   << dataBuffer[3].cbBuffer << "bytes";
#endif
                    intermediateBuffer = ciphertext.right(int(dataBuffer[3].cbBuffer));
                }
            }

            if (status == SEC_E_INCOMPLETE_MESSAGE) {
                // Need more data before we can decrypt.. to the buffer it goes!
#ifdef QSSLSOCKET_DEBUG
                qCDebug(lcSsl, "We didn't have enough data to decrypt anything, will try again!");
#endif
                Q_ASSERT(intermediateBuffer.isEmpty());
                intermediateBuffer.swap(ciphertext);
                // We try again, but if we don't get any more data then we leave
                hadIncompleteData = true;
            } else if (status == SEC_E_INVALID_HANDLE) {
                // I don't think this should happen, if it does we're done...
                qCWarning(lcSsl, "The internal SSPI handle is invalid!");
                Q_UNREACHABLE();
            } else if (status == SEC_E_INVALID_TOKEN) {
                qCWarning(lcSsl, "Got SEC_E_INVALID_TOKEN!");
                Q_UNREACHABLE(); // Happened once due to a bug, but shouldn't generally happen(?)
            } else if (status == SEC_E_MESSAGE_ALTERED) {
                // The message has been altered, disconnect now.
                shutdown = true; // skips sending the shutdown alert
                disconnectFromHost();
                setErrorAndEmit(QAbstractSocket::SslInternalError,
                                schannelErrorToString(status));
                break;
            } else if (status == SEC_E_OUT_OF_SEQUENCE) {
                // @todo: I don't know if this one is actually "fatal"..
                // This path might never be hit as it seems this is for connection-oriented connections,
                // while SEC_E_MESSAGE_ALTERED is for stream-oriented ones (what we use).
                shutdown = true; // skips sending the shutdown alert
                disconnectFromHost();
                setErrorAndEmit(QAbstractSocket::SslInternalError,
                                schannelErrorToString(status));
                break;
            } else if (status == SEC_I_CONTEXT_EXPIRED) {
                // 'remote' has initiated a shutdown
                disconnectFromHost();
                setErrorAndEmit(QAbstractSocket::RemoteHostClosedError,
                                schannelErrorToString(status));
                break;
            } else if (status == SEC_I_RENEGOTIATE) {
                // 'remote' wants to renegotiate
#ifdef QSSLSOCKET_DEBUG
                qCDebug(lcSsl, "The peer wants to renegotiate.");
#endif
                schannelState = SchannelState::Renegotiate;
                renegotiating = true;

                // We need to call 'continueHandshake' or else there's no guarantee it ever gets called
                continueHandshake();
                break;
            }
        }

        if (totalRead) {
            if (readyReadEmittedPointer)
                *readyReadEmittedPointer = true;
            emit q->readyRead();
            emit q->channelReadyRead(0);
        }
    }
}

void QSslSocketBackendPrivate::sendShutdown()
{
    const bool isClient = mode == QSslSocket::SslClientMode;
    DWORD shutdownToken = SCHANNEL_SHUTDOWN;
    SecBuffer buffer = createSecBuffer(&shutdownToken, sizeof(SCHANNEL_SHUTDOWN), SECBUFFER_TOKEN);
    SecBufferDesc token{
        SECBUFFER_VERSION,
        1,
        &buffer
    };
    auto status = ApplyControlToken(&contextHandle, &token);

    if (status != SEC_E_OK) {
#ifdef QSSLSOCKET_DEBUG
        qCDebug(lcSsl) << "Failed to apply shutdown control token:" << schannelErrorToString(status);
#endif
        return;
    }

    SecBuffer outBuffers[3];
    outBuffers[0] = createSecBuffer(nullptr, 0, SECBUFFER_TOKEN);
    outBuffers[1] = createSecBuffer(nullptr, 0, SECBUFFER_ALERT);
    outBuffers[2] = createSecBuffer(nullptr, 0, SECBUFFER_EMPTY);
    auto freeBuffers = qScopeGuard([&outBuffers]() {
        for (auto i = 0ull; i < ARRAYSIZE(outBuffers); i++) {
            if (outBuffers[i].pvBuffer)
                FreeContextBuffer(outBuffers[i].pvBuffer);
        }
    });
    SecBufferDesc outputBufferDesc{
        SECBUFFER_VERSION,
        ARRAYSIZE(outBuffers),
        outBuffers
    };

    ULONG contextReq = getContextRequirements();
    TimeStamp expiry;
    if (isClient) {
        status = InitializeSecurityContext(&credentialHandle, // phCredential
                                           &contextHandle, // phContext
                                           const_reinterpret_cast<SEC_WCHAR *>(targetName().utf16()), // pszTargetName
                                           contextReq, // fContextReq
                                           0, // Reserved1
                                           0, // TargetDataRep (unused)
                                           nullptr, // pInput
                                           0, // Reserved2
                                           nullptr, // phNewContext (we already have one)
                                           &outputBufferDesc, // pOutput
                                           &contextAttributes, // pfContextAttr
                                           &expiry // ptsExpiry
        );
    } else {
        status = AcceptSecurityContext(
                &credentialHandle, // phCredential
                &contextHandle, // phContext
                nullptr, // pInput
                contextReq, // fContextReq
                0, // TargetDataRep (unused)
                nullptr, // phNewContext
                &outputBufferDesc, // pOutput
                &contextAttributes, // pfContextAttr,
                &expiry // ptsTimeStamp
        );
    }
    if (status == SEC_E_OK || status == SEC_I_CONTEXT_EXPIRED) {
        if (!sendToken(outBuffers[0].pvBuffer, outBuffers[0].cbBuffer, false)) {
            // We failed to send the shutdown message, but it's not that important since we're
            // shutting down anyway.
            return;
        }
    } else {
#ifdef QSSLSOCKET_DEBUG
        qCDebug(lcSsl) << "Failed to initialize shutdown:" << schannelErrorToString(status);
#endif
    }
}

void QSslSocketBackendPrivate::disconnectFromHost()
{
    if (SecIsValidHandle(&contextHandle)) {
        if (!shutdown) {
            shutdown = true;
            if (plainSocket->state() != QAbstractSocket::UnconnectedState) {
                if (connectionEncrypted) {
                    // Read as much as possible because this is likely our last chance
                    qint64 tempMax = readBufferMaxSize;
                    readBufferMaxSize = 0;
                    transmit();
                    readBufferMaxSize = tempMax;
                    sendShutdown();
                }
            }
        }
    }
    if (plainSocket->state() != QAbstractSocket::UnconnectedState)
        plainSocket->disconnectFromHost();
}

void QSslSocketBackendPrivate::disconnected()
{
    shutdown = true;
    connectionEncrypted = false;
    deallocateContext();
    freeCredentialsHandle();
}

QSslCipher QSslSocketBackendPrivate::sessionCipher() const
{
    if (!connectionEncrypted)
        return QSslCipher();
    return QSslCipher(QStringLiteral("Schannel"), sessionProtocol());
}

QSsl::SslProtocol QSslSocketBackendPrivate::sessionProtocol() const
{
    if (!connectionEncrypted)
        return QSsl::SslProtocol::UnknownProtocol;
    return toQtSslProtocol(connectionInfo.dwProtocol);
}

void QSslSocketBackendPrivate::continueHandshake()
{
    Q_Q(QSslSocket);
    const bool isServer = mode == QSslSocket::SslServerMode;
    switch (schannelState) {
    case SchannelState::InitializeHandshake:
        if (!SecIsValidHandle(&credentialHandle) && !acquireCredentialsHandle()) {
            disconnectFromHost();
            return;
        }
        if (!SecIsValidHandle(&credentialHandle)) // Needed to support tst_QSslSocket::setEmptyKey
            return;
        if (!SecIsValidHandle(&contextHandle) && !(isServer ? acceptContext() : createContext())) {
            disconnectFromHost();
            return;
        }
        if (schannelState != SchannelState::PerformHandshake)
            break;
        Q_FALLTHROUGH();
    case SchannelState::PerformHandshake:
        if (!performHandshake()) {
            disconnectFromHost();
            return;
        }
        if (schannelState != SchannelState::VerifyHandshake)
            break;
        Q_FALLTHROUGH();
    case SchannelState::VerifyHandshake:
        // if we're in shutdown or renegotiating then we might not need to verify
        // (since we already did)
        if (!verifyHandshake()) {
            shutdown = true; // Skip sending shutdown alert
            q->abort(); // We don't want to send buffered data
            disconnectFromHost();
            return;
        }
        if (schannelState != SchannelState::Done)
            break;
        Q_FALLTHROUGH();
    case SchannelState::Done:
        // connectionEncrypted is already true if we come here from a renegotiation
        if (!connectionEncrypted) {
            connectionEncrypted = true; // all is done
            emit q->encrypted();
        }
        renegotiating = false;
        if (pendingClose) {
            pendingClose = false;
            disconnectFromHost();
        } else {
            transmit();
        }
        break;
    case SchannelState::Renegotiate:
        if (!renegotiate()) {
            disconnectFromHost();
            return;
        }
        break;
    }
}

QList<QSslCipher> QSslSocketBackendPrivate::defaultCiphers()
{
    QList<QSslCipher> ciphers;
    // @temp (I hope), stolen from qsslsocket_winrt.cpp
    const QString protocolStrings[] = { QStringLiteral("TLSv1"), QStringLiteral("TLSv1.1"),
                                        QStringLiteral("TLSv1.2"), QStringLiteral("TLSv1.3") };
    const QSsl::SslProtocol protocols[] = { QSsl::TlsV1_0, QSsl::TlsV1_1,
                                            QSsl::TlsV1_2, QSsl::TlsV1_3 };
    const int size = ARRAYSIZE(protocols);
    Q_STATIC_ASSERT(size == ARRAYSIZE(protocolStrings));
    ciphers.reserve(size);
    for (int i = 0; i < size; ++i) {
        QSslCipher cipher;
        cipher.d->isNull = false;
        cipher.d->name = QStringLiteral("Schannel");
        cipher.d->protocol = protocols[i];
        cipher.d->protocolString = protocolStrings[i];
        ciphers.append(cipher);
    }

    return ciphers;
}

QList<QSslError> QSslSocketBackendPrivate::verify(const QList<QSslCertificate> &certificateChain,
                                                  const QString &hostName)
{
    Q_UNUSED(certificateChain);
    Q_UNUSED(hostName);

    Q_UNIMPLEMENTED();
    return {}; // @future implement(?)
}

bool QSslSocketBackendPrivate::importPkcs12(QIODevice *device, QSslKey *key, QSslCertificate *cert,
                                            QList<QSslCertificate> *caCertificates,
                                            const QByteArray &passPhrase)
{
    Q_UNUSED(device);
    Q_UNUSED(key);
    Q_UNUSED(cert);
    Q_UNUSED(caCertificates);
    Q_UNUSED(passPhrase);
    // @future: can load into its own certificate store (encountered problems extracting key).
    Q_UNIMPLEMENTED();
    return false;
}

/*
    Copied from qsslsocket_mac.cpp, which was copied from qsslsocket_openssl.cpp
*/
bool QSslSocketBackendPrivate::checkSslErrors()
{
    if (sslErrors.isEmpty())
        return true;
    Q_Q(QSslSocket);

    emit q->sslErrors(sslErrors);

    const bool doVerifyPeer = configuration.peerVerifyMode == QSslSocket::VerifyPeer
            || (configuration.peerVerifyMode == QSslSocket::AutoVerifyPeer
                && mode == QSslSocket::SslClientMode);
    const bool doEmitSslError = !verifyErrorsHaveBeenIgnored();
    // check whether we need to emit an SSL handshake error
    if (doVerifyPeer && doEmitSslError) {
        if (q->pauseMode() & QAbstractSocket::PauseOnSslErrors) {
            pauseSocketNotifiers(q);
            paused = true;
        } else {
            setErrorAndEmit(QAbstractSocket::SslHandshakeFailedError,
                            sslErrors.constFirst().errorString());
            plainSocket->disconnectFromHost();
        }
        return false;
    }

    return true;
}

void QSslSocketBackendPrivate::initializeCertificateStores()
{
    //// helper function which turns a chain into a certificate store
    auto createStoreFromCertificateChain = [](const QList<QSslCertificate> certChain, const QSslKey &privateKey) {
        const wchar_t *passphrase = L"";
        // Need to embed the private key in the certificate
        QByteArray pkcs12 = _q_makePkcs12(certChain,
                                          privateKey,
                                          QString::fromWCharArray(passphrase, 0));
        CRYPT_DATA_BLOB pfxBlob;
        pfxBlob.cbData = DWORD(pkcs12.length());
        pfxBlob.pbData = reinterpret_cast<unsigned char *>(pkcs12.data());
        return QHCertStorePointer(PFXImportCertStore(&pfxBlob, passphrase, 0));
    };

    if (!configuration.localCertificateChain.isEmpty()) {
        if (configuration.privateKey.isNull()) {
            setErrorAndEmit(QAbstractSocket::SslInvalidUserDataError,
                            QSslSocket::tr("Cannot provide a certificate with no key"));
            return;
        }
        if (localCertificateStore == nullptr) {
            localCertificateStore = createStoreFromCertificateChain(configuration.localCertificateChain,
                                                                    configuration.privateKey);
            if (localCertificateStore == nullptr)
                qCWarning(lcSsl, "Failed to load certificate chain!");
        }
    }

    if (!configuration.caCertificates.isEmpty() && !caCertificateStore) {
        caCertificateStore = createStoreFromCertificateChain(configuration.caCertificates,
                                                             {}); // No private key for the CA certs
    }
}

bool QSslSocketBackendPrivate::verifyCertContext(CERT_CONTEXT *certContext)
{
    Q_ASSERT(certContext);
    Q_Q(QSslSocket);

    const bool isClient = mode == QSslSocket::SslClientMode;

    // Create a collection of stores so we can pass in multiple stores as additional locations to
    // search for the certificate chain
    auto tempCertCollection = QHCertStorePointer(CertOpenStore(CERT_STORE_PROV_COLLECTION,
                                                               X509_ASN_ENCODING,
                                                               0,
                                                               CERT_STORE_CREATE_NEW_FLAG,
                                                               nullptr));
    if (!tempCertCollection) {
#ifdef QSSLSOCKET_DEBUG
        qCWarning(lcSsl, "Failed to create certificate store collection!");
#endif
        return false;
    }

    if (rootCertOnDemandLoadingAllowed()) {
        // @future(maybe): following the OpenSSL backend these certificates should be added into
        // the Ca list, not just included during verification.
        // That being said, it's not trivial to add the root certificates (if and only if they
        // came from the system root store). And I don't see this mentioned in our documentation.
        auto rootStore = QHCertStorePointer(CertOpenSystemStore(0, L"ROOT"));
        if (!rootStore) {
#ifdef QSSLSOCKET_DEBUG
            qCWarning(lcSsl, "Failed to open the system root CA certificate store!");
#endif
            return false;
        } else if (!CertAddStoreToCollection(tempCertCollection.get(), rootStore.get(), 0, 1)) {
#ifdef QSSLSOCKET_DEBUG
            qCWarning(lcSsl, "Failed to add the system root CA certificate store to the certificate store collection!");
#endif
            return false;
        }
    }
    if (caCertificateStore) {
        if (!CertAddStoreToCollection(tempCertCollection.get(), caCertificateStore.get(), 0, 1)) {
#ifdef QSSLSOCKET_DEBUG
            qCWarning(lcSsl, "Failed to add the user's CA certificate store to the certificate store collection!");
#endif
            return false;
        }
    }

    if (!CertAddStoreToCollection(tempCertCollection.get(), certContext->hCertStore, 0, 0)) {
#ifdef QSSLSOCKET_DEBUG
        qCWarning(lcSsl, "Failed to add certificate's origin store to the certificate store collection!");
#endif
        return false;
    }

    CERT_CHAIN_PARA parameters;
    ZeroMemory(&parameters, sizeof(parameters));
    parameters.cbSize = sizeof(CERT_CHAIN_PARA);
    parameters.RequestedUsage.dwType = USAGE_MATCH_TYPE_AND;
    parameters.RequestedUsage.Usage.cUsageIdentifier = 1;
    LPSTR oid = LPSTR(isClient ? szOID_PKIX_KP_SERVER_AUTH
                               : szOID_PKIX_KP_CLIENT_AUTH);
    parameters.RequestedUsage.Usage.rgpszUsageIdentifier = &oid;

    configuration.peerCertificate.clear();
    configuration.peerCertificateChain.clear();
    const CERT_CHAIN_CONTEXT *chainContext = nullptr;
    auto freeCertChain = qScopeGuard([&chainContext]() {
        if (chainContext)
            CertFreeCertificateChain(chainContext);
    });
    BOOL status = CertGetCertificateChain(nullptr, // hChainEngine, default
                                          certContext, // pCertContext
                                          nullptr, // pTime, 'now'
                                          tempCertCollection.get(), // hAdditionalStore, additional cert store
                                          &parameters, // pChainPara
                                          CERT_CHAIN_REVOCATION_CHECK_CHAIN_EXCLUDE_ROOT, // dwFlags
                                          nullptr, // reserved
                                          &chainContext // ppChainContext
    );
    if (status == FALSE || !chainContext || chainContext->cChain == 0) {
        QSslError error(QSslError::UnableToVerifyFirstCertificate);
        sslErrors += error;
        emit q->peerVerifyError(error);
        return q->state() == QAbstractSocket::ConnectedState;
    }

    // Helper-function to get a QSslCertificate given a CERT_CHAIN_ELEMENT
    static auto getCertificateFromChainElement = [](CERT_CHAIN_ELEMENT *element) {
        if (!element)
            return QSslCertificate();

        const CERT_CONTEXT *certContext = element->pCertContext;
        return QSslCertificatePrivate::QSslCertificate_from_CERT_CONTEXT(certContext);
    };

    // Pick a chain to use as the certificate chain, if multiple are available:
    // According to https://docs.microsoft.com/en-gb/windows/desktop/api/wincrypt/ns-wincrypt-_cert_chain_context
    // this seems to be the best way to get a trusted chain.
    CERT_SIMPLE_CHAIN *chain = chainContext->rgpChain[chainContext->cChain - 1];

    if (chain->TrustStatus.dwErrorStatus & CERT_TRUST_IS_PARTIAL_CHAIN) {
        auto error = QSslError(QSslError::SslError::UnableToGetIssuerCertificate,
                               getCertificateFromChainElement(chain->rgpElement[chain->cElement - 1]));
        sslErrors += error;
        emit q->peerVerifyError(error);
        if (q->state() != QAbstractSocket::ConnectedState)
            return false;
    }
    if (chain->TrustStatus.dwErrorStatus & CERT_TRUST_INVALID_BASIC_CONSTRAINTS) {
        // @Note: This is actually one of two errors:
        // "either the certificate cannot be used to issue other certificates, or the chain path length has been exceeded."
        // But here we are checking the chain's status, so we assume the "issuing" error cannot occur here.
        auto error = QSslError(QSslError::PathLengthExceeded);
        sslErrors += error;
        emit q->peerVerifyError(error);
        if (q->state() != QAbstractSocket::ConnectedState)
            return false;
    }
    static const DWORD leftoverCertChainErrorMask = CERT_TRUST_IS_CYCLIC | CERT_TRUST_INVALID_EXTENSION
            | CERT_TRUST_INVALID_POLICY_CONSTRAINTS | CERT_TRUST_INVALID_NAME_CONSTRAINTS
            | CERT_TRUST_CTL_IS_NOT_TIME_VALID | CERT_TRUST_CTL_IS_NOT_SIGNATURE_VALID
            | CERT_TRUST_CTL_IS_NOT_VALID_FOR_USAGE;
    if (chain->TrustStatus.dwErrorStatus & leftoverCertChainErrorMask) {
        auto error = QSslError(QSslError::SslError::UnspecifiedError);
        sslErrors += error;
        emit q->peerVerifyError(error);
        if (q->state() != QAbstractSocket::ConnectedState)
            return false;
    }

    DWORD verifyDepth = chain->cElement;
    if (configuration.peerVerifyDepth > 0 && DWORD(configuration.peerVerifyDepth) < verifyDepth)
        verifyDepth = DWORD(configuration.peerVerifyDepth);

    for (DWORD i = 0; i < verifyDepth; i++) {
        CERT_CHAIN_ELEMENT *element = chain->rgpElement[i];
        QSslCertificate certificate = getCertificateFromChainElement(element);
        const QList<QSslCertificateExtension> extensions = certificate.extensions();

#ifdef QSSLSOCKET_DEBUG
        qCDebug(lcSsl) << "issuer:" << certificate.issuerDisplayName()
                       << "\nsubject:" << certificate.subjectDisplayName()
                       << "\nQSslCertificate info:" << certificate
                       << "\nextended error info:" << element->pwszExtendedErrorInfo
                       << "\nerror status:" << element->TrustStatus.dwErrorStatus;
#endif

        configuration.peerCertificateChain.append(certificate);

        if (certificate.isBlacklisted()) {
            const auto error = QSslError(QSslError::CertificateBlacklisted, certificate);
            sslErrors += error;
            emit q->peerVerifyError(error);
            if (q->state() != QAbstractSocket::ConnectedState)
                return false;
        }

        LONG result = CertVerifyTimeValidity(nullptr /*== now */, element->pCertContext->pCertInfo);
        if (result != 0) {
            auto error = QSslError(result == -1 ? QSslError::CertificateNotYetValid
                                                : QSslError::CertificateExpired,
                                   certificate);
            sslErrors += error;
            emit q->peerVerifyError(error);
            if (q->state() != QAbstractSocket::ConnectedState)
                return false;
        }

        //// Errors
        if (element->TrustStatus.dwErrorStatus & CERT_TRUST_IS_NOT_TIME_VALID) {
            // handled right above
            Q_ASSERT(!sslErrors.isEmpty());
        }
        if (element->TrustStatus.dwErrorStatus & CERT_TRUST_IS_REVOKED) {
            auto error = QSslError(QSslError::CertificateRevoked, certificate);
            sslErrors += error;
            emit q->peerVerifyError(error);
            if (q->state() != QAbstractSocket::ConnectedState)
                return false;
        }
        if (element->TrustStatus.dwErrorStatus & CERT_TRUST_IS_NOT_SIGNATURE_VALID) {
            auto error = QSslError(QSslError::CertificateSignatureFailed, certificate);
            sslErrors += error;
            emit q->peerVerifyError(error);
            if (q->state() != QAbstractSocket::ConnectedState)
                return false;
        }

        // While netscape shouldn't be relevant now it defined an extension which is
        // still in use. Schannel does not check this automatically, so we do it here.
        // It is used to differentiate between client and server certificates.
        if (netscapeWrongCertType(extensions, isClient))
            element->TrustStatus.dwErrorStatus |= CERT_TRUST_IS_NOT_VALID_FOR_USAGE;

        if (element->TrustStatus.dwErrorStatus & CERT_TRUST_IS_NOT_VALID_FOR_USAGE) {
            auto error = QSslError(QSslError::InvalidPurpose, certificate);
            sslErrors += error;
            emit q->peerVerifyError(error);
            if (q->state() != QAbstractSocket::ConnectedState)
                return false;
        }
        if (element->TrustStatus.dwErrorStatus & CERT_TRUST_IS_UNTRUSTED_ROOT) {
            // Override this error if we have the certificate inside our trusted CAs list.
            const bool isTrustedRoot = configuration.caCertificates.contains(certificate);
            if (!isTrustedRoot) {
                auto error = QSslError(QSslError::CertificateUntrusted, certificate);
                sslErrors += error;
                emit q->peerVerifyError(error);
                if (q->state() != QAbstractSocket::ConnectedState)
                    return false;
            }
        }
        static const DWORD certRevocationCheckUnavailableError = CERT_TRUST_IS_OFFLINE_REVOCATION
                | CERT_TRUST_REVOCATION_STATUS_UNKNOWN;
        if (element->TrustStatus.dwErrorStatus & certRevocationCheckUnavailableError) {
            // @future(maybe): Do something with this
        }

        // Dumping ground of errors that don't fit our specific errors
        static const DWORD leftoverCertErrorMask = CERT_TRUST_IS_CYCLIC
                | CERT_TRUST_INVALID_EXTENSION | CERT_TRUST_INVALID_NAME_CONSTRAINTS
                | CERT_TRUST_INVALID_POLICY_CONSTRAINTS
                | CERT_TRUST_HAS_EXCLUDED_NAME_CONSTRAINT
                | CERT_TRUST_HAS_NOT_SUPPORTED_CRITICAL_EXT
                | CERT_TRUST_HAS_NOT_DEFINED_NAME_CONSTRAINT
                | CERT_TRUST_HAS_NOT_PERMITTED_NAME_CONSTRAINT
                | CERT_TRUST_HAS_NOT_SUPPORTED_NAME_CONSTRAINT;
        if (element->TrustStatus.dwErrorStatus & leftoverCertErrorMask) {
            auto error = QSslError(QSslError::UnspecifiedError, certificate);
            sslErrors += error;
            emit q->peerVerifyError(error);
            if (q->state() != QAbstractSocket::ConnectedState)
                return false;
        }
        if (element->TrustStatus.dwErrorStatus & CERT_TRUST_INVALID_BASIC_CONSTRAINTS) {
            auto it = std::find_if(extensions.cbegin(), extensions.cend(),
                                   [](const QSslCertificateExtension &extension) {
                                       return extension.name() == QLatin1String("basicConstraints");
                                   });
            if (it != extensions.cend()) {
                // @Note: This is actually one of two errors:
                // "either the certificate cannot be used to issue other certificates,
                // or the chain path length has been exceeded."
                QVariantMap basicConstraints = it->value().toMap();
                QSslError error;
                if (i > 0 && !basicConstraints.value(QLatin1String("ca"), false).toBool())
                    error = QSslError(QSslError::InvalidPurpose, certificate);
                else
                    error = QSslError(QSslError::PathLengthExceeded, certificate);
                sslErrors += error;
                emit q->peerVerifyError(error);
                if (q->state() != QAbstractSocket::ConnectedState)
                    return false;
            }
        }
        if (element->TrustStatus.dwErrorStatus & CERT_TRUST_IS_EXPLICIT_DISTRUST) {
            auto error = QSslError(QSslError::CertificateBlacklisted, certificate);
            sslErrors += error;
            emit q->peerVerifyError(error);
            if (q->state() != QAbstractSocket::ConnectedState)
                return false;
        }

        if (element->TrustStatus.dwInfoStatus & CERT_TRUST_IS_SELF_SIGNED) {
            // If it's self-signed *and* a CA then we can assume it's a root CA certificate
            // and we can ignore the "self-signed" note:
            // We check the basicConstraints certificate extension when possible, but this didn't
            // exist for version 1, so we can only guess in that case
            const bool isRootCertificateAuthority = isCertificateAuthority(extensions)
                    || certificate.version() == "1";

            // Root certificate tends to be signed by themselves, so ignore self-signed status.
            if (!isRootCertificateAuthority) {
                auto error = QSslError(QSslError::SelfSignedCertificate, certificate);
                sslErrors += error;
                emit q->peerVerifyError(error);
                if (q->state() != QAbstractSocket::ConnectedState)
                    return false;
            }
        }
    }

    if (!configuration.peerCertificateChain.isEmpty())
        configuration.peerCertificate = configuration.peerCertificateChain.first();

    // @Note: Somewhat copied from qsslsocket_mac.cpp
    const bool doVerifyPeer = configuration.peerVerifyMode == QSslSocket::VerifyPeer
            || (configuration.peerVerifyMode == QSslSocket::AutoVerifyPeer
                && mode == QSslSocket::SslClientMode);
    // Check the peer certificate itself. First try the subject's common name
    // (CN) as a wildcard, then try all alternate subject name DNS entries the
    // same way.
    if (!configuration.peerCertificate.isNull()) {
        // but only if we're a client connecting to a server
        // if we're the server, don't check CN
        if (mode == QSslSocket::SslClientMode) {
            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);
                sslErrors += error;
                emit q->peerVerifyError(error);
                if (q->state() != QAbstractSocket::ConnectedState)
                    return false;
            }
        }
    } else if (doVerifyPeer) {
        // No peer certificate presented. Report as error if the socket
        // expected one.
        const QSslError error(QSslError::NoPeerCertificate);
        sslErrors += error;
        emit q->peerVerifyError(error);
        if (q->state() != QAbstractSocket::ConnectedState)
            return false;
    }

    return true;
}

bool QSslSocketBackendPrivate::rootCertOnDemandLoadingAllowed()
{
    return allowRootCertOnDemandLoading && s_loadRootCertsOnDemand;
}

QT_END_NAMESPACE
