summaryrefslogtreecommitdiffstats
path: root/src/network/ssl/qsslsocket_schannel.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/network/ssl/qsslsocket_schannel.cpp')
-rw-r--r--src/network/ssl/qsslsocket_schannel.cpp32
1 files changed, 32 insertions, 0 deletions
diff --git a/src/network/ssl/qsslsocket_schannel.cpp b/src/network/ssl/qsslsocket_schannel.cpp
index 3166cda4c9..78d807106b 100644
--- a/src/network/ssl/qsslsocket_schannel.cpp
+++ b/src/network/ssl/qsslsocket_schannel.cpp
@@ -467,6 +467,17 @@ void retainExtraData(QByteArray &buffer, const SecBuffer &secBuffer)
buffer.resize(secBuffer.cbBuffer);
}
+qint64 checkIncompleteData(const SecBuffer &secBuffer)
+{
+ if (secBuffer.BufferType == SECBUFFER_MISSING) {
+#ifdef QSSLSOCKET_DEBUG
+ qCDebug(lcSsl, "Need %lu more bytes.", secBuffer.cbBuffer);
+#endif
+ return secBuffer.cbBuffer;
+}
+ return 0;
+}
+
} // anonymous namespace
bool QSslSocketPrivate::s_loadRootCertsOnDemand = true;
@@ -810,6 +821,10 @@ bool QSslSocketBackendPrivate::acceptContext()
Q_ASSERT(mode == QSslSocket::SslServerMode);
ULONG contextReq = getContextRequirements();
+ if (missingData > plainSocket->bytesAvailable())
+ return true;
+
+ missingData = 0;
readToBuffer(intermediateBuffer, plainSocket);
if (intermediateBuffer.isEmpty())
return true; // definitely need more data..
@@ -866,6 +881,7 @@ bool QSslSocketBackendPrivate::acceptContext()
if (status == SEC_E_INCOMPLETE_MESSAGE) {
// Need more data
+ missingData = checkIncompleteData(outBuffers[0]);
return true;
}
@@ -905,6 +921,10 @@ bool QSslSocketBackendPrivate::performHandshake()
qCDebug(lcSsl, "intermediateBuffer size: %d", intermediateBuffer.size());
#endif
+ if (missingData > plainSocket->bytesAvailable())
+ return true;
+
+ missingData = 0;
readToBuffer(intermediateBuffer, plainSocket);
if (intermediateBuffer.isEmpty())
return true; // no data, will fail
@@ -990,6 +1010,7 @@ bool QSslSocketBackendPrivate::performHandshake()
return true;
case SEC_E_INCOMPLETE_MESSAGE:
// Simply incomplete, wait for more data
+ missingData = checkIncompleteData(outBuffers[0]);
return true;
case SEC_E_ALGORITHM_MISMATCH:
setErrorAndEmit(QAbstractSocket::SslHandshakeFailedError,
@@ -1192,6 +1213,8 @@ void QSslSocketBackendPrivate::reset()
connectionEncrypted = false;
shutdown = false;
renegotiating = false;
+
+ missingData = 0;
}
void QSslSocketBackendPrivate::startClientEncryption()
@@ -1288,6 +1311,14 @@ void QSslSocketBackendPrivate::transmit()
int totalRead = 0;
bool hadIncompleteData = false;
while (!readBufferMaxSize || buffer.size() < readBufferMaxSize) {
+ if (missingData > plainSocket->bytesAvailable()) {
+#ifdef QSSLSOCKET_DEBUG
+ qCDebug(lcSsl, "We're still missing %lld bytes, will check later.", missingData);
+#endif
+ break;
+ }
+
+ missingData = 0;
const qint64 bytesRead = readToBuffer(intermediateBuffer, plainSocket);
#ifdef QSSLSOCKET_DEBUG
qCDebug(lcSsl, "Read %lld encrypted bytes from the socket", bytesRead);
@@ -1341,6 +1372,7 @@ void QSslSocketBackendPrivate::transmit()
}
if (status == SEC_E_INCOMPLETE_MESSAGE) {
+ missingData = checkIncompleteData(dataBuffer[0]);
#ifdef QSSLSOCKET_DEBUG
qCDebug(lcSsl, "We didn't have enough data to decrypt anything, will try again!");
#endif