[prev in list] [next in list] [prev in thread] [next in thread]
List: kde-commits
Subject: [kio] src/core: - Add support for TLSv1.1 and TLSv1.2 protocols.
From: Dawit Alemayehu <adawit () kde ! org>
Date: 2015-01-18 12:43:23
Message-ID: E1YCpCN-00012d-8S () scm ! kde ! org
[Download RAW message or body]
Git commit a1be52944f8b7dc99afb1d906b055d5c27863d55 by Dawit Alemayehu.
Committed on 12/01/2015 at 03:13.
Pushed by adawit into branch 'master'.
- Add support for TLSv1.1 and TLSv1.2 protocols.
- Fix negotiatedSslVersion and negotiatedSslVersionName to return the
actual negotiated protocol. Prior to v5.4, Qt did not provide a means
to obtain the actual negotiated protocol.
- Removed SSLv3 from manual renegotiation and added TLSv1.1 and TLSv1.2.
- Removed explicit disabling of SSL compression since it has been defauled
to off in Qt since 4.8.4.
REVIEW: 122007
M +40 -11 src/core/ktcpsocket.cpp
M +4 -0 src/core/ktcpsocket.h
M +23 -30 src/core/tcpslavebase.cpp
http://commits.kde.org/kio/a1be52944f8b7dc99afb1d906b055d5c27863d55
diff --git a/src/core/ktcpsocket.cpp b/src/core/ktcpsocket.cpp
index f223986..fde35a7 100644
--- a/src/core/ktcpsocket.cpp
+++ b/src/core/ktcpsocket.cpp
@@ -40,14 +40,16 @@ static KTcpSocket::SslVersion kSslVersionFromQ(QSsl::SslProtocol \
protocol) return KTcpSocket::SslV3;
case QSsl::TlsV1_0:
return KTcpSocket::TlsV1;
+ case QSsl::TlsV1_1:
+ return KTcpSocket::TlsV1_1;
+ case QSsl::TlsV1_2:
+ return KTcpSocket::TlsV1_2;
case QSsl::AnyProtocol:
return KTcpSocket::AnySslVersion;
-#if QT_VERSION >= 0x040800
case QSsl::TlsV1SslV3:
return KTcpSocket::TlsV1SslV3;
case QSsl::SecureProtocols:
return KTcpSocket::SecureProtocols;
-#endif
default:
return KTcpSocket::UnknownSslVersion;
}
@@ -61,10 +63,11 @@ static QSsl::SslProtocol qSslProtocolFromK(KTcpSocket::SslVersion \
sslVersion) }
//does it contain any valid protocol?
KTcpSocket::SslVersions validVersions(KTcpSocket::SslV2 | KTcpSocket::SslV3 | \
KTcpSocket::TlsV1);
-#if QT_VERSION >= 0x040800
+ validVersions |= KTcpSocket::TlsV1_1;
+ validVersions |= KTcpSocket::TlsV1_2;
validVersions |= KTcpSocket::TlsV1SslV3;
validVersions |= KTcpSocket::SecureProtocols;
-#endif
+
if (!(sslVersion & validVersions)) {
return QSsl::UnknownProtocol;
}
@@ -74,14 +77,16 @@ static QSsl::SslProtocol qSslProtocolFromK(KTcpSocket::SslVersion \
sslVersion) return QSsl::SslV2;
case KTcpSocket::SslV3:
return QSsl::SslV3;
- case KTcpSocket::TlsV1:
+ case KTcpSocket::TlsV1_0:
return QSsl::TlsV1_0;
-#if QT_VERSION >= 0x040800
+ case KTcpSocket::TlsV1_1:
+ return QSsl::TlsV1_1;
+ case KTcpSocket::TlsV1_2:
+ return QSsl::TlsV1_2;
case KTcpSocket::TlsV1SslV3:
return QSsl::TlsV1SslV3;
case KTcpSocket::SecureProtocols:
return QSsl::SecureProtocols;
-#endif
default:
//QSslSocket doesn't really take arbitrary combinations. It's one or all.
@@ -89,6 +94,24 @@ static QSsl::SslProtocol qSslProtocolFromK(KTcpSocket::SslVersion \
sslVersion) }
}
+static QString protocolString(QSsl::SslProtocol protocol)
+{
+ switch (protocol) {
+ case QSsl::SslV2:
+ return QLatin1String("SSLv2");
+ case QSsl::SslV3:
+ return QLatin1String("SSLv3");
+ case QSsl::TlsV1_0:
+ return QLatin1String("TLSv1.0");
+ case QSsl::TlsV1_1:
+ return QLatin1String("TLSv1.1");
+ case QSsl::TlsV1_2:
+ return QLatin1String("TLSv1.2");
+ default:
+ return QLatin1String("Unknown");;
+ }
+}
+
//cipher class converter KSslCipher -> QSslCipher
class CipherCc
{
@@ -702,11 +725,7 @@ void KTcpSocket::setLocalCertificate(const QString &fileName, \
QSsl::EncodingForm
void KTcpSocket::setVerificationPeerName(const QString &hostName)
{
-#if QT_VERSION >= 0x040800
d->sock.setPeerVerifyName(hostName);
-#else
- Q_UNUSED(hostName);
-#endif
}
void KTcpSocket::setPrivateKey(const KSslKey &key)
@@ -805,7 +824,12 @@ KTcpSocket::SslVersion KTcpSocket::negotiatedSslVersion() const
if (!d->sock.isEncrypted()) {
return UnknownSslVersion;
}
+
+#if QT_VERSION >= QT_VERSION_CHECK(5, 4, 0)
+ return kSslVersionFromQ(d->sock.sessionProtocol());
+#else
return kSslVersionFromQ(d->sock.protocol());
+#endif
}
QString KTcpSocket::negotiatedSslVersionName() const
@@ -813,7 +837,12 @@ QString KTcpSocket::negotiatedSslVersionName() const
if (!d->sock.isEncrypted()) {
return QString();
}
+
+#if QT_VERSION >= QT_VERSION_CHECK(5, 4, 0)
+ return protocolString(d->sock.sessionProtocol());
+#else
return d->sock.sessionCipher().protocolString();
+#endif
}
////////////////////////////// KSslKey
diff --git a/src/core/ktcpsocket.h b/src/core/ktcpsocket.h
index d59b180..2faf35c 100644
--- a/src/core/ktcpsocket.h
+++ b/src/core/ktcpsocket.h
@@ -160,9 +160,13 @@ public:
SslV3_1 = 0x08,
TlsV1SslV3 = 0x10,
SecureProtocols = 0x20,
+ TlsV1_0 = TlsV1,
+ TlsV1_1 = 0x40,
+ TlsV1_2 = 0x80,
AnySslVersion = SslV2 | SslV3 | TlsV1
};
Q_DECLARE_FLAGS(SslVersions, SslVersion)
+
enum Error {
UnknownError = 0,
ConnectionRefusedError,
diff --git a/src/core/tcpslavebase.cpp b/src/core/tcpslavebase.cpp
index e62e72a..751c153 100644
--- a/src/core/tcpslavebase.cpp
+++ b/src/core/tcpslavebase.cpp
@@ -150,7 +150,6 @@ public:
}
SslResult startTLSInternal(KTcpSocket::SslVersion sslVersion,
- const QSslConfiguration &configuration = \
QSslConfiguration(), int waitForEncryptedTimeout = -1);
TCPSlaveBase *q;
@@ -336,23 +335,20 @@ int TCPSlaveBase::connectToHost(const QString &host, quint16 \
port, QString *erro }
/*
- By default the SSL handshake attempt uses these settings in the order shown:
+ SSL handshake is attempted in the following order:
- 1.) Protocol: KTcpSocket::SecureProtocols SSL compression: OFF (DEFAULT)
- 2.) Protocol: KTcpSocket::TlsV1 SSL compression: OFF
- 3.) Protocol: KTcpSocket::SslV3 SSL compression: OFF
+ 1.) KTcpSocket::SecureProtocols
+ 2.) KTcpSocket::TlsV1_2
+ 3.) KTcpSocket::TlsV1_1
+ 4.) KTcpSocket::TlsV1_0
- If any combination other than the one marked DEFAULT is used to complete
- the SSL handshake, then that combination will be cached using KIO's internal
- meta-data mechanism in order to speed up future connections to the same host.
- */
-
- QSslConfiguration sslConfig = d->socket.sslConfiguration();
+ Note that we indivially attempt connection with each TLS version
+ because some sites don't support SSL negotiation. #275524
-#if QT_VERSION >= 0x040800
- // NOTE: Due to 'CRIME' SSL attacks, compression is always disabled.
- sslConfig.setSslOption(QSsl::SslOptionDisableCompression, true);
-#endif
+ The version used to successfully make encrypted connection with the
+ remote server is cached within the process to make subsequent
+ connection requests to the same server faster.
+ */
const int lastSslVerson = config()->readEntry("LastUsedSslVersion", \
static_cast<int>(KTcpSocket::SecureProtocols));
KTcpSocket::SslVersion trySslVersion = \
static_cast<KTcpSocket::SslVersion>(lastSslVerson); @@ -394,7 +390,7 @@ int \
TCPSlaveBase::connectToHost(const QString &host, quint16 port, QString *erro d->port \
= d->socket.peerPort();
if (d->autoSSL) {
- SslResult res = d->startTLSInternal(trySslVersion, sslConfig, timeout);
+ SslResult res = d->startTLSInternal(trySslVersion, timeout);
if ((res & ResultFailed) && (res & ResultFailedEarly)) {
if (!(alreadyTriedSslVersions & KTcpSocket::SecureProtocols)) {
trySslVersion = KTcpSocket::SecureProtocols;
@@ -402,14 +398,20 @@ int TCPSlaveBase::connectToHost(const QString &host, quint16 \
port, QString *erro continue;
}
- if (!(alreadyTriedSslVersions & KTcpSocket::TlsV1)) {
+ if (!(alreadyTriedSslVersions & KTcpSocket::TlsV1_2)) {
trySslVersion = KTcpSocket::TlsV1;
alreadyTriedSslVersions |= trySslVersion;
continue;
}
- if (!(alreadyTriedSslVersions & KTcpSocket::SslV3)) {
- trySslVersion = KTcpSocket::SslV3;
+ if (!(alreadyTriedSslVersions & KTcpSocket::TlsV1_1)) {
+ trySslVersion = KTcpSocket::TlsV1;
+ alreadyTriedSslVersions |= trySslVersion;
+ continue;
+ }
+
+ if (!(alreadyTriedSslVersions & KTcpSocket::TlsV1_0)) {
+ trySslVersion = KTcpSocket::TlsV1_0;
alreadyTriedSslVersions |= trySslVersion;
continue;
}
@@ -493,26 +495,17 @@ bool TCPSlaveBase::startSsl()
}
TCPSlaveBase::SslResult \
TCPSlaveBase::TcpSlaveBasePrivate::startTLSInternal(KTcpSocket::SslVersion \
version,
- const QSslConfiguration &sslConfig,
- int waitForEncryptedTimeout)
+ int \
waitForEncryptedTimeout) {
q->selectClientCertificate();
//setMetaData("ssl_session_id", d->kssl->session()->toString());
//### we don't support session reuse for now...
usingSSL = true;
-#if QT_VERSION >= 0x040800
- /*qDebug() << "Trying SSL handshake with protocol:" << version
- << ", SSL compression ON:" << \
sslConfig.testSslOption(QSsl::SslOptionDisableCompression);*/
-#endif
+
// Set the SSL version to use...
socket.setAdvertisedSslVersion(version);
- // Set SSL configuration information
- if (!sslConfig.isNull()) {
- socket.setSslConfiguration(sslConfig);
- }
-
/* Usually ignoreSslErrors() would be called in the slot invoked by the \
sslErrors()
signal but that would mess up the flow of control. We will check for errors
anyway to decide if we want to continue connecting. Otherwise \
ignoreSslErrors()
[prev in list] [next in list] [prev in thread] [next in thread]
Configure |
About |
News |
Add a list |
Sponsored by KoreLogic