From 28a08434c67df1eb72efa28c9587467771a4303b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?G=C3=BCnter=20Obiltschnig?= Date: Sun, 24 Nov 2024 16:59:40 +0100 Subject: [PATCH] chore(NetSSL_Win): use state machine also for blocking connections; fix non-blocking renegotiation --- .../include/Poco/Net/SecureSocketImpl.h | 6 +- NetSSL_Win/src/SecureSocketImpl.cpp | 115 ++++-------------- 2 files changed, 26 insertions(+), 95 deletions(-) diff --git a/NetSSL_Win/include/Poco/Net/SecureSocketImpl.h b/NetSSL_Win/include/Poco/Net/SecureSocketImpl.h index 6a52239dc..7eeedcef0 100644 --- a/NetSSL_Win/include/Poco/Net/SecureSocketImpl.h +++ b/NetSSL_Win/include/Poco/Net/SecureSocketImpl.h @@ -281,9 +281,7 @@ protected: void performClientHandshakeSendError(); void sendOutSecBufferAndAdvanceState(State state); - void performClientHandshake(); - SECURITY_STATUS performClientHandshakeLoop(); - void performClientHandshakeLoopCondReceive(); + SECURITY_STATUS performClientHandshake(); SECURITY_STATUS decodeMessage(BYTE* pBuffer, DWORD bufSize, AutoSecBufferDesc<4>& msg, SecBuffer*& pData, SecBuffer*& pExtra); SECURITY_STATUS decodeBufferFull(BYTE* pBuffer, DWORD bufSize, char* pOutBuffer, int outLength, int& bytesDecoded); @@ -293,7 +291,7 @@ protected: void connectSSL(bool completeHandshake); void completeHandshake(); static int lastError(); - void stateMachine(); + bool stateMachine(); State getState() const; void setState(State st); static bool isLocalHost(const std::string& hostName); diff --git a/NetSSL_Win/src/SecureSocketImpl.cpp b/NetSSL_Win/src/SecureSocketImpl.cpp index ee861e8f4..f4510acc8 100644 --- a/NetSSL_Win/src/SecureSocketImpl.cpp +++ b/NetSSL_Win/src/SecureSocketImpl.cpp @@ -372,17 +372,16 @@ int SecureSocketImpl::sendBytes(const void* buffer, int length, int flags) if (_state != ST_DONE) { - bool establish = _pSocket->getBlocking(); - if (establish) + if (_pSocket->getBlocking()) { - while (_state != ST_DONE) - { - stateMachine(); - } + performClientHandshake(); } else { - stateMachine(); + while (_state != ST_DONE && stateMachine()) + { + // no-op + } if (_state != ST_DONE) return -1; } } @@ -470,17 +469,16 @@ int SecureSocketImpl::receiveBytes(void* buffer, int length, int flags) if (_state == ST_ERROR) return 0; if (_state != ST_DONE) { - bool establish = _pSocket->getBlocking(); - if (establish) + if (_pSocket->getBlocking()) { - while (_state != ST_DONE) - { - stateMachine(); - } + performClientHandshake(); } else { - stateMachine(); + while (_state != ST_DONE && stateMachine()) + { + // no-op + } if (_state != ST_DONE) return -1; } } @@ -591,9 +589,9 @@ int SecureSocketImpl::receiveBytes(void* buffer, int length, int flags) _needData = false; setState(ST_CLIENT_HSK_LOOP_INIT); if (!_pSocket->getBlocking()) - return -1; + return bytesDecoded > 0 ? bytesDecoded : -1; - securityStatus = performClientHandshakeLoop(); + securityStatus = performClientHandshake(); if (securityStatus != SEC_E_OK) break; @@ -725,9 +723,7 @@ SECURITY_STATUS SecureSocketImpl::decodeBufferFull(BYTE* pBuffer, DWORD bufSize, if (securityStatus == SEC_I_RENEGOTIATE) { _needData = false; - securityStatus = performClientHandshakeLoop(); - if (securityStatus != SEC_E_OK) - break; + return securityStatus; } } while (securityStatus == SEC_E_OK && pBuffer); @@ -782,7 +778,7 @@ void SecureSocketImpl::connectSSL(bool completeHandshake) _peerHostName = _pSocket->peerAddress().host().toString(); } - initClientContext(); + setState(ST_CONNECTING); if (completeHandshake) { performClientHandshake(); @@ -843,12 +839,13 @@ void SecureSocketImpl::initClientContext() } -void SecureSocketImpl::performClientHandshake() +SECURITY_STATUS SecureSocketImpl::performClientHandshake() { - performInitialClientHandshake(); - performClientHandshakeSendToken(); - performClientHandshakeLoop(); - clientConnectVerify(); + while (_state != ST_DONE) + { + stateMachine(); + } + return _securityStatus; } @@ -934,55 +931,6 @@ void SecureSocketImpl::performClientHandshakeSendToken() } -SECURITY_STATUS SecureSocketImpl::performClientHandshakeLoop() -{ - _recvBufferOffset = 0; - _securityStatus = SEC_E_INCOMPLETE_MESSAGE; - - while (_securityStatus == SEC_I_CONTINUE_NEEDED || _securityStatus == SEC_E_INCOMPLETE_MESSAGE || _securityStatus == SEC_I_INCOMPLETE_CREDENTIALS) - { - performClientHandshakeLoopCondReceive(); - - if (_securityStatus == SEC_E_OK) - { - performClientHandshakeLoopDone(); - performClientHandshakeSendFinal(); - } - else if (_securityStatus == SEC_I_CONTINUE_NEEDED) - { - performClientHandshakeLoopContinue(); - performClientHandshakeLoopSend(); - } - else if (_securityStatus == SEC_E_INCOMPLETE_MESSAGE) - { - performClientHandshakeLoopIncompleteMessage(); - } - else if (FAILED(_securityStatus)) - { - if (_outFlags & ISC_RET_EXTENDED_ERROR) - { - performClientHandshakeSendError(); - } - else - { - performClientHandshakeError(); - } - } - else - { - performClientHandshakeLoopIncompleteMessage(); - } - } - - if (FAILED(_securityStatus)) - { - performClientHandshakeError(); - } - - return _securityStatus; -} - - void SecureSocketImpl::performClientHandshakeSendError() { poco_assert_dbg (FAILED(_securityStatus)); @@ -1117,21 +1065,6 @@ void SecureSocketImpl::performClientHandshakeLoopProcess() } -void SecureSocketImpl::performClientHandshakeLoopCondReceive() -{ - poco_assert_dbg (_securityStatus == SEC_E_INCOMPLETE_MESSAGE || SEC_I_CONTINUE_NEEDED); - - performClientHandshakeLoopInit(); - - if (_state == ST_CLIENT_HSK_LOOP_RECV) - { - performClientHandshakeLoopRecv(); - } - - performClientHandshakeLoopProcess(); -} - - void SecureSocketImpl::performClientHandshakeLoopContinue() { performClientHandshakeExtraBuffer(); @@ -1682,9 +1615,9 @@ void SecureSocketImpl::performClientHandshakeStart() } -void SecureSocketImpl::stateMachine() +bool SecureSocketImpl::stateMachine() { - StateMachine::instance().execute(this); + return StateMachine::instance().execute(this); }