diff options
author | Peter Hartmann <peter-qt@hartmann.tk> | 2015-02-05 14:05:21 +0100 |
---|---|---|
committer | Peter Hartmann <peter-qt@hartmann.tk> | 2015-02-05 14:07:19 +0000 |
commit | 3c24dddaf963026c6e3cd90dd7d538dfa8044c83 (patch) | |
tree | 3756fa437205bb55b9d3ce1df7171fb1d9d7ffe5 /src/network | |
parent | 239f67f158c55d3eb88348a53b87fa272402c733 (diff) |
SSL NPN negotiation: Do not abort on unmatched protocols
... but choose HTTP/1.1 and continue connecting anyhow. According to
the NPN spec, actually we should choose SPDY:
"In the event that the client doesn't support any of server's protocols,
or the server doesn't advertise any, it SHOULD select the first protocol
that it supports."
However, some tested servers did not advertise anything and did not
support SPDY, so blindly trying the newest protocol would fail. We are
conservative in that case and choose HTTP.
Task-number: QTBUG-40714
Change-Id: Ia8aaf01fea74e13d9e4416306f85f1890b25559e
Reviewed-by: Richard J. Moore <rich@kde.org>
Diffstat (limited to 'src/network')
-rw-r--r-- | src/network/access/qhttpnetworkconnectionchannel.cpp | 7 | ||||
-rw-r--r-- | src/network/ssl/qsslsocket_openssl.cpp | 20 |
2 files changed, 15 insertions, 12 deletions
diff --git a/src/network/access/qhttpnetworkconnectionchannel.cpp b/src/network/access/qhttpnetworkconnectionchannel.cpp index d24fb159e2..9f63280bf8 100644 --- a/src/network/access/qhttpnetworkconnectionchannel.cpp +++ b/src/network/access/qhttpnetworkconnectionchannel.cpp @@ -931,7 +931,8 @@ void QHttpNetworkConnectionChannel::_q_encrypted() if (!protocolHandler) { switch (sslSocket->sslConfiguration().nextProtocolNegotiationStatus()) { - case QSslConfiguration::NextProtocolNegotiationNegotiated: { + case QSslConfiguration::NextProtocolNegotiationNegotiated: /* fall through */ + case QSslConfiguration::NextProtocolNegotiationUnsupported: { QByteArray nextProtocol = sslSocket->sslConfiguration().nextNegotiatedProtocol(); if (nextProtocol == QSslConfiguration::NextProtocolHttp1_1) { // fall through to create a QHttpProtocolHandler @@ -953,10 +954,6 @@ void QHttpNetworkConnectionChannel::_q_encrypted() // re-queue requests from SPDY queue to HTTP queue, if any requeueSpdyRequests(); break; - case QSslConfiguration::NextProtocolNegotiationUnsupported: - emitFinishedWithError(QNetworkReply::SslHandshakeFailedError, - "chosen Next Protocol Negotiation value unsupported"); - break; default: emitFinishedWithError(QNetworkReply::SslHandshakeFailedError, "detected unknown Next Protocol Negotiation protocol"); diff --git a/src/network/ssl/qsslsocket_openssl.cpp b/src/network/ssl/qsslsocket_openssl.cpp index 8833e3fdd8..0e1a3e53c9 100644 --- a/src/network/ssl/qsslsocket_openssl.cpp +++ b/src/network/ssl/qsslsocket_openssl.cpp @@ -1518,14 +1518,20 @@ void QSslSocketBackendPrivate::continueHandshake() } #if OPENSSL_VERSION_NUMBER >= 0x1000100fL && !defined(OPENSSL_NO_TLSEXT) && !defined(OPENSSL_NO_NEXTPROTONEG) - const unsigned char *proto = 0; - unsigned int proto_len = 0; - q_SSL_get0_next_proto_negotiated(ssl, &proto, &proto_len); - if (proto_len) - configuration.nextNegotiatedProtocol = QByteArray(reinterpret_cast<const char *>(proto), proto_len); - else - configuration.nextNegotiatedProtocol.clear(); + configuration.nextProtocolNegotiationStatus = sslContextPointer->npnContext().status; + if (sslContextPointer->npnContext().status == QSslConfiguration::NextProtocolNegotiationUnsupported) { + // we could not agree -> be conservative and use HTTP/1.1 + configuration.nextNegotiatedProtocol = QByteArrayLiteral("http/1.1"); + } else { + const unsigned char *proto = 0; + unsigned int proto_len = 0; + q_SSL_get0_next_proto_negotiated(ssl, &proto, &proto_len); + if (proto_len) + configuration.nextNegotiatedProtocol = QByteArray(reinterpret_cast<const char *>(proto), proto_len); + else + configuration.nextNegotiatedProtocol.clear(); + } #endif // OPENSSL_VERSION_NUMBER >= 0x1000100fL ... connectionEncrypted = true; |