Skip to content

Commit

Permalink
QSslSocket: backport TLSv1_1 and TLSv1_2 from Qt 5.
Browse files Browse the repository at this point in the history
  • Loading branch information
mkrautz committed Dec 25, 2014
1 parent 812f3b3 commit 73e9c4b
Show file tree
Hide file tree
Showing 5 changed files with 57 additions and 5 deletions.
3 changes: 3 additions & 0 deletions src/network/ssl/qssl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,9 @@ QT_BEGIN_NAMESPACE
\value SslV3 SSLv3
\value SslV2 SSLv2
\value TlsV1 TLSv1
\value TlsV1_0 TLSv1
\value TlsV1_1 TLSv1
\value TlsV1_2 TLSv1
\value UnknownProtocol The cipher's protocol cannot be determined.
\value AnyProtocol The socket understands SSLv2, SSLv3, and TLSv1. This
value is used by QSslSocket only.
Expand Down
7 changes: 6 additions & 1 deletion src/network/ssl/qssl.h
Original file line number Diff line number Diff line change
Expand Up @@ -76,10 +76,15 @@ namespace QSsl {
enum SslProtocol {
SslV3,
SslV2,
TlsV1, // ### Qt 5: rename to TlsV1_0 or so
TlsV1_0,
TlsV1 = TlsV1_0,
AnyProtocol,
TlsV1SslV3,
SecureProtocols,

TlsV1_1,
TlsV1_2,

UnknownProtocol = -1
};

Expand Down
20 changes: 16 additions & 4 deletions src/network/ssl/qsslsocket_openssl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -212,7 +212,11 @@ QSslCipher QSslSocketBackendPrivate::QSslCipher_from_SSL_CIPHER(SSL_CIPHER *ciph
else if (protoString == QLatin1String("SSLv2"))
ciph.d->protocol = QSsl::SslV2;
else if (protoString == QLatin1String("TLSv1"))
ciph.d->protocol = QSsl::TlsV1;
ciph.d->protocol = QSsl::TlsV1_0;
else if (protoString == QLatin1String("TLSv1.1"))
ciph.d->protocol = QSsl::TlsV1_1;
else if (protoString == QLatin1String("TLSv1.2"))
ciph.d->protocol = QSsl::TlsV1_2;

if (descriptionList.at(2).startsWith(QLatin1String("Kx=")))
ciph.d->keyExchangeMethod = descriptionList.at(2).mid(3);
Expand Down Expand Up @@ -258,7 +262,7 @@ bool QSslSocketBackendPrivate::initSslContext()
{
Q_Q(QSslSocket);

// Create and initialize SSL context. Accept SSLv2, SSLv3 and TLSv1.
// Create and initialize SSL context. Accept SSLv2, SSLv3, TLSv1_0, TLSv1_1 and TLSv1_2.
bool client = (mode == QSslSocket::SslClientMode);

bool reinitialized = false;
Expand All @@ -280,9 +284,15 @@ bool QSslSocketBackendPrivate::initSslContext()
default:
ctx = q_SSL_CTX_new(client ? q_SSLv23_client_method() : q_SSLv23_server_method());
break;
case QSsl::TlsV1:
case QSsl::TlsV1_0:
ctx = q_SSL_CTX_new(client ? q_TLSv1_client_method() : q_TLSv1_server_method());
break;
case QSsl::TlsV1_1:
ctx = q_SSL_CTX_new(client ? q_TLSv1_1_client_method() : q_TLSv1_1_server_method());
break;
case QSsl::TlsV1_2:
ctx = q_SSL_CTX_new(client ? q_TLSv1_2_client_method() : q_TLSv1_2_server_method());
break;
}
if (!ctx) {
// After stopping Flash 10 the SSL library looses its ciphers. Try re-adding them
Expand Down Expand Up @@ -446,7 +456,9 @@ bool QSslSocketBackendPrivate::initSslContext()

#if OPENSSL_VERSION_NUMBER >= 0x0090806fL && !defined(OPENSSL_NO_TLSEXT)
if ((configuration.protocol == QSsl::TlsV1SslV3 ||
configuration.protocol == QSsl::TlsV1 ||
configuration.protocol == QSsl::TlsV1_0 ||
configuration.protocol == QSsl::TlsV1_1 ||
configuration.protocol == QSsl::TlsV1_2 ||
configuration.protocol == QSsl::SecureProtocols ||
configuration.protocol == QSsl::AnyProtocol) &&
client && q_SSLeay() >= 0x00090806fL) {
Expand Down
24 changes: 24 additions & 0 deletions src/network/ssl/qsslsocket_openssl_symbols.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -231,12 +231,20 @@ DEFINEFUNC(const SSL_METHOD *, SSLv2_client_method, DUMMYARG, DUMMYARG, return 0
DEFINEFUNC(const SSL_METHOD *, SSLv3_client_method, DUMMYARG, DUMMYARG, return 0, return)
DEFINEFUNC(const SSL_METHOD *, SSLv23_client_method, DUMMYARG, DUMMYARG, return 0, return)
DEFINEFUNC(const SSL_METHOD *, TLSv1_client_method, DUMMYARG, DUMMYARG, return 0, return)
#if OPENSSL_VERSION_NUMBER >= 0x10001000L
DEFINEFUNC(const SSL_METHOD *, TLSv1_1_client_method, DUMMYARG, DUMMYARG, return 0, return)
DEFINEFUNC(const SSL_METHOD *, TLSv1_2_client_method, DUMMYARG, DUMMYARG, return 0, return)
#endif
#ifndef OPENSSL_NO_SSL2
DEFINEFUNC(const SSL_METHOD *, SSLv2_server_method, DUMMYARG, DUMMYARG, return 0, return)
#endif
DEFINEFUNC(const SSL_METHOD *, SSLv3_server_method, DUMMYARG, DUMMYARG, return 0, return)
DEFINEFUNC(const SSL_METHOD *, SSLv23_server_method, DUMMYARG, DUMMYARG, return 0, return)
DEFINEFUNC(const SSL_METHOD *, TLSv1_server_method, DUMMYARG, DUMMYARG, return 0, return)
#if OPENSSL_VERSION_NUMBER >= 0x10001000L
DEFINEFUNC(const SSL_METHOD *, TLSv1_1_server_method, DUMMYARG, DUMMYARG, return 0, return)
DEFINEFUNC(const SSL_METHOD *, TLSv1_2_server_method, DUMMYARG, DUMMYARG, return 0, return)
#endif
#else
DEFINEFUNC(SSL_METHOD *, SSLv2_client_method, DUMMYARG, DUMMYARG, return 0, return)
DEFINEFUNC(SSL_METHOD *, SSLv3_client_method, DUMMYARG, DUMMYARG, return 0, return)
Expand Down Expand Up @@ -691,10 +699,18 @@ bool q_resolveOpenSslSymbols()
RESOLVEFUNC(SSLv3_client_method, 195, libs.first )
RESOLVEFUNC(SSLv23_client_method, 189, libs.first )
RESOLVEFUNC(TLSv1_client_method, 198, libs.first )
#if OPENSSL_VERSION_NUMBER >= 0x10001000L
RESOLVEFUNC(TLSv1_1_client_method, 300, libs.first )
RESOLVEFUNC(TLSv1_2_client_method, 301, libs.first )
#endif
RESOLVEFUNC(SSLv2_server_method, 194, libs.first )
RESOLVEFUNC(SSLv3_server_method, 197, libs.first )
RESOLVEFUNC(SSLv23_server_method, 191, libs.first )
RESOLVEFUNC(TLSv1_server_method, 200, libs.first )
#if OPENSSL_VERSION_NUMBER >= 0x10001000L
RESOLVEFUNC(TLSv1_1_server_method, 400, libs.first )
RESOLVEFUNC(TLSv1_2_server_method, 401, libs.first )
#endif
RESOLVEFUNC(SSL_CTX_load_verify_locations, 34, libs.first )
RESOLVEFUNC(X509_NAME_entry_count, 1821, libs.second )
RESOLVEFUNC(X509_NAME_get_entry, 1823, libs.second )
Expand Down Expand Up @@ -826,12 +842,20 @@ bool q_resolveOpenSslSymbols()
RESOLVEFUNC(SSLv3_client_method)
RESOLVEFUNC(SSLv23_client_method)
RESOLVEFUNC(TLSv1_client_method)
#if OPENSSL_VERSION_NUMBER >= 0x10001000L
RESOLVEFUNC(TLSv1_1_client_method)
RESOLVEFUNC(TLSv1_2_client_method)
#endif
#ifndef OPENSSL_NO_SSL2
RESOLVEFUNC(SSLv2_server_method)
#endif
RESOLVEFUNC(SSLv3_server_method)
RESOLVEFUNC(SSLv23_server_method)
RESOLVEFUNC(TLSv1_server_method)
#if OPENSSL_VERSION_NUMBER >= 0x10001000L
RESOLVEFUNC(TLSv1_1_server_method)
RESOLVEFUNC(TLSv1_2_server_method)
#endif
RESOLVEFUNC(X509_NAME_entry_count)
RESOLVEFUNC(X509_NAME_get_entry)
RESOLVEFUNC(X509_NAME_ENTRY_get_data)
Expand Down
8 changes: 8 additions & 0 deletions src/network/ssl/qsslsocket_openssl_symbols_p.h
Original file line number Diff line number Diff line change
Expand Up @@ -330,19 +330,27 @@ const SSL_METHOD *q_SSLv2_client_method();
const SSL_METHOD *q_SSLv3_client_method();
const SSL_METHOD *q_SSLv23_client_method();
const SSL_METHOD *q_TLSv1_client_method();
const SSL_METHOD *q_TLSv1_1_client_method();
const SSL_METHOD *q_TLSv1_2_client_method();
const SSL_METHOD *q_SSLv2_server_method();
const SSL_METHOD *q_SSLv3_server_method();
const SSL_METHOD *q_SSLv23_server_method();
const SSL_METHOD *q_TLSv1_server_method();
const SSL_METHOD *q_TLSv1_1_server_method();
const SSL_METHOD *q_TLSv1_2_server_method();
#else
SSL_METHOD *q_SSLv2_client_method();
SSL_METHOD *q_SSLv3_client_method();
SSL_METHOD *q_SSLv23_client_method();
SSL_METHOD *q_TLSv1_client_method();
SSL_METHOD *q_TLSv1_1_client_method();
SSL_METHOD *q_TLSv1_2_client_method();
SSL_METHOD *q_SSLv2_server_method();
SSL_METHOD *q_SSLv3_server_method();
SSL_METHOD *q_SSLv23_server_method();
SSL_METHOD *q_TLSv1_server_method();
SSL_METHOD *q_TLSv1_1_server_method();
SSL_METHOD *q_TLSv1_2_server_method();
#endif
int q_SSL_write(SSL *a, const void *b, int c);
int q_X509_cmp(X509 *a, X509 *b);
Expand Down

3 comments on commit 73e9c4b

@eecklund
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If I modify my 4.8.5 source similar to this, then TLS 1.2 should be supported? Guessing OpenSSL needs to be updated to at least 1.0.1 as well.

@mkrautz
Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, but you'd need to setup the QSslSocket to use protocol QSsl::TlsV1_2 explicitly.

Another possibility is to use this patch from OpenBSD's ports tree:
http://cvsweb.openbsd.org/cgi-bin/cvsweb/~checkout~/ports/x11/qt4/patches/patch-src_network_ssl_qsslsocket_openssl_cpp?rev=1.4&content-type=text/plain

It makes the default of QSslSocket::TlsV1 mean "TLS 1.0 or later."

@mkrautz
Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The benefit of the OpenBSD patch being that your source code would still be compatible with an unpatched Qt 4.

Please sign in to comment.