mirror of https://github.com/qt/qtbase.git
Move plugin code from QtNetwork to qtbase/plugins
All TLS (and non-TLS) backends that QSsl classes rely on are now in plugins/tls (as openssl, securetransport, schannel and certonly plugins). For now, I have to disable some tests that were using OpenSSL calls - this to be refactored/re-thought. These include: qsslsocket auto-test (test-case where we work with private keys), qsslkey auto-test (similar to qsslsocket - test-case working with keys using OpenSSL calls). qasn1element moved to plugins too, so its auto-test have to be re-thought. Since now we can have more than one working TLS-backend on a given platform, the presence of OpenSSL also means I force this backend as active before running tests, to make sure features implemented only in OpenSSL-backend are tested. OCSP auto test is disabled for now, since it heavily relies on OpenSSL symbols (to be refactored). [ChangeLog][QtNetwork][QSslSocket] QSslSocket by default prefers 'openssl' backend if it is available. [ChangeLog][QtNetwork][QSslSocket] TLS-backends are not mutually exclusive anymore, depending on a platform, more than one TLS backend can be built. E.g., configuring Qt with -openssl does not prevent SecureTransport or Schannel plugin from being built. Fixes: QTBUG-91928 Change-Id: I4c05e32f10179066bee3a518bdfdd6c4b15320c3 Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org> Reviewed-by: Edward Welbourne <edward.welbourne@qt.io> Reviewed-by: Mårten Nordheim <marten.nordheim@qt.io>
This commit is contained in:
parent
6b1a7341fe
commit
d385158d52
|
@ -5,7 +5,7 @@
|
|||
#####################################################################
|
||||
|
||||
qt_internal_add_module(Network
|
||||
PLUGIN_TYPES networkaccessbackends networkinformationbackends
|
||||
PLUGIN_TYPES networkaccessbackends networkinformationbackends tls
|
||||
SOURCES
|
||||
access/qabstractnetworkcache.cpp access/qabstractnetworkcache.h access/qabstractnetworkcache_p.h
|
||||
access/qhsts.cpp access/qhsts_p.h
|
||||
|
@ -41,15 +41,11 @@ qt_internal_add_module(Network
|
|||
socket/qtcpserver.cpp socket/qtcpserver.h socket/qtcpserver_p.h
|
||||
socket/qtcpsocket.cpp socket/qtcpsocket.h socket/qtcpsocket_p.h
|
||||
socket/qudpsocket.cpp socket/qudpsocket.h
|
||||
ssl/qasn1element.cpp ssl/qasn1element_p.h
|
||||
ssl/qpassworddigestor.cpp ssl/qpassworddigestor.h
|
||||
ssl/qssl.cpp ssl/qssl.h ssl/qssl_p.h
|
||||
ssl/qsslcertificate.cpp ssl/qsslcertificate.h ssl/qsslcertificate_p.h
|
||||
ssl/qsslcertificateextension.cpp ssl/qsslcertificateextension.h ssl/qsslcertificateextension_p.h
|
||||
ssl/qtlsbackend.cpp ssl/qtlsbackend_p.h
|
||||
ssl/qtlsbackend_cert.cpp ssl/qtlsbackend_cert_p.h
|
||||
ssl/qx509_base.cpp ssl/qx509_base_p.h
|
||||
ssl/qx509_generic.cpp ssl/qx509_generic_p.h
|
||||
DEFINES
|
||||
QT_NO_FOREACH
|
||||
QT_NO_USING_NAMESPACE
|
||||
|
@ -324,59 +320,11 @@ qt_internal_extend_target(Network CONDITION QT_FEATURE_ssl
|
|||
ssl/qsslkey.h ssl/qsslkey_p.cpp ssl/qsslkey_p.h
|
||||
ssl/qsslpresharedkeyauthenticator.cpp ssl/qsslpresharedkeyauthenticator.h ssl/qsslpresharedkeyauthenticator_p.h
|
||||
ssl/qsslsocket.cpp ssl/qsslsocket.h ssl/qsslsocket_p.h
|
||||
ssl/qtlskey_base.cpp ssl/qtlskey_base_p.h
|
||||
)
|
||||
|
||||
qt_internal_extend_target(Network CONDITION QT_FEATURE_schannel AND QT_FEATURE_ssl
|
||||
SOURCES
|
||||
ssl/qsslsocket_qt.cpp
|
||||
ssl/qwincrypt_p.h
|
||||
ssl/qtls_schannel.cpp ssl/qtls_schannel_p.h
|
||||
ssl/qtlsbackend_schannel_p.h
|
||||
ssl/qtlskey_generic.cpp ssl/qtlskey_generic_p.h
|
||||
ssl/qtlskey_schannel.cpp ssl/qtlskey_schannel_p.h
|
||||
ssl/qx509_schannel.cpp ssl/qx509_schannel_p.h
|
||||
LIBRARIES
|
||||
Crypt32
|
||||
Secur32
|
||||
bcrypt
|
||||
ncrypt
|
||||
)
|
||||
|
||||
qt_internal_extend_target(Network CONDITION QT_FEATURE_securetransport AND QT_FEATURE_ssl
|
||||
SOURCES
|
||||
ssl/qtls_st.cpp ssl/qtls_st_p.h
|
||||
ssl/qsslsocket_mac_shared.cpp
|
||||
ssl/qsslsocket_qt.cpp
|
||||
ssl/qtlskey_generic.cpp ssl/qtlskey_generic_p.h
|
||||
ssl/qtlskey_st.cpp ssl/qtlskey_st_p.h
|
||||
ssl/qtlsbackend_st.cpp ssl/qtlsbackend_st_p.h
|
||||
ssl/qx509_st.cpp ssl/qx509_st_p.h
|
||||
)
|
||||
|
||||
qt_internal_extend_target(Network CONDITION QT_FEATURE_dtls AND QT_FEATURE_ssl
|
||||
SOURCES
|
||||
ssl/qdtls.cpp ssl/qdtls.h ssl/qdtls_p.h
|
||||
ssl/qdtls_base.cpp ssl/qdtls_base_p.h
|
||||
)
|
||||
|
||||
qt_internal_extend_target(Network CONDITION QT_FEATURE_openssl AND QT_FEATURE_ssl
|
||||
SOURCES
|
||||
ssl/qsslcontext_openssl.cpp ssl/qsslcontext_openssl_p.h
|
||||
ssl/qssldiffiehellmanparameters_openssl.cpp
|
||||
ssl/qopenssl.cpp ssl/qopenssl_p.h
|
||||
ssl/qsslsocket_openssl_symbols.cpp ssl/qsslsocket_openssl_symbols_p.h
|
||||
ssl/qtls_openssl.cpp ssl/qtls_openssl_p.h
|
||||
ssl/qtlskey_openssl.cpp ssl/qtlskey_openssl_p.h
|
||||
ssl/qtlsbackend_openssl.cpp ssl/qtlsbackend_openssl_p.h
|
||||
ssl/qx509_openssl.cpp ssl/qx509_openssl_p.h
|
||||
DEFINES
|
||||
OPENSSL_API_COMPAT=0x10100000L
|
||||
)
|
||||
|
||||
qt_internal_extend_target(Network CONDITION QT_FEATURE_dtls AND QT_FEATURE_openssl AND QT_FEATURE_ssl
|
||||
SOURCES
|
||||
ssl/qdtls_openssl.cpp ssl/qdtls_openssl_p.h
|
||||
)
|
||||
|
||||
qt_internal_extend_target(Network CONDITION QT_FEATURE_ocsp AND QT_FEATURE_openssl AND QT_FEATURE_ssl
|
||||
|
@ -384,16 +332,6 @@ qt_internal_extend_target(Network CONDITION QT_FEATURE_ocsp AND QT_FEATURE_opens
|
|||
ssl/qocsp_p.h
|
||||
)
|
||||
|
||||
qt_internal_extend_target(Network CONDITION APPLE AND QT_FEATURE_openssl AND QT_FEATURE_ssl
|
||||
SOURCES
|
||||
ssl/qsslsocket_mac_shared.cpp
|
||||
)
|
||||
|
||||
qt_internal_extend_target(Network CONDITION ANDROID AND QT_FEATURE_openssl AND QT_FEATURE_ssl AND NOT ANDROID_EMBEDDED
|
||||
SOURCES
|
||||
ssl/qsslsocket_openssl_android.cpp
|
||||
)
|
||||
|
||||
qt_internal_extend_target(Network CONDITION QT_FEATURE_openssl AND QT_FEATURE_openssl_linked AND QT_FEATURE_ssl
|
||||
LIBRARIES
|
||||
WrapOpenSSL::WrapOpenSSL
|
||||
|
@ -408,13 +346,6 @@ qt_internal_extend_target(Network CONDITION QT_FEATURE_openssl AND QT_FEATURE_ss
|
|||
WrapOpenSSLHeaders::WrapOpenSSLHeaders
|
||||
)
|
||||
|
||||
qt_internal_extend_target(Network CONDITION QT_FEATURE_openssl AND QT_FEATURE_ssl AND WIN32
|
||||
SOURCES
|
||||
ssl/qwindowscarootfetcher.cpp ssl/qwindowscarootfetcher_p.h
|
||||
LIBRARIES
|
||||
crypt32
|
||||
)
|
||||
|
||||
qt_internal_extend_target(Network CONDITION QT_FEATURE_dnslookup AND UNIX AND NOT ANDROID AND NOT INTEGRITY
|
||||
SOURCES
|
||||
kernel/qdnslookup_unix.cpp
|
||||
|
|
|
@ -263,27 +263,26 @@ qt_feature_definition("openssl" "QT_NO_OPENSSL" NEGATE)
|
|||
qt_feature_config("openssl" QMAKE_PUBLIC_QT_CONFIG)
|
||||
qt_feature("openssl-runtime"
|
||||
AUTODETECT NOT WASM
|
||||
CONDITION NOT QT_FEATURE_securetransport AND NOT QT_FEATURE_schannel AND TEST_openssl_headers
|
||||
CONDITION TEST_openssl_headers
|
||||
ENABLE INPUT_openssl STREQUAL 'yes' OR INPUT_openssl STREQUAL 'runtime'
|
||||
DISABLE INPUT_openssl STREQUAL 'no' OR INPUT_openssl STREQUAL 'linked' OR INPUT_ssl STREQUAL 'no'
|
||||
)
|
||||
qt_feature("openssl-linked" PRIVATE
|
||||
LABEL " Qt directly linked to OpenSSL"
|
||||
AUTODETECT OFF
|
||||
CONDITION NOT QT_FEATURE_securetransport AND NOT QT_FEATURE_schannel AND TEST_openssl
|
||||
CONDITION TEST_openssl
|
||||
ENABLE INPUT_openssl STREQUAL 'linked'
|
||||
)
|
||||
qt_feature_definition("openssl-linked" "QT_LINKED_OPENSSL")
|
||||
qt_feature("securetransport" PUBLIC
|
||||
LABEL "SecureTransport"
|
||||
CONDITION APPLE AND ( INPUT_openssl STREQUAL '' OR INPUT_openssl STREQUAL 'no' )
|
||||
CONDITION APPLE
|
||||
DISABLE INPUT_ssl STREQUAL 'no'
|
||||
)
|
||||
qt_feature_definition("securetransport" "QT_SECURETRANSPORT")
|
||||
qt_feature("schannel" PUBLIC
|
||||
LABEL "Schannel"
|
||||
AUTODETECT OFF
|
||||
CONDITION WIN32 AND ( INPUT_openssl STREQUAL '' OR INPUT_openssl STREQUAL 'no' )
|
||||
CONDITION WIN32
|
||||
DISABLE INPUT_ssl STREQUAL 'no'
|
||||
)
|
||||
qt_feature_definition("schannel" "QT_SCHANNEL")
|
||||
|
|
|
@ -284,13 +284,13 @@
|
|||
"autoDetect": "!config.wasm",
|
||||
"enable": "input.openssl == 'yes' || input.openssl == 'runtime'",
|
||||
"disable": "input.openssl == 'no' || input.openssl == 'linked' || input.ssl == 'no'",
|
||||
"condition": "!features.securetransport && !features.schannel && libs.openssl_headers"
|
||||
"condition": "libs.openssl_headers"
|
||||
},
|
||||
"openssl-linked": {
|
||||
"label": " Qt directly linked to OpenSSL",
|
||||
"autoDetect": false,
|
||||
"enable": "input.openssl == 'linked'",
|
||||
"condition": "!features.securetransport && !features.schannel && libs.openssl",
|
||||
"condition": "libs.openssl",
|
||||
"output": [
|
||||
"privateFeature",
|
||||
{ "type": "define", "name": "QT_LINKED_OPENSSL" }
|
||||
|
@ -299,7 +299,7 @@
|
|||
"securetransport": {
|
||||
"label": "SecureTransport",
|
||||
"disable": "input.ssl == 'no'",
|
||||
"condition": "config.darwin && (input.openssl == '' || input.openssl == 'no')",
|
||||
"condition": "config.darwin",
|
||||
"output": [
|
||||
"publicFeature",
|
||||
{ "type": "define", "name": "QT_SECURETRANSPORT" }
|
||||
|
@ -309,7 +309,7 @@
|
|||
"label": "Schannel",
|
||||
"autoDetect": false,
|
||||
"disable": "input.ssl == 'no'",
|
||||
"condition": "config.win32 && (input.openssl == '' || input.openssl == 'no')",
|
||||
"condition": "config.win32",
|
||||
"output": [
|
||||
"publicFeature",
|
||||
{ "type": "define", "name": "QT_SCHANNEL" }
|
||||
|
|
|
@ -1,71 +0,0 @@
|
|||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2021 The Qt Company Ltd.
|
||||
** Copyright (C) 2014 Governikus GmbH & Co. KG
|
||||
** 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$
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
**
|
||||
** In addition, as a special exception, the copyright holders listed above give
|
||||
** permission to link the code of its release of Qt with the OpenSSL project's
|
||||
** "OpenSSL" library (or modified versions of the "OpenSSL" library that use the
|
||||
** same license as the original version), and distribute the linked executables.
|
||||
**
|
||||
** You must comply with the GNU General Public License version 2 in all
|
||||
** respects for all of the code used other than the "OpenSSL" code. If you
|
||||
** modify this file, you may extend this exception to your version of the file,
|
||||
** but you are not obligated to do so. If you do not wish to do so, delete
|
||||
** this exception statement from your version of this file.
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#include "qtlsbackend_openssl_p.h"
|
||||
#include "qopenssl_p.h"
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
Q_GLOBAL_STATIC(QTlsBackendOpenSSL, backendOpenSsl)
|
||||
|
||||
void QSslSocketPrivate::registerAdHocFactory()
|
||||
{
|
||||
// TLSTODO: this is a temporary solution, waiting for
|
||||
// backends to move to ... plugins.
|
||||
if (!backendOpenSsl())
|
||||
qCWarning(lcSsl, "Failed to create backend factory");
|
||||
}
|
||||
|
||||
QT_END_NAMESPACE
|
|
@ -57,12 +57,8 @@
|
|||
#include "qssl_p.h"
|
||||
#include "qsslkey.h"
|
||||
#include "qsslkey_p.h"
|
||||
#ifndef QT_NO_OPENSSL
|
||||
#include "qsslsocket_openssl_symbols_p.h"
|
||||
#endif
|
||||
#include "qsslsocket.h"
|
||||
#include "qsslsocket_p.h"
|
||||
#include "qasn1element_p.h"
|
||||
#include "qtlsbackend_p.h"
|
||||
|
||||
#include <QtCore/qatomic.h>
|
||||
|
|
|
@ -73,8 +73,8 @@ public:
|
|||
|
||||
using Cipher = QTlsPrivate::Cipher;
|
||||
|
||||
Q_AUTOTEST_EXPORT static QByteArray decrypt(Cipher cipher, const QByteArray &data, const QByteArray &key, const QByteArray &iv);
|
||||
Q_AUTOTEST_EXPORT static QByteArray encrypt(Cipher cipher, const QByteArray &data, const QByteArray &key, const QByteArray &iv);
|
||||
Q_NETWORK_EXPORT static QByteArray decrypt(Cipher cipher, const QByteArray &data, const QByteArray &key, const QByteArray &iv);
|
||||
Q_NETWORK_EXPORT static QByteArray encrypt(Cipher cipher, const QByteArray &data, const QByteArray &key, const QByteArray &iv);
|
||||
|
||||
std::unique_ptr<QTlsPrivate::TlsKey> backend;
|
||||
QAtomicInt ref;
|
||||
|
|
|
@ -1573,7 +1573,7 @@ QList<QString> QSslSocket::availableBackends()
|
|||
from the list of available backends.
|
||||
|
||||
\note When selecting a default backend implicitly, QSslSocket prefers
|
||||
native backends, such as SecureTransport on Darwin, or Schannel on Windows.
|
||||
the OpenSSL backend if available.
|
||||
|
||||
\sa setActiveBackend(), availableBackends()
|
||||
*/
|
||||
|
|
|
@ -103,7 +103,7 @@ public:
|
|||
static bool s_loadRootCertsOnDemand;
|
||||
|
||||
static bool supportsSsl();
|
||||
static void ensureInitialized();
|
||||
Q_NETWORK_EXPORT static void ensureInitialized();
|
||||
|
||||
static QList<QSslCipher> defaultCiphers();
|
||||
static QList<QSslCipher> defaultDtlsCiphers();
|
||||
|
@ -117,7 +117,7 @@ public:
|
|||
static void resetDefaultEllipticCurves();
|
||||
|
||||
static QList<QSslCertificate> defaultCaCertificates();
|
||||
static QList<QSslCertificate> systemCaCertificates();
|
||||
Q_NETWORK_EXPORT static QList<QSslCertificate> systemCaCertificates();
|
||||
static void setDefaultCaCertificates(const QList<QSslCertificate> &certs);
|
||||
static void addDefaultCaCertificate(const QSslCertificate &cert);
|
||||
static void addDefaultCaCertificates(const QList<QSslCertificate> &certs);
|
||||
|
@ -168,7 +168,6 @@ public:
|
|||
Q_NETWORK_PRIVATE_EXPORT static void setRootCertOnDemandLoadingSupported(bool supported);
|
||||
|
||||
static QTlsBackend *tlsBackendInUse();
|
||||
static void registerAdHocFactory();
|
||||
|
||||
// Needed by TlsCryptograph:
|
||||
Q_NETWORK_PRIVATE_EXPORT QSslSocket::SslMode tlsMode() const;
|
||||
|
|
|
@ -46,8 +46,6 @@
|
|||
#include "qsslcipher_p.h"
|
||||
#include "qsslkey_p.h"
|
||||
#include "qsslkey.h"
|
||||
#else
|
||||
#include "qtlsbackend_cert_p.h"
|
||||
#endif
|
||||
|
||||
#include "qssl_p.h"
|
||||
|
@ -63,7 +61,7 @@
|
|||
QT_BEGIN_NAMESPACE
|
||||
|
||||
Q_GLOBAL_STATIC_WITH_ARGS(QFactoryLoader, loader,
|
||||
(QTlsBackend_iid, QStringLiteral("/tlsbackends")))
|
||||
(QTlsBackend_iid, QStringLiteral("/tls")))
|
||||
|
||||
namespace {
|
||||
|
||||
|
@ -104,14 +102,6 @@ public:
|
|||
while (loader->instance(index))
|
||||
++index;
|
||||
|
||||
// TLSTODO: obviously, these two below should
|
||||
// disappear as soon as plugins are in place.
|
||||
#if QT_CONFIG(ssl)
|
||||
QSslSocketPrivate::registerAdHocFactory();
|
||||
#else
|
||||
static QTlsBackendCertOnly certGenerator;
|
||||
#endif // QT_CONFIG(ssl)
|
||||
|
||||
return loaded = true;
|
||||
}
|
||||
|
||||
|
@ -244,6 +234,13 @@ bool TlsCryptograph::isMatchingHostname(const QString &cn, const QString &hostna
|
|||
return QSslSocketPrivate::isMatchingHostname(cn, hostname);
|
||||
}
|
||||
|
||||
void TlsCryptograph::setErrorAndEmit(QSslSocketPrivate *d, QAbstractSocket::SocketError errorCode,
|
||||
const QString &errorDescription) const
|
||||
{
|
||||
Q_ASSERT(d);
|
||||
d->setErrorAndEmit(errorCode, errorDescription);
|
||||
}
|
||||
|
||||
#endif // QT_CONFIG(ssl)
|
||||
|
||||
#if QT_CONFIG(dtls)
|
||||
|
@ -255,7 +252,8 @@ DtlsBase::~DtlsBase() = default;
|
|||
const QString QTlsBackend::builtinBackendNames[] = {
|
||||
QStringLiteral("schannel"),
|
||||
QStringLiteral("securetransport"),
|
||||
QStringLiteral("openssl")
|
||||
QStringLiteral("openssl"),
|
||||
QStringLiteral("cert-only")
|
||||
};
|
||||
|
||||
QTlsBackend::QTlsBackend()
|
||||
|
@ -436,17 +434,24 @@ QList<QString> QTlsBackend::availableBackendNames()
|
|||
|
||||
QString QTlsBackend::defaultBackendName()
|
||||
{
|
||||
// We prefer native as default:
|
||||
// We prefer OpenSSL as default:
|
||||
const auto names = availableBackendNames();
|
||||
auto name = builtinBackendNames[nameIndexSchannel];
|
||||
auto name = builtinBackendNames[nameIndexOpenSSL];
|
||||
if (names.contains(name))
|
||||
return name;
|
||||
name = builtinBackendNames[nameIndexSchannel];
|
||||
if (names.contains(name))
|
||||
return name;
|
||||
name = builtinBackendNames[nameIndexSecureTransport];
|
||||
if (names.contains(name))
|
||||
return name;
|
||||
name = builtinBackendNames[nameIndexOpenSSL];
|
||||
if (names.contains(name))
|
||||
return name;
|
||||
|
||||
const auto pos = std::find_if(names.begin(), names.end(), [](const auto &name) {
|
||||
return name != builtinBackendNames[nameIndexCertOnly];
|
||||
});
|
||||
|
||||
if (pos != names.end())
|
||||
return *pos;
|
||||
|
||||
if (names.size())
|
||||
return names[0];
|
||||
|
@ -787,6 +792,16 @@ void QTlsBackend::setEphemeralKey(QSslSocketPrivate *d, const QSslKey &key)
|
|||
d->configuration.ephemeralServerKey = key;
|
||||
}
|
||||
|
||||
void QTlsBackend::forceAutotestSecurityLevel()
|
||||
{
|
||||
}
|
||||
|
||||
Q_NETWORK_EXPORT void qt_ForceTlsSecurityLevel()
|
||||
{
|
||||
if (auto *backend = QSslSocketPrivate::tlsBackendInUse())
|
||||
backend->forceAutotestSecurityLevel();
|
||||
}
|
||||
|
||||
#endif // QT_CONFIG(ssl)
|
||||
|
||||
QT_END_NAMESPACE
|
||||
|
|
|
@ -226,6 +226,9 @@ public:
|
|||
|
||||
static bool isMatchingHostname(const QSslCertificate &cert, const QString &peerName);
|
||||
static bool isMatchingHostname(const QString &cn, const QString &hostname);
|
||||
|
||||
void setErrorAndEmit(QSslSocketPrivate *d, QAbstractSocket::SocketError errorCode,
|
||||
const QString &errorDescription) const;
|
||||
};
|
||||
#else
|
||||
class TlsCryptograph;
|
||||
|
@ -371,6 +374,7 @@ public:
|
|||
static constexpr const int nameIndexSchannel = 0;
|
||||
static constexpr const int nameIndexSecureTransport = 1;
|
||||
static constexpr const int nameIndexOpenSSL = 2;
|
||||
static constexpr const int nameIndexCertOnly = 3;
|
||||
|
||||
static const QString builtinBackendNames[];
|
||||
|
||||
|
@ -428,6 +432,8 @@ public:
|
|||
static void addTustedRoot(QSslSocketPrivate *d, const QSslCertificate &rootCert);
|
||||
// The next one - is a "very important" feature! Kidding ...
|
||||
static void setEphemeralKey(QSslSocketPrivate *d, const QSslKey &key);
|
||||
|
||||
virtual void forceAutotestSecurityLevel();
|
||||
#endif // QT_CONFIG(ssl)
|
||||
|
||||
Q_DISABLE_COPY_MOVE(QTlsBackend)
|
||||
|
|
|
@ -22,4 +22,5 @@ if(TARGET Qt::PrintSupport)
|
|||
endif()
|
||||
if (TARGET Qt::Network)
|
||||
add_subdirectory(networkinformationbackends)
|
||||
add_subdirectory(tls)
|
||||
endif()
|
||||
|
|
|
@ -0,0 +1,13 @@
|
|||
if(QT_FEATURE_securetransport)
|
||||
add_subdirectory(securetransport)
|
||||
endif()
|
||||
|
||||
if (QT_FEATURE_openssl OR QT_FEATURE_openssl_linked)
|
||||
add_subdirectory(openssl)
|
||||
endif()
|
||||
|
||||
if (QT_FEATURE_schannel)
|
||||
add_subdirectory(schannel)
|
||||
endif()
|
||||
|
||||
add_subdirectory(certonly)
|
|
@ -0,0 +1,16 @@
|
|||
qt_internal_add_plugin(QTlsBackendCertOnly
|
||||
OUTPUT_NAME certonlybackend
|
||||
CLASS_NAME QTlsBackendCertOnly
|
||||
TYPE tls
|
||||
SOURCES
|
||||
../shared/qx509_base_p.h
|
||||
../shared/qx509_base.cpp
|
||||
../shared/qx509_generic_p.h
|
||||
../shared/qx509_generic.cpp
|
||||
../shared/qasn1element_p.h
|
||||
../shared/qasn1element.cpp
|
||||
qtlsbackend_cert.cpp
|
||||
qtlsbackend_cert_p.h
|
||||
PUBLIC_LIBRARIES
|
||||
Qt::NetworkPrivate
|
||||
)
|
|
@ -39,9 +39,7 @@
|
|||
|
||||
#include "qtlsbackend_cert_p.h"
|
||||
|
||||
#ifdef QT_NO_SSL
|
||||
|
||||
#include "qx509_generic_p.h"
|
||||
#include "../shared/qx509_generic_p.h"
|
||||
|
||||
#include <qssl.h>
|
||||
|
||||
|
@ -53,7 +51,7 @@ Q_LOGGING_CATEGORY(lcTlsBackend, "qt.tlsbackend.cert-only");
|
|||
|
||||
QString QTlsBackendCertOnly::backendName() const
|
||||
{
|
||||
return QStringLiteral("cert-only");
|
||||
return builtinBackendNames[nameIndexCertOnly];
|
||||
}
|
||||
|
||||
|
||||
|
@ -92,5 +90,3 @@ QTlsPrivate::X509DerReaderPtr QTlsBackendCertOnly::X509DerReader() const
|
|||
|
||||
QT_END_NAMESPACE
|
||||
|
||||
#endif // QT_NO_SSL
|
||||
|
|
@ -51,19 +51,19 @@
|
|||
// We mean it.
|
||||
//
|
||||
|
||||
#include <private/qtnetworkglobal_p.h>
|
||||
#include <QtNetwork/private/qtnetworkglobal_p.h>
|
||||
|
||||
#include "qtlsbackend_p.h"
|
||||
#include <QtNetwork/private/qtlsbackend_p.h>
|
||||
|
||||
#include <QtCore/qglobal.h>
|
||||
|
||||
#ifdef QT_NO_SSL
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
class QTlsBackendCertOnly final : public QTlsBackend
|
||||
{
|
||||
public:
|
||||
Q_OBJECT
|
||||
Q_PLUGIN_METADATA(IID QTlsBackend_iid)
|
||||
Q_INTERFACES(QTlsBackend)
|
||||
private:
|
||||
QString backendName() const override;
|
||||
|
||||
|
@ -78,6 +78,4 @@ private:
|
|||
|
||||
QT_END_NAMESPACE
|
||||
|
||||
#endif // QT_NO_SSL
|
||||
|
||||
#endif // QTLSBACKEND_CERT_P_H
|
|
@ -0,0 +1,51 @@
|
|||
qt_internal_add_plugin(QTlsBackendOpenSSL
|
||||
OUTPUT_NAME opensslbackend
|
||||
CLASS_NAME QTlsBackendOpenSSL
|
||||
TYPE tls
|
||||
SOURCES
|
||||
../shared/qx509_base.cpp ../shared/qx509_base_p.h
|
||||
../shared/qtlskey_base.cpp ../shared/qtlskey_base_p.h
|
||||
../shared/qasn1element.cpp ../shared/qasn1element_p.h
|
||||
qtlsbackend_openssl.cpp qtlsbackend_openssl_p.h
|
||||
qx509_openssl.cpp qx509_openssl_p.h
|
||||
qtlskey_openssl.cpp qtlskey_openssl_p.h
|
||||
qtls_openssl.cpp qtls_openssl_p.h
|
||||
qssldiffiehellmanparameters_openssl.cpp
|
||||
qsslcontext_openssl.cpp qsslcontext_openssl_p.h
|
||||
qsslsocket_openssl_symbols.cpp qsslsocket_openssl_symbols_p.h
|
||||
qopenssl_p.h
|
||||
PUBLIC_LIBRARIES
|
||||
Qt::NetworkPrivate
|
||||
Qt::CorePrivate
|
||||
DEFINES
|
||||
OPENSSL_API_COMPAT=0x10100000L
|
||||
)
|
||||
|
||||
qt_internal_extend_target(QTlsBackendOpenSSL CONDITION QT_FEATURE_dtls
|
||||
SOURCES
|
||||
qdtls_openssl.cpp qdtls_openssl_p.h
|
||||
../shared/qdtls_base.cpp ../shared/qdtls_base_p.h
|
||||
)
|
||||
|
||||
qt_internal_extend_target(QTlsBackendOpenSSL CONDITION APPLE
|
||||
SOURCES
|
||||
../shared/qsslsocket_mac_shared.cpp
|
||||
LIBRARIES
|
||||
${FWCoreFoundation}
|
||||
${FWSecurity}
|
||||
)
|
||||
|
||||
qt_internal_extend_target(QTlsBackendOpenSSL CONDITION ANDROID AND NOT ANDROID_EMBEDDED
|
||||
SOURCES
|
||||
qsslsocket_openssl_android.cpp
|
||||
)
|
||||
|
||||
qt_internal_extend_target(QTlsBackendOpenSSL CONDITION QT_FEATURE_openssl
|
||||
AND QT_FEATURE_ssl AND WIN32
|
||||
SOURCES
|
||||
qwindowscarootfetcher.cpp qwindowscarootfetcher_p.h
|
||||
../shared/qwincrypt_p.h
|
||||
LIBRARIES
|
||||
crypt32
|
||||
)
|
||||
|
|
@ -40,20 +40,23 @@
|
|||
#ifndef NOMINMAX
|
||||
#define NOMINMAX
|
||||
#endif // NOMINMAX
|
||||
#include "private/qnativesocketengine_p.h"
|
||||
|
||||
#include "qsslpresharedkeyauthenticator_p.h"
|
||||
#include <QtNetwork/private/qnativesocketengine_p.h>
|
||||
|
||||
#include "qsslsocket_openssl_symbols_p.h"
|
||||
#include "qsslcertificate_p.h"
|
||||
#include "qdtls_openssl_p.h"
|
||||
#include "qx509_openssl_p.h"
|
||||
#include "qudpsocket.h"
|
||||
#include "qssl_p.h"
|
||||
|
||||
#include "qmessageauthenticationcode.h"
|
||||
#include "qcryptographichash.h"
|
||||
#include <QtNetwork/private/qsslpresharedkeyauthenticator_p.h>
|
||||
#include <QtNetwork/private/qsslcertificate_p.h>
|
||||
#include <QtNetwork/private/qssl_p.h>
|
||||
|
||||
#include "qdebug.h"
|
||||
#include <QtNetwork/qudpsocket.h>
|
||||
|
||||
#include <QtCore/qmessageauthenticationcode.h>
|
||||
#include <QtCore/qcryptographichash.h>
|
||||
|
||||
#include <QtCore/qdebug.h>
|
||||
|
||||
#include <cstring>
|
||||
#include <cstddef>
|
||||
|
@ -84,13 +87,13 @@ QByteArray cookie_for_peer(SSL *ssl)
|
|||
// SSL_get_rbio does not increment the reference count
|
||||
BIO *readBIO = q_SSL_get_rbio(ssl);
|
||||
if (!readBIO) {
|
||||
qCWarning(lcSsl, "No BIO (dgram) found in SSL object");
|
||||
qCWarning(lcTlsBackend, "No BIO (dgram) found in SSL object");
|
||||
return {};
|
||||
}
|
||||
|
||||
auto listener = static_cast<dtlsopenssl::DtlsState *>(q_BIO_get_app_data(readBIO));
|
||||
if (!listener) {
|
||||
qCWarning(lcSsl, "BIO_get_app_data returned invalid (nullptr) value");
|
||||
qCWarning(lcTlsBackend, "BIO_get_app_data returned invalid (nullptr) value");
|
||||
return {};
|
||||
}
|
||||
|
||||
|
@ -192,14 +195,14 @@ extern "C" int q_generate_cookie_callback(SSL *ssl, unsigned char *dst,
|
|||
unsigned *cookieLength)
|
||||
{
|
||||
if (!ssl || !dst || !cookieLength) {
|
||||
qCWarning(lcSsl,
|
||||
qCWarning(lcTlsBackend,
|
||||
"Failed to generate cookie - invalid (nullptr) parameter(s)");
|
||||
return 0;
|
||||
}
|
||||
|
||||
void *generic = q_SSL_get_ex_data(ssl, QTlsBackendOpenSSL::s_indexForSSLExtraData);
|
||||
if (!generic) {
|
||||
qCWarning(lcSsl, "SSL_get_ex_data returned nullptr, cannot generate cookie");
|
||||
qCWarning(lcTlsBackend, "SSL_get_ex_data returned nullptr, cannot generate cookie");
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -228,7 +231,7 @@ extern "C" int q_verify_cookie_callback(SSL *ssl, const unsigned char *cookie,
|
|||
unsigned cookieLength)
|
||||
{
|
||||
if (!ssl || !cookie || !cookieLength) {
|
||||
qCWarning(lcSsl, "Could not verify cookie, invalid (nullptr or zero) parameters");
|
||||
qCWarning(lcTlsBackend, "Could not verify cookie, invalid (nullptr or zero) parameters");
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -247,13 +250,13 @@ extern "C" int q_X509DtlsCallback(int ok, X509_STORE_CTX *ctx)
|
|||
// Store the error and at which depth the error was detected.
|
||||
SSL *ssl = static_cast<SSL *>(q_X509_STORE_CTX_get_ex_data(ctx, q_SSL_get_ex_data_X509_STORE_CTX_idx()));
|
||||
if (!ssl) {
|
||||
qCWarning(lcSsl, "X509_STORE_CTX_get_ex_data returned nullptr, handshake failure");
|
||||
qCWarning(lcTlsBackend, "X509_STORE_CTX_get_ex_data returned nullptr, handshake failure");
|
||||
return 0;
|
||||
}
|
||||
|
||||
void *generic = q_SSL_get_ex_data(ssl, QTlsBackendOpenSSL::s_indexForSSLExtraData);
|
||||
if (!generic) {
|
||||
qCWarning(lcSsl, "SSL_get_ex_data returned nullptr, handshake failure");
|
||||
qCWarning(lcTlsBackend, "SSL_get_ex_data returned nullptr, handshake failure");
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -300,7 +303,7 @@ namespace dtlsbio
|
|||
extern "C" int q_dgram_read(BIO *bio, char *dst, int bytesToRead)
|
||||
{
|
||||
if (!bio || !dst || bytesToRead <= 0) {
|
||||
qCWarning(lcSsl, "invalid input parameter(s)");
|
||||
qCWarning(lcTlsBackend, "invalid input parameter(s)");
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -330,7 +333,7 @@ extern "C" int q_dgram_read(BIO *bio, char *dst, int bytesToRead)
|
|||
extern "C" int q_dgram_write(BIO *bio, const char *src, int bytesToWrite)
|
||||
{
|
||||
if (!bio || !src || bytesToWrite <= 0) {
|
||||
qCWarning(lcSsl, "invalid input parameter(s)");
|
||||
qCWarning(lcTlsBackend, "invalid input parameter(s)");
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -365,7 +368,7 @@ extern "C" int q_dgram_write(BIO *bio, const char *src, int bytesToWrite)
|
|||
extern "C" int q_dgram_puts(BIO *bio, const char *src)
|
||||
{
|
||||
if (!bio || !src) {
|
||||
qCWarning(lcSsl, "invalid input parameter(s)");
|
||||
qCWarning(lcTlsBackend, "invalid input parameter(s)");
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -390,7 +393,7 @@ extern "C" long q_dgram_ctrl(BIO *bio, int cmd, long num, void *ptr)
|
|||
// command.
|
||||
|
||||
if (!bio) {
|
||||
qDebug(lcSsl, "invalid 'bio' parameter (nullptr)");
|
||||
qDebug(lcTlsBackend, "invalid 'bio' parameter (nullptr)");
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
@ -1425,7 +1428,7 @@ void QDtlsPrivateOpenSSL::fetchNegotiatedParameters()
|
|||
sessionProtocol = QSsl::DtlsV1_2;
|
||||
break;
|
||||
default:
|
||||
qCWarning(lcSsl, "unknown protocol version");
|
||||
qCWarning(lcTlsBackend, "unknown protocol version");
|
||||
sessionProtocol = QSsl::UnknownProtocol;
|
||||
}
|
||||
}
|
|
@ -40,27 +40,26 @@
|
|||
#ifndef QDTLS_OPENSSL_P_H
|
||||
#define QDTLS_OPENSSL_P_H
|
||||
|
||||
#include <private/qtnetworkglobal_p.h>
|
||||
|
||||
#include <QtCore/qglobal.h>
|
||||
|
||||
#include <openssl/ossl_typ.h>
|
||||
#include <QtNetwork/private/qtnetworkglobal_p.h>
|
||||
|
||||
#include "qsslcontext_openssl_p.h"
|
||||
#include "qtlsbackend_openssl_p.h"
|
||||
#include "qtls_openssl_p.h"
|
||||
#include "qdtls_base_p.h"
|
||||
#include "qdtls_p.h"
|
||||
#include "qopenssl_p.h"
|
||||
|
||||
#include <private/qsslcontext_openssl_p.h>
|
||||
#include <private/qopenssl_p.h>
|
||||
#include "../shared/qdtls_base_p.h"
|
||||
|
||||
#include <QtNetwork/private/qdtls_p.h>
|
||||
|
||||
#include <QtNetwork/qsslpresharedkeyauthenticator.h>
|
||||
#include <QtNetwork/qhostaddress.h>
|
||||
|
||||
#include <QtCore/qsharedpointer.h>
|
||||
#include <QtCore/qbytearray.h>
|
||||
#include <QtCore/qglobal.h>
|
||||
#include <QtCore/qlist.h>
|
||||
#include <QtCore/qsharedpointer.h>
|
||||
|
||||
#include <openssl/ossl_typ.h>
|
||||
|
||||
//
|
||||
// W A R N I N G
|
|
@ -68,8 +68,9 @@
|
|||
|
||||
#include <QtNetwork/private/qtnetworkglobal_p.h>
|
||||
|
||||
#include "qsslsocket_p.h"
|
||||
#include "qsslcipher.h"
|
||||
#include <QtNetwork/private/qsslsocket_p.h>
|
||||
|
||||
#include <QtNetwork/qsslcipher.h>
|
||||
|
||||
#ifdef Q_OS_WIN
|
||||
#include <qt_windows.h>
|
|
@ -43,13 +43,16 @@
|
|||
#include <QtNetwork/qsslsocket.h>
|
||||
#include <QtNetwork/qssldiffiehellmanparameters.h>
|
||||
|
||||
#include "private/qopenssl_p.h"
|
||||
#include "private/qssl_p.h"
|
||||
#include "private/qsslsocket_p.h"
|
||||
#include "private/qsslcontext_openssl_p.h"
|
||||
#include "private/qsslsocket_openssl_symbols_p.h"
|
||||
#include "private/qssldiffiehellmanparameters_p.h"
|
||||
#include "private/qtlsbackend_openssl_p.h"
|
||||
#include "qsslsocket_openssl_symbols_p.h"
|
||||
#include "qsslcontext_openssl_p.h"
|
||||
#include "qtlsbackend_openssl_p.h"
|
||||
#include "qopenssl_p.h"
|
||||
|
||||
#include <QtNetwork/private/qssl_p.h>
|
||||
#include <QtNetwork/private/qsslsocket_p.h>
|
||||
#include <QtNetwork/private/qtlsbackend_p.h>
|
||||
|
||||
#include <QtNetwork/private/qssldiffiehellmanparameters_p.h>
|
||||
|
||||
#include <vector>
|
||||
|
||||
|
@ -57,11 +60,6 @@ QT_BEGIN_NAMESPACE
|
|||
|
||||
Q_GLOBAL_STATIC(bool, forceSecurityLevel)
|
||||
|
||||
Q_NETWORK_EXPORT void qt_ForceTlsSecurityLevel()
|
||||
{
|
||||
*forceSecurityLevel() = true;
|
||||
}
|
||||
|
||||
namespace QTlsPrivate
|
||||
{
|
||||
// These callback functions are defined in qtls_openssl.cpp.
|
||||
|
@ -218,7 +216,7 @@ static int next_proto_cb(SSL *, unsigned char **out, unsigned char *outlen,
|
|||
ctx->status = QSslConfiguration::NextProtocolNegotiationUnsupported;
|
||||
break;
|
||||
default:
|
||||
qCWarning(lcSsl, "OpenSSL sent unknown NPN status");
|
||||
qCWarning(lcTlsBackend, "OpenSSL sent unknown NPN status");
|
||||
}
|
||||
|
||||
return SSL_TLSEXT_ERR_OK;
|
||||
|
@ -248,7 +246,7 @@ SSL* QSslContext::createSsl()
|
|||
if (session) {
|
||||
// Try to resume the last session we cached
|
||||
if (!q_SSL_set_session(ssl, session)) {
|
||||
qCWarning(lcSsl, "could not set SSL session");
|
||||
qCWarning(lcTlsBackend, "could not set SSL session");
|
||||
q_SSL_SESSION_free(session);
|
||||
session = nullptr;
|
||||
}
|
||||
|
@ -260,7 +258,7 @@ SSL* QSslContext::createSsl()
|
|||
m_supportedNPNVersions.clear();
|
||||
for (int a = 0; a < protocols.count(); ++a) {
|
||||
if (protocols.at(a).size() > 255) {
|
||||
qCWarning(lcSsl) << "TLS NPN extension" << protocols.at(a)
|
||||
qCWarning(lcTlsBackend) << "TLS NPN extension" << protocols.at(a)
|
||||
<< "is too long and will be ignored.";
|
||||
continue;
|
||||
} else if (protocols.at(a).isEmpty()) {
|
||||
|
@ -313,7 +311,7 @@ bool QSslContext::cacheSession(SSL* ssl)
|
|||
m_sessionASN1.resize(sessionSize);
|
||||
unsigned char *data = reinterpret_cast<unsigned char *>(m_sessionASN1.data());
|
||||
if (!q_i2d_SSL_SESSION(session, &data))
|
||||
qCWarning(lcSsl, "could not store persistent version of SSL session");
|
||||
qCWarning(lcTlsBackend, "could not store persistent version of SSL session");
|
||||
m_sessionTicketLifeTimeHint = q_SSL_SESSION_get_ticket_lifetime_hint(session);
|
||||
}
|
||||
}
|
||||
|
@ -336,6 +334,11 @@ int QSslContext::sessionTicketLifeTimeHint() const
|
|||
return m_sessionTicketLifeTimeHint;
|
||||
}
|
||||
|
||||
void QSslContext::forceAutoTestSecurityLevel()
|
||||
{
|
||||
*forceSecurityLevel() = true;
|
||||
}
|
||||
|
||||
QSslError::SslError QSslContext::error() const
|
||||
{
|
||||
return errorCode;
|
||||
|
@ -370,13 +373,13 @@ init_context:
|
|||
#else // dtls
|
||||
sslContext->ctx = nullptr;
|
||||
unsupportedProtocol = true;
|
||||
qCWarning(lcSsl, "DTLS protocol requested, but feature 'dtls' is disabled");
|
||||
qCWarning(lcTlsBackend, "DTLS protocol requested, but feature 'dtls' is disabled");
|
||||
#endif // dtls
|
||||
break;
|
||||
case QSsl::TlsV1_3:
|
||||
case QSsl::TlsV1_3OrLater:
|
||||
#if !defined(TLS1_3_VERSION)
|
||||
qCWarning(lcSsl, "TLS 1.3 is not supported");
|
||||
qCWarning(lcTlsBackend, "TLS 1.3 is not supported");
|
||||
sslContext->ctx = nullptr;
|
||||
unsupportedProtocol = true;
|
||||
break;
|
||||
|
@ -591,7 +594,7 @@ init_context:
|
|||
#endif // OPENSSL_VERSION_MAJOR
|
||||
if (success != 1) {
|
||||
const auto qtErrors = QTlsBackendOpenSSL::getErrorsFromOpenSsl();
|
||||
qCWarning(lcSsl) << "An error encountered while to set root certificates location:"
|
||||
qCWarning(lcTlsBackend) << "An error encountered while to set root certificates location:"
|
||||
<< qtErrors;
|
||||
}
|
||||
}
|
|
@ -87,6 +87,8 @@ public:
|
|||
void setSessionASN1(const QByteArray &sessionASN1);
|
||||
int sessionTicketLifeTimeHint() const;
|
||||
|
||||
static void forceAutoTestSecurityLevel();
|
||||
|
||||
#ifndef OPENSSL_NO_NEXTPROTONEG
|
||||
// must be public because we want to use it from an OpenSSL callback
|
||||
struct NPNContext {
|
|
@ -40,7 +40,8 @@
|
|||
|
||||
#include "qsslsocket_openssl_symbols_p.h"
|
||||
#include "qtlsbackend_openssl_p.h"
|
||||
#include "qsslsocket_p.h"
|
||||
|
||||
#include <QtNetwork/private/qsslsocket_p.h>
|
||||
|
||||
#include <QtCore/qscopeguard.h>
|
||||
#include <QtCore/qbytearray.h>
|
|
@ -52,7 +52,6 @@
|
|||
**
|
||||
****************************************************************************/
|
||||
|
||||
#include "qsslsocket_p.h"
|
||||
#include <QtCore/QJniEnvironment>
|
||||
#include <QtCore/QJniObject>
|
||||
|
|
@ -54,11 +54,12 @@
|
|||
**
|
||||
****************************************************************************/
|
||||
|
||||
#include "qssl_p.h"
|
||||
#include "qsslsocket_openssl_symbols_p.h"
|
||||
|
||||
#include <QtNetwork/private/qssl_p.h>
|
||||
|
||||
#ifdef Q_OS_WIN
|
||||
# include <private/qsystemlibrary_p.h>
|
||||
# include <QtCore/private/qsystemlibrary_p.h>
|
||||
#elif QT_CONFIG(library)
|
||||
# include <QtCore/qlibrary.h>
|
||||
#endif
|
||||
|
@ -72,7 +73,7 @@
|
|||
#include <link.h>
|
||||
#endif
|
||||
#ifdef Q_OS_DARWIN
|
||||
#include "private/qcore_mac_p.h"
|
||||
#include <QtCore/private/qcore_mac_p.h>
|
||||
#endif
|
||||
|
||||
#include <algorithm>
|
||||
|
@ -123,13 +124,13 @@ QT_BEGIN_NAMESPACE
|
|||
namespace {
|
||||
void qsslSocketUnresolvedSymbolWarning(const char *functionName)
|
||||
{
|
||||
qCWarning(lcSsl, "QSslSocket: cannot call unresolved function %s", functionName);
|
||||
qCWarning(lcTlsBackend, "QSslSocket: cannot call unresolved function %s", functionName);
|
||||
}
|
||||
|
||||
#if QT_CONFIG(library)
|
||||
void qsslSocketCannotResolveSymbolWarning(const char *functionName)
|
||||
{
|
||||
qCWarning(lcSsl, "QSslSocket: cannot resolve %s", functionName);
|
||||
qCWarning(lcTlsBackend, "QSslSocket: cannot resolve %s", functionName);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
@ -522,9 +523,9 @@ DEFINEFUNC(void, PKCS12_free, PKCS12 *pkcs12, pkcs12, return, DUMMYARG)
|
|||
#if !QT_CONFIG(library)
|
||||
bool q_resolveOpenSslSymbols()
|
||||
{
|
||||
qCWarning(lcSsl, "QSslSocket: unable to resolve symbols. Qt is configured without the "
|
||||
qCWarning(lcTlsBackend, "QSslSocket: unable to resolve symbols. Qt is configured without the "
|
||||
"'library' feature, which means runtime resolving of libraries won't work.");
|
||||
qCWarning(lcSsl, "Either compile Qt statically or with support for runtime resolving "
|
||||
qCWarning(lcTlsBackend, "Either compile Qt statically or with support for runtime resolving "
|
||||
"of libraries.");
|
||||
return false;
|
||||
}
|
||||
|
@ -904,7 +905,7 @@ bool q_resolveOpenSslSymbols()
|
|||
if (!_q_OpenSSL_version) {
|
||||
// Apparently, we were built with OpenSSL 1.1 enabled but are now using
|
||||
// a wrong library.
|
||||
qCWarning(lcSsl, "Incompatible version of OpenSSL");
|
||||
qCWarning(lcTlsBackend, "Incompatible version of OpenSSL");
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -1217,18 +1218,4 @@ bool q_resolveOpenSslSymbols()
|
|||
}
|
||||
#endif // !defined QT_LINKED_OPENSSL
|
||||
|
||||
QDateTime q_getTimeFromASN1(const ASN1_TIME *aTime)
|
||||
{
|
||||
QDateTime result;
|
||||
tm lTime;
|
||||
|
||||
if (q_ASN1_TIME_to_tm(aTime, &lTime)) {
|
||||
QDate resDate(lTime.tm_year + 1900, lTime.tm_mon + 1, lTime.tm_mday);
|
||||
QTime resTime(lTime.tm_hour, lTime.tm_min, lTime.tm_sec);
|
||||
result = QDateTime(resDate, resTime, Qt::UTC);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
QT_END_NAMESPACE
|
|
@ -69,11 +69,13 @@
|
|||
//
|
||||
|
||||
#include <QtNetwork/private/qtnetworkglobal_p.h>
|
||||
|
||||
#include "qopenssl_p.h"
|
||||
|
||||
#include <QtCore/qglobal.h>
|
||||
|
||||
#if QT_CONFIG(ocsp)
|
||||
#include "qocsp_p.h"
|
||||
#include <QtNetwork/private/qocsp_p.h>
|
||||
#endif
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
@ -227,23 +229,23 @@ QT_BEGIN_NAMESPACE
|
|||
|
||||
const unsigned char * q_ASN1_STRING_get0_data(const ASN1_STRING *x);
|
||||
|
||||
Q_AUTOTEST_EXPORT BIO *q_BIO_new(const BIO_METHOD *a);
|
||||
Q_AUTOTEST_EXPORT const BIO_METHOD *q_BIO_s_mem();
|
||||
BIO *q_BIO_new(const BIO_METHOD *a);
|
||||
const BIO_METHOD *q_BIO_s_mem();
|
||||
|
||||
int q_DSA_bits(DSA *a);
|
||||
int q_EVP_CIPHER_CTX_reset(EVP_CIPHER_CTX *c);
|
||||
Q_AUTOTEST_EXPORT int q_EVP_PKEY_up_ref(EVP_PKEY *a);
|
||||
int q_EVP_PKEY_up_ref(EVP_PKEY *a);
|
||||
EVP_PKEY_CTX *q_EVP_PKEY_CTX_new(EVP_PKEY *pkey, ENGINE *e);
|
||||
void q_EVP_PKEY_CTX_free(EVP_PKEY_CTX *ctx);
|
||||
int q_EVP_PKEY_param_check(EVP_PKEY_CTX *ctx);
|
||||
int q_EVP_PKEY_base_id(EVP_PKEY *a);
|
||||
int q_RSA_bits(RSA *a);
|
||||
Q_AUTOTEST_EXPORT int q_OPENSSL_sk_num(OPENSSL_STACK *a);
|
||||
Q_AUTOTEST_EXPORT void q_OPENSSL_sk_pop_free(OPENSSL_STACK *a, void (*b)(void *));
|
||||
Q_AUTOTEST_EXPORT OPENSSL_STACK *q_OPENSSL_sk_new_null();
|
||||
Q_AUTOTEST_EXPORT void q_OPENSSL_sk_push(OPENSSL_STACK *st, void *data);
|
||||
Q_AUTOTEST_EXPORT void q_OPENSSL_sk_free(OPENSSL_STACK *a);
|
||||
Q_AUTOTEST_EXPORT void * q_OPENSSL_sk_value(OPENSSL_STACK *a, int b);
|
||||
int q_OPENSSL_sk_num(OPENSSL_STACK *a);
|
||||
void q_OPENSSL_sk_pop_free(OPENSSL_STACK *a, void (*b)(void *));
|
||||
OPENSSL_STACK *q_OPENSSL_sk_new_null();
|
||||
void q_OPENSSL_sk_push(OPENSSL_STACK *st, void *data);
|
||||
void q_OPENSSL_sk_free(OPENSSL_STACK *a);
|
||||
void * q_OPENSSL_sk_value(OPENSSL_STACK *a, int b);
|
||||
int q_SSL_session_reused(SSL *a);
|
||||
unsigned long q_SSL_CTX_set_options(SSL_CTX *ctx, unsigned long op);
|
||||
int q_OPENSSL_init_ssl(uint64_t opts, const OPENSSL_INIT_SETTINGS *settings);
|
||||
|
@ -256,7 +258,7 @@ const SSL_METHOD *q_TLS_server_method();
|
|||
ASN1_TIME *q_X509_getm_notBefore(X509 *a);
|
||||
ASN1_TIME *q_X509_getm_notAfter(X509 *a);
|
||||
|
||||
Q_AUTOTEST_EXPORT void q_X509_up_ref(X509 *a);
|
||||
void q_X509_up_ref(X509 *a);
|
||||
long q_X509_get_version(X509 *a);
|
||||
EVP_PKEY *q_X509_get_pubkey(X509 *a);
|
||||
void q_X509_STORE_set_verify_cb(X509_STORE *ctx, X509_STORE_CTX_verify_cb verify_cb);
|
||||
|
@ -370,10 +372,10 @@ int q_ASN1_STRING_length(ASN1_STRING *a);
|
|||
int q_ASN1_STRING_to_UTF8(unsigned char **a, ASN1_STRING *b);
|
||||
int q_ASN1_TIME_to_tm(const ASN1_TIME *s, struct tm *tm);
|
||||
long q_BIO_ctrl(BIO *a, int b, long c, void *d);
|
||||
Q_AUTOTEST_EXPORT int q_BIO_free(BIO *a);
|
||||
int q_BIO_free(BIO *a);
|
||||
BIO *q_BIO_new_mem_buf(void *a, int b);
|
||||
int q_BIO_read(BIO *a, void *b, int c);
|
||||
Q_AUTOTEST_EXPORT int q_BIO_write(BIO *a, const void *b, int c);
|
||||
int q_BIO_write(BIO *a, const void *b, int c);
|
||||
int q_BN_num_bits(const BIGNUM *a);
|
||||
int q_BN_is_word(BIGNUM *a, BN_ULONG w);
|
||||
BN_ULONG q_BN_mod_word(const BIGNUM *a, BN_ULONG w);
|
||||
|
@ -414,18 +416,18 @@ const EVP_CIPHER *q_EVP_aes_192_cbc();
|
|||
const EVP_CIPHER *q_EVP_aes_256_cbc();
|
||||
#endif // OPENSSL_NO_AES
|
||||
|
||||
Q_AUTOTEST_EXPORT const EVP_MD *q_EVP_sha1();
|
||||
const EVP_MD *q_EVP_sha1();
|
||||
int q_EVP_PKEY_assign(EVP_PKEY *a, int b, void *r);
|
||||
Q_AUTOTEST_EXPORT int q_EVP_PKEY_set1_RSA(EVP_PKEY *a, RSA *b);
|
||||
Q_AUTOTEST_EXPORT int q_EVP_PKEY_set1_DSA(EVP_PKEY *a, DSA *b);
|
||||
Q_AUTOTEST_EXPORT int q_EVP_PKEY_set1_DH(EVP_PKEY *a, DH *b);
|
||||
int q_EVP_PKEY_set1_RSA(EVP_PKEY *a, RSA *b);
|
||||
int q_EVP_PKEY_set1_DSA(EVP_PKEY *a, DSA *b);
|
||||
int q_EVP_PKEY_set1_DH(EVP_PKEY *a, DH *b);
|
||||
|
||||
#ifndef OPENSSL_NO_EC
|
||||
Q_AUTOTEST_EXPORT int q_EVP_PKEY_set1_EC_KEY(EVP_PKEY *a, EC_KEY *b);
|
||||
int q_EVP_PKEY_set1_EC_KEY(EVP_PKEY *a, EC_KEY *b);
|
||||
#endif
|
||||
|
||||
Q_AUTOTEST_EXPORT int q_EVP_PKEY_cmp(const EVP_PKEY *a, const EVP_PKEY *b);
|
||||
Q_AUTOTEST_EXPORT void q_EVP_PKEY_free(EVP_PKEY *a);
|
||||
int q_EVP_PKEY_cmp(const EVP_PKEY *a, const EVP_PKEY *b);
|
||||
void q_EVP_PKEY_free(EVP_PKEY *a);
|
||||
RSA *q_EVP_PKEY_get1_RSA(EVP_PKEY *a);
|
||||
DSA *q_EVP_PKEY_get1_DSA(EVP_PKEY *a);
|
||||
DH *q_EVP_PKEY_get1_DH(EVP_PKEY *a);
|
||||
|
@ -433,7 +435,7 @@ DH *q_EVP_PKEY_get1_DH(EVP_PKEY *a);
|
|||
EC_KEY *q_EVP_PKEY_get1_EC_KEY(EVP_PKEY *a);
|
||||
#endif
|
||||
int q_EVP_PKEY_type(int a);
|
||||
Q_AUTOTEST_EXPORT EVP_PKEY *q_EVP_PKEY_new();
|
||||
EVP_PKEY *q_EVP_PKEY_new();
|
||||
int q_i2d_X509(X509 *a, unsigned char **b);
|
||||
const char *q_OBJ_nid2sn(int a);
|
||||
const char *q_OBJ_nid2ln(int a);
|
||||
|
@ -443,7 +445,7 @@ int q_i2t_ASN1_OBJECT(char *buf, int buf_len, ASN1_OBJECT *obj);
|
|||
int q_OBJ_obj2txt(char *buf, int buf_len, ASN1_OBJECT *obj, int no_name);
|
||||
int q_OBJ_obj2nid(const ASN1_OBJECT *a);
|
||||
#define q_EVP_get_digestbynid(a) q_EVP_get_digestbyname(q_OBJ_nid2sn(a))
|
||||
Q_AUTOTEST_EXPORT EVP_PKEY *q_PEM_read_bio_PrivateKey(BIO *a, EVP_PKEY **b, pem_password_cb *c, void *d);
|
||||
EVP_PKEY *q_PEM_read_bio_PrivateKey(BIO *a, EVP_PKEY **b, pem_password_cb *c, void *d);
|
||||
DSA *q_PEM_read_bio_DSAPrivateKey(BIO *a, DSA **b, pem_password_cb *c, void *d);
|
||||
RSA *q_PEM_read_bio_RSAPrivateKey(BIO *a, RSA **b, pem_password_cb *c, void *d);
|
||||
|
||||
|
@ -462,7 +464,7 @@ int q_PEM_write_bio_RSAPrivateKey(BIO *a, RSA *b, const EVP_CIPHER *c, unsigned
|
|||
int e, pem_password_cb *f, void *g);
|
||||
int q_PEM_write_bio_PrivateKey(BIO *a, EVP_PKEY *b, const EVP_CIPHER *c, unsigned char *d,
|
||||
int e, pem_password_cb *f, void *g);
|
||||
Q_AUTOTEST_EXPORT EVP_PKEY *q_PEM_read_bio_PUBKEY(BIO *a, EVP_PKEY **b, pem_password_cb *c, void *d);
|
||||
EVP_PKEY *q_PEM_read_bio_PUBKEY(BIO *a, EVP_PKEY **b, pem_password_cb *c, void *d);
|
||||
DSA *q_PEM_read_bio_DSA_PUBKEY(BIO *a, DSA **b, pem_password_cb *c, void *d);
|
||||
RSA *q_PEM_read_bio_RSA_PUBKEY(BIO *a, RSA **b, pem_password_cb *c, void *d);
|
||||
int q_PEM_write_bio_DSA_PUBKEY(BIO *a, DSA *b);
|
||||
|
@ -541,9 +543,9 @@ X509 *q_X509_dup(X509 *a);
|
|||
void q_X509_print(BIO *a, X509*b);
|
||||
int q_X509_digest(const X509 *x509, const EVP_MD *type, unsigned char *md, unsigned int *len);
|
||||
ASN1_OBJECT *q_X509_EXTENSION_get_object(X509_EXTENSION *a);
|
||||
Q_AUTOTEST_EXPORT void q_X509_free(X509 *a);
|
||||
Q_AUTOTEST_EXPORT ASN1_TIME *q_X509_gmtime_adj(ASN1_TIME *s, long adj);
|
||||
Q_AUTOTEST_EXPORT void q_ASN1_TIME_free(ASN1_TIME *t);
|
||||
void q_X509_free(X509 *a);
|
||||
ASN1_TIME *q_X509_gmtime_adj(ASN1_TIME *s, long adj);
|
||||
void q_ASN1_TIME_free(ASN1_TIME *t);
|
||||
X509_EXTENSION *q_X509_get_ext(X509 *a, int b);
|
||||
int q_X509_get_ext_count(X509 *a);
|
||||
void *q_X509_get_ext_d2i(X509 *a, int b, int *c, int *d);
|
||||
|
@ -698,28 +700,24 @@ int q_BIO_set_ex_data(BIO *b, int idx, void *data);
|
|||
#define q_BIO_set_app_data(s,arg) q_BIO_set_ex_data(s,0,arg)
|
||||
#define q_BIO_get_app_data(s) q_BIO_get_ex_data(s,0)
|
||||
|
||||
// Helper function
|
||||
class QDateTime;
|
||||
QDateTime q_getTimeFromASN1(const ASN1_TIME *aTime);
|
||||
|
||||
#define q_SSL_set_tlsext_status_type(ssl, type) \
|
||||
q_SSL_ctrl((ssl), SSL_CTRL_SET_TLSEXT_STATUS_REQ_TYPE, (type), nullptr)
|
||||
|
||||
#if QT_CONFIG(ocsp)
|
||||
|
||||
OCSP_RESPONSE *q_d2i_OCSP_RESPONSE(OCSP_RESPONSE **a, const unsigned char **in, long len);
|
||||
Q_AUTOTEST_EXPORT int q_i2d_OCSP_RESPONSE(OCSP_RESPONSE *r, unsigned char **ppout);
|
||||
Q_AUTOTEST_EXPORT OCSP_RESPONSE *q_OCSP_response_create(int status, OCSP_BASICRESP *bs);
|
||||
Q_AUTOTEST_EXPORT void q_OCSP_RESPONSE_free(OCSP_RESPONSE *rs);
|
||||
int q_i2d_OCSP_RESPONSE(OCSP_RESPONSE *r, unsigned char **ppout);
|
||||
OCSP_RESPONSE *q_OCSP_response_create(int status, OCSP_BASICRESP *bs);
|
||||
void q_OCSP_RESPONSE_free(OCSP_RESPONSE *rs);
|
||||
int q_OCSP_response_status(OCSP_RESPONSE *resp);
|
||||
OCSP_BASICRESP *q_OCSP_response_get1_basic(OCSP_RESPONSE *resp);
|
||||
Q_AUTOTEST_EXPORT OCSP_SINGLERESP *q_OCSP_basic_add1_status(OCSP_BASICRESP *rsp, OCSP_CERTID *cid,
|
||||
OCSP_SINGLERESP *q_OCSP_basic_add1_status(OCSP_BASICRESP *rsp, OCSP_CERTID *cid,
|
||||
int status, int reason, ASN1_TIME *revtime,
|
||||
ASN1_TIME *thisupd, ASN1_TIME *nextupd);
|
||||
Q_AUTOTEST_EXPORT int q_OCSP_basic_sign(OCSP_BASICRESP *brsp, X509 *signer, EVP_PKEY *key, const EVP_MD *dgst,
|
||||
int q_OCSP_basic_sign(OCSP_BASICRESP *brsp, X509 *signer, EVP_PKEY *key, const EVP_MD *dgst,
|
||||
STACK_OF(X509) *certs, unsigned long flags);
|
||||
Q_AUTOTEST_EXPORT OCSP_BASICRESP *q_OCSP_BASICRESP_new();
|
||||
Q_AUTOTEST_EXPORT void q_OCSP_BASICRESP_free(OCSP_BASICRESP *bs);
|
||||
OCSP_BASICRESP *q_OCSP_BASICRESP_new();
|
||||
void q_OCSP_BASICRESP_free(OCSP_BASICRESP *bs);
|
||||
int q_OCSP_basic_verify(OCSP_BASICRESP *bs, STACK_OF(X509) *certs, X509_STORE *st, unsigned long flags);
|
||||
int q_OCSP_resp_count(OCSP_BASICRESP *bs);
|
||||
OCSP_SINGLERESP *q_OCSP_resp_get0(OCSP_BASICRESP *bs, int idx);
|
||||
|
@ -730,8 +728,8 @@ int q_OCSP_id_get0_info(ASN1_OCTET_STRING **piNameHash, ASN1_OBJECT **pmd, ASN1_
|
|||
ASN1_INTEGER **pserial, OCSP_CERTID *cid);
|
||||
|
||||
const STACK_OF(X509) *q_OCSP_resp_get0_certs(const OCSP_BASICRESP *bs);
|
||||
Q_AUTOTEST_EXPORT OCSP_CERTID *q_OCSP_cert_to_id(const EVP_MD *dgst, X509 *subject, X509 *issuer);
|
||||
Q_AUTOTEST_EXPORT void q_OCSP_CERTID_free(OCSP_CERTID *cid);
|
||||
OCSP_CERTID *q_OCSP_cert_to_id(const EVP_MD *dgst, X509 *subject, X509 *issuer);
|
||||
void q_OCSP_CERTID_free(OCSP_CERTID *cid);
|
||||
int q_OCSP_id_cmp(OCSP_CERTID *a, OCSP_CERTID *b);
|
||||
|
||||
#define q_SSL_get_tlsext_status_ocsp_resp(ssl, arg) \
|
|
@ -37,19 +37,21 @@
|
|||
**
|
||||
****************************************************************************/
|
||||
|
||||
#include "qsslpresharedkeyauthenticator_p.h"
|
||||
#include "qsslpresharedkeyauthenticator.h"
|
||||
#include "qsslsocket_openssl_symbols_p.h"
|
||||
#include "qsslcertificate_p.h"
|
||||
#include "qx509_openssl_p.h"
|
||||
#include "qocspresponse_p.h"
|
||||
#include "qtls_openssl_p.h"
|
||||
#include "qsslsocket_p.h"
|
||||
|
||||
#ifdef Q_OS_WIN
|
||||
#include "qwindowscarootfetcher_p.h"
|
||||
#endif
|
||||
|
||||
#include <QtNetwork/private/qsslpresharedkeyauthenticator_p.h>
|
||||
#include <QtNetwork/private/qsslcertificate_p.h>
|
||||
#include <QtNetwork/private/qocspresponse_p.h>
|
||||
#include <QtNetwork/private/qsslsocket_p.h>
|
||||
|
||||
#include <QtNetwork/qsslpresharedkeyauthenticator.h>
|
||||
|
||||
#include <QtCore/qscopedvaluerollback.h>
|
||||
#include <QtCore/qscopeguard.h>
|
||||
|
||||
|
@ -195,7 +197,7 @@ int q_X509CallbackDirect(int ok, X509_STORE_CTX *ctx)
|
|||
// errors immediately and returning 0 or 1 depending on an application
|
||||
// either ignoring or not ignoring verification errors as they come.
|
||||
if (!ctx) {
|
||||
qCWarning(lcSsl, "Invalid store context (nullptr)");
|
||||
qCWarning(lcTlsBackend, "Invalid store context (nullptr)");
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -430,7 +432,7 @@ bool qt_OCSP_certificate_match(OCSP_SINGLERESP *singleResponse, X509 *peerCert,
|
|||
|
||||
const OCSP_CERTID *certId = q_OCSP_SINGLERESP_get0_id(singleResponse); // Does not increment refcount.
|
||||
if (!certId) {
|
||||
qCWarning(lcSsl, "A SingleResponse without CertID");
|
||||
qCWarning(lcTlsBackend, "A SingleResponse without CertID");
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -438,7 +440,7 @@ bool qt_OCSP_certificate_match(OCSP_SINGLERESP *singleResponse, X509 *peerCert,
|
|||
ASN1_INTEGER *reportedSerialNumber = nullptr;
|
||||
const int result = q_OCSP_id_get0_info(nullptr, &md, nullptr, &reportedSerialNumber, const_cast<OCSP_CERTID *>(certId));
|
||||
if (result != 1 || !md || !reportedSerialNumber) {
|
||||
qCWarning(lcSsl, "Failed to extract a hash and serial number from CertID structure");
|
||||
qCWarning(lcTlsBackend, "Failed to extract a hash and serial number from CertID structure");
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -446,31 +448,31 @@ bool qt_OCSP_certificate_match(OCSP_SINGLERESP *singleResponse, X509 *peerCert,
|
|||
// Is this possible at all? But we have to check this,
|
||||
// ASN1_INTEGER_cmp (called from OCSP_id_cmp) dereferences
|
||||
// without any checks at all.
|
||||
qCWarning(lcSsl, "No serial number in peer's ceritificate");
|
||||
qCWarning(lcTlsBackend, "No serial number in peer's ceritificate");
|
||||
return false;
|
||||
}
|
||||
|
||||
const int nid = q_OBJ_obj2nid(md);
|
||||
if (nid == NID_undef) {
|
||||
qCWarning(lcSsl, "Unknown hash algorithm in CertID");
|
||||
qCWarning(lcTlsBackend, "Unknown hash algorithm in CertID");
|
||||
return false;
|
||||
}
|
||||
|
||||
const EVP_MD *digest = q_EVP_get_digestbynid(nid); // Does not increment refcount.
|
||||
if (!digest) {
|
||||
qCWarning(lcSsl) << "No digest for nid" << nid;
|
||||
qCWarning(lcTlsBackend) << "No digest for nid" << nid;
|
||||
return false;
|
||||
}
|
||||
|
||||
OCSP_CERTID *recreatedId = q_OCSP_cert_to_id(digest, peerCert, issuer);
|
||||
if (!recreatedId) {
|
||||
qCWarning(lcSsl, "Failed to re-create CertID");
|
||||
qCWarning(lcTlsBackend, "Failed to re-create CertID");
|
||||
return false;
|
||||
}
|
||||
const QSharedPointer<OCSP_CERTID> guard(recreatedId, q_OCSP_CERTID_free);
|
||||
|
||||
if (q_OCSP_id_cmp(const_cast<OCSP_CERTID *>(certId), recreatedId)) {
|
||||
qDebug(lcSsl, "Certificate ID mismatch");
|
||||
qDebug(lcTlsBackend, "Certificate ID mismatch");
|
||||
return false;
|
||||
}
|
||||
// Bingo!
|
||||
|
@ -522,8 +524,8 @@ void TlsCryptographOpenSSL::startClientEncryption()
|
|||
{
|
||||
if (!initSslContext()) {
|
||||
Q_ASSERT(d);
|
||||
d->setErrorAndEmit(QAbstractSocket::SslInternalError,
|
||||
QSslSocket::tr("Unable to init SSL Context: %1").arg(QTlsBackendOpenSSL::getErrorsFromOpenSsl()));
|
||||
setErrorAndEmit(d, QAbstractSocket::SslInternalError,
|
||||
QSslSocket::tr("Unable to init SSL Context: %1").arg(QTlsBackendOpenSSL::getErrorsFromOpenSsl()));
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -537,8 +539,8 @@ void TlsCryptographOpenSSL::startServerEncryption()
|
|||
{
|
||||
if (!initSslContext()) {
|
||||
Q_ASSERT(d);
|
||||
d->setErrorAndEmit(QAbstractSocket::SslInternalError,
|
||||
QSslSocket::tr("Unable to init SSL Context: %1").arg(QTlsBackendOpenSSL::getErrorsFromOpenSsl()));
|
||||
setErrorAndEmit(d, QAbstractSocket::SslInternalError,
|
||||
QSslSocket::tr("Unable to init SSL Context: %1").arg(QTlsBackendOpenSSL::getErrorsFromOpenSsl()));
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -614,7 +616,7 @@ bool TlsCryptographOpenSSL::startHandshake()
|
|||
#endif
|
||||
{
|
||||
const ScopedBool bg(inSetAndEmitError, true);
|
||||
d->setErrorAndEmit(QAbstractSocket::SslHandshakeFailedError, errorString);
|
||||
setErrorAndEmit(d, QAbstractSocket::SslHandshakeFailedError, errorString);
|
||||
if (pendingFatalAlert) {
|
||||
trySendFatalAlert();
|
||||
pendingFatalAlert = false;
|
||||
|
@ -657,7 +659,7 @@ bool TlsCryptographOpenSSL::startHandshake()
|
|||
if (ocspErrors.isEmpty()) {
|
||||
{
|
||||
const ScopedBool bg(inSetAndEmitError, true);
|
||||
d->setErrorAndEmit(QAbstractSocket::SslHandshakeFailedError, ocspErrorDescription);
|
||||
setErrorAndEmit(d, QAbstractSocket::SslHandshakeFailedError, ocspErrorDescription);
|
||||
}
|
||||
q->abort();
|
||||
return false;
|
||||
|
@ -800,9 +802,9 @@ void TlsCryptographOpenSSL::continueHandshake()
|
|||
QString sslKeyFile = QDir::tempPath() + QLatin1String("/qt-ssl-keys");
|
||||
QFile file(sslKeyFile);
|
||||
if (!file.open(QIODevice::Append))
|
||||
qCWarning(lcSsl) << "could not open file" << sslKeyFile << "for appending";
|
||||
qCWarning(lcTlsBackend) << "could not open file" << sslKeyFile << "for appending";
|
||||
if (!file.write(debugLineClientRandom))
|
||||
qCWarning(lcSsl) << "could not write to file" << sslKeyFile;
|
||||
qCWarning(lcTlsBackend) << "could not write to file" << sslKeyFile;
|
||||
file.close();
|
||||
} else {
|
||||
qCWarning(lcTlsBackend, "could not decrypt SSL traffic");
|
||||
|
@ -911,9 +913,9 @@ void TlsCryptographOpenSSL::transmit()
|
|||
} else {
|
||||
// ### Better error handling.
|
||||
const ScopedBool bg(inSetAndEmitError, true);
|
||||
d->setErrorAndEmit(QAbstractSocket::SslInternalError,
|
||||
QSslSocket::tr("Unable to write data: %1").arg(
|
||||
QTlsBackendOpenSSL::getErrorsFromOpenSsl()));
|
||||
setErrorAndEmit(d, QAbstractSocket::SslInternalError,
|
||||
QSslSocket::tr("Unable to write data: %1").arg(
|
||||
QTlsBackendOpenSSL::getErrorsFromOpenSsl()));
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
@ -959,7 +961,7 @@ void TlsCryptographOpenSSL::transmit()
|
|||
if (actualWritten < 0) {
|
||||
//plain socket write fails if it was in the pending close state.
|
||||
const ScopedBool bg(inSetAndEmitError, true);
|
||||
d->setErrorAndEmit(plainSocket->error(), plainSocket->errorString());
|
||||
setErrorAndEmit(d, plainSocket->error(), plainSocket->errorString());
|
||||
return;
|
||||
}
|
||||
transmitting = true;
|
||||
|
@ -985,9 +987,9 @@ void TlsCryptographOpenSSL::transmit()
|
|||
} else {
|
||||
// ### Better error handling.
|
||||
const ScopedBool bg(inSetAndEmitError, true);
|
||||
d->setErrorAndEmit(QAbstractSocket::SslInternalError,
|
||||
QSslSocket::tr("Unable to decrypt data: %1")
|
||||
.arg(QTlsBackendOpenSSL::getErrorsFromOpenSsl()));
|
||||
setErrorAndEmit(d, QAbstractSocket::SslInternalError,
|
||||
QSslSocket::tr("Unable to decrypt data: %1")
|
||||
.arg(QTlsBackendOpenSSL::getErrorsFromOpenSsl()));
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -1068,8 +1070,8 @@ void TlsCryptographOpenSSL::transmit()
|
|||
shutdown = true; // the other side shut down, make sure we do not send shutdown ourselves
|
||||
{
|
||||
const ScopedBool bg(inSetAndEmitError, true);
|
||||
d->setErrorAndEmit(QAbstractSocket::RemoteHostClosedError,
|
||||
QSslSocket::tr("The TLS/SSL connection has been closed"));
|
||||
setErrorAndEmit(d, QAbstractSocket::RemoteHostClosedError,
|
||||
QSslSocket::tr("The TLS/SSL connection has been closed"));
|
||||
}
|
||||
return;
|
||||
case SSL_ERROR_SYSCALL: // some IO error
|
||||
|
@ -1079,9 +1081,9 @@ void TlsCryptographOpenSSL::transmit()
|
|||
systemOrSslErrorDetected = true;
|
||||
{
|
||||
const ScopedBool bg(inSetAndEmitError, true);
|
||||
d->setErrorAndEmit(QAbstractSocket::SslInternalError,
|
||||
QSslSocket::tr("Error while reading: %1")
|
||||
.arg(QTlsBackendOpenSSL::getErrorsFromOpenSsl()));
|
||||
setErrorAndEmit(d, QAbstractSocket::SslInternalError,
|
||||
QSslSocket::tr("Error while reading: %1")
|
||||
.arg(QTlsBackendOpenSSL::getErrorsFromOpenSsl()));
|
||||
}
|
||||
return;
|
||||
default:
|
||||
|
@ -1092,9 +1094,9 @@ void TlsCryptographOpenSSL::transmit()
|
|||
// So this default case should never be triggered.
|
||||
{
|
||||
const ScopedBool bg(inSetAndEmitError, true);
|
||||
d->setErrorAndEmit(QAbstractSocket::SslInternalError,
|
||||
QSslSocket::tr("Error while reading: %1")
|
||||
.arg(QTlsBackendOpenSSL::getErrorsFromOpenSsl()));
|
||||
setErrorAndEmit(d, QAbstractSocket::SslInternalError,
|
||||
QSslSocket::tr("Error while reading: %1")
|
||||
.arg(QTlsBackendOpenSSL::getErrorsFromOpenSsl()));
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
@ -1196,7 +1198,7 @@ bool TlsCryptographOpenSSL::checkSslErrors()
|
|||
QSslSocketPrivate::pauseSocketNotifiers(q);
|
||||
d->setPaused(true);
|
||||
} else {
|
||||
d->setErrorAndEmit(QAbstractSocket::SslHandshakeFailedError, sslErrors.constFirst().errorString());
|
||||
setErrorAndEmit(d, QAbstractSocket::SslHandshakeFailedError, sslErrors.constFirst().errorString());
|
||||
auto *plainSocket = d->plainTcpSocket();
|
||||
Q_ASSERT(plainSocket);
|
||||
plainSocket->disconnectFromHost();
|
||||
|
@ -1360,15 +1362,15 @@ bool TlsCryptographOpenSSL::initSslContext()
|
|||
sslContextPointer = QSslContext::sharedFromConfiguration(mode, configuration, d->isRootsOnDemandAllowed());
|
||||
|
||||
if (sslContextPointer->error() != QSslError::NoError) {
|
||||
d->setErrorAndEmit(QAbstractSocket::SslInvalidUserDataError, sslContextPointer->errorString());
|
||||
setErrorAndEmit(d, QAbstractSocket::SslInvalidUserDataError, sslContextPointer->errorString());
|
||||
sslContextPointer.clear(); // deletes the QSslContext
|
||||
return false;
|
||||
}
|
||||
|
||||
// Create and initialize SSL session
|
||||
if (!(ssl = sslContextPointer->createSsl())) {
|
||||
d->setErrorAndEmit(QAbstractSocket::SslInternalError,
|
||||
QSslSocket::tr("Error creating SSL session, %1").arg(QTlsBackendOpenSSL::getErrorsFromOpenSsl()));
|
||||
setErrorAndEmit(d, QAbstractSocket::SslInternalError,
|
||||
QSslSocket::tr("Error creating SSL session, %1").arg(QTlsBackendOpenSSL::getErrorsFromOpenSsl()));
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -1399,8 +1401,8 @@ bool TlsCryptographOpenSSL::initSslContext()
|
|||
readBio = q_BIO_new(q_BIO_s_mem());
|
||||
writeBio = q_BIO_new(q_BIO_s_mem());
|
||||
if (!readBio || !writeBio) {
|
||||
d->setErrorAndEmit(QAbstractSocket::SslInternalError,
|
||||
QSslSocket::tr("Error creating SSL session: %1").arg(QTlsBackendOpenSSL::getErrorsFromOpenSsl()));
|
||||
setErrorAndEmit(d, QAbstractSocket::SslInternalError,
|
||||
QSslSocket::tr("Error creating SSL session: %1").arg(QTlsBackendOpenSSL::getErrorsFromOpenSsl()));
|
||||
if (readBio)
|
||||
q_BIO_free(readBio);
|
||||
if (writeBio)
|
||||
|
@ -1438,13 +1440,13 @@ bool TlsCryptographOpenSSL::initSslContext()
|
|||
#if QT_CONFIG(ocsp)
|
||||
if (configuration.ocspStaplingEnabled()) {
|
||||
if (mode == QSslSocket::SslServerMode) {
|
||||
d->setErrorAndEmit(QAbstractSocket::SslInvalidUserDataError,
|
||||
QSslSocket::tr("Server-side QSslSocket does not support OCSP stapling"));
|
||||
setErrorAndEmit(d, QAbstractSocket::SslInvalidUserDataError,
|
||||
QSslSocket::tr("Server-side QSslSocket does not support OCSP stapling"));
|
||||
return false;
|
||||
}
|
||||
if (q_SSL_set_tlsext_status_type(ssl, TLSEXT_STATUSTYPE_ocsp) != 1) {
|
||||
d->setErrorAndEmit(QAbstractSocket::SslInternalError,
|
||||
QSslSocket::tr("Failed to enable OCSP stapling"));
|
||||
setErrorAndEmit(d, QAbstractSocket::SslInternalError,
|
||||
QSslSocket::tr("Failed to enable OCSP stapling"));
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
@ -1463,8 +1465,8 @@ bool TlsCryptographOpenSSL::initSslContext()
|
|||
|
||||
if (ocspResponseDer.size()) {
|
||||
if (mode != QSslSocket::SslServerMode) {
|
||||
d->setErrorAndEmit(QAbstractSocket::SslInvalidUserDataError,
|
||||
QSslSocket::tr("Client-side sockets do not send OCSP responses"));
|
||||
setErrorAndEmit(d, QAbstractSocket::SslInvalidUserDataError,
|
||||
QSslSocket::tr("Client-side sockets do not send OCSP responses"));
|
||||
return false;
|
||||
}
|
||||
}
|
|
@ -51,14 +51,15 @@
|
|||
// We mean it.
|
||||
//
|
||||
|
||||
#include <private/qtnetworkglobal_p.h>
|
||||
#include <QtNetwork/private/qtnetworkglobal_p.h>
|
||||
|
||||
#include "qtlsbackend_openssl_p.h"
|
||||
#include "qsslcontext_openssl_p.h"
|
||||
#include "qsslcertificate.h"
|
||||
#include "qocspresponse.h"
|
||||
#include "qopenssl_p.h"
|
||||
|
||||
#include <QtNetwork/qsslcertificate.h>
|
||||
#include <QtNetwork/qocspresponse.h>
|
||||
|
||||
#include <QtCore/qsharedpointer.h>
|
||||
#include <QtCore/qbytearray.h>
|
||||
#include <QtCore/qglobal.h>
|
|
@ -37,29 +37,29 @@
|
|||
**
|
||||
****************************************************************************/
|
||||
|
||||
#include "qsslsocket_openssl_symbols_p.h"
|
||||
#include "qtlsbackend_openssl_p.h"
|
||||
#include "qtlskey_openssl_p.h"
|
||||
#include "qx509_openssl_p.h"
|
||||
#include "qtls_openssl_p.h"
|
||||
#include "qsslcipher_p.h"
|
||||
//#include "qsslsocket_p.h"
|
||||
#include "qsslcipher.h"
|
||||
|
||||
#if QT_CONFIG(dtls)
|
||||
#include "qdtls_openssl_p.h"
|
||||
#endif // QT_CONFIG(dtls)
|
||||
|
||||
#include "qsslsocket_openssl_symbols_p.h"
|
||||
#include <QtNetwork/private/qsslcipher_p.h>
|
||||
|
||||
#include <QtNetwork/qsslcipher.h>
|
||||
#include <QtNetwork/qssl.h>
|
||||
|
||||
#include <QtCore/qdir.h>
|
||||
#include <QtCore/qdiriterator.h>
|
||||
#include <QtCore/qlist.h>
|
||||
#include <QtCore/qmutex.h>
|
||||
#include <QtCore/qscopeguard.h>
|
||||
|
||||
#include "qopenssl_p.h"
|
||||
|
||||
#include <qssl.h>
|
||||
|
||||
#include <qdir.h>
|
||||
#include <qdiriterator.h>
|
||||
#include <qlist.h>
|
||||
#include <qmutex.h>
|
||||
#include <qscopeguard.h>
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
@ -335,7 +335,9 @@ QList<QSsl::ImplementedClass> QTlsBackendOpenSSL::implementedClasses() const
|
|||
classes << QSsl::ImplementedClass::Key;
|
||||
classes << QSsl::ImplementedClass::Certificate;
|
||||
classes << QSsl::ImplementedClass::Socket;
|
||||
#if QT_CONFIG(dtls)
|
||||
classes << QSsl::ImplementedClass::Dtls;
|
||||
#endif
|
||||
classes << QSsl::ImplementedClass::EllipticCurve;
|
||||
classes << QSsl::ImplementedClass::DiffieHellman;
|
||||
|
||||
|
@ -627,4 +629,9 @@ QSslCipher QTlsBackendOpenSSL::qt_OpenSSL_cipher_to_QSslCipher(const SSL_CIPHER
|
|||
return createCiphersuite(desc, bits, supportedBits);
|
||||
}
|
||||
|
||||
void QTlsBackendOpenSSL::forceAutotestSecurityLevel()
|
||||
{
|
||||
QSslContext::forceAutoTestSecurityLevel();
|
||||
}
|
||||
|
||||
QT_END_NAMESPACE
|
|
@ -51,11 +51,12 @@
|
|||
// We mean it.
|
||||
//
|
||||
|
||||
#include <private/qtnetworkglobal_p.h>
|
||||
#include <QtNetwork/private/qtnetworkglobal_p.h>
|
||||
|
||||
#include "qssldiffiehellmanparameters.h"
|
||||
#include "qsslcertificate.h"
|
||||
#include "qtlsbackend_p.h"
|
||||
#include <QtNetwork/qssldiffiehellmanparameters.h>
|
||||
#include <QtNetwork/qsslcertificate.h>
|
||||
|
||||
#include <QtNetwork/private/qtlsbackend_p.h>
|
||||
|
||||
#include <QtCore/qglobal.h>
|
||||
#include <QtCore/qlist.h>
|
||||
|
@ -66,6 +67,10 @@ QT_BEGIN_NAMESPACE
|
|||
|
||||
class QTlsBackendOpenSSL final : public QTlsBackend
|
||||
{
|
||||
Q_OBJECT
|
||||
Q_PLUGIN_METADATA(IID QTlsBackend_iid)
|
||||
Q_INTERFACES(QTlsBackend)
|
||||
|
||||
public:
|
||||
|
||||
static QString getErrorsFromOpenSsl();
|
||||
|
@ -125,6 +130,8 @@ private:
|
|||
using DHParams = QSslDiffieHellmanParameters;
|
||||
int dhParametersFromDer(const QByteArray &derData, QByteArray *data) const override;
|
||||
int dhParametersFromPem(const QByteArray &pemData, QByteArray *data) const override;
|
||||
|
||||
void forceAutotestSecurityLevel() override;
|
||||
};
|
||||
|
||||
QT_END_NAMESPACE
|
|
@ -39,10 +39,12 @@
|
|||
|
||||
#include "qsslsocket_openssl_symbols_p.h"
|
||||
#include "qtlskey_openssl_p.h"
|
||||
#include "qsslsocket.h"
|
||||
#include "qsslkey_p.h"
|
||||
|
||||
#include <qscopeguard.h>
|
||||
#include <QtNetwork/private/qsslkey_p.h>
|
||||
|
||||
#include <QtNetwork/qsslsocket.h>
|
||||
|
||||
#include <QtCore/qscopeguard.h>
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
|
@ -51,11 +51,12 @@
|
|||
// We mean it.
|
||||
//
|
||||
|
||||
#include <private/qtnetworkglobal_p.h>
|
||||
#include <QtNetwork/private/qtnetworkglobal_p.h>
|
||||
|
||||
#include "qtlskey_base_p.h"
|
||||
#include "qtlsbackend_p.h"
|
||||
#include "qsslkey_p.h"
|
||||
#include "../shared/qtlskey_base_p.h"
|
||||
|
||||
#include <QtNetwork/private/qtlsbackend_p.h>
|
||||
#include <QtNetwork/private/qsslkey_p.h>
|
||||
|
||||
#include <QtNetwork/qssl.h>
|
||||
|
|
@ -38,6 +38,8 @@
|
|||
****************************************************************************/
|
||||
|
||||
#include "qwindowscarootfetcher_p.h"
|
||||
#include "qx509_openssl_p.h"
|
||||
#include "qopenssl_p.h"
|
||||
|
||||
#include <QtCore/QThread>
|
||||
#include <QtGlobal>
|
||||
|
@ -45,17 +47,10 @@
|
|||
#include <QtCore/qscopeguard.h>
|
||||
|
||||
#ifdef QSSLSOCKET_DEBUG
|
||||
#include "qssl_p.h" // for debug categories
|
||||
#include <QtNetwork/private/qtlsbackend_p.h> // for debug categories
|
||||
#include <QtCore/QElapsedTimer>
|
||||
#endif
|
||||
|
||||
#include "qsslsocket_p.h" // Transitively includes Wincrypt.h
|
||||
|
||||
#if QT_CONFIG(openssl)
|
||||
#include "qopenssl_p.h"
|
||||
#include "qx509_openssl_p.h"
|
||||
#endif
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
class QWindowsCaRootFetcherThread : public QThread
|
||||
|
@ -76,11 +71,8 @@ public:
|
|||
|
||||
Q_GLOBAL_STATIC(QWindowsCaRootFetcherThread, windowsCaRootFetcherThread);
|
||||
|
||||
#if QT_CONFIG(openssl)
|
||||
namespace {
|
||||
// TLSTODO: we have to ask the currently active TLS backend about verification
|
||||
// support and get a function pointer. QT_CONFIG(openssl) check is becoming useless
|
||||
// as soon as we have several plugins.
|
||||
|
||||
const QList<QSslCertificate> buildVerifiedChain(const QList<QSslCertificate> &caCertificates,
|
||||
PCCERT_CHAIN_CONTEXT chainContext,
|
||||
const QString &peerVerifyName)
|
||||
|
@ -134,7 +126,6 @@ const QList<QSslCertificate> buildVerifiedChain(const QList<QSslCertificate> &ca
|
|||
}
|
||||
|
||||
} // unnamed namespace
|
||||
#endif // QT_CONFIG(openssl)
|
||||
|
||||
QWindowsCaRootFetcher::QWindowsCaRootFetcher(const QSslCertificate &certificate, QSslSocket::SslMode sslMode,
|
||||
const QList<QSslCertificate> &caCertificates, const QString &hostName)
|
||||
|
@ -153,7 +144,7 @@ void QWindowsCaRootFetcher::start()
|
|||
PCCERT_CONTEXT wincert = CertCreateCertificateContext(X509_ASN_ENCODING, (const BYTE *)der.constData(), der.length());
|
||||
if (!wincert) {
|
||||
#ifdef QSSLSOCKET_DEBUG
|
||||
qCDebug(lcSsl, "QWindowsCaRootFetcher failed to convert certificate to windows form");
|
||||
qCDebug(lcTlsBackend, "QWindowsCaRootFetcher failed to convert certificate to windows form");
|
||||
#endif
|
||||
emit finished(cert, QSslCertificate());
|
||||
deleteLater();
|
|
@ -42,13 +42,13 @@
|
|||
|
||||
#include <QtNetwork/private/qtnetworkglobal_p.h>
|
||||
|
||||
#include <QtNetwork/qsslcertificate.h>
|
||||
#include <QtNetwork/qsslsocket.h>
|
||||
|
||||
#include <QtCore/QtGlobal>
|
||||
#include <QtCore/QObject>
|
||||
|
||||
#include "qsslcertificate.h"
|
||||
#include "qsslsocket.h"
|
||||
|
||||
#include "qwincrypt_p.h"
|
||||
#include "../shared/qwincrypt_p.h"
|
||||
|
||||
//
|
||||
// W A R N I N G
|
|
@ -37,16 +37,15 @@
|
|||
**
|
||||
****************************************************************************/
|
||||
|
||||
#include "qtlsbackend_openssl_p.h"
|
||||
#include "qsslcertificate_p.h"
|
||||
#include "qtlskey_openssl_p.h"
|
||||
#include "qx509_openssl_p.h"
|
||||
|
||||
#include "qsslsocket_openssl_symbols_p.h"
|
||||
#include "qtlsbackend_openssl_p.h"
|
||||
#include "qtlskey_openssl_p.h"
|
||||
#include "qx509_openssl_p.h"
|
||||
#include "qtls_openssl_p.h"
|
||||
#include "qsslsocket.h"
|
||||
|
||||
#include <QtNetwork/private/qsslcertificate_p.h>
|
||||
|
||||
#include <QtNetwork/qsslsocket.h>
|
||||
#include <QtNetwork/qhostaddress.h>
|
||||
|
||||
#include <QtCore/qvarlengtharray.h>
|
||||
|
@ -62,10 +61,6 @@ namespace QTlsPrivate {
|
|||
|
||||
namespace {
|
||||
|
||||
// TLSTODO: These helper functions below were static member-functions of
|
||||
// QSslCertificatePrivate, if-defed with !QT_NO_OPENSSL, no need
|
||||
// for them to be exposed this way anymore. Remove this comment when
|
||||
// plugins are ready.
|
||||
QByteArray asn1ObjectId(ASN1_OBJECT *object)
|
||||
{
|
||||
if (!object)
|
||||
|
@ -108,6 +103,21 @@ QMultiMap<QByteArray, QString> mapFromX509Name(X509_NAME *name)
|
|||
return info;
|
||||
}
|
||||
|
||||
QDateTime dateTimeFromASN1(const ASN1_TIME *aTime)
|
||||
{
|
||||
QDateTime result;
|
||||
tm lTime;
|
||||
|
||||
if (q_ASN1_TIME_to_tm(aTime, &lTime)) {
|
||||
QDate resDate(lTime.tm_year + 1900, lTime.tm_mon + 1, lTime.tm_mday);
|
||||
QTime resTime(lTime.tm_hour, lTime.tm_min, lTime.tm_sec);
|
||||
result = QDateTime(resDate, resTime, Qt::UTC);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
#define BEGINCERTSTRING "-----BEGIN CERTIFICATE-----"
|
||||
#define ENDCERTSTRING "-----END CERTIFICATE-----"
|
||||
|
||||
|
@ -528,11 +538,11 @@ QSslCertificate X509CertificateOpenSSL::certificateFromX509(X509 *x509)
|
|||
|
||||
ASN1_TIME *nbef = q_X509_getm_notBefore(x509);
|
||||
if (nbef)
|
||||
backend->notValidBefore = q_getTimeFromASN1(nbef);
|
||||
backend->notValidBefore = dateTimeFromASN1(nbef);
|
||||
|
||||
ASN1_TIME *naft = q_X509_getm_notAfter(x509);
|
||||
if (naft)
|
||||
backend->notValidAfter = q_getTimeFromASN1(naft);
|
||||
backend->notValidAfter = dateTimeFromASN1(naft);
|
||||
|
||||
backend->null = false;
|
||||
backend->x509 = q_X509_dup(x509);
|
||||
|
@ -685,7 +695,7 @@ QList<QSslError> X509CertificateOpenSSL::verify(const QList<QSslCertificate> &ca
|
|||
errors << QSslError(QSslError::CertificateBlacklisted, certificateChain[0]);
|
||||
|
||||
// Check the certificate name against the hostname if one was specified
|
||||
if (!hostName.isEmpty() && !QSslSocketPrivate::isMatchingHostname(certificateChain[0], hostName)) {
|
||||
if (!hostName.isEmpty() && !TlsCryptograph::isMatchingHostname(certificateChain[0], hostName)) {
|
||||
// No matches in common names or alternate names.
|
||||
QSslError error(QSslError::HostNameMismatch, certificateChain[0]);
|
||||
errors << error;
|
|
@ -51,18 +51,17 @@
|
|||
// We mean it.
|
||||
//
|
||||
|
||||
#include <private/qtnetworkglobal_p.h>
|
||||
#include <QtNetwork/private/qtnetworkglobal_p.h>
|
||||
|
||||
#include <private/qopenssl_p.h>
|
||||
#include "../shared/qx509_base_p.h"
|
||||
|
||||
#include <private/qtlsbackend_p.h>
|
||||
#include <private/qx509_base_p.h>
|
||||
#include <QtNetwork/private/qtlsbackend_p.h>
|
||||
|
||||
#include <QtCore/qvariant.h>
|
||||
#include <QtCore/qglobal.h>
|
||||
#include <QtCore/qstring.h>
|
||||
|
||||
#include <openssl/x509.h>
|
||||
#include "qopenssl_p.h"
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
|
@ -70,9 +69,6 @@ QT_BEGIN_NAMESPACE
|
|||
|
||||
namespace QTlsPrivate {
|
||||
|
||||
// TLSTODO: This class is essentially what qsslcertificate_openssl.cpp
|
||||
// contains - OpenSSL-based version of QSslCertificatePrivate. Remove
|
||||
// this comment when plugins are ready.
|
||||
class X509CertificateOpenSSL final : public X509CertificateBase
|
||||
{
|
||||
public:
|
||||
|
@ -94,15 +90,10 @@ public:
|
|||
|
||||
size_t hash(size_t seed) const noexcept override;
|
||||
|
||||
// TLSTODO: these are needed by qsslsocket_openssl and later, by
|
||||
// TLS code inside OpenSSL plugin. Remove this comment when
|
||||
// plugins are ready.
|
||||
static QSslCertificate certificateFromX509(X509 *x);
|
||||
static QList<QSslCertificate> stackOfX509ToQSslCertificates(STACK_OF(X509) *x509);
|
||||
static QSslErrorEntry errorEntryFromStoreContext(X509_STORE_CTX *ctx);
|
||||
|
||||
// TLSTODO: remove this comment when plugins are in place. This is what QSslSocketPrivate::verify()
|
||||
// in qsslsocket_openssl.cpp is (was) doing (in the past).
|
||||
static QList<QSslError> verify(const QList<QSslCertificate> &chain, const QString &hostName);
|
||||
static QList<QSslError> verify(const QList<QSslCertificate> &caCertificates,
|
||||
const QList<QSslCertificate> &certificateChain,
|
|
@ -0,0 +1,30 @@
|
|||
qt_internal_add_plugin(QSchannelBackend
|
||||
OUTPUT_NAME schannelbackend
|
||||
CLASS_NAME QSchannelBackend
|
||||
TYPE tls
|
||||
DEFAULT_IF WINDOWS
|
||||
SOURCES
|
||||
../shared/qtlskey_base_p.h
|
||||
../shared/qtlskey_base.cpp
|
||||
../shared/qtlskey_generic_p.h
|
||||
../shared/qtlskey_generic.cpp
|
||||
../shared/qx509_base_p.h
|
||||
../shared/qx509_base.cpp
|
||||
../shared/qx509_generic_p.h
|
||||
../shared/qx509_generic.cpp
|
||||
../shared/qsslsocket_qt.cpp
|
||||
../shared/qwincrypt_p.h
|
||||
../shared/qasn1element_p.h
|
||||
../shared/qasn1element.cpp
|
||||
qtls_schannel.cpp qtls_schannel_p.h
|
||||
qtlsbackend_schannel_p.h
|
||||
qtlskey_schannel.cpp qtlskey_schannel_p.h
|
||||
qx509_schannel.cpp qx509_schannel_p.h
|
||||
LIBRARIES
|
||||
Crypt32
|
||||
Secur32
|
||||
bcrypt
|
||||
ncrypt
|
||||
PUBLIC_LIBRARIES
|
||||
Qt::NetworkPrivate
|
||||
)
|
|
@ -39,16 +39,18 @@
|
|||
|
||||
// #define QSSLSOCKET_DEBUG
|
||||
|
||||
#include "qssl_p.h"
|
||||
#include "qsslsocket.h"
|
||||
#include "qtls_schannel_p.h"
|
||||
#include "qsslcertificate.h"
|
||||
#include "qsslcertificateextension.h"
|
||||
#include "qsslcertificate_p.h"
|
||||
#include "qsslcipher_p.h"
|
||||
#include "qtlsbackend_schannel_p.h"
|
||||
#include "qtlskey_schannel_p.h"
|
||||
#include "qx509_schannel_p.h"
|
||||
#include "qtls_schannel_p.h"
|
||||
|
||||
#include <QtNetwork/private/qsslcertificate_p.h>
|
||||
#include <QtNetwork/private/qsslcipher_p.h>
|
||||
#include <QtNetwork/private/qssl_p.h>
|
||||
|
||||
#include <QtNetwork/qsslcertificate.h>
|
||||
#include <QtNetwork/qsslcertificateextension.h>
|
||||
#include <QtNetwork/qsslsocket.h>
|
||||
|
||||
#include <QtCore/qscopeguard.h>
|
||||
#include <QtCore/qoperatingsystemversion.h>
|
||||
|
@ -347,8 +349,6 @@ QTlsPrivate::X509DerReaderPtr QSchannelBackend::X509DerReader() const
|
|||
return QTlsPrivate::X509CertificateGeneric::certificatesFromDer;
|
||||
}
|
||||
|
||||
Q_GLOBAL_STATIC(QSchannelBackend, backendSchannel)
|
||||
|
||||
namespace {
|
||||
|
||||
SecBuffer createSecBuffer(void *ptr, unsigned long length, unsigned long bufferType)
|
||||
|
@ -573,7 +573,7 @@ bool matchesContextRequirements(DWORD attributes, DWORD requirements,
|
|||
bool isClient)
|
||||
{
|
||||
#ifdef QSSLSOCKET_DEBUG
|
||||
#define DEBUG_WARN(message) qCWarning(lcSsl, message)
|
||||
#define DEBUG_WARN(message) qCWarning(lcTlsBackend, message)
|
||||
#else
|
||||
#define DEBUG_WARN(message)
|
||||
#endif
|
||||
|
@ -630,8 +630,8 @@ QByteArray createAlpnString(const QByteArrayList &nextAllowedProtocols)
|
|||
QByteArray protocolString;
|
||||
for (QByteArray proto : nextAllowedProtocols) {
|
||||
if (proto.size() > 255) {
|
||||
qCWarning(lcSsl) << "TLS ALPN extension" << proto
|
||||
<< "is too long and will be ignored.";
|
||||
qCWarning(lcTlsBackend) << "TLS ALPN extension" << proto
|
||||
<< "is too long and will be ignored.";
|
||||
continue;
|
||||
} else if (proto.isEmpty()) {
|
||||
continue;
|
||||
|
@ -684,7 +684,7 @@ void retainExtraData(QByteArray &buffer, const SecBuffer &secBuffer)
|
|||
return;
|
||||
|
||||
#ifdef QSSLSOCKET_DEBUG
|
||||
qCDebug(lcSsl, "We got SECBUFFER_EXTRA, will retain %lu bytes", secBuffer.cbBuffer);
|
||||
qCDebug(lcTlsBackend, "We got SECBUFFER_EXTRA, will retain %lu bytes", secBuffer.cbBuffer);
|
||||
#endif
|
||||
std::move(buffer.end() - secBuffer.cbBuffer, buffer.end(), buffer.begin());
|
||||
buffer.resize(secBuffer.cbBuffer);
|
||||
|
@ -694,7 +694,7 @@ qint64 checkIncompleteData(const SecBuffer &secBuffer)
|
|||
{
|
||||
if (secBuffer.BufferType == SECBUFFER_MISSING) {
|
||||
#ifdef QSSLSOCKET_DEBUG
|
||||
qCDebug(lcSsl, "Need %lu more bytes.", secBuffer.cbBuffer);
|
||||
qCDebug(lcTlsBackend, "Need %lu more bytes.", secBuffer.cbBuffer);
|
||||
#endif
|
||||
return secBuffer.cbBuffer;
|
||||
}
|
||||
|
@ -745,7 +745,7 @@ bool TlsCryptographSchannel::sendToken(void *token, unsigned long tokenLength, b
|
|||
if (written != qint64(tokenLength)) {
|
||||
// Failed to write/buffer everything or an error occurred
|
||||
if (emitError)
|
||||
d->setErrorAndEmit(plainSocket->error(), plainSocket->errorString());
|
||||
setErrorAndEmit(d, plainSocket->error(), plainSocket->errorString());
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
|
@ -804,8 +804,8 @@ bool TlsCryptographSchannel::acquireCredentialsHandle()
|
|||
const bool isClient = d->tlsMode() == QSslSocket::SslClientMode;
|
||||
const DWORD protocols = toSchannelProtocol(configuration.protocol());
|
||||
if (protocols == DWORD(-1)) {
|
||||
d->setErrorAndEmit(QAbstractSocket::SslInvalidUserDataError,
|
||||
QSslSocket::tr("Invalid protocol chosen"));
|
||||
setErrorAndEmit(d, QAbstractSocket::SslInvalidUserDataError,
|
||||
QSslSocket::tr("Invalid protocol chosen"));
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -842,7 +842,7 @@ bool TlsCryptographSchannel::acquireCredentialsHandle()
|
|||
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.");
|
||||
d->setErrorAndEmit(QAbstractSocket::SocketError::SslInvalidUserDataError, message);
|
||||
setErrorAndEmit(d, QAbstractSocket::SocketError::SslInvalidUserDataError, message);
|
||||
return false;
|
||||
}
|
||||
Q_ASSERT(chainContext->cChain == 1);
|
||||
|
@ -931,7 +931,7 @@ bool TlsCryptographSchannel::acquireCredentialsHandle()
|
|||
}
|
||||
|
||||
if (status != SEC_E_OK) {
|
||||
d->setErrorAndEmit(QAbstractSocket::SslInternalError, schannelErrorToString(status));
|
||||
setErrorAndEmit(d, QAbstractSocket::SslInternalError, schannelErrorToString(status));
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
|
@ -964,7 +964,6 @@ bool TlsCryptographSchannel::createContext()
|
|||
{
|
||||
Q_ASSERT(q);
|
||||
Q_ASSERT(d);
|
||||
const auto &configuration = q->sslConfiguration();
|
||||
|
||||
Q_ASSERT(SecIsValidHandle(&credentialHandle));
|
||||
Q_ASSERT(schannelState == SchannelState::InitializeHandshake);
|
||||
|
@ -993,7 +992,7 @@ bool TlsCryptographSchannel::createContext()
|
|||
bool useAlpn = false;
|
||||
#ifdef SUPPORTS_ALPN
|
||||
QTlsBackend::setAlpnStatus(d, QSslConfiguration::NextProtocolNegotiationNone);
|
||||
QByteArray alpnString = createAlpnString(configuration.allowedNextProtocols());
|
||||
QByteArray alpnString = createAlpnString(q->sslConfiguration().allowedNextProtocols());
|
||||
useAlpn = !alpnString.isEmpty();
|
||||
SecBuffer alpnBuffers[1];
|
||||
alpnBuffers[0] = createSecBuffer(alpnString, SECBUFFER_APPLICATION_PROTOCOLS);
|
||||
|
@ -1021,8 +1020,8 @@ bool TlsCryptographSchannel::createContext()
|
|||
// 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) {
|
||||
d->setErrorAndEmit(QAbstractSocket::SslInternalError,
|
||||
QSslSocket::tr("Error creating SSL context (%1)").arg(schannelErrorToString(status)));
|
||||
setErrorAndEmit(d, QAbstractSocket::SslInternalError,
|
||||
QSslSocket::tr("Error creating SSL context (%1)").arg(schannelErrorToString(status)));
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -1036,8 +1035,9 @@ bool TlsCryptographSchannel::acceptContext()
|
|||
{
|
||||
Q_ASSERT(d);
|
||||
Q_ASSERT(q);
|
||||
const auto &configuration = q->sslConfiguration();
|
||||
|
||||
auto *plainSocket = d->plainTcpSocket();
|
||||
Q_ASSERT(plainSocket);
|
||||
|
||||
Q_ASSERT(SecIsValidHandle(&credentialHandle));
|
||||
Q_ASSERT(schannelState == SchannelState::InitializeHandshake);
|
||||
|
@ -1058,7 +1058,7 @@ bool TlsCryptographSchannel::acceptContext()
|
|||
#ifdef SUPPORTS_ALPN
|
||||
QTlsBackend::setAlpnStatus(d, QSslConfiguration::NextProtocolNegotiationNone);
|
||||
// The string must be alive when we call AcceptSecurityContext
|
||||
QByteArray alpnString = createAlpnString(configuration.allowedNextProtocols());
|
||||
QByteArray alpnString = createAlpnString(q->sslConfiguration().allowedNextProtocols());
|
||||
if (!alpnString.isEmpty()) {
|
||||
inBuffers[1] = createSecBuffer(alpnString, SECBUFFER_APPLICATION_PROTOCOLS);
|
||||
} else
|
||||
|
@ -1118,8 +1118,8 @@ bool TlsCryptographSchannel::acceptContext()
|
|||
}
|
||||
|
||||
if (status != SEC_I_CONTINUE_NEEDED) {
|
||||
d->setErrorAndEmit(QAbstractSocket::SslHandshakeFailedError,
|
||||
QSslSocket::tr("Error creating SSL context (%1)").arg(schannelErrorToString(status)));
|
||||
setErrorAndEmit(d, QAbstractSocket::SslHandshakeFailedError,
|
||||
QSslSocket::tr("Error creating SSL context (%1)").arg(schannelErrorToString(status)));
|
||||
return false;
|
||||
}
|
||||
if (!sendToken(outBuffers[0].pvBuffer, outBuffers[0].cbBuffer))
|
||||
|
@ -1135,8 +1135,8 @@ bool TlsCryptographSchannel::performHandshake()
|
|||
Q_ASSERT(plainSocket);
|
||||
|
||||
if (plainSocket->state() == QAbstractSocket::UnconnectedState) {
|
||||
d->setErrorAndEmit(QAbstractSocket::RemoteHostClosedError,
|
||||
QSslSocket::tr("The TLS/SSL connection has been closed"));
|
||||
setErrorAndEmit(d, QAbstractSocket::RemoteHostClosedError,
|
||||
QSslSocket::tr("The TLS/SSL connection has been closed"));
|
||||
return false;
|
||||
}
|
||||
Q_ASSERT(SecIsValidHandle(&credentialHandle));
|
||||
|
@ -1144,8 +1144,8 @@ bool TlsCryptographSchannel::performHandshake()
|
|||
Q_ASSERT(schannelState == SchannelState::PerformHandshake);
|
||||
|
||||
#ifdef QSSLSOCKET_DEBUG
|
||||
qCDebug(lcSsl, "Bytes available from socket: %lld", plainSocket->bytesAvailable());
|
||||
qCDebug(lcSsl, "intermediateBuffer size: %d", intermediateBuffer.size());
|
||||
qCDebug(lcTlsBackend, "Bytes available from socket: %lld", plainSocket->bytesAvailable());
|
||||
qCDebug(lcTlsBackend, "intermediateBuffer size: %d", intermediateBuffer.size());
|
||||
#endif
|
||||
|
||||
if (missingData > plainSocket->bytesAvailable())
|
||||
|
@ -1236,8 +1236,8 @@ bool TlsCryptographSchannel::performHandshake()
|
|||
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.
|
||||
d->setErrorAndEmit(QAbstractSocket::SslHandshakeFailedError,
|
||||
QSslSocket::tr("Server did not accept any certificate we could present."));
|
||||
setErrorAndEmit(d, 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."
|
||||
|
@ -1246,8 +1246,8 @@ bool TlsCryptographSchannel::performHandshake()
|
|||
return false;
|
||||
}
|
||||
if (!shutdown) { // we did not initiate this
|
||||
d->setErrorAndEmit(QAbstractSocket::RemoteHostClosedError,
|
||||
QSslSocket::tr("The TLS/SSL connection has been closed"));
|
||||
setErrorAndEmit(d, QAbstractSocket::RemoteHostClosedError,
|
||||
QSslSocket::tr("The TLS/SSL connection has been closed"));
|
||||
}
|
||||
return true;
|
||||
case SEC_E_INCOMPLETE_MESSAGE:
|
||||
|
@ -1255,8 +1255,8 @@ bool TlsCryptographSchannel::performHandshake()
|
|||
missingData = checkIncompleteData(outBuffers[0]);
|
||||
return true;
|
||||
case SEC_E_ALGORITHM_MISMATCH:
|
||||
d->setErrorAndEmit(QAbstractSocket::SslHandshakeFailedError,
|
||||
QSslSocket::tr("Algorithm mismatch"));
|
||||
setErrorAndEmit(d, QAbstractSocket::SslHandshakeFailedError,
|
||||
QSslSocket::tr("Algorithm mismatch"));
|
||||
shutdown = true; // skip sending the "Shutdown" alert
|
||||
return false;
|
||||
}
|
||||
|
@ -1264,8 +1264,8 @@ bool TlsCryptographSchannel::performHandshake()
|
|||
// 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)
|
||||
d->setErrorAndEmit(QAbstractSocket::SslHandshakeFailedError,
|
||||
QSslSocket::tr("Handshake failed: %1").arg(schannelErrorToString(status)));
|
||||
setErrorAndEmit(d, QAbstractSocket::SslHandshakeFailedError,
|
||||
QSslSocket::tr("Handshake failed: %1").arg(schannelErrorToString(status)));
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -1280,7 +1280,7 @@ bool TlsCryptographSchannel::verifyHandshake()
|
|||
const bool isClient = d->tlsMode() == QSslSocket::SslClientMode;
|
||||
#define CHECK_STATUS(status) \
|
||||
if (status != SEC_E_OK) { \
|
||||
d->setErrorAndEmit(QAbstractSocket::SslInternalError, \
|
||||
setErrorAndEmit(d, QAbstractSocket::SslInternalError, \
|
||||
QSslSocket::tr("Failed to query the TLS context: %1") \
|
||||
.arg(schannelErrorToString(status))); \
|
||||
return false; \
|
||||
|
@ -1289,8 +1289,8 @@ bool TlsCryptographSchannel::verifyHandshake()
|
|||
// Everything is set up, now make sure there's nothing wrong and query some attributes...
|
||||
if (!matchesContextRequirements(contextAttributes, getContextRequirements(),
|
||||
configuration.peerVerifyMode(), isClient)) {
|
||||
d->setErrorAndEmit(QAbstractSocket::SslHandshakeFailedError,
|
||||
QSslSocket::tr("Did not get the required attributes for the connection."));
|
||||
setErrorAndEmit(d, QAbstractSocket::SslHandshakeFailedError,
|
||||
QSslSocket::tr("Did not get the required attributes for the connection."));
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -1318,7 +1318,7 @@ bool TlsCryptographSchannel::verifyHandshake()
|
|||
QByteArray negotiatedProto = QByteArray((const char *)alpn.ProtocolId,
|
||||
alpn.ProtocolIdSize);
|
||||
if (!allowedProtos.contains(negotiatedProto)) {
|
||||
d->setErrorAndEmit(QAbstractSocket::SslHandshakeFailedError,
|
||||
setErrorAndEmit(d, QAbstractSocket::SslHandshakeFailedError,
|
||||
QSslSocket::tr("Unwanted protocol was negotiated"));
|
||||
return false;
|
||||
}
|
||||
|
@ -1353,8 +1353,8 @@ bool TlsCryptographSchannel::verifyHandshake()
|
|||
&& configuration.peerVerifyMode() != QSslSocket::PeerVerifyMode::QueryPeer)) {
|
||||
if (status != SEC_E_OK) {
|
||||
#ifdef QSSLSOCKET_DEBUG
|
||||
qCDebug(lcSsl) << "Couldn't retrieve peer certificate, status:"
|
||||
<< schannelErrorToString(status);
|
||||
qCDebug(lcTlsBackend) << "Couldn't retrieve peer certificate, status:"
|
||||
<< schannelErrorToString(status);
|
||||
#endif
|
||||
const QSslError error{ QSslError::NoPeerCertificate };
|
||||
sslErrors += error;
|
||||
|
@ -1370,7 +1370,7 @@ bool TlsCryptographSchannel::verifyHandshake()
|
|||
|
||||
if (!checkSslErrors() || q->state() != QAbstractSocket::ConnectedState) {
|
||||
#ifdef QSSLSOCKET_DEBUG
|
||||
qCDebug(lcSsl) << __func__ << "was unsuccessful. Paused:" << paused;
|
||||
qCDebug(lcTlsBackend) << __func__ << "was unsuccessful. Paused:" << paused;
|
||||
#endif
|
||||
// If we're paused then checkSslErrors returned false, but it's not an error
|
||||
return d->isPaused() && q->state() == QAbstractSocket::ConnectedState;
|
||||
|
@ -1437,7 +1437,7 @@ bool TlsCryptographSchannel::renegotiate()
|
|||
schannelState = SchannelState::PerformHandshake;
|
||||
return true;
|
||||
}
|
||||
d->setErrorAndEmit(QAbstractSocket::SslHandshakeFailedError,
|
||||
setErrorAndEmit(d, QAbstractSocket::SslHandshakeFailedError,
|
||||
QSslSocket::tr("Renegotiation was unsuccessful: %1").arg(schannelErrorToString(status)));
|
||||
return false;
|
||||
}
|
||||
|
@ -1541,7 +1541,7 @@ void TlsCryptographSchannel::transmit()
|
|||
};
|
||||
auto status = EncryptMessage(&contextHandle, 0, &message, 0);
|
||||
if (status != SEC_E_OK) {
|
||||
d->setErrorAndEmit(QAbstractSocket::SslInternalError,
|
||||
setErrorAndEmit(d, QAbstractSocket::SslInternalError,
|
||||
QSslSocket::tr("Schannel failed to encrypt data: %1")
|
||||
.arg(schannelErrorToString(status)));
|
||||
return;
|
||||
|
@ -1553,12 +1553,12 @@ void TlsCryptographSchannel::transmit()
|
|||
fullMessage.resize(inputBuffers[0].cbBuffer + inputBuffers[1].cbBuffer + inputBuffers[2].cbBuffer);
|
||||
const qint64 bytesWritten = plainSocket->write(fullMessage);
|
||||
#ifdef QSSLSOCKET_DEBUG
|
||||
qCDebug(lcSsl, "Wrote %lld of total %d bytes", bytesWritten, fullMessage.length());
|
||||
qCDebug(lcTlsBackend, "Wrote %lld of total %d bytes", bytesWritten, fullMessage.length());
|
||||
#endif
|
||||
if (bytesWritten >= 0) {
|
||||
totalBytesWritten += bytesWritten;
|
||||
} else {
|
||||
d->setErrorAndEmit(plainSocket->error(), plainSocket->errorString());
|
||||
setErrorAndEmit(d, plainSocket->error(), plainSocket->errorString());
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
@ -1583,7 +1583,7 @@ void TlsCryptographSchannel::transmit()
|
|||
if (missingData > plainSocket->bytesAvailable()
|
||||
&& (!readBufferMaxSize || readBufferMaxSize >= missingData)) {
|
||||
#ifdef QSSLSOCKET_DEBUG
|
||||
qCDebug(lcSsl, "We're still missing %lld bytes, will check later.", missingData);
|
||||
qCDebug(lcTlsBackend, "We're still missing %lld bytes, will check later.", missingData);
|
||||
#endif
|
||||
break;
|
||||
}
|
||||
|
@ -1591,18 +1591,18 @@ void TlsCryptographSchannel::transmit()
|
|||
missingData = 0;
|
||||
const qint64 bytesRead = readToBuffer(intermediateBuffer, plainSocket);
|
||||
#ifdef QSSLSOCKET_DEBUG
|
||||
qCDebug(lcSsl, "Read %lld encrypted bytes from the socket", bytesRead);
|
||||
qCDebug(lcTlsBackend, "Read %lld encrypted bytes from the socket", bytesRead);
|
||||
#endif
|
||||
if (intermediateBuffer.length() == 0 || (hadIncompleteData && bytesRead == 0)) {
|
||||
#ifdef QSSLSOCKET_DEBUG
|
||||
qCDebug(lcSsl, (hadIncompleteData ? "No new data received, leaving loop!"
|
||||
: "Nothing to decrypt, leaving loop!"));
|
||||
qCDebug(lcTlsBackend, (hadIncompleteData ? "No new data received, leaving loop!"
|
||||
: "Nothing to decrypt, leaving loop!"));
|
||||
#endif
|
||||
break;
|
||||
}
|
||||
hadIncompleteData = false;
|
||||
#ifdef QSSLSOCKET_DEBUG
|
||||
qCDebug(lcSsl, "Total amount of bytes to decrypt: %d", intermediateBuffer.length());
|
||||
qCDebug(lcTlsBackend, "Total amount of bytes to decrypt: %d", intermediateBuffer.length());
|
||||
#endif
|
||||
|
||||
SecBuffer dataBuffer[4]{
|
||||
|
@ -1627,7 +1627,7 @@ void TlsCryptographSchannel::transmit()
|
|||
dataBuffer[1].cbBuffer);
|
||||
totalRead += dataBuffer[1].cbBuffer;
|
||||
#ifdef QSSLSOCKET_DEBUG
|
||||
qCDebug(lcSsl, "Decrypted %lu bytes. New read buffer size: %d",
|
||||
qCDebug(lcTlsBackend, "Decrypted %lu bytes. New read buffer size: %d",
|
||||
dataBuffer[1].cbBuffer, buffer.size());
|
||||
#endif
|
||||
}
|
||||
|
@ -1644,22 +1644,22 @@ void TlsCryptographSchannel::transmit()
|
|||
if (status == SEC_E_INCOMPLETE_MESSAGE) {
|
||||
missingData = checkIncompleteData(dataBuffer[0]);
|
||||
#ifdef QSSLSOCKET_DEBUG
|
||||
qCDebug(lcSsl, "We didn't have enough data to decrypt anything, will try again!");
|
||||
qCDebug(lcTlsBackend, "We didn't have enough data to decrypt anything, will try again!");
|
||||
#endif
|
||||
// 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!");
|
||||
qCWarning(lcTlsBackend, "The internal SSPI handle is invalid!");
|
||||
Q_UNREACHABLE();
|
||||
} else if (status == SEC_E_INVALID_TOKEN) {
|
||||
qCWarning(lcSsl, "Got SEC_E_INVALID_TOKEN!");
|
||||
qCWarning(lcTlsBackend, "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();
|
||||
d->setErrorAndEmit(QAbstractSocket::SslInternalError,
|
||||
setErrorAndEmit(d, QAbstractSocket::SslInternalError,
|
||||
schannelErrorToString(status));
|
||||
break;
|
||||
} else if (status == SEC_E_OUT_OF_SEQUENCE) {
|
||||
|
@ -1668,19 +1668,19 @@ void TlsCryptographSchannel::transmit()
|
|||
// while SEC_E_MESSAGE_ALTERED is for stream-oriented ones (what we use).
|
||||
shutdown = true; // skips sending the shutdown alert
|
||||
disconnectFromHost();
|
||||
d->setErrorAndEmit(QAbstractSocket::SslInternalError,
|
||||
setErrorAndEmit(d, QAbstractSocket::SslInternalError,
|
||||
schannelErrorToString(status));
|
||||
break;
|
||||
} else if (status == SEC_I_CONTEXT_EXPIRED) {
|
||||
// 'remote' has initiated a shutdown
|
||||
disconnectFromHost();
|
||||
d->setErrorAndEmit(QAbstractSocket::RemoteHostClosedError,
|
||||
setErrorAndEmit(d, 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.");
|
||||
qCDebug(lcTlsBackend, "The peer wants to renegotiate.");
|
||||
#endif
|
||||
schannelState = SchannelState::Renegotiate;
|
||||
renegotiating = true;
|
||||
|
@ -1716,7 +1716,7 @@ void TlsCryptographSchannel::sendShutdown()
|
|||
|
||||
if (status != SEC_E_OK) {
|
||||
#ifdef QSSLSOCKET_DEBUG
|
||||
qCDebug(lcSsl) << "Failed to apply shutdown control token:" << schannelErrorToString(status);
|
||||
qCDebug(lcTlsBackend) << "Failed to apply shutdown control token:" << schannelErrorToString(status);
|
||||
#endif
|
||||
return;
|
||||
}
|
||||
|
@ -1774,7 +1774,7 @@ void TlsCryptographSchannel::sendShutdown()
|
|||
}
|
||||
} else {
|
||||
#ifdef QSSLSOCKET_DEBUG
|
||||
qCDebug(lcSsl) << "Failed to initialize shutdown:" << schannelErrorToString(status);
|
||||
qCDebug(lcTlsBackend) << "Failed to initialize shutdown:" << schannelErrorToString(status);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
@ -1929,7 +1929,7 @@ bool TlsCryptographSchannel::checkSslErrors()
|
|||
QSslSocketPrivate::pauseSocketNotifiers(q);
|
||||
d->setPaused(true);
|
||||
} else {
|
||||
d->setErrorAndEmit(QAbstractSocket::SslHandshakeFailedError,
|
||||
setErrorAndEmit(d, QAbstractSocket::SslHandshakeFailedError,
|
||||
sslErrors.constFirst().errorString());
|
||||
plainSocket->disconnectFromHost();
|
||||
}
|
||||
|
@ -1960,7 +1960,7 @@ void TlsCryptographSchannel::initializeCertificateStores()
|
|||
|
||||
if (!configuration.localCertificateChain().isEmpty()) {
|
||||
if (configuration.privateKey().isNull()) {
|
||||
d->setErrorAndEmit(QAbstractSocket::SslInvalidUserDataError,
|
||||
setErrorAndEmit(d, QAbstractSocket::SslInvalidUserDataError,
|
||||
QSslSocket::tr("Cannot provide a certificate with no key"));
|
||||
return;
|
||||
}
|
||||
|
@ -1968,7 +1968,7 @@ void TlsCryptographSchannel::initializeCertificateStores()
|
|||
localCertificateStore = createStoreFromCertificateChain(configuration.localCertificateChain(),
|
||||
configuration.privateKey());
|
||||
if (localCertificateStore == nullptr)
|
||||
qCWarning(lcSsl, "Failed to load certificate chain!");
|
||||
qCWarning(lcTlsBackend, "Failed to load certificate chain!");
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1995,7 +1995,7 @@ bool TlsCryptographSchannel::verifyCertContext(CERT_CONTEXT *certContext)
|
|||
nullptr));
|
||||
if (!tempCertCollection) {
|
||||
#ifdef QSSLSOCKET_DEBUG
|
||||
qCWarning(lcSsl, "Failed to create certificate store collection!");
|
||||
qCWarning(lcTlsBackend, "Failed to create certificate store collection!");
|
||||
#endif
|
||||
return false;
|
||||
}
|
||||
|
@ -2008,12 +2008,12 @@ bool TlsCryptographSchannel::verifyCertContext(CERT_CONTEXT *certContext)
|
|||
auto rootStore = QHCertStorePointer(CertOpenSystemStore(0, L"ROOT"));
|
||||
if (!rootStore) {
|
||||
#ifdef QSSLSOCKET_DEBUG
|
||||
qCWarning(lcSsl, "Failed to open the system root CA certificate store!");
|
||||
qCWarning(lcTlsBackend, "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!");
|
||||
qCWarning(lcTlsBackend, "Failed to add the system root CA certificate store to the certificate store collection!");
|
||||
#endif
|
||||
return false;
|
||||
}
|
||||
|
@ -2021,7 +2021,7 @@ bool TlsCryptographSchannel::verifyCertContext(CERT_CONTEXT *certContext)
|
|||
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!");
|
||||
qCWarning(lcTlsBackend, "Failed to add the user's CA certificate store to the certificate store collection!");
|
||||
#endif
|
||||
return false;
|
||||
}
|
||||
|
@ -2029,7 +2029,7 @@ bool TlsCryptographSchannel::verifyCertContext(CERT_CONTEXT *certContext)
|
|||
|
||||
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!");
|
||||
qCWarning(lcTlsBackend, "Failed to add certificate's origin store to the certificate store collection!");
|
||||
#endif
|
||||
return false;
|
||||
}
|
||||
|
@ -2311,12 +2311,4 @@ bool TlsCryptographSchannel::rootCertOnDemandLoadingAllowed()
|
|||
|
||||
} // namespace QTlsPrivate
|
||||
|
||||
void QSslSocketPrivate::registerAdHocFactory()
|
||||
{
|
||||
// TLSTODO: this is a temporary solution, waiting for
|
||||
// backends to move to ... plugins.
|
||||
if (!backendSchannel())
|
||||
qCWarning(lcTlsBackend, "Failed to create backend factory");
|
||||
}
|
||||
|
||||
QT_END_NAMESPACE
|
|
@ -55,12 +55,11 @@
|
|||
|
||||
QT_REQUIRE_CONFIG(schannel);
|
||||
|
||||
#include <QtCore/qt_windows.h>
|
||||
#include "../shared/qwincrypt_p.h"
|
||||
|
||||
#include "qtlsbackend_schannel_p.h"
|
||||
#include "qsslsocket_p.h"
|
||||
|
||||
#include "qwincrypt_p.h"
|
||||
#include <QtNetwork/private/qsslsocket_p.h>
|
||||
|
||||
#define SECURITY_WIN32
|
||||
#define SCHANNEL_USE_BLACKLISTS 1
|
|
@ -53,7 +53,7 @@
|
|||
|
||||
#include <private/qtnetworkglobal_p.h>
|
||||
|
||||
#include "qtlsbackend_p.h"
|
||||
#include <QtNetwork/private/qtlsbackend_p.h>
|
||||
|
||||
#include <QtCore/qglobal.h>
|
||||
|
||||
|
@ -62,6 +62,10 @@ QT_BEGIN_NAMESPACE
|
|||
|
||||
class QSchannelBackend : public QTlsBackend
|
||||
{
|
||||
Q_OBJECT
|
||||
Q_PLUGIN_METADATA(IID QTlsBackend_iid)
|
||||
Q_INTERFACES(QTlsBackend)
|
||||
|
||||
public:
|
||||
static void ensureInitializedImplementation();
|
||||
|
|
@ -37,18 +37,20 @@
|
|||
**
|
||||
****************************************************************************/
|
||||
|
||||
#include "qssl_p.h"
|
||||
#include <QtNetwork/private/qssl_p.h>
|
||||
|
||||
#include "qtlskey_schannel_p.h"
|
||||
#include "qtlsbackend_p.h"
|
||||
#include "qsslkey_p.h"
|
||||
#include "qsslkey.h"
|
||||
|
||||
#include "../shared/qwincrypt_p.h"
|
||||
|
||||
#include <QtNetwork/private/qtlsbackend_p.h>
|
||||
#include <QtNetwork/private/qsslkey_p.h>
|
||||
|
||||
#include <QtNetwork/qsslkey.h>
|
||||
|
||||
#include <QtCore/qscopeguard.h>
|
||||
#include <QtCore/qbytearray.h>
|
||||
|
||||
#include <QtCore/qt_windows.h>
|
||||
#include <wincrypt.h>
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
namespace {
|
|
@ -51,9 +51,9 @@
|
|||
// We mean it.
|
||||
//
|
||||
|
||||
#include <private/qtnetworkglobal_p.h>
|
||||
#include <QtNetwork/private/qtnetworkglobal_p.h>
|
||||
|
||||
#include <private/qtlskey_generic_p.h>
|
||||
#include "../shared/qtlskey_generic_p.h"
|
||||
|
||||
#include <QtCore/qglobal.h>
|
||||
|
|
@ -38,9 +38,10 @@
|
|||
****************************************************************************/
|
||||
|
||||
#include "qtlskey_schannel_p.h"
|
||||
#include "qsslcertificate_p.h"
|
||||
#include "qx509_schannel_p.h"
|
||||
|
||||
#include <QtNetwork/private/qsslcertificate_p.h>
|
||||
|
||||
#include <memory>
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
|
@ -51,15 +51,13 @@
|
|||
// We mean it.
|
||||
//
|
||||
|
||||
#include <private/qtnetworkglobal_p.h>
|
||||
#include <QtNetwork/private/qtnetworkglobal_p.h>
|
||||
|
||||
#include <private/qx509_generic_p.h>
|
||||
#include "../shared/qx509_generic_p.h"
|
||||
#include "../shared/qwincrypt_p.h"
|
||||
|
||||
#include <QtCore/qglobal.h>
|
||||
|
||||
#include <QtCore/qt_windows.h>
|
||||
#include <wincrypt.h>
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
namespace QTlsPrivate {
|
|
@ -0,0 +1,33 @@
|
|||
qt_internal_add_plugin(QSecureTransportBackend
|
||||
OUTPUT_NAME securetransportbackend
|
||||
CLASS_NAME QSecureTransportBackend
|
||||
TYPE tls
|
||||
DEFAULT_IF APPLE
|
||||
SOURCES
|
||||
../shared/qsslsocket_mac_shared.cpp
|
||||
../shared/qtlskey_generic_p.h
|
||||
../shared/qtlskey_generic.cpp
|
||||
../shared/qx509_base_p.h
|
||||
../shared/qx509_base.cpp
|
||||
../shared/qx509_generic_p.h
|
||||
../shared/qx509_generic.cpp
|
||||
../shared/qtlskey_base_p.h
|
||||
../shared/qtlskey_base.cpp
|
||||
../shared/qsslsocket_qt.cpp
|
||||
../shared/qasn1element_p.h
|
||||
../shared/qasn1element.cpp
|
||||
qtlsbackend_st.cpp
|
||||
qtlsbackend_st_p.h
|
||||
qx509_st.cpp
|
||||
qtlskey_st.cpp
|
||||
qtlskey_st_p.h
|
||||
qx509_st_p.h
|
||||
qtls_st.cpp
|
||||
qtls_st_p.h
|
||||
PUBLIC_LIBRARIES
|
||||
Qt::NetworkPrivate
|
||||
Qt::CorePrivate
|
||||
LIBRARIES
|
||||
${FWCoreFoundation}
|
||||
${FWSecurity}
|
||||
)
|
|
@ -38,16 +38,17 @@
|
|||
**
|
||||
****************************************************************************/
|
||||
|
||||
#include "qsslsocket.h"
|
||||
|
||||
#include "qssl_p.h"
|
||||
#include "qtls_st_p.h"
|
||||
#include "qasn1element_p.h"
|
||||
#include "qsslcertificate_p.h"
|
||||
#include "qtlsbackend_st_p.h"
|
||||
#include "qsslcipher_p.h"
|
||||
#include "qtlskey_st_p.h"
|
||||
#include "qsslkey_p.h"
|
||||
|
||||
#include <QtNetwork/private/qssl_p.h>
|
||||
|
||||
#include <QtNetwork/private/qsslcertificate_p.h>
|
||||
#include <QtNetwork/private/qsslcipher_p.h>
|
||||
#include <QtNetwork/private/qsslkey_p.h>
|
||||
|
||||
#include <QtNetwork/qsslsocket.h>
|
||||
|
||||
#include <QtCore/qmessageauthenticationcode.h>
|
||||
#include <QtCore/qoperatingsystemversion.h>
|
||||
|
@ -75,8 +76,6 @@
|
|||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
Q_GLOBAL_STATIC(QSecureTransportBackend, backendSecureTransport)
|
||||
|
||||
// Defined in qsslsocket_qt.cpp.
|
||||
QByteArray _q_makePkcs12(const QList<QSslCertificate> &certs, const QSslKey &key,
|
||||
const QString &passPhrase);
|
||||
|
@ -205,7 +204,7 @@ SSLContextRef qt_createSecureTransportContext(QSslSocket::SslMode mode)
|
|||
// We never use kSSLDatagramType, so it's kSSLStreamType unconditionally.
|
||||
SSLContextRef context = SSLCreateContext(nullptr, side, kSSLStreamType);
|
||||
if (!context)
|
||||
qCWarning(lcSsl) << "SSLCreateContext failed";
|
||||
qCWarning(lcTlsBackend) << "SSLCreateContext failed";
|
||||
return context;
|
||||
}
|
||||
|
||||
|
@ -457,9 +456,9 @@ void TlsCryptographSecureTransport::startClientEncryption()
|
|||
if (!initSslContext()) {
|
||||
Q_ASSERT(d);
|
||||
// Error description/code were set, 'error' emitted
|
||||
// by initSslContext, but OpenSSL socket also sets error
|
||||
// by initSslContext, but OpenSSL socket also sets error,
|
||||
// emits a signal twice, so ...
|
||||
d->setErrorAndEmit(QAbstractSocket::SslInternalError, QStringLiteral("Unable to init SSL Context"));
|
||||
setErrorAndEmit(d, QAbstractSocket::SslInternalError, QStringLiteral("Unable to init SSL Context"));
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -472,7 +471,7 @@ void TlsCryptographSecureTransport::startServerEncryption()
|
|||
// Error description/code were set, 'error' emitted
|
||||
// by initSslContext, but OpenSSL socket also sets error
|
||||
// emits a signal twice, so ...
|
||||
d->setErrorAndEmit(QAbstractSocket::SslInternalError, QStringLiteral("Unable to init SSL Context"));
|
||||
setErrorAndEmit(d, QAbstractSocket::SslInternalError, QStringLiteral("Unable to init SSL Context"));
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -503,8 +502,8 @@ void TlsCryptographSecureTransport::transmit()
|
|||
qCDebug(lcTlsBackend) << d->plainTcpSocket() << "SSLWrite returned" << err;
|
||||
#endif
|
||||
if (err != errSecSuccess && err != errSSLWouldBlock) {
|
||||
d->setErrorAndEmit(QAbstractSocket::SslInternalError,
|
||||
QStringLiteral("SSLWrite failed: %1").arg(err));
|
||||
setErrorAndEmit(d, QAbstractSocket::SslInternalError,
|
||||
QStringLiteral("SSLWrite failed: %1").arg(err));
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -542,12 +541,12 @@ void TlsCryptographSecureTransport::transmit()
|
|||
#endif
|
||||
if (err == errSSLClosedGraceful) {
|
||||
shutdown = true; // the other side shut down, make sure we do not send shutdown ourselves
|
||||
d->setErrorAndEmit(QAbstractSocket::RemoteHostClosedError,
|
||||
QSslSocket::tr("The TLS/SSL connection has been closed"));
|
||||
setErrorAndEmit(d, QAbstractSocket::RemoteHostClosedError,
|
||||
QSslSocket::tr("The TLS/SSL connection has been closed"));
|
||||
break;
|
||||
} else if (err != errSecSuccess && err != errSSLWouldBlock) {
|
||||
d->setErrorAndEmit(QAbstractSocket::SslInternalError,
|
||||
QStringLiteral("SSLRead failed: %1").arg(err));
|
||||
setErrorAndEmit(d, QAbstractSocket::SslInternalError,
|
||||
QStringLiteral("SSLRead failed: %1").arg(err));
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -662,7 +661,7 @@ bool TlsCryptographSecureTransport::initSslContext()
|
|||
|
||||
context.reset(qt_createSecureTransportContext(mode));
|
||||
if (!context) {
|
||||
d->setErrorAndEmit(QAbstractSocket::SslInternalError, QStringLiteral("SSLCreateContext failed"));
|
||||
setErrorAndEmit(d, QAbstractSocket::SslInternalError, QStringLiteral("SSLCreateContext failed"));
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -671,8 +670,8 @@ bool TlsCryptographSecureTransport::initSslContext()
|
|||
reinterpret_cast<SSLWriteFunc>(&TlsCryptographSecureTransport::WriteCallback));
|
||||
if (err != errSecSuccess) {
|
||||
destroySslContext();
|
||||
d->setErrorAndEmit(QAbstractSocket::SslInternalError,
|
||||
QStringLiteral("SSLSetIOFuncs failed: %1").arg(err));
|
||||
setErrorAndEmit(d, QAbstractSocket::SslInternalError,
|
||||
QStringLiteral("SSLSetIOFuncs failed: %1").arg(err));
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -685,14 +684,14 @@ bool TlsCryptographSecureTransport::initSslContext()
|
|||
QAbstractSocket::SocketError errorCode = QAbstractSocket::UnknownSocketError;
|
||||
if (!setSessionCertificate(errorDescription, errorCode)) {
|
||||
destroySslContext();
|
||||
d->setErrorAndEmit(errorCode, errorDescription);
|
||||
setErrorAndEmit(d, errorCode, errorDescription);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if (!setSessionProtocol()) {
|
||||
destroySslContext();
|
||||
d->setErrorAndEmit(QAbstractSocket::SslInternalError, QStringLiteral("Failed to set protocol version"));
|
||||
setErrorAndEmit(d, QAbstractSocket::SslInternalError, QStringLiteral("Failed to set protocol version"));
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -742,8 +741,8 @@ bool TlsCryptographSecureTransport::initSslContext()
|
|||
|
||||
if (err != errSecSuccess) {
|
||||
destroySslContext();
|
||||
d->setErrorAndEmit(QSslSocket::SslInternalError,
|
||||
QStringLiteral("SSLSetSessionOption failed: %1").arg(err));
|
||||
setErrorAndEmit(d, QSslSocket::SslInternalError,
|
||||
QStringLiteral("SSLSetSessionOption failed: %1").arg(err));
|
||||
return false;
|
||||
}
|
||||
//
|
||||
|
@ -759,8 +758,8 @@ bool TlsCryptographSecureTransport::initSslContext()
|
|||
|
||||
if (err != errSecSuccess) {
|
||||
destroySslContext();
|
||||
d->setErrorAndEmit(QAbstractSocket::SslInternalError,
|
||||
QStringLiteral("failed to set SSL context option in server mode: %1").arg(err));
|
||||
setErrorAndEmit(d, QAbstractSocket::SslInternalError,
|
||||
QStringLiteral("failed to set SSL context option in server mode: %1").arg(err));
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
@ -1033,8 +1032,8 @@ bool TlsCryptographSecureTransport::verifyPeerTrust()
|
|||
// !trust - SSLCopyPeerTrust can return errSecSuccess but null trust.
|
||||
if (err != errSecSuccess || !trust) {
|
||||
if (!canIgnoreVerify) {
|
||||
d->setErrorAndEmit(QAbstractSocket::SslHandshakeFailedError,
|
||||
QStringLiteral("Failed to obtain peer trust: %1").arg(err));
|
||||
setErrorAndEmit(d, QAbstractSocket::SslHandshakeFailedError,
|
||||
QStringLiteral("Failed to obtain peer trust: %1").arg(err));
|
||||
plainSocket->disconnectFromHost();
|
||||
return false;
|
||||
} else {
|
||||
|
@ -1055,8 +1054,8 @@ bool TlsCryptographSecureTransport::verifyPeerTrust()
|
|||
if (err != errSecSuccess) {
|
||||
// We can not ignore this, it's not even about trust verification
|
||||
// probably ...
|
||||
d->setErrorAndEmit(QAbstractSocket::SslHandshakeFailedError,
|
||||
QStringLiteral("SecTrustEvaluate failed: %1").arg(err));
|
||||
setErrorAndEmit(d, QAbstractSocket::SslHandshakeFailedError,
|
||||
QStringLiteral("SecTrustEvaluate failed: %1").arg(err));
|
||||
plainSocket->disconnectFromHost();
|
||||
return false;
|
||||
}
|
||||
|
@ -1214,8 +1213,8 @@ bool TlsCryptographSecureTransport::checkSslErrors()
|
|||
QSslSocketPrivate::pauseSocketNotifiers(q);
|
||||
d->setPaused(true);
|
||||
} else {
|
||||
d->setErrorAndEmit(QAbstractSocket::SslHandshakeFailedError,
|
||||
sslErrors.constFirst().errorString());
|
||||
setErrorAndEmit(d, QAbstractSocket::SslHandshakeFailedError,
|
||||
sslErrors.constFirst().errorString());
|
||||
Q_ASSERT(d->plainTcpSocket());
|
||||
d->plainTcpSocket()->disconnectFromHost();
|
||||
}
|
||||
|
@ -1258,7 +1257,7 @@ bool TlsCryptographSecureTransport::startHandshake()
|
|||
// setSessionCertificate does not fail if we have no certificate.
|
||||
// Failure means a real error (invalid certificate, no private key, etc).
|
||||
if (!setSessionCertificate(errorDescription, errorCode)) {
|
||||
d->setErrorAndEmit(errorCode, errorDescription);
|
||||
setErrorAndEmit(d, errorCode, errorDescription);
|
||||
renegotiating = false;
|
||||
return false;
|
||||
} else {
|
||||
|
@ -1275,8 +1274,8 @@ bool TlsCryptographSecureTransport::startHandshake()
|
|||
}
|
||||
|
||||
renegotiating = false;
|
||||
d->setErrorAndEmit(QAbstractSocket::SslHandshakeFailedError,
|
||||
QStringLiteral("SSLHandshake failed: %1").arg(err));
|
||||
setErrorAndEmit(d, QAbstractSocket::SslHandshakeFailedError,
|
||||
QStringLiteral("SSLHandshake failed: %1").arg(err));
|
||||
plainSocket->disconnectFromHost();
|
||||
return false;
|
||||
}
|
||||
|
@ -1291,7 +1290,7 @@ bool TlsCryptographSecureTransport::startHandshake()
|
|||
// check protocol version ourselves, as Secure Transport does not enforce
|
||||
// the requested min / max versions.
|
||||
if (!verifySessionProtocol()) {
|
||||
d->setErrorAndEmit(QAbstractSocket::SslHandshakeFailedError, QStringLiteral("Protocol version mismatch"));
|
||||
setErrorAndEmit(d, QAbstractSocket::SslHandshakeFailedError, QStringLiteral("Protocol version mismatch"));
|
||||
plainSocket->disconnectFromHost();
|
||||
renegotiating = false;
|
||||
return false;
|
||||
|
@ -1320,12 +1319,4 @@ QList<QSslError> TlsCryptographSecureTransport::tlsErrors() const
|
|||
|
||||
} // namespace QTlsPrivate
|
||||
|
||||
void QSslSocketPrivate::registerAdHocFactory()
|
||||
{
|
||||
// TLSTODO: this is a temporary solution, waiting for
|
||||
// backends to move to ... plugins.
|
||||
if (!backendSecureTransport())
|
||||
qCWarning(lcTlsBackend, "Failed to create backend factory");
|
||||
}
|
||||
|
||||
QT_END_NAMESPACE
|
|
@ -60,8 +60,8 @@
|
|||
#include <QtCore/qglobal.h>
|
||||
#include <QtCore/qlist.h>
|
||||
|
||||
#include "qabstractsocket.h"
|
||||
#include "qsslsocket_p.h"
|
||||
#include <QtNetwork/qabstractsocket.h>
|
||||
#include <QtNetwork/private/qsslsocket_p.h>
|
||||
|
||||
#include <Security/Security.h>
|
||||
#include <Security/SecureTransport.h>
|
|
@ -51,9 +51,9 @@
|
|||
// We mean it.
|
||||
//
|
||||
|
||||
#include <private/qtnetworkglobal_p.h>
|
||||
#include <QtNetwork/private/qtnetworkglobal_p.h>
|
||||
|
||||
#include "qtlsbackend_p.h"
|
||||
#include <QtNetwork/private/qtlsbackend_p.h>
|
||||
|
||||
#include <QtCore/qglobal.h>
|
||||
|
||||
|
@ -62,6 +62,10 @@ QT_BEGIN_NAMESPACE
|
|||
|
||||
class QSecureTransportBackend : public QTlsBackend
|
||||
{
|
||||
Q_OBJECT
|
||||
Q_PLUGIN_METADATA(IID QTlsBackend_iid)
|
||||
Q_INTERFACES(QTlsBackend)
|
||||
|
||||
private:
|
||||
|
||||
QString tlsLibraryVersionString() const override;
|
|
@ -39,9 +39,10 @@
|
|||
****************************************************************************/
|
||||
|
||||
#include "qtlskey_st_p.h"
|
||||
#include "qsslkey_p.h"
|
||||
|
||||
#include <qbytearray.h>
|
||||
#include <QtNetwork/private/qsslkey_p.h>
|
||||
|
||||
#include <QtCore/qbytearray.h>
|
||||
|
||||
#include <CommonCrypto/CommonCrypto.h>
|
||||
|
|
@ -51,9 +51,9 @@
|
|||
// We mean it.
|
||||
//
|
||||
|
||||
#include <private/qtnetworkglobal_p.h>
|
||||
#include <QtNetwork/private/qtnetworkglobal_p.h>
|
||||
|
||||
#include <private/qtlskey_generic_p.h>
|
||||
#include "../shared/qtlskey_generic_p.h"
|
||||
|
||||
#include <QtCore/qglobal.h>
|
||||
|
|
@ -51,9 +51,9 @@
|
|||
// We mean it.
|
||||
//
|
||||
|
||||
#include <private/qtnetworkglobal_p.h>
|
||||
#include <QtNetwork/private/qtnetworkglobal_p.h>
|
||||
|
||||
#include <private/qx509_generic_p.h>
|
||||
#include "../shared/qx509_generic_p.h"
|
||||
|
||||
#include <QtCore/qglobal.h>
|
||||
|
|
@ -115,7 +115,7 @@ QT_BEGIN_NAMESPACE
|
|||
#define AES192_CBC_ENCRYPTION_OID QByteArrayLiteral(AES_OID "22") // Not (yet) implemented
|
||||
#define AES256_CBC_ENCRYPTION_OID QByteArrayLiteral(AES_OID "42") // Not (yet) implemented
|
||||
|
||||
class Q_AUTOTEST_EXPORT QAsn1Element
|
||||
class QAsn1Element
|
||||
{
|
||||
public:
|
||||
enum ElementType {
|
|
@ -51,15 +51,16 @@
|
|||
// We mean it.
|
||||
//
|
||||
|
||||
#include <private/qtnetworkglobal_p.h>
|
||||
#include <QtNetwork/private/qtnetworkglobal_p.h>
|
||||
|
||||
QT_REQUIRE_CONFIG(dtls);
|
||||
|
||||
#include "qsslconfiguration.h"
|
||||
#include "qtlsbackend_p.h"
|
||||
#include "qsslcipher.h"
|
||||
#include "qsslsocket.h"
|
||||
#include "qssl.h"
|
||||
#include <QtNetwork/private/qtlsbackend_p.h>
|
||||
|
||||
#include <QtNetwork/qsslconfiguration.h>
|
||||
#include <QtNetwork/qsslcipher.h>
|
||||
#include <QtNetwork/qsslsocket.h>
|
||||
#include <QtNetwork/qssl.h>
|
||||
|
||||
#include <QtNetwork/qhostaddress.h>
|
||||
|
|
@ -38,17 +38,17 @@
|
|||
**
|
||||
****************************************************************************/
|
||||
|
||||
#include "qsslcertificate.h"
|
||||
#include <QtNetwork/private/qtlsbackend_p.h>
|
||||
|
||||
#include <QtNetwork/qsslcertificate.h>
|
||||
|
||||
#include <QtCore/qglobal.h>
|
||||
#include <QtCore/qdebug.h>
|
||||
|
||||
|
||||
#ifdef Q_OS_MACOS
|
||||
|
||||
#include "qtlsbackend_p.h"
|
||||
|
||||
#include <private/qcore_mac_p.h>
|
||||
|
||||
#include <QtCore/qdebug.h>
|
||||
#include <QtCore/private/qcore_mac_p.h>
|
||||
|
||||
#include <CoreFoundation/CFArray.h>
|
||||
#include <Security/Security.h>
|
||||
|
@ -57,6 +57,8 @@
|
|||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
Q_DECLARE_LOGGING_CATEGORY(lcTlsBackend)
|
||||
|
||||
#ifdef Q_OS_MACOS
|
||||
namespace {
|
||||
|
||||
|
@ -132,7 +134,7 @@ QList<QSslCertificate> systemCaCertificates()
|
|||
QCFType<CFDataRef> derData = SecCertificateCopyData(cfCert);
|
||||
if (isCaCertificateTrusted(cfCert, dom)) {
|
||||
if (derData == nullptr) {
|
||||
qCWarning(lcSsl, "Error retrieving a CA certificate from the system store");
|
||||
qCWarning(lcTlsBackend, "Error retrieving a CA certificate from the system store");
|
||||
} else {
|
||||
systemCerts << QSslCertificate(QByteArray::fromCFData(derData), QSsl::Der);
|
||||
}
|
|
@ -36,14 +36,16 @@
|
|||
** $QT_END_LICENSE$
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#include "qasn1element_p.h"
|
||||
|
||||
#include <QtCore/qbytearray.h>
|
||||
#include <QtCore/qdatastream.h>
|
||||
#include <QtCore/qmessageauthenticationcode.h>
|
||||
#include <QtCore/qrandom.h>
|
||||
|
||||
#include "qsslsocket_p.h"
|
||||
#include "qasn1element_p.h"
|
||||
#include "qsslkey_p.h"
|
||||
#include <QtNetwork/private/qsslsocket_p.h>
|
||||
#include <QtNetwork/private/qsslkey_p.h>
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
|
@ -51,11 +51,11 @@
|
|||
// We mean it.
|
||||
//
|
||||
|
||||
#include <private/qtnetworkglobal_p.h>
|
||||
#include <QtNetwork/private/qtnetworkglobal_p.h>
|
||||
|
||||
#include <private/qtlsbackend_p.h>
|
||||
#include <QtNetwork/private/qtlsbackend_p.h>
|
||||
|
||||
#include <qssl.h>
|
||||
#include <QtNetwork/qssl.h>
|
||||
|
||||
#include <QtCore/qglobal.h>
|
||||
|
||||
|
@ -63,8 +63,6 @@ QT_BEGIN_NAMESPACE
|
|||
|
||||
namespace QTlsPrivate {
|
||||
|
||||
// TLSTODO: Note, 'base' is supposed to move to plugins together with
|
||||
// 'generic' and 'backendXXX'.
|
||||
class TlsKeyBase : public TlsKey
|
||||
{
|
||||
public:
|
||||
|
@ -97,9 +95,7 @@ protected:
|
|||
static QByteArray pkcs8Header(bool encrypted);
|
||||
static QByteArray pkcs8Footer(bool encrypted);
|
||||
static bool isEncryptedPkcs8(const QByteArray &der);
|
||||
public:
|
||||
// TLSTODO: this public is quick fix needed by old _openssl classes
|
||||
// will become non-public as soon as those classes fixed.
|
||||
|
||||
bool keyIsNull = true;
|
||||
KeyType keyType = QSsl::PublicKey;
|
||||
KeyAlgorithm keyAlgorithm = QSsl::Opaque;
|
|
@ -40,7 +40,8 @@
|
|||
|
||||
#include "qtlskey_generic_p.h"
|
||||
#include "qasn1element_p.h"
|
||||
#include "qsslkey_p.h"
|
||||
|
||||
#include <QtNetwork/private/qsslkey_p.h>
|
||||
|
||||
#include <QtNetwork/qpassworddigestor.h>
|
||||
|
|
@ -51,10 +51,12 @@
|
|||
// We mean it.
|
||||
//
|
||||
|
||||
#include <private/qtnetworkglobal_p.h>
|
||||
#include <QtNetwork/private/qtnetworkglobal_p.h>
|
||||
|
||||
#include <QtNetwork/private/qtlsbackend_p.h>
|
||||
|
||||
#include "qtlskey_base_p.h"
|
||||
|
||||
#include <private/qtlskey_base_p.h>
|
||||
#include <private/qtlsbackend_p.h>
|
||||
|
||||
#include <QtCore/qnamespace.h>
|
||||
#include <QtCore/qglobal.h>
|
|
@ -51,11 +51,11 @@
|
|||
// We mean it.
|
||||
//
|
||||
|
||||
#include <private/qtnetworkglobal_p.h>
|
||||
#include <QtNetwork/private/qtnetworkglobal_p.h>
|
||||
|
||||
#include <private/qtlsbackend_p.h>
|
||||
#include <QtNetwork/private/qtlsbackend_p.h>
|
||||
|
||||
#include <qssl.h>
|
||||
#include <QtNetwork/qssl.h>
|
||||
|
||||
#include <QtCore/qbytearray.h>
|
||||
#include <QtCore/qstring.h>
|
|
@ -37,15 +37,16 @@
|
|||
**
|
||||
****************************************************************************/
|
||||
|
||||
#include "qsslcertificate_p.h"
|
||||
#include "qx509_generic_p.h"
|
||||
#include <QtNetwork/private/qsslcertificate_p.h>
|
||||
#include <QtNetwork/private/qssl_p.h>
|
||||
|
||||
#include "qasn1element_p.h"
|
||||
#include "qx509_generic_p.h"
|
||||
|
||||
#include "qssl_p.h"
|
||||
#include <QtNetwork/qhostaddress.h>
|
||||
|
||||
#include <qhostaddress.h>
|
||||
#include <qendian.h>
|
||||
#include <qhash.h>
|
||||
#include <QtCore/qendian.h>
|
||||
#include <QtCore/qhash.h>
|
||||
|
||||
#include <memory>
|
||||
|
|
@ -50,10 +50,11 @@
|
|||
// We mean it.
|
||||
//
|
||||
|
||||
#include <private/qtnetworkglobal_p.h>
|
||||
#include <QtNetwork/private/qtnetworkglobal_p.h>
|
||||
|
||||
#include <private/qtlsbackend_p.h>
|
||||
#include <private/qx509_base_p.h>
|
||||
#include <QtNetwork/private/qtlsbackend_p.h>
|
||||
|
||||
#include "qx509_base_p.h"
|
||||
|
||||
#include <QtCore/qbytearray.h>
|
||||
#include <QtCore/qglobal.h>
|
||||
|
@ -62,7 +63,6 @@ QT_BEGIN_NAMESPACE
|
|||
|
||||
namespace QTlsPrivate {
|
||||
|
||||
// TLSTODO: This class is what previously was known as qsslcertificate_qt.
|
||||
// A part of SecureTransport and Schannel plugin.
|
||||
class X509CertificateGeneric : public X509CertificateBase
|
||||
{
|
|
@ -45,12 +45,6 @@
|
|||
#include <QtCore/qthread.h>
|
||||
#include <QtCore/qurl.h>
|
||||
|
||||
#ifndef QT_NO_SSL
|
||||
#ifndef QT_NO_OPENSSL
|
||||
#include <QtNetwork/private/qsslsocket_openssl_symbols_p.h>
|
||||
#endif // NO_OPENSSL
|
||||
#endif // NO_SSL
|
||||
|
||||
#include <cstdlib>
|
||||
#include <memory>
|
||||
#include <string>
|
||||
|
|
|
@ -26,6 +26,7 @@
|
|||
**
|
||||
****************************************************************************/
|
||||
|
||||
#include <QtNetwork/qtnetworkglobal.h>
|
||||
|
||||
#include <QTest>
|
||||
#include <QSemaphore>
|
||||
|
@ -71,6 +72,7 @@
|
|||
#ifndef QT_NO_SSL
|
||||
#include <QtNetwork/qsslerror.h>
|
||||
#include <QtNetwork/qsslconfiguration.h>
|
||||
#include <QtNetwork/qsslsocket.h>
|
||||
#ifdef QT_BUILD_INTERNAL
|
||||
#include <QtNetwork/private/qsslconfiguration_p.h>
|
||||
#endif
|
||||
|
@ -105,11 +107,10 @@ Q_DECLARE_METATYPE(QNetworkProxyQuery)
|
|||
|
||||
typedef QSharedPointer<QNetworkReply> QNetworkReplyPtr;
|
||||
|
||||
#ifndef QT_NO_OPENSSL
|
||||
QT_BEGIN_NAMESPACE
|
||||
// Technically, a workaround, and only needed for OpenSSL:
|
||||
void qt_ForceTlsSecurityLevel();
|
||||
QT_END_NAMESPACE
|
||||
#endif
|
||||
|
||||
class MyCookieJar;
|
||||
class tst_QNetworkReply: public QObject
|
||||
|
@ -163,11 +164,14 @@ class tst_QNetworkReply: public QObject
|
|||
#endif
|
||||
QNetworkAccessManager manager;
|
||||
MyCookieJar *cookieJar;
|
||||
#ifndef QT_NO_SSL
|
||||
#if QT_CONFIG(ssl)
|
||||
QSslConfiguration storedSslConfiguration;
|
||||
QList<QSslError> storedExpectedSslErrors;
|
||||
static const QString certsFilePath;
|
||||
#endif
|
||||
#endif // QT_CONFIG(ssl)
|
||||
|
||||
bool isSecureTransport = false;
|
||||
bool isSchannel = false;
|
||||
|
||||
using QObject::connect;
|
||||
static bool connect(const QNetworkReplyPtr &ptr, const char *signal, const QObject *receiver, const char *slot, Qt::ConnectionType ct = Qt::AutoConnection)
|
||||
|
@ -1289,9 +1293,14 @@ tst_QNetworkReply::tst_QNetworkReply()
|
|||
#ifndef QT_NO_NETWORKPROXY
|
||||
qRegisterMetaType<QNetworkProxy>();
|
||||
#endif
|
||||
#ifndef QT_NO_SSL
|
||||
|
||||
#if QT_CONFIG(ssl)
|
||||
qRegisterMetaType<QList<QSslError> >();
|
||||
isSecureTransport = QSslSocket::activeBackend() == QStringLiteral("securetransport");
|
||||
if (!isSecureTransport)
|
||||
isSchannel = QSslSocket::activeBackend() == QStringLiteral("schannel");
|
||||
#endif
|
||||
|
||||
qRegisterMetaType<QNetworkReply::NetworkError>();
|
||||
|
||||
uniqueExtension = createUniqueExtension();
|
||||
|
@ -1577,10 +1586,8 @@ void tst_QNetworkReply::initTestCase()
|
|||
QString::fromLatin1("Couldn't find echo dir starting from %1.").arg(QDir::currentPath())));
|
||||
|
||||
cleanupTestData();
|
||||
#ifndef QT_NO_OPENSSL
|
||||
QT_PREPEND_NAMESPACE(qt_ForceTlsSecurityLevel)();
|
||||
#endif // QT_NO_OPENSSL
|
||||
|
||||
QT_PREPEND_NAMESPACE(qt_ForceTlsSecurityLevel)();
|
||||
}
|
||||
|
||||
void tst_QNetworkReply::cleanupTestCase()
|
||||
|
@ -2781,9 +2788,9 @@ void tst_QNetworkReply::putToHttpMultipart()
|
|||
#ifndef QT_NO_SSL
|
||||
void tst_QNetworkReply::putToHttps_data()
|
||||
{
|
||||
#if QT_CONFIG(securetransport)
|
||||
QSKIP("SecTrustEvaluate() returns recoverable error, update the certificate on server");
|
||||
#endif
|
||||
if (isSecureTransport)
|
||||
QSKIP("SecTrustEvaluate() returns recoverable error, update the certificate on server");
|
||||
|
||||
uniqueExtension = createUniqueExtension();
|
||||
putToFile_data();
|
||||
}
|
||||
|
@ -2825,9 +2832,9 @@ void tst_QNetworkReply::putToHttps()
|
|||
|
||||
void tst_QNetworkReply::putToHttpsSynchronous_data()
|
||||
{
|
||||
#if QT_CONFIG(securetransport)
|
||||
QSKIP("SecTrustEvalueate() retruns recoverable error, update the server's certificate");
|
||||
#endif
|
||||
if (isSecureTransport)
|
||||
QSKIP("SecTrustEvalueate() retruns recoverable error, update the server's certificate");
|
||||
|
||||
uniqueExtension = createUniqueExtension();
|
||||
putToFile_data();
|
||||
}
|
||||
|
@ -2873,9 +2880,9 @@ void tst_QNetworkReply::putToHttpsSynchronous()
|
|||
|
||||
void tst_QNetworkReply::postToHttps_data()
|
||||
{
|
||||
#if QT_CONFIG(securetransport)
|
||||
QSKIP("SecTrustEvaluate() returns recoverable error, update the certificate on server");
|
||||
#endif
|
||||
if (isSecureTransport)
|
||||
QSKIP("SecTrustEvaluate() returns recoverable error, update the certificate on server");
|
||||
|
||||
putToFile_data();
|
||||
}
|
||||
|
||||
|
@ -2907,9 +2914,9 @@ void tst_QNetworkReply::postToHttps()
|
|||
|
||||
void tst_QNetworkReply::postToHttpsSynchronous_data()
|
||||
{
|
||||
#if QT_CONFIG(securetransport)
|
||||
QSKIP("SecTrustEvaluate() returns recoverable error, update the certificate on server");
|
||||
#endif
|
||||
if (isSecureTransport)
|
||||
QSKIP("SecTrustEvaluate() returns recoverable error, update the certificate on server");
|
||||
|
||||
putToFile_data();
|
||||
}
|
||||
|
||||
|
@ -2946,9 +2953,9 @@ void tst_QNetworkReply::postToHttpsSynchronous()
|
|||
|
||||
void tst_QNetworkReply::postToHttpsMultipart_data()
|
||||
{
|
||||
#if QT_CONFIG(securetransport)
|
||||
QSKIP("SecTrustEvaluate() returns recoverable error, update the certificate on server");
|
||||
#endif
|
||||
if (isSecureTransport)
|
||||
QSKIP("SecTrustEvaluate() returns recoverable error, update the certificate on server");
|
||||
|
||||
postToHttpMultipart_data();
|
||||
}
|
||||
|
||||
|
@ -6467,23 +6474,23 @@ void tst_QNetworkReply::sslConfiguration_data()
|
|||
QTest::newRow("empty") << QSslConfiguration() << false;
|
||||
QSslConfiguration conf = QSslConfiguration::defaultConfiguration();
|
||||
QTest::newRow("default") << conf << false; // does not contain test server cert
|
||||
#if QT_CONFIG(securetransport)
|
||||
qWarning("SecTrustEvaluate() will fail, update the certificate on server");
|
||||
#else
|
||||
QList<QSslCertificate> testServerCert = QSslCertificate::fromPath(testDataDir + certsFilePath);
|
||||
conf.setCaCertificates(testServerCert);
|
||||
if (isSecureTransport) {
|
||||
qWarning("SecTrustEvaluate() will fail, update the certificate on server");
|
||||
} else {
|
||||
QList<QSslCertificate> testServerCert = QSslCertificate::fromPath(testDataDir + certsFilePath);
|
||||
conf.setCaCertificates(testServerCert);
|
||||
|
||||
QTest::newRow("set-root-cert") << conf << true;
|
||||
conf.setProtocol(QSsl::SecureProtocols);
|
||||
QTest::newRow("secure") << conf << true;
|
||||
#endif
|
||||
QTest::newRow("set-root-cert") << conf << true;
|
||||
conf.setProtocol(QSsl::SecureProtocols);
|
||||
QTest::newRow("secure") << conf << true;
|
||||
}
|
||||
}
|
||||
|
||||
void tst_QNetworkReply::encrypted()
|
||||
{
|
||||
#if QT_CONFIG(securetransport)
|
||||
QSKIP("SecTrustEvalute() fails with old server certificate");
|
||||
#endif
|
||||
if (isSecureTransport)
|
||||
QSKIP("SecTrustEvalute() fails with old server certificate");
|
||||
|
||||
QUrl url("https://" + QtNetworkSettings::httpServerName());
|
||||
QNetworkRequest request(url);
|
||||
QNetworkReply *reply = manager.get(request);
|
||||
|
@ -6556,9 +6563,8 @@ void tst_QNetworkReply::sslSessionSharing_data()
|
|||
|
||||
void tst_QNetworkReply::sslSessionSharing()
|
||||
{
|
||||
#if QT_CONFIG(schannel) || defined(QT_SECURETRANSPORT)
|
||||
QSKIP("Not implemented with SecureTransport/Schannel");
|
||||
#endif
|
||||
if (isSchannel || isSecureTransport)
|
||||
QSKIP("Not implemented with SecureTransport/Schannel");
|
||||
|
||||
QString urlString("https://" + QtNetworkSettings::httpServerName());
|
||||
QList<QNetworkReplyPtr> replies;
|
||||
|
@ -6627,9 +6633,8 @@ void tst_QNetworkReply::sslSessionSharingFromPersistentSession_data()
|
|||
|
||||
void tst_QNetworkReply::sslSessionSharingFromPersistentSession()
|
||||
{
|
||||
#if QT_CONFIG(schannel) || defined(QT_SECURETRANSPORT)
|
||||
QSKIP("Not implemented with SecureTransport/Schannel");
|
||||
#endif
|
||||
if (isSchannel || isSecureTransport)
|
||||
QSKIP("Not implemented with SecureTransport/Schannel");
|
||||
|
||||
QString urlString("https://" + QtNetworkSettings::httpServerName());
|
||||
|
||||
|
@ -7752,17 +7757,17 @@ void tst_QNetworkReply::synchronousRequest_data()
|
|||
// ### we would need to enflate (un-deflate) the file content and compare the sizes
|
||||
<< QString("text/plain");
|
||||
|
||||
#ifndef QT_NO_SSL
|
||||
#if QT_CONFIG(securetransport)
|
||||
qWarning("Skipping https scheme, SecTrustEvalue() fails, update the certificate on server");
|
||||
#else
|
||||
QTest::newRow("https")
|
||||
<< QUrl("https://" + QtNetworkSettings::httpServerName() + "/qtest/rfc3252.txt")
|
||||
<< QString("file:" + testDataDir + "/rfc3252.txt")
|
||||
<< true
|
||||
<< QString("text/plain");
|
||||
#endif
|
||||
#endif
|
||||
#if QT_CONFIG(ssl)
|
||||
if (isSecureTransport) {
|
||||
qWarning("Skipping https scheme, SecTrustEvalue() fails, update the certificate on server");
|
||||
} else {
|
||||
QTest::newRow("https")
|
||||
<< QUrl("https://" + QtNetworkSettings::httpServerName() + "/qtest/rfc3252.txt")
|
||||
<< QString("file:" + testDataDir + "/rfc3252.txt")
|
||||
<< true
|
||||
<< QString("text/plain");
|
||||
}
|
||||
#endif // QT_CONFIG(ssl)
|
||||
|
||||
QTest::newRow("data")
|
||||
<< QUrl(QString::fromLatin1("data:text/plain,hello world"))
|
||||
|
|
|
@ -12,7 +12,7 @@ if(QT_FEATURE_private_tests AND QT_FEATURE_ssl)
|
|||
add_subdirectory(qsslsocket)
|
||||
add_subdirectory(qsslsocket_onDemandCertificates_member)
|
||||
add_subdirectory(qsslsocket_onDemandCertificates_static)
|
||||
add_subdirectory(qasn1element)
|
||||
# add_subdirectory(qasn1element)
|
||||
add_subdirectory(qssldiffiehellmanparameters)
|
||||
endif()
|
||||
if(QT_FEATURE_dtls AND QT_FEATURE_private_tests AND QT_FEATURE_ssl)
|
||||
|
|
|
@ -31,8 +31,6 @@
|
|||
|
||||
#include <QtNetwork/private/qtnetworkglobal_p.h>
|
||||
|
||||
#include <QtNetwork/private/qsslsocket_openssl_symbols_p.h>
|
||||
|
||||
#include <QtNetwork/qsslcertificate.h>
|
||||
#include <QtNetwork/qtcpserver.h>
|
||||
#include <QtNetwork/qsslerror.h>
|
||||
|
@ -66,6 +64,9 @@ QT_BEGIN_NAMESPACE
|
|||
|
||||
namespace {
|
||||
|
||||
// TLSTODO: the test is temporarily disabled due to openssl code
|
||||
// moved into plugin and not in QtNetwork anymore.
|
||||
#if 0
|
||||
using OcspResponse = QSharedPointer<OCSP_RESPONSE>;
|
||||
using BasicResponse = QSharedPointer<OCSP_BASICRESP>;
|
||||
using SingleResponse = QSharedPointer<OCSP_SINGLERESP>;
|
||||
|
@ -74,6 +75,9 @@ using EvpKey = QSharedPointer<EVP_PKEY>;
|
|||
using Asn1Time = QSharedPointer<ASN1_TIME>;
|
||||
using CertificateChain = QList<QSslCertificate>;
|
||||
|
||||
// TLSTODO: test temporarily disabled due to openssl code moved
|
||||
// into plugin and not in QtNetwork anymore.
|
||||
|
||||
using NativeX509Ptr = X509 *;
|
||||
|
||||
class X509Stack {
|
||||
|
@ -372,12 +376,16 @@ void OcspServer::incomingConnection(qintptr socketDescriptor)
|
|||
serverSocket.startServerEncryption();
|
||||
}
|
||||
|
||||
#endif // if 0
|
||||
|
||||
} // unnamed namespace
|
||||
|
||||
class tst_QOcsp : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
// TLSTODO: test temporarily disabled due to openssl code moved
|
||||
// into plugin and not in QtNetwork anymore.
|
||||
#if 0
|
||||
public slots:
|
||||
void initTestCase();
|
||||
|
||||
|
@ -426,6 +434,7 @@ private:
|
|||
QSslError::OcspResponseCertIdUnknown,
|
||||
QSslError::OcspResponseExpired,
|
||||
QSslError::OcspStatusUnknown};
|
||||
#endif // if 0
|
||||
};
|
||||
|
||||
#define QCOMPARE_SINGLE_ERROR(sslSocket, expectedError) \
|
||||
|
@ -446,6 +455,9 @@ private:
|
|||
QSslKey key; \
|
||||
QVERIFY(loadPrivateKey(QLatin1String(keyFileName), key))
|
||||
|
||||
// TLSTODO: test temporarily disabled due to openssl code moved
|
||||
// into plugin and not in QtNetwork anymore.
|
||||
#if 0
|
||||
QString tst_QOcsp::certDirPath;
|
||||
|
||||
void tst_QOcsp::initTestCase()
|
||||
|
@ -827,6 +839,8 @@ CertificateChain tst_QOcsp::subjectToChain(const CertificateChain &chain)
|
|||
return CertificateChain() << chain[0];
|
||||
}
|
||||
|
||||
#endif // if 0
|
||||
|
||||
QT_END_NAMESPACE
|
||||
|
||||
QTEST_MAIN(tst_QOcsp)
|
||||
|
|
|
@ -28,6 +28,7 @@
|
|||
|
||||
|
||||
#include <QTest>
|
||||
|
||||
#include <qsslcertificate.h>
|
||||
#include <qsslkey.h>
|
||||
#include <qsslsocket.h>
|
||||
|
@ -120,6 +121,7 @@ private slots:
|
|||
#endif
|
||||
private:
|
||||
QString testDataDir;
|
||||
bool isNonOpenSslTls = false;
|
||||
};
|
||||
|
||||
void tst_QSslCertificate::initTestCase()
|
||||
|
@ -129,6 +131,13 @@ void tst_QSslCertificate::initTestCase()
|
|||
testDataDir = QCoreApplication::applicationDirPath();
|
||||
if (!testDataDir.endsWith(QLatin1String("/")))
|
||||
testDataDir += QLatin1String("/");
|
||||
#if QT_CONFIG(opensslv11)
|
||||
// In the presence of 'openssl' backend, QSslSocket will
|
||||
// select 'openssl' as the default one.
|
||||
isNonOpenSslTls = false;
|
||||
#else
|
||||
isNonOpenSslTls = true;
|
||||
#endif // QT_CONFIG(ssl)
|
||||
|
||||
QDir dir(testDataDir + "certificates");
|
||||
QFileInfoList fileInfoList = dir.entryInfoList(QDir::Files | QDir::Readable);
|
||||
|
@ -889,9 +898,9 @@ void tst_QSslCertificate::task256066toPem()
|
|||
|
||||
void tst_QSslCertificate::nulInCN()
|
||||
{
|
||||
#if QT_CONFIG(securetransport) || QT_CONFIG(schannel)
|
||||
QSKIP("Generic QSslCertificatePrivate fails this test");
|
||||
#endif
|
||||
if (isNonOpenSslTls)
|
||||
QSKIP("Generic QSslCertificatePrivate fails this test");
|
||||
|
||||
QList<QSslCertificate> certList =
|
||||
QSslCertificate::fromPath(testDataDir + "more-certificates/badguy-nul-cn.crt", QSsl::Pem, QSslCertificate::PatternSyntax::FixedString);
|
||||
QCOMPARE(certList.size(), 1);
|
||||
|
@ -908,9 +917,10 @@ void tst_QSslCertificate::nulInCN()
|
|||
|
||||
void tst_QSslCertificate::nulInSan()
|
||||
{
|
||||
#if QT_CONFIG(securetransport) || QT_CONFIG(schannel)
|
||||
QSKIP("Generic QSslCertificatePrivate fails this test");
|
||||
#endif
|
||||
|
||||
if (isNonOpenSslTls)
|
||||
QSKIP("Generic QSslCertificatePrivate fails this test");
|
||||
|
||||
QList<QSslCertificate> certList =
|
||||
QSslCertificate::fromPath(testDataDir + "more-certificates/badguy-nul-san.crt", QSsl::Pem, QSslCertificate::PatternSyntax::FixedString);
|
||||
QCOMPARE(certList.size(), 1);
|
||||
|
@ -1047,9 +1057,9 @@ void tst_QSslCertificate::subjectAndIssuerAttributes()
|
|||
|
||||
void tst_QSslCertificate::verify()
|
||||
{
|
||||
#if QT_CONFIG(securetransport)
|
||||
QSKIP("Not implemented in SecureTransport");
|
||||
#endif
|
||||
if (isNonOpenSslTls)
|
||||
QSKIP("Not implemented in SecureTransport or Schannel");
|
||||
|
||||
QList<QSslError> errors;
|
||||
QList<QSslCertificate> toVerify;
|
||||
|
||||
|
@ -1059,9 +1069,6 @@ void tst_QSslCertificate::verify()
|
|||
qPrintable(QString("errors: %1").arg(toString(errors))) \
|
||||
)
|
||||
|
||||
#ifdef QT_NO_OPENSSL
|
||||
QEXPECT_FAIL("", "Verifying a chain is not supported without openssl", Abort); // TODO?
|
||||
#endif
|
||||
// Empty chain is unspecified error
|
||||
errors = QSslCertificate::verify(toVerify);
|
||||
VERIFY_VERBOSE(errors.count() == 1);
|
||||
|
|
|
@ -26,7 +26,6 @@
|
|||
**
|
||||
****************************************************************************/
|
||||
|
||||
|
||||
#include <QTest>
|
||||
#include <qsslkey.h>
|
||||
#include <qsslsocket.h>
|
||||
|
@ -46,11 +45,18 @@
|
|||
#include "private/qsslkey_p.h"
|
||||
#define TEST_CRYPTO
|
||||
#endif
|
||||
#ifndef QT_NO_OPENSSL
|
||||
#include "private/qsslsocket_openssl_symbols_p.h"
|
||||
#endif
|
||||
// TLSTODO: find another solution, for now this code
|
||||
// (OpenSSL specific) is a part of plugin, not in
|
||||
// QtNetwork anymore.
|
||||
//#ifndef QT_NO_OPENSSL
|
||||
// #include "private/qsslsocket_openssl_symbols_p.h"
|
||||
//#endif
|
||||
#endif
|
||||
|
||||
#if QT_CONFIG(ssl)
|
||||
#include <QtNetwork/qsslsocket.h>
|
||||
#endif // QT_CONFIG(ssl)
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
class tst_QSslKey : public QObject
|
||||
|
@ -113,11 +119,15 @@ private:
|
|||
|
||||
bool fileContainsUnsupportedEllipticCurve(const QString &fileName) const;
|
||||
QVector<QString> unsupportedCurves;
|
||||
|
||||
bool isOpenSsl = false;
|
||||
bool isSecureTransport = false;
|
||||
bool isSchannel = false;
|
||||
};
|
||||
|
||||
tst_QSslKey::tst_QSslKey()
|
||||
{
|
||||
#ifndef QT_NO_SSL
|
||||
#if QT_CONFIG(ssl)
|
||||
const QString expectedCurves[] = {
|
||||
// See how we generate them in keys/genkey.sh.
|
||||
QStringLiteral("secp224r1"),
|
||||
|
@ -140,6 +150,13 @@ tst_QSslKey::tst_QSslKey()
|
|||
unsupportedCurves.push_back(requestedEc);
|
||||
}
|
||||
}
|
||||
// Alas, we don't use network-private (and why?).
|
||||
const auto backendName = QSslSocket::activeBackend();
|
||||
isOpenSsl = backendName == QStringLiteral("openssl");
|
||||
if (!isOpenSsl)
|
||||
isSecureTransport = backendName == QStringLiteral("securetransport");
|
||||
if (!isOpenSsl && !isSecureTransport)
|
||||
isSchannel = backendName == QStringLiteral("schannel");
|
||||
#else
|
||||
unsupportedCurves = {}; // not unsued anymore.
|
||||
#endif
|
||||
|
@ -221,10 +238,12 @@ void tst_QSslKey::createPlainTestRows(bool pemOnly)
|
|||
foreach (KeyInfo keyInfo, keyInfoList) {
|
||||
if (pemOnly && keyInfo.format != QSsl::EncodingFormat::Pem)
|
||||
continue;
|
||||
#if QT_CONFIG(schannel)
|
||||
if (keyInfo.fileInfo.fileName().contains("RC2-64"))
|
||||
continue; // Schannel treats RC2 as 128 bit
|
||||
#endif
|
||||
|
||||
if (isSchannel) {
|
||||
if (keyInfo.fileInfo.fileName().contains("RC2-64"))
|
||||
continue; // Schannel treats RC2 as 128 bit
|
||||
}
|
||||
|
||||
#if QT_CONFIG(ssl) && defined(QT_NO_OPENSSL) // generic backend
|
||||
if (keyInfo.fileInfo.fileName().contains(QRegularExpression("-aes\\d\\d\\d-")))
|
||||
continue; // No AES support in the generic back-end
|
||||
|
@ -272,7 +291,12 @@ void tst_QSslKey::constructorHandle()
|
|||
{
|
||||
#ifndef QT_BUILD_INTERNAL
|
||||
QSKIP("This test requires -developer-build.");
|
||||
#else
|
||||
#endif // previously, else, see if 0 below.
|
||||
|
||||
// TLSTODO: OpenSSL-specific code and symbols are now
|
||||
// part of 'openssl' plugin, not in QtNetwork anymore.
|
||||
// For now - disabling.
|
||||
#if 0
|
||||
if (!QSslSocket::supportsSsl())
|
||||
return;
|
||||
|
||||
|
@ -328,7 +352,8 @@ void tst_QSslKey::constructorHandle()
|
|||
QCOMPARE(key.type(), type);
|
||||
QCOMPARE(key.length(), length);
|
||||
QCOMPARE(q_EVP_PKEY_cmp(origin, handle), 1);
|
||||
#endif
|
||||
|
||||
#endif // if 0
|
||||
}
|
||||
|
||||
#endif // !QT_NO_OPENSSL
|
||||
|
@ -419,13 +444,13 @@ void tst_QSslKey::toPemOrDer()
|
|||
QByteArray dataTag = QByteArray(QTest::currentDataTag());
|
||||
if (dataTag.contains("-pkcs8-")) // these are encrypted
|
||||
QSKIP("Encrypted PKCS#8 keys gets decrypted when loaded. So we can't compare it to the encrypted version.");
|
||||
#ifndef QT_NO_OPENSSL
|
||||
if (dataTag.contains("pkcs8"))
|
||||
QSKIP("OpenSSL converts PKCS#8 keys to other formats, invalidating comparisons.");
|
||||
#else // !openssl
|
||||
if (dataTag.contains("pkcs8") && dataTag.contains("rsa"))
|
||||
QSKIP("PKCS#8 RSA keys are changed into a different format in the generic back-end, meaning the comparison fails.");
|
||||
#endif // openssl
|
||||
|
||||
if (dataTag.contains("pkcs8")) {
|
||||
if (isOpenSsl)
|
||||
QSKIP("OpenSSL converts PKCS#8 keys to other formats, invalidating comparisons.");
|
||||
else if (dataTag.contains("rsa"))
|
||||
QSKIP("PKCS#8 RSA keys are changed into a different format in the generic back-end, meaning the comparison fails.");
|
||||
}
|
||||
|
||||
QByteArray encoded = readFile(absFilePath);
|
||||
QSslKey key(encoded, algorithm, format, type);
|
||||
|
@ -759,12 +784,13 @@ void tst_QSslKey::encrypt()
|
|||
QFETCH(QByteArray, cipherText);
|
||||
QFETCH(QByteArray, iv);
|
||||
|
||||
#if QT_CONFIG(schannel)
|
||||
QEXPECT_FAIL("RC2-40-CBC, length 0", "Schannel treats RC2 as 128-bit", Abort);
|
||||
QEXPECT_FAIL("RC2-40-CBC, length 8", "Schannel treats RC2 as 128-bit", Abort);
|
||||
QEXPECT_FAIL("RC2-64-CBC, length 0", "Schannel treats RC2 as 128-bit", Abort);
|
||||
QEXPECT_FAIL("RC2-64-CBC, length 8", "Schannel treats RC2 as 128-bit", Abort);
|
||||
#endif
|
||||
if (isSchannel) {
|
||||
QEXPECT_FAIL("RC2-40-CBC, length 0", "Schannel treats RC2 as 128-bit", Abort);
|
||||
QEXPECT_FAIL("RC2-40-CBC, length 8", "Schannel treats RC2 as 128-bit", Abort);
|
||||
QEXPECT_FAIL("RC2-64-CBC, length 0", "Schannel treats RC2 as 128-bit", Abort);
|
||||
QEXPECT_FAIL("RC2-64-CBC, length 8", "Schannel treats RC2 as 128-bit", Abort);
|
||||
}
|
||||
|
||||
QByteArray encrypted = QSslKeyPrivate::encrypt(cipher, plainText, key, iv);
|
||||
QCOMPARE(encrypted, cipherText);
|
||||
|
||||
|
|
|
@ -59,7 +59,10 @@
|
|||
#include "private/qtlsbackend_p.h"
|
||||
|
||||
#ifndef QT_NO_OPENSSL
|
||||
#include "private/qsslsocket_openssl_symbols_p.h"
|
||||
// TLSTODO:
|
||||
// Disabling tests requiring this - moving OpenSSL code into plugins,
|
||||
// find a workaround if needed.
|
||||
//#include "private/qsslsocket_openssl_symbols_p.h"
|
||||
#endif // QT_NO_OPENSSL
|
||||
|
||||
#include "private/qsslsocket_p.h"
|
||||
|
@ -110,12 +113,12 @@ static const QByteArray PSK_CLIENT_PRESHAREDKEY = QByteArrayLiteral("\x1a\x2b\x3
|
|||
static const QByteArray PSK_SERVER_IDENTITY_HINT = QByteArrayLiteral("QtTestServerHint");
|
||||
static const QByteArray PSK_CLIENT_IDENTITY = QByteArrayLiteral("Client_identity");
|
||||
|
||||
#endif // !QT_NO_OPENSSL
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
void qt_ForceTlsSecurityLevel();
|
||||
QT_END_NAMESPACE
|
||||
|
||||
#endif // !QT_NO_OPENSSL
|
||||
|
||||
class tst_QSslSocket : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
|
@ -319,11 +322,36 @@ protected slots:
|
|||
private:
|
||||
QSslSocket *socket;
|
||||
QList<QSslError> storedExpectedSslErrors;
|
||||
bool isTestingOpenSsl = false;
|
||||
bool isTestingSecureTransport = false;
|
||||
bool isTestingSchannel = false;
|
||||
#endif // QT_NO_SSL
|
||||
private:
|
||||
static int loopLevel;
|
||||
public:
|
||||
static QString testDataDir;
|
||||
|
||||
bool supportsTls13() const
|
||||
{
|
||||
if (isTestingOpenSsl) {
|
||||
#ifdef TLS1_3_VERSION
|
||||
return true;
|
||||
#endif
|
||||
}
|
||||
if (isTestingSchannel) {
|
||||
// Copied from qtls_schannel.cpp #supportsTls13()
|
||||
static bool supported = []() {
|
||||
const auto current = QOperatingSystemVersion::current();
|
||||
const auto minimum =
|
||||
QOperatingSystemVersion(QOperatingSystemVersion::Windows, 10, 0, 20221);
|
||||
return current >= minimum;
|
||||
}();
|
||||
return supported;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
};
|
||||
QString tst_QSslSocket::testDataDir;
|
||||
|
||||
|
@ -348,24 +376,6 @@ QString httpServerCertChainPath()
|
|||
#endif // QT_TEST_SERVER
|
||||
}
|
||||
|
||||
bool supportsTls13()
|
||||
{
|
||||
#ifdef TLS1_3_VERSION
|
||||
return true;
|
||||
#elif QT_CONFIG(schannel)
|
||||
// Copied from qsslsocket_schannel.cpp #supportsTls13()
|
||||
static bool supported = []() {
|
||||
const auto current = QOperatingSystemVersion::current();
|
||||
const auto minimum =
|
||||
QOperatingSystemVersion(QOperatingSystemVersion::Windows, 10, 0, 20221);
|
||||
return current >= minimum;
|
||||
}();
|
||||
return supported;
|
||||
#else
|
||||
return false;
|
||||
#endif
|
||||
}
|
||||
|
||||
} // unnamed namespace
|
||||
|
||||
tst_QSslSocket::tst_QSslSocket()
|
||||
|
@ -417,6 +427,20 @@ void tst_QSslSocket::initTestCase()
|
|||
testDataDir = QCoreApplication::applicationDirPath();
|
||||
if (!testDataDir.endsWith(QLatin1String("/")))
|
||||
testDataDir += QLatin1String("/");
|
||||
|
||||
// Several plugins (TLS-backends) can co-exist. QSslSocket would implicitly
|
||||
// select 'openssl' if available, and if not: 'securetransport' (Darwin) or
|
||||
// 'schannel' (Windows). Check what we actually have:
|
||||
const auto &tlsBackends = QSslSocket::availableBackends();
|
||||
if (tlsBackends.contains(QTlsBackend::builtinBackendNames[QTlsBackend::nameIndexOpenSSL])) {
|
||||
isTestingOpenSsl = true;
|
||||
} else if (tlsBackends.contains(QTlsBackend::builtinBackendNames[QTlsBackend::nameIndexSchannel])) {
|
||||
isTestingSchannel = true;
|
||||
} else {
|
||||
QVERIFY(tlsBackends.contains(QTlsBackend::builtinBackendNames[QTlsBackend::nameIndexSecureTransport]));
|
||||
isTestingSecureTransport = true;
|
||||
}
|
||||
|
||||
#ifndef QT_NO_SSL
|
||||
qDebug("Using SSL library %s (%ld)",
|
||||
qPrintable(QSslSocket::sslLibraryVersionString()),
|
||||
|
@ -474,9 +498,7 @@ void tst_QSslSocket::init()
|
|||
#endif // QT_NO_NETWORKPROXY
|
||||
}
|
||||
|
||||
#ifndef QT_NO_OPENSSL
|
||||
QT_PREPEND_NAMESPACE(qt_ForceTlsSecurityLevel)();
|
||||
#endif // QT_NO_OPENSSL
|
||||
|
||||
qt_qhostinfo_clear_cache();
|
||||
}
|
||||
|
@ -519,8 +541,6 @@ void tst_QSslSocket::activeBackend()
|
|||
if (setProxy) // Not interesting for backend test.
|
||||
return;
|
||||
|
||||
QCOMPARE(QSslSocket::activeBackend(), QTlsBackend::defaultBackendName());
|
||||
|
||||
// We cannot set non-existing as active:
|
||||
const QString nonExistingBackend = QStringLiteral("TheQtTLS");
|
||||
QCOMPARE(QSslSocket::setActiveBackend(nonExistingBackend), false);
|
||||
|
@ -609,17 +629,21 @@ void tst_QSslSocket::backends()
|
|||
const auto sizeBefore = backendNames.size();
|
||||
QVERIFY(sizeBefore > 0);
|
||||
|
||||
const auto builtinBackend = backendNames.first();
|
||||
const auto builtinProtocols = QSslSocket::supportedProtocols(builtinBackend);
|
||||
const QString tlsBackend = QSslSocket::activeBackend();
|
||||
QVERIFY(tlsBackend == QTlsBackend::builtinBackendNames[QTlsBackend::nameIndexOpenSSL]
|
||||
|| tlsBackend == QTlsBackend::builtinBackendNames[QTlsBackend::nameIndexSchannel]
|
||||
|| tlsBackend == QTlsBackend::builtinBackendNames[QTlsBackend::nameIndexSecureTransport]);
|
||||
|
||||
const auto builtinProtocols = QSslSocket::supportedProtocols(tlsBackend);
|
||||
QVERIFY(builtinProtocols.contains(QSsl::SecureProtocols));
|
||||
// Socket and ALPN are supported by all our backends:
|
||||
const auto builtinClasses = QSslSocket::implementedClasses(builtinBackend);
|
||||
const auto builtinClasses = QSslSocket::implementedClasses(tlsBackend);
|
||||
QVERIFY(builtinClasses.contains(QSsl::ImplementedClass::Socket));
|
||||
const auto builtinFeatures = QSslSocket::supportedFeatures(builtinBackend);
|
||||
const auto builtinFeatures = QSslSocket::supportedFeatures(tlsBackend);
|
||||
QVERIFY(builtinFeatures.contains(QSsl::SupportedFeature::ClientSideAlpn));
|
||||
|
||||
// Verify that non-dummy backend can be created (and delete it):
|
||||
auto *systemBackend = QTlsBackend::findBackend(builtinBackend);
|
||||
// Verify that non-dummy backend can be found:
|
||||
auto *systemBackend = QTlsBackend::findBackend(tlsBackend);
|
||||
QVERIFY(systemBackend);
|
||||
|
||||
const auto protocols = QList<QSsl::SslProtocol>{QSsl::SecureProtocols};
|
||||
|
@ -913,10 +937,11 @@ void tst_QSslSocket::sslErrors()
|
|||
QFETCH(int, port);
|
||||
|
||||
QSslSocketPtr socket = newSocket();
|
||||
#if QT_CONFIG(schannel)
|
||||
// Needs to be < 1.2 because of the old certificate and <= 1.0 because of the mail server
|
||||
socket->setProtocol(QSsl::SslProtocol::TlsV1_0);
|
||||
#endif
|
||||
if (isTestingSchannel) {
|
||||
// Needs to be < 1.2 because of the old certificate and <= 1.0 because of the mail server
|
||||
socket->setProtocol(QSsl::SslProtocol::TlsV1_0);
|
||||
}
|
||||
|
||||
QSignalSpy sslErrorsSpy(socket.data(), SIGNAL(sslErrors(QList<QSslError>)));
|
||||
QSignalSpy peerVerifyErrorSpy(socket.data(), SIGNAL(peerVerifyError(QSslError)));
|
||||
|
||||
|
@ -1013,26 +1038,28 @@ void tst_QSslSocket::ciphers()
|
|||
if (!ciphers.size())
|
||||
QSKIP("No proper ciphersuite was found to test 'setCiphers'");
|
||||
|
||||
#if QT_CONFIG(schannel)
|
||||
qWarning("Schannel doesn't support setting ciphers from a cipher-string.");
|
||||
#else
|
||||
sslConfig.setCiphers(ciphersAsString);
|
||||
socket.setSslConfiguration(sslConfig);
|
||||
QCOMPARE(ciphers, socket.sslConfiguration().ciphers());
|
||||
#endif
|
||||
|
||||
if (isTestingSchannel) {
|
||||
qWarning("Schannel doesn't support setting ciphers from a cipher-string.");
|
||||
} else {
|
||||
sslConfig.setCiphers(ciphersAsString);
|
||||
socket.setSslConfiguration(sslConfig);
|
||||
QCOMPARE(ciphers, socket.sslConfiguration().ciphers());
|
||||
}
|
||||
|
||||
sslConfig.setCiphers(ciphers);
|
||||
socket.setSslConfiguration(sslConfig);
|
||||
QCOMPARE(ciphers, socket.sslConfiguration().ciphers());
|
||||
|
||||
#ifndef QT_NO_OPENSSL
|
||||
for (const auto &cipher : ciphers) {
|
||||
if (cipher.name().size() && cipher.protocol() != QSsl::UnknownProtocol) {
|
||||
const QSslCipher aCopy(cipher.name(), cipher.protocol());
|
||||
QCOMPARE(aCopy, cipher);
|
||||
break;
|
||||
if (isTestingOpenSsl) {
|
||||
for (const auto &cipher : ciphers) {
|
||||
if (cipher.name().size() && cipher.protocol() != QSsl::UnknownProtocol) {
|
||||
const QSslCipher aCopy(cipher.name(), cipher.protocol());
|
||||
QCOMPARE(aCopy, cipher);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif // QT_NO_OPENSSL
|
||||
}
|
||||
|
||||
void tst_QSslSocket::connectToHostEncrypted()
|
||||
|
@ -1041,9 +1068,9 @@ void tst_QSslSocket::connectToHostEncrypted()
|
|||
return;
|
||||
|
||||
QSslSocketPtr socket = newSocket();
|
||||
#if QT_CONFIG(schannel) // old certificate not supported with TLS 1.2
|
||||
socket->setProtocol(QSsl::SslProtocol::TlsV1_1);
|
||||
#endif
|
||||
if (isTestingSchannel) // old certificate not supported with TLS 1.2
|
||||
socket->setProtocol(QSsl::SslProtocol::TlsV1_1);
|
||||
|
||||
this->socket = socket.data();
|
||||
auto config = socket->sslConfiguration();
|
||||
QVERIFY(config.addCaCertificates(httpServerCertChainPath()));
|
||||
|
@ -1079,9 +1106,9 @@ void tst_QSslSocket::connectToHostEncryptedWithVerificationPeerName()
|
|||
return;
|
||||
|
||||
QSslSocketPtr socket = newSocket();
|
||||
#if QT_CONFIG(schannel) // old certificate not supported with TLS 1.2
|
||||
socket->setProtocol(QSsl::SslProtocol::TlsV1_1);
|
||||
#endif
|
||||
if (isTestingSchannel) // old certificate not supported with TLS 1.2
|
||||
socket->setProtocol(QSsl::SslProtocol::TlsV1_1);
|
||||
|
||||
this->socket = socket.data();
|
||||
|
||||
auto config = socket->sslConfiguration();
|
||||
|
@ -1250,7 +1277,9 @@ void tst_QSslSocket::privateKeyOpaque()
|
|||
{
|
||||
if (!QSslSocket::supportsSsl())
|
||||
return;
|
||||
|
||||
// TLSTODO: OpenSSL symbols are now a part of 'openssl' plugin,
|
||||
// not QtNetwork anymore.
|
||||
#if 0
|
||||
QFile file(testDataDir + "certs/fluke.key");
|
||||
QVERIFY(file.open(QIODevice::ReadOnly));
|
||||
QSslKey key(file.readAll(), QSsl::Rsa, QSsl::Pem, QSsl::PrivateKey);
|
||||
|
@ -1278,6 +1307,7 @@ void tst_QSslSocket::privateKeyOpaque()
|
|||
QFETCH_GLOBAL(bool, setProxy);
|
||||
if (setProxy && !socket->waitForEncrypted(10000))
|
||||
QSKIP("Skipping flaky test - See QTBUG-29941");
|
||||
#endif // if 0
|
||||
}
|
||||
#endif
|
||||
|
||||
|
@ -1745,11 +1775,12 @@ void tst_QSslSocket::setLocalCertificateChain()
|
|||
loop.exec();
|
||||
|
||||
QList<QSslCertificate> chain = socket->peerCertificateChain();
|
||||
#if QT_CONFIG(schannel)
|
||||
QEXPECT_FAIL("", "Schannel cannot send intermediate certificates not "
|
||||
"located in a system certificate store",
|
||||
Abort);
|
||||
#endif
|
||||
if (isTestingSchannel) {
|
||||
QEXPECT_FAIL("", "Schannel cannot send intermediate certificates not "
|
||||
"located in a system certificate store",
|
||||
Abort);
|
||||
}
|
||||
|
||||
QCOMPARE(chain.size(), 2);
|
||||
QCOMPARE(chain[0].serialNumber(), QByteArray("10:a0:ad:77:58:f6:6e:ae:46:93:a3:43:f9:59:8a:9e"));
|
||||
QCOMPARE(chain[1].serialNumber(), QByteArray("3b:eb:99:c5:ea:d8:0b:5d:0b:97:5d:4f:06:75:4b:e1"));
|
||||
|
@ -1824,15 +1855,16 @@ void tst_QSslSocket::setSslConfiguration_data()
|
|||
QTest::newRow("empty") << QSslConfiguration() << false;
|
||||
QSslConfiguration conf = QSslConfiguration::defaultConfiguration();
|
||||
QTest::newRow("default") << conf << false; // does not contain test server cert
|
||||
#if !QT_CONFIG(securetransport)
|
||||
QList<QSslCertificate> testServerCert = QSslCertificate::fromPath(httpServerCertChainPath());
|
||||
conf.setCaCertificates(testServerCert);
|
||||
QTest::newRow("set-root-cert") << conf << true;
|
||||
conf.setProtocol(QSsl::SecureProtocols);
|
||||
QTest::newRow("secure") << conf << true;
|
||||
#else
|
||||
qWarning("Skipping the cases with certificate, SecureTransport does not like old certificate on the test server");
|
||||
#endif
|
||||
|
||||
if (!isTestingSecureTransport) {
|
||||
QList<QSslCertificate> testServerCert = QSslCertificate::fromPath(httpServerCertChainPath());
|
||||
conf.setCaCertificates(testServerCert);
|
||||
QTest::newRow("set-root-cert") << conf << true;
|
||||
conf.setProtocol(QSsl::SecureProtocols);
|
||||
QTest::newRow("secure") << conf << true;
|
||||
} else {
|
||||
qWarning("Skipping the cases with certificate, SecureTransport does not like old certificate on the test server");
|
||||
}
|
||||
}
|
||||
|
||||
void tst_QSslSocket::setSslConfiguration()
|
||||
|
@ -1843,9 +1875,9 @@ void tst_QSslSocket::setSslConfiguration()
|
|||
QSslSocketPtr socket = newSocket();
|
||||
QFETCH(QSslConfiguration, configuration);
|
||||
socket->setSslConfiguration(configuration);
|
||||
#if QT_CONFIG(schannel) // old certificate not supported with TLS 1.2
|
||||
socket->setProtocol(QSsl::SslProtocol::TlsV1_1);
|
||||
#endif
|
||||
if (isTestingSchannel) // old certificate not supported with TLS 1.2
|
||||
socket->setProtocol(QSsl::SslProtocol::TlsV1_1);
|
||||
|
||||
this->socket = socket.data();
|
||||
socket->connectToHostEncrypted(QtNetworkSettings::httpServerName(), 443);
|
||||
QFETCH(bool, works);
|
||||
|
@ -2545,9 +2577,9 @@ void tst_QSslSocket::verifyMode()
|
|||
return;
|
||||
|
||||
QSslSocket socket;
|
||||
#if QT_CONFIG(schannel) // old certificate not supported with TLS 1.2
|
||||
socket.setProtocol(QSsl::SslProtocol::TlsV1_1);
|
||||
#endif
|
||||
if (isTestingSchannel) // old certificate not supported with TLS 1.2
|
||||
socket.setProtocol(QSsl::SslProtocol::TlsV1_1);
|
||||
|
||||
QCOMPARE(socket.peerVerifyMode(), QSslSocket::AutoVerifyPeer);
|
||||
socket.setPeerVerifyMode(QSslSocket::VerifyNone);
|
||||
QCOMPARE(socket.peerVerifyMode(), QSslSocket::VerifyNone);
|
||||
|
@ -2884,9 +2916,9 @@ void tst_QSslSocket::abortOnSslErrors()
|
|||
void tst_QSslSocket::readFromClosedSocket()
|
||||
{
|
||||
QSslSocketPtr socket = newSocket();
|
||||
#if QT_CONFIG(schannel) // old certificate not supported with TLS 1.2
|
||||
socket->setProtocol(QSsl::SslProtocol::TlsV1_1);
|
||||
#endif
|
||||
if (isTestingSchannel) // old certificate not supported with TLS 1.2
|
||||
socket->setProtocol(QSsl::SslProtocol::TlsV1_1);
|
||||
|
||||
socket->ignoreSslErrors();
|
||||
socket->connectToHostEncrypted(QtNetworkSettings::httpServerName(), 443);
|
||||
socket->ignoreSslErrors();
|
||||
|
@ -3547,14 +3579,15 @@ void tst_QSslSocket::verifyClientCertificate_data()
|
|||
|
||||
void tst_QSslSocket::verifyClientCertificate()
|
||||
{
|
||||
#if QT_CONFIG(securetransport)
|
||||
// We run both client and server on the same machine,
|
||||
// this means, client can update keychain with client's certificates,
|
||||
// and server later will use the same certificates from the same
|
||||
// keychain thus making tests fail (wrong number of certificates,
|
||||
// success instead of failure etc.).
|
||||
QSKIP("This test can not work with Secure Transport");
|
||||
#endif // QT_CONFIG(securetransport)
|
||||
if (isTestingSecureTransport) {
|
||||
// We run both client and server on the same machine,
|
||||
// this means, client can update keychain with client's certificates,
|
||||
// and server later will use the same certificates from the same
|
||||
// keychain thus making tests fail (wrong number of certificates,
|
||||
// success instead of failure etc.).
|
||||
QSKIP("This test can not work with Secure Transport");
|
||||
}
|
||||
|
||||
if (!QSslSocket::supportsSsl()) {
|
||||
qWarning("SSL not supported, skipping test");
|
||||
return;
|
||||
|
@ -3565,10 +3598,10 @@ void tst_QSslSocket::verifyClientCertificate()
|
|||
return;
|
||||
|
||||
QFETCH(QSslSocket::PeerVerifyMode, peerVerifyMode);
|
||||
#if QT_CONFIG(schannel)
|
||||
if (peerVerifyMode == QSslSocket::QueryPeer || peerVerifyMode == QSslSocket::AutoVerifyPeer)
|
||||
QSKIP("Schannel doesn't tackle requesting a certificate and not receiving one.");
|
||||
#endif
|
||||
if (isTestingSchannel) {
|
||||
if (peerVerifyMode == QSslSocket::QueryPeer || peerVerifyMode == QSslSocket::AutoVerifyPeer)
|
||||
QSKIP("Schannel doesn't tackle requesting a certificate and not receiving one.");
|
||||
}
|
||||
|
||||
SslServer server;
|
||||
server.addCaCertificates = testDataDir + "certs/bogus-ca.crt";
|
||||
|
@ -3608,13 +3641,13 @@ void tst_QSslSocket::verifyClientCertificate()
|
|||
QVERIFY(server.socket->peerCertificateChain().isEmpty());
|
||||
} else {
|
||||
QCOMPARE(server.socket->peerCertificate(), clientCerts.first());
|
||||
#if QT_CONFIG(schannel)
|
||||
if (clientCerts.count() == 1 && server.socket->peerCertificateChain().count() == 2) {
|
||||
QEXPECT_FAIL("",
|
||||
"Schannel includes the entire chain, not just the leaf and intermediates",
|
||||
Continue);
|
||||
if (isTestingSchannel) {
|
||||
if (clientCerts.count() == 1 && server.socket->peerCertificateChain().count() == 2) {
|
||||
QEXPECT_FAIL("",
|
||||
"Schannel includes the entire chain, not just the leaf and intermediates",
|
||||
Continue);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
QCOMPARE(server.socket->peerCertificateChain(), clientCerts);
|
||||
}
|
||||
|
||||
|
@ -3625,7 +3658,6 @@ void tst_QSslSocket::verifyClientCertificate()
|
|||
|
||||
void tst_QSslSocket::readBufferMaxSize()
|
||||
{
|
||||
#if QT_CONFIG(securetransport) || QT_CONFIG(schannel)
|
||||
// QTBUG-55170:
|
||||
// SecureTransport back-end was ignoring read-buffer
|
||||
// size limit, resulting (potentially) in a constantly
|
||||
|
@ -3680,9 +3712,6 @@ void tst_QSslSocket::readBufferMaxSize()
|
|||
loop.exec();
|
||||
|
||||
QCOMPARE(client->bytesAvailable() + readSoFar, message.size());
|
||||
#else
|
||||
// Not needed, QSslSocket works correctly with other back-ends.
|
||||
#endif // QT_CONFIG(securetransport) || QT_CONFIG(schannel)
|
||||
}
|
||||
|
||||
void tst_QSslSocket::setEmptyDefaultConfiguration() // this test should be last, as it has some side effects
|
||||
|
@ -3711,16 +3740,15 @@ void tst_QSslSocket::allowedProtocolNegotiation()
|
|||
QSKIP("ALPN is unsupported, skipping test");
|
||||
#endif
|
||||
|
||||
#if QT_CONFIG(schannel)
|
||||
if (QOperatingSystemVersion::current() < QOperatingSystemVersion::Windows8_1)
|
||||
QSKIP("ALPN is not supported on this version of Windows using Schannel.");
|
||||
#endif
|
||||
if (isTestingSchannel) {
|
||||
if (QOperatingSystemVersion::current() < QOperatingSystemVersion::Windows8_1)
|
||||
QSKIP("ALPN is not supported on this version of Windows using Schannel.");
|
||||
}
|
||||
|
||||
QFETCH_GLOBAL(bool, setProxy);
|
||||
if (setProxy)
|
||||
return;
|
||||
|
||||
|
||||
const QByteArray expectedNegotiated("cool-protocol");
|
||||
QList<QByteArray> serverProtos;
|
||||
serverProtos << expectedNegotiated << "not-so-cool-protocol";
|
||||
|
@ -4158,9 +4186,9 @@ void tst_QSslSocket::ephemeralServerKey()
|
|||
|
||||
void tst_QSslSocket::pskServer()
|
||||
{
|
||||
#if QT_CONFIG(schannel)
|
||||
QSKIP("Schannel does not have PSK support implemented.");
|
||||
#endif
|
||||
if (!isTestingOpenSsl)
|
||||
QSKIP("The active TLS-backend does not have PSK support implemented.");
|
||||
|
||||
QFETCH_GLOBAL(bool, setProxy);
|
||||
if (!QSslSocket::supportsSsl() || setProxy)
|
||||
return;
|
||||
|
|
Loading…
Reference in New Issue