From 9c2ecf89eb773b4929d39a0a4929ce2b647aaaef Mon Sep 17 00:00:00 2001 From: Peter Hartmann Date: Wed, 26 Mar 2014 09:40:52 -0400 Subject: network: finish all pending replies upon error ... and not only one. This was a problem e.g. when there were several requests to the same host and the host was not reachable; only one reply would get an error signal in case we suppressed other errors in "happy eyeballs" host lookup style. Task-number: QTBUG-36890 Change-Id: I1b5757498bd644b0d773cf6c43e4950620949c5c Reviewed-by: Richard J. Moore --- .../access/qhttpnetworkconnectionchannel.cpp | 27 +++++++++++++--------- 1 file changed, 16 insertions(+), 11 deletions(-) (limited to 'src/network') diff --git a/src/network/access/qhttpnetworkconnectionchannel.cpp b/src/network/access/qhttpnetworkconnectionchannel.cpp index fb40958178..169124e9f4 100644 --- a/src/network/access/qhttpnetworkconnectionchannel.cpp +++ b/src/network/access/qhttpnetworkconnectionchannel.cpp @@ -873,18 +873,23 @@ void QHttpNetworkConnectionChannel::_q_error(QAbstractSocket::SocketError socket if (!connection->d_func()->shouldEmitChannelError(socket)) return; - // Need to dequeu the request so that we can emit the error. - if (!reply) - connection->d_func()->dequeueRequest(socket); - if (reply) { - reply->d_func()->errorString = errorString; - emit reply->finishedWithError(errorCode, errorString); - reply = 0; - if (protocolHandler) - protocolHandler->setReply(0); - } + // emit error for all waiting replies + do { + // Need to dequeu the request so that we can emit the error. + if (!reply) + connection->d_func()->dequeueRequest(socket); + + if (reply) { + reply->d_func()->errorString = errorString; + emit reply->finishedWithError(errorCode, errorString); + reply = 0; + if (protocolHandler) + protocolHandler->setReply(0); + } + } while (!connection->d_func()->highPriorityQueue.isEmpty() + || !connection->d_func()->lowPriorityQueue.isEmpty()); #ifndef QT_NO_SSL - else if (connection->connectionType() == QHttpNetworkConnection::ConnectionTypeSPDY) { + if (connection->connectionType() == QHttpNetworkConnection::ConnectionTypeSPDY) { QList spdyPairs = spdyRequestsToSend.values(); for (int a = 0; a < spdyPairs.count(); ++a) { // emit error for all replies -- cgit v1.2.3 From 0ed1042092f6cc514ed604583b6f90d3b826d2cf Mon Sep 17 00:00:00 2001 From: "Richard J. Moore" Date: Fri, 4 Apr 2014 15:10:29 +0100 Subject: Fix QNetworkRequest::setRawHeader() for QT_NO_CAST_FROM_BYTEARRAY Avoid the implicit conversion in the doc snippet. Change-Id: Iacec6dab371a22c16f537af471f6653d9c5ad43d Reviewed-by: Andy Shaw --- src/network/doc/snippets/code/src_network_access_qnetworkrequest.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/network') diff --git a/src/network/doc/snippets/code/src_network_access_qnetworkrequest.cpp b/src/network/doc/snippets/code/src_network_access_qnetworkrequest.cpp index 53eadda7e9..61e7cf0ea3 100644 --- a/src/network/doc/snippets/code/src_network_access_qnetworkrequest.cpp +++ b/src/network/doc/snippets/code/src_network_access_qnetworkrequest.cpp @@ -39,5 +39,5 @@ ****************************************************************************/ //! [0] -request.setRawHeader("Last-Modified", "Sun, 06 Nov 1994 08:49:37 GMT"); +request.setRawHeader(QByteArray("Last-Modified"), QByteArray("Sun, 06 Nov 1994 08:49:37 GMT")); //! [0] -- cgit v1.2.3 From 6ea574d4461199e036fb9cd05b1bbdb0f93c390c Mon Sep 17 00:00:00 2001 From: David Faure Date: Mon, 7 Apr 2014 14:02:29 +0200 Subject: QNetworkReplyHttpImpl: fix misuse of QDateTime::addSecs() QDateTime::addSecs() is a const function and returns a new QDateTime with the given seconds added, thus the current statement had no effect. Found by applying Q_REQUIRED_RESULT in dev branch. Change-Id: Id712334f91e0adb40bafc23470bf46479334c81a Reviewed-by: Richard J. Moore --- src/network/access/qnetworkreplyhttpimpl.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'src/network') diff --git a/src/network/access/qnetworkreplyhttpimpl.cpp b/src/network/access/qnetworkreplyhttpimpl.cpp index de4c8d0964..f043307c10 100644 --- a/src/network/access/qnetworkreplyhttpimpl.cpp +++ b/src/network/access/qnetworkreplyhttpimpl.cpp @@ -560,8 +560,7 @@ bool QNetworkReplyHttpImplPrivate::loadFromCacheIfAllowed(QHttpNetworkRequest &h if (!expirationDate.isValid()) { if (lastModified.isValid()) { int diff = currentDateTime.secsTo(lastModified); - expirationDate = lastModified; - expirationDate.addSecs(diff / 10); + expirationDate = lastModified.addSecs(diff / 10); if (httpRequest.headerField("Warning").isEmpty()) { QDateTime dt; dt.setTime_t(current_age); -- cgit v1.2.3 From f41418aeb20ddc190892216a09feb564d2cef5b4 Mon Sep 17 00:00:00 2001 From: "Richard J. Moore" Date: Sun, 6 Apr 2014 15:56:08 +0100 Subject: Ensure we initialize things before checking the openssl version. Task-number: QTBUG-37783 Change-Id: Ie276e597062d8bfc74ef57251ed21a94020e030f Reviewed-by: Friedemann Kleint --- src/network/ssl/qsslsocket_openssl.cpp | 3 +++ 1 file changed, 3 insertions(+) (limited to 'src/network') diff --git a/src/network/ssl/qsslsocket_openssl.cpp b/src/network/ssl/qsslsocket_openssl.cpp index bcb2254d11..1b3928fdfb 100644 --- a/src/network/ssl/qsslsocket_openssl.cpp +++ b/src/network/ssl/qsslsocket_openssl.cpp @@ -569,6 +569,9 @@ void QSslSocketPrivate::ensureInitialized() long QSslSocketPrivate::sslLibraryVersionNumber() { + if (!supportsSsl()) + return 0; + return q_SSLeay(); } -- cgit v1.2.3 From 814a1c7b2b940cdf6b1716406b26063576ac0d95 Mon Sep 17 00:00:00 2001 From: "Richard J. Moore" Date: Sun, 6 Apr 2014 12:38:52 +0100 Subject: Support for DH and ECDH key exchange for QSslSocket servers Despite supporting DH and ECDH key exchange as a client, Qt did not provide any default parameters which prevented them being used as a server. A future change should allow the user to control the parameters used, but these defaults should be okay for most users. [ChangeLog][Important Behavior Changes] Support for DH and ECDH key exchange cipher suites when acting as an SSL server has been made possible. This change means the you can now implement servers that offer forward-secrecy using Qt. Task-number: QTBUG-20666 Change-Id: I469163900e4313da9d2d0c3e1e5e47ef46320b17 Reviewed-by: Daniel Molkentin Reviewed-by: Peter Hartmann --- src/network/ssl/qsslcontext.cpp | 59 ++++++++++++++++++++++++++ src/network/ssl/qsslsocket_openssl_symbols.cpp | 10 +++++ src/network/ssl/qsslsocket_openssl_symbols_p.h | 11 +++++ 3 files changed, 80 insertions(+) (limited to 'src/network') diff --git a/src/network/ssl/qsslcontext.cpp b/src/network/ssl/qsslcontext.cpp index 1634ba0649..9c68218062 100644 --- a/src/network/ssl/qsslcontext.cpp +++ b/src/network/ssl/qsslcontext.cpp @@ -55,6 +55,53 @@ QT_BEGIN_NAMESPACE extern int q_X509Callback(int ok, X509_STORE_CTX *ctx); extern QString getErrorsFromOpenSsl(); +// Default DH params +// 1024-bit MODP Group with 160-bit Prime Order Subgroup +// From RFC 5114 +static unsigned const char dh1024_p[]={ + 0xB1,0x0B,0x8F,0x96,0xA0,0x80,0xE0,0x1D,0xDE,0x92,0xDE,0x5E, + 0xAE,0x5D,0x54,0xEC,0x52,0xC9,0x9F,0xBC,0xFB,0x06,0xA3,0xC6, + 0x9A,0x6A,0x9D,0xCA,0x52,0xD2,0x3B,0x61,0x60,0x73,0xE2,0x86, + 0x75,0xA2,0x3D,0x18,0x98,0x38,0xEF,0x1E,0x2E,0xE6,0x52,0xC0, + 0x13,0xEC,0xB4,0xAE,0xA9,0x06,0x11,0x23,0x24,0x97,0x5C,0x3C, + 0xD4,0x9B,0x83,0xBF,0xAC,0xCB,0xDD,0x7D,0x90,0xC4,0xBD,0x70, + 0x98,0x48,0x8E,0x9C,0x21,0x9A,0x73,0x72,0x4E,0xFF,0xD6,0xFA, + 0xE5,0x64,0x47,0x38,0xFA,0xA3,0x1A,0x4F,0xF5,0x5B,0xCC,0xC0, + 0xA1,0x51,0xAF,0x5F,0x0D,0xC8,0xB4,0xBD,0x45,0xBF,0x37,0xDF, + 0x36,0x5C,0x1A,0x65,0xE6,0x8C,0xFD,0xA7,0x6D,0x4D,0xA7,0x08, + 0xDF,0x1F,0xB2,0xBC,0x2E,0x4A,0x43,0x71 +}; + +static unsigned const char dh1024_g[]={ + 0xA4,0xD1,0xCB,0xD5,0xC3,0xFD,0x34,0x12,0x67,0x65,0xA4,0x42, + 0xEF,0xB9,0x99,0x05,0xF8,0x10,0x4D,0xD2,0x58,0xAC,0x50,0x7F, + 0xD6,0x40,0x6C,0xFF,0x14,0x26,0x6D,0x31,0x26,0x6F,0xEA,0x1E, + 0x5C,0x41,0x56,0x4B,0x77,0x7E,0x69,0x0F,0x55,0x04,0xF2,0x13, + 0x16,0x02,0x17,0xB4,0xB0,0x1B,0x88,0x6A,0x5E,0x91,0x54,0x7F, + 0x9E,0x27,0x49,0xF4,0xD7,0xFB,0xD7,0xD3,0xB9,0xA9,0x2E,0xE1, + 0x90,0x9D,0x0D,0x22,0x63,0xF8,0x0A,0x76,0xA6,0xA2,0x4C,0x08, + 0x7A,0x09,0x1F,0x53,0x1D,0xBF,0x0A,0x01,0x69,0xB6,0xA2,0x8A, + 0xD6,0x62,0xA4,0xD1,0x8E,0x73,0xAF,0xA3,0x2D,0x77,0x9D,0x59, + 0x18,0xD0,0x8B,0xC8,0x85,0x8F,0x4D,0xCE,0xF9,0x7C,0x2A,0x24, + 0x85,0x5E,0x6E,0xEB,0x22,0xB3,0xB2,0xE5 +}; + +static DH *get_dh1024() +{ + DH *dh = q_DH_new(); + if (!dh) + return 0; + + dh->p = q_BN_bin2bn(dh1024_p, sizeof(dh1024_p), 0); + dh->g = q_BN_bin2bn(dh1024_g, sizeof(dh1024_g), 0); + if (!dh->p || !dh->g) { + q_DH_free(dh); + return 0; + } + + return dh; +} + QSslContext::QSslContext() : ctx(0), pkey(0), @@ -261,6 +308,18 @@ init_context: if (!configuration.sessionTicket().isEmpty()) sslContext->setSessionASN1(configuration.sessionTicket()); + // Set temp DH params + DH *dh = 0; + dh = get_dh1024(); + q_SSL_CTX_set_tmp_dh(sslContext->ctx, dh); + q_DH_free(dh); + + // Set temp ECDH params + EC_KEY *ecdh = 0; + ecdh = q_EC_KEY_new_by_curve_name(NID_X9_62_prime256v1); + q_SSL_CTX_set_tmp_ecdh(sslContext->ctx, ecdh); + q_EC_KEY_free(ecdh); + return sslContext; } diff --git a/src/network/ssl/qsslsocket_openssl_symbols.cpp b/src/network/ssl/qsslsocket_openssl_symbols.cpp index 79bce22b0d..01c0f6f810 100644 --- a/src/network/ssl/qsslsocket_openssl_symbols.cpp +++ b/src/network/ssl/qsslsocket_openssl_symbols.cpp @@ -361,6 +361,11 @@ DEFINEFUNC3(void, SSL_CTX_set_next_proto_select_cb, SSL_CTX *s, s, DEFINEFUNC3(void, SSL_get0_next_proto_negotiated, const SSL *s, s, const unsigned char **data, data, unsigned *len, len, return, DUMMYARG) #endif // OPENSSL_VERSION_NUMBER >= 0x1000100fL ... +DEFINEFUNC(DH *, DH_new, DUMMYARG, DUMMYARG, return 0, return) +DEFINEFUNC(void, DH_free, DH *dh, dh, return, DUMMYARG) +DEFINEFUNC3(BIGNUM *, BN_bin2bn, const unsigned char *s, s, int len, len, BIGNUM *ret, ret, return 0, return) +DEFINEFUNC(EC_KEY *, EC_KEY_new_by_curve_name, int nid, nid, return 0, return) +DEFINEFUNC(void, EC_KEY_free, EC_KEY *ecdh, ecdh, return, DUMMYARG) #define RESOLVEFUNC(func) \ if (!(_q_##func = _q_PTR_##func(libs.first->resolve(#func))) \ @@ -835,6 +840,11 @@ bool q_resolveOpenSslSymbols() RESOLVEFUNC(SSL_CTX_set_next_proto_select_cb) RESOLVEFUNC(SSL_get0_next_proto_negotiated) #endif // OPENSSL_VERSION_NUMBER >= 0x1000100fL ... + RESOLVEFUNC(DH_new) + RESOLVEFUNC(DH_free) + RESOLVEFUNC(BN_bin2bn) + RESOLVEFUNC(EC_KEY_new_by_curve_name) + RESOLVEFUNC(EC_KEY_free) symbolsResolved = true; delete libs.first; diff --git a/src/network/ssl/qsslsocket_openssl_symbols_p.h b/src/network/ssl/qsslsocket_openssl_symbols_p.h index 500fe9493b..1e68fdd6c2 100644 --- a/src/network/ssl/qsslsocket_openssl_symbols_p.h +++ b/src/network/ssl/qsslsocket_openssl_symbols_p.h @@ -427,6 +427,17 @@ int q_X509_STORE_CTX_get_error_depth(X509_STORE_CTX *ctx); X509 *q_X509_STORE_CTX_get_current_cert(X509_STORE_CTX *ctx); STACK_OF(X509) *q_X509_STORE_CTX_get_chain(X509_STORE_CTX *ctx); +// Diffie-Hellman support +DH *q_DH_new(); +void q_DH_free(DH *dh); +BIGNUM *q_BN_bin2bn(const unsigned char *s, int len, BIGNUM *ret); +#define q_SSL_CTX_set_tmp_dh(ctx, dh) q_SSL_CTX_ctrl((ctx), SSL_CTRL_SET_TMP_DH, 0, (char *)dh) + +// EC Diffie-Hellman support +EC_KEY *q_EC_KEY_new_by_curve_name(int nid); +void q_EC_KEY_free(EC_KEY *ecdh); +#define q_SSL_CTX_set_tmp_ecdh(ctx, ecdh) q_SSL_CTX_ctrl((ctx), SSL_CTRL_SET_TMP_ECDH, 0, (char *)ecdh) + #define q_BIO_get_mem_data(b, pp) (int)q_BIO_ctrl(b,BIO_CTRL_INFO,0,(char *)pp) #define q_BIO_pending(b) (int)q_BIO_ctrl(b,BIO_CTRL_PENDING,0,NULL) #ifdef SSLEAY_MACROS -- cgit v1.2.3