qsslsocket_mac: handle 'OrLater' SslProtocols in verifySessionProtocol()

The verifySessionProtocol() method in the SecureTransport backend did not
properly handle TlsV1_0OrLater, TlsV1_1OrLater and TlsV1_2OrLater.

This commit teaches verifySessionProtocol() about them.
It also adds TlsV1_0OrLater, TlsV1_1OrLater and TlsV1_2OrLater to the
protocolServerSide() test in tst_qsslsocket.

Backport from 5.10 to 5.9 (LTS).

Reviewed-by: Timur Pocheptsov <timur.pocheptsov@qt.io>
(cherry picked from commit 9c765522d1)
Change-Id: I58c53bdf43e0f19b4506f3696d793f657eb4dc6f
Reviewed-by: Edward Welbourne <edward.welbourne@qt.io>
This commit is contained in:
Mikkel Krautz 2017-02-13 21:35:02 +01:00 committed by Timur Pocheptsov
parent 7c334301bd
commit 55f8d7dfe5
2 changed files with 51 additions and 1 deletions

View File

@ -1108,6 +1108,12 @@ bool QSslSocketBackendPrivate::verifySessionProtocol() const
protocolOk = (sessionProtocol() >= QSsl::SslV3);
else if (configuration.protocol == QSsl::SecureProtocols)
protocolOk = (sessionProtocol() >= QSsl::TlsV1_0);
else if (configuration.protocol == QSsl::TlsV1_0OrLater)
protocolOk = (sessionProtocol() >= QSsl::TlsV1_0);
else if (configuration.protocol == QSsl::TlsV1_1OrLater)
protocolOk = (sessionProtocol() >= QSsl::TlsV1_1);
else if (configuration.protocol == QSsl::TlsV1_2OrLater)
protocolOk = (sessionProtocol() >= QSsl::TlsV1_2);
else
protocolOk = (sessionProtocol() == configuration.protocol);

View File

@ -1098,6 +1098,9 @@ public:
QString m_interFile;
QString ciphers;
signals:
void socketError(QAbstractSocket::SocketError);
protected:
void incomingConnection(qintptr socketDescriptor)
{
@ -1107,6 +1110,7 @@ protected:
socket->setProtocol(protocol);
if (ignoreSslErrors)
connect(socket, SIGNAL(sslErrors(QList<QSslError>)), this, SLOT(ignoreErrorSlot()));
connect(socket, SIGNAL(error(QAbstractSocket::SocketError)), this, SIGNAL(socketError(QAbstractSocket::SocketError)));
QFile file(m_keyFile);
QVERIFY(file.open(QIODevice::ReadOnly));
@ -1242,6 +1246,37 @@ void tst_QSslSocket::protocolServerSide_data()
#if !defined(OPENSSL_NO_SSL3)
QTest::newRow("any-ssl3") << QSsl::AnyProtocol << QSsl::SslV3 << true;
#endif
#if !defined(OPENSSL_NO_SSL2) && !defined(QT_SECURETRANSPORT)
QTest::newRow("tls1.0orlater-ssl2") << QSsl::TlsV1_0OrLater << QSsl::SslV2 << false;
#endif
#if !defined(OPENSSL_NO_SSL3)
QTest::newRow("tls1.0orlater-ssl3") << QSsl::TlsV1_0OrLater << QSsl::SslV3 << false;
#endif
QTest::newRow("tls1.0orlater-tls1.0") << QSsl::TlsV1_0OrLater << QSsl::TlsV1_0 << true;
QTest::newRow("tls1.0orlater-tls1.1") << QSsl::TlsV1_0OrLater << QSsl::TlsV1_1 << true;
QTest::newRow("tls1.0orlater-tls1.2") << QSsl::TlsV1_0OrLater << QSsl::TlsV1_2 << true;
#if !defined(OPENSSL_NO_SSL2) && !defined(QT_SECURETRANSPORT)
QTest::newRow("tls1.1orlater-ssl2") << QSsl::TlsV1_1OrLater << QSsl::SslV2 << false;
#endif
#if !defined(OPENSSL_NO_SSL3)
QTest::newRow("tls1.1orlater-ssl3") << QSsl::TlsV1_1OrLater << QSsl::SslV3 << false;
#endif
QTest::newRow("tls1.1orlater-tls1.0") << QSsl::TlsV1_1OrLater << QSsl::TlsV1_0 << false;
QTest::newRow("tls1.1orlater-tls1.1") << QSsl::TlsV1_1OrLater << QSsl::TlsV1_1 << true;
QTest::newRow("tls1.1orlater-tls1.2") << QSsl::TlsV1_1OrLater << QSsl::TlsV1_2 << true;
#if !defined(OPENSSL_NO_SSL2) && !defined(QT_SECURETRANSPORT)
QTest::newRow("tls1.2orlater-ssl2") << QSsl::TlsV1_2OrLater << QSsl::SslV2 << false;
#endif
#if !defined(OPENSSL_NO_SSL3)
QTest::newRow("tls1.2orlater-ssl3") << QSsl::TlsV1_2OrLater << QSsl::SslV3 << false;
#endif
QTest::newRow("tls1.2orlater-tls1.0") << QSsl::TlsV1_2OrLater << QSsl::TlsV1_0 << false;
QTest::newRow("tls1.2orlater-tls1.1") << QSsl::TlsV1_2OrLater << QSsl::TlsV1_1 << false;
QTest::newRow("tls1.2orlater-tls1.2") << QSsl::TlsV1_2OrLater << QSsl::TlsV1_2 << true;
QTest::newRow("any-tls1.0") << QSsl::AnyProtocol << QSsl::TlsV1_0 << true;
QTest::newRow("any-tls1ssl3") << QSsl::AnyProtocol << QSsl::TlsV1SslV3 << true;
QTest::newRow("any-secure") << QSsl::AnyProtocol << QSsl::SecureProtocols << true;
@ -1264,6 +1299,7 @@ void tst_QSslSocket::protocolServerSide()
QVERIFY(server.listen());
QEventLoop loop;
connect(&server, SIGNAL(socketError(QAbstractSocket::SocketError)), &loop, SLOT(quit()));
QTimer::singleShot(5000, &loop, SLOT(quit()));
QSslSocket client;
@ -1281,7 +1317,15 @@ void tst_QSslSocket::protocolServerSide()
QFETCH(bool, works);
QAbstractSocket::SocketState expectedState = (works) ? QAbstractSocket::ConnectedState : QAbstractSocket::UnconnectedState;
QCOMPARE(int(client.state()), int(expectedState));
// Determine whether the client or the server caused the event loop
// to quit due to a socket error, and investigate the culprit.
if (server.socket->error() != QAbstractSocket::UnknownSocketError) {
QVERIFY(client.error() == QAbstractSocket::UnknownSocketError);
QCOMPARE(int(server.socket->state()), int(expectedState));
} else if (client.error() != QAbstractSocket::UnknownSocketError) {
QVERIFY(server.socket->error() == QAbstractSocket::UnknownSocketError);
QCOMPARE(int(client.state()), int(expectedState));
}
QCOMPARE(client.isEncrypted(), works);
}