diff options
author | Timur Pocheptsov <timur.pocheptsov@qt.io> | 2021-03-25 12:41:08 +0100 |
---|---|---|
committer | Timur Pocheptsov <timur.pocheptsov@qt.io> | 2021-04-22 22:51:54 +0200 |
commit | d385158d5213ef568b7629e2aa4a818016bbffac (patch) | |
tree | 2c111b462fe39dffacb3c7f5cdd8db269f87ed6c /tests/auto/network/ssl/qsslsocket/tst_qsslsocket.cpp | |
parent | 6b1a7341fed4b9456ea6bfa2de7412d45ef56c65 (diff) |
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>
Diffstat (limited to 'tests/auto/network/ssl/qsslsocket/tst_qsslsocket.cpp')
-rw-r--r-- | tests/auto/network/ssl/qsslsocket/tst_qsslsocket.cpp | 246 |
1 files changed, 137 insertions, 109 deletions
diff --git a/tests/auto/network/ssl/qsslsocket/tst_qsslsocket.cpp b/tests/auto/network/ssl/qsslsocket/tst_qsslsocket.cpp index d982368086..79cb26c075 100644 --- a/tests/auto/network/ssl/qsslsocket/tst_qsslsocket.cpp +++ b/tests/auto/network/ssl/qsslsocket/tst_qsslsocket.cpp @@ -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; |