Schannel: no longer keep old ssl errors around when reusing socket
And add a test for it so it can no longer happen in any current or future implementation. Change-Id: I3214aa90595e291b1e1c66befe185cfe1ea7bc6b Reviewed-by: Timur Pocheptsov <timur.pocheptsov@qt.io>
This commit is contained in:
parent
e00d888dae
commit
3dd8f6dc34
@ -974,6 +974,7 @@ bool QSslSocketBackendPrivate::performHandshake()
|
||||
bool QSslSocketBackendPrivate::verifyHandshake()
|
||||
{
|
||||
Q_Q(QSslSocket);
|
||||
sslErrors.clear();
|
||||
|
||||
const bool isClient = mode == QSslSocket::SslClientMode;
|
||||
#define CHECK_STATUS(status) \
|
||||
@ -1062,7 +1063,7 @@ bool QSslSocketBackendPrivate::verifyHandshake()
|
||||
}
|
||||
|
||||
// verifyCertContext returns false if the user disconnected while it was checking errors.
|
||||
if (certificateContext && sslErrors.isEmpty() && !verifyCertContext(certificateContext))
|
||||
if (certificateContext && !verifyCertContext(certificateContext))
|
||||
return false;
|
||||
|
||||
if (!checkSslErrors() || state != QAbstractSocket::ConnectedState) {
|
||||
|
@ -259,6 +259,8 @@ private slots:
|
||||
void disabledProtocols_data();
|
||||
void disabledProtocols();
|
||||
|
||||
void oldErrorsOnSocketReuse();
|
||||
|
||||
void setEmptyDefaultConfiguration(); // this test should be last
|
||||
|
||||
protected slots:
|
||||
@ -4192,6 +4194,53 @@ void tst_QSslSocket::disabledProtocols()
|
||||
}
|
||||
}
|
||||
|
||||
void tst_QSslSocket::oldErrorsOnSocketReuse()
|
||||
{
|
||||
QFETCH_GLOBAL(bool, setProxy);
|
||||
if (setProxy)
|
||||
return; // not relevant
|
||||
SslServer server;
|
||||
server.protocol = QSsl::TlsV1_1;
|
||||
server.m_certFile = testDataDir + "certs/fluke.cert";
|
||||
server.m_keyFile = testDataDir + "certs/fluke.key";
|
||||
QVERIFY(server.listen(QHostAddress::SpecialAddress::LocalHost));
|
||||
|
||||
QSslSocket socket;
|
||||
socket.setProtocol(QSsl::TlsV1_1);
|
||||
QList<QSslError> errorList;
|
||||
auto connection = connect(&socket, QOverload<const QList<QSslError> &>::of(&QSslSocket::sslErrors),
|
||||
[&socket, &errorList](const QList<QSslError> &errors) {
|
||||
errorList += errors;
|
||||
socket.ignoreSslErrors(errors);
|
||||
socket.resume();
|
||||
});
|
||||
|
||||
socket.connectToHostEncrypted(QString::fromLatin1("localhost"), server.serverPort());
|
||||
QVERIFY(QTest::qWaitFor([&socket](){ return socket.isEncrypted(); }));
|
||||
socket.disconnectFromHost();
|
||||
if (socket.state() != QAbstractSocket::UnconnectedState) {
|
||||
QVERIFY(QTest::qWaitFor(
|
||||
[&socket](){
|
||||
return socket.state() == QAbstractSocket::UnconnectedState;
|
||||
}));
|
||||
}
|
||||
|
||||
auto oldList = errorList;
|
||||
errorList.clear();
|
||||
server.close();
|
||||
server.m_certFile = testDataDir + "certs/bogus-client.crt";
|
||||
server.m_keyFile = testDataDir + "certs/bogus-client.key";
|
||||
QVERIFY(server.listen(QHostAddress::SpecialAddress::LocalHost));
|
||||
|
||||
socket.connectToHostEncrypted(QString::fromLatin1("localhost"), server.serverPort());
|
||||
QVERIFY(QTest::qWaitFor([&socket](){ return socket.isEncrypted(); }));
|
||||
|
||||
for (const auto &error : oldList) {
|
||||
QVERIFY2(!errorList.contains(error),
|
||||
"The new errors should not contain any of the old ones");
|
||||
}
|
||||
}
|
||||
|
||||
#endif // QT_NO_SSL
|
||||
|
||||
QTEST_MAIN(tst_QSslSocket)
|
||||
|
Loading…
Reference in New Issue
Block a user