summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorTimur Pocheptsov <Timur.Pocheptsov@digia.com>2015-03-02 17:29:55 +0100
committerTimur Pocheptsov <Timur.Pocheptsov@digia.com>2015-03-12 13:32:23 +0000
commit53207e820c894a1408aa77aa2237cc664eabc119 (patch)
treeecd8dfd2ae0f9c0a049f47995d0b36f5d251746a /src
parentfd6a2d1c8ff0488757378080f6003c434fd68de2 (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')
-rw-r--r--src/network/ssl/qsslsocket_mac.cpp21
-rw-r--r--src/network/ssl/qsslsocket_mac_p.h1
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();