QSslSocket::transmit (macOS/iOS) - do not use invalid context
1. QSslSocketBackendPrivate::transmit can invalidate SSL context causing subsequent SSLWrite or SSLRead calls to fail; these report errSecParam (as null context is an invalid parameter) spuriously, when we should rather report the cause of invalidation. The OpenSSL backend can trigger this when it aborts connection during an SSL handshake, on an sslErrors signal. As transmit() emits readReady(), a directly connected slot can trigger the same problem if it aborts or closes. 2. If during peer verification (and in checkSslErrors) we disconnect on sslErrors signal, peer verification must be considered failed and should not continue handshake/set connectionEncrypted. Task-number: QTBUG-52975 Task-number: QTBUG-53906 Change-Id: Iacd3b489a4156e25ef3460ace40d21f34a946bed Reviewed-by: Edward Welbourne <edward.welbourne@qt.io>
This commit is contained in:
parent
7a8330ddf7
commit
faeaddc1b9
@ -634,7 +634,7 @@ void QSslSocketBackendPrivate::transmit()
|
||||
|
||||
if (connectionEncrypted && !writeBuffer.isEmpty()) {
|
||||
qint64 totalBytesWritten = 0;
|
||||
while (writeBuffer.nextDataBlockSize() > 0) {
|
||||
while (writeBuffer.nextDataBlockSize() > 0 && context) {
|
||||
const size_t nextDataBlockSize = writeBuffer.nextDataBlockSize();
|
||||
size_t writtenBytes = 0;
|
||||
const OSStatus err = SSLWrite(context, writeBuffer.readPointer(), nextDataBlockSize, &writtenBytes);
|
||||
@ -668,7 +668,7 @@ void QSslSocketBackendPrivate::transmit()
|
||||
|
||||
if (connectionEncrypted) {
|
||||
QVarLengthArray<char, 4096> data;
|
||||
while (true) {
|
||||
while (context) {
|
||||
size_t readBytes = 0;
|
||||
data.resize(4096);
|
||||
const OSStatus err = SSLRead(context, data.data(), data.size(), &readBytes);
|
||||
@ -1305,7 +1305,10 @@ bool QSslSocketBackendPrivate::verifyPeerTrust()
|
||||
// report errors
|
||||
if (!errors.isEmpty() && !canIgnoreVerify) {
|
||||
sslErrors = errors;
|
||||
if (!checkSslErrors())
|
||||
// checkSslErrors unconditionally emits sslErrors:
|
||||
// a user's slot can abort/close/disconnect on this
|
||||
// signal, so we also test the socket's state:
|
||||
if (!checkSslErrors() || q->state() != QAbstractSocket::ConnectedState)
|
||||
return false;
|
||||
} else {
|
||||
sslErrors.clear();
|
||||
|
Loading…
Reference in New Issue
Block a user