diff options
author | Timur Pocheptsov <Timur.Pocheptsov@digia.com> | 2015-03-02 17:29:55 +0100 |
---|---|---|
committer | Timur Pocheptsov <Timur.Pocheptsov@digia.com> | 2015-03-12 13:32:23 +0000 |
commit | 53207e820c894a1408aa77aa2237cc664eabc119 (patch) | |
tree | ecd8dfd2ae0f9c0a049f47995d0b36f5d251746a /src/network | |
parent | fd6a2d1c8ff0488757378080f6003c434fd68de2 (diff) |
Secure Transport - handle errSSLBadCert in server mode
Suddenly :(( With Security Framework v 7.0 dated by 17/02 SSLHandshake
works differently when our server socket is requesting a client side authentication
and client provides no certificate. Despite of kTryAuthenticate (this means,
auth. _can_ fail) server receives an error from SSLHandshake too early.
We have to handle this in startHandshake (when serveMode && canIgnore).
Change-Id: Ie55540078e2944e80cf2f4ade8b000acf29d6ca2
Reviewed-by: Richard J. Moore <rich@kde.org>
Diffstat (limited to 'src/network')
-rw-r--r-- | src/network/ssl/qsslsocket_mac.cpp | 21 | ||||
-rw-r--r-- | src/network/ssl/qsslsocket_mac_p.h | 1 |
2 files changed, 18 insertions, 4 deletions
diff --git a/src/network/ssl/qsslsocket_mac.cpp b/src/network/ssl/qsslsocket_mac.cpp index 3326362d66..e833bb70c5 100644 --- a/src/network/ssl/qsslsocket_mac.cpp +++ b/src/network/ssl/qsslsocket_mac.cpp @@ -942,6 +942,15 @@ bool QSslSocketBackendPrivate::setSessionProtocol() return err == noErr; } +bool QSslSocketBackendPrivate::canIgnoreTrustVerificationFailure() const +{ + const QSslSocket::PeerVerifyMode verifyMode = configuration.peerVerifyMode; + return mode == QSslSocket::SslServerMode + && (verifyMode == QSslSocket::QueryPeer + || verifyMode == QSslSocket::AutoVerifyPeer + || verifyMode == QSslSocket::VerifyNone); +} + bool QSslSocketBackendPrivate::verifySessionProtocol() const { bool protocolOk = false; @@ -962,10 +971,7 @@ bool QSslSocketBackendPrivate::verifyPeerTrust() Q_Q(QSslSocket); const QSslSocket::PeerVerifyMode verifyMode = configuration.peerVerifyMode; - const bool canIgnoreVerify = mode == QSslSocket::SslServerMode - && (verifyMode == QSslSocket::QueryPeer - || verifyMode == QSslSocket::AutoVerifyPeer - || verifyMode == QSslSocket::VerifyNone); + const bool canIgnoreVerify = canIgnoreTrustVerificationFailure(); Q_ASSERT_X(context, Q_FUNC_INFO, "invalid SSL context (null)"); Q_ASSERT(plainSocket); @@ -1164,6 +1170,13 @@ bool QSslSocketBackendPrivate::startHandshake() return startHandshake(); } } else if (err != errSecSuccess) { + if (err == errSSLBadCert && canIgnoreTrustVerificationFailure()) { + // We're on the server side and client did not provide any + // certificate. This is the new 'nice' error returned by + // Security Framework after it was recently updated. + return startHandshake(); + } + setError(QStringLiteral("Error during SSL handshake: %1").arg(err), QAbstractSocket::SslHandshakeFailedError); plainSocket->disconnectFromHost(); diff --git a/src/network/ssl/qsslsocket_mac_p.h b/src/network/ssl/qsslsocket_mac_p.h index 4901a8576f..868b816957 100644 --- a/src/network/ssl/qsslsocket_mac_p.h +++ b/src/network/ssl/qsslsocket_mac_p.h @@ -94,6 +94,7 @@ private: QAbstractSocket::SocketError &errorCode); bool setSessionProtocol(); // Aux. functions to do a verification during handshake phase: + bool canIgnoreTrustVerificationFailure() const; bool verifySessionProtocol() const; bool verifyPeerTrust(); |