chore(NetSSL_Win): use state machine also for blocking connections; fix non-blocking renegotiation

This commit is contained in:
Günter Obiltschnig 2024-11-24 16:59:40 +01:00
parent 3c1c92ce50
commit 34852d1c62
2 changed files with 26 additions and 95 deletions

View File

@ -281,9 +281,7 @@ protected:
void performClientHandshakeSendError(); void performClientHandshakeSendError();
void sendOutSecBufferAndAdvanceState(State state); void sendOutSecBufferAndAdvanceState(State state);
void performClientHandshake(); SECURITY_STATUS performClientHandshake();
SECURITY_STATUS performClientHandshakeLoop();
void performClientHandshakeLoopCondReceive();
SECURITY_STATUS decodeMessage(BYTE* pBuffer, DWORD bufSize, AutoSecBufferDesc<4>& msg, SecBuffer*& pData, SecBuffer*& pExtra); 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); SECURITY_STATUS decodeBufferFull(BYTE* pBuffer, DWORD bufSize, char* pOutBuffer, int outLength, int& bytesDecoded);
@ -293,7 +291,7 @@ protected:
void connectSSL(bool completeHandshake); void connectSSL(bool completeHandshake);
void completeHandshake(); void completeHandshake();
static int lastError(); static int lastError();
void stateMachine(); bool stateMachine();
State getState() const; State getState() const;
void setState(State st); void setState(State st);
static bool isLocalHost(const std::string& hostName); static bool isLocalHost(const std::string& hostName);

View File

@ -372,17 +372,16 @@ int SecureSocketImpl::sendBytes(const void* buffer, int length, int flags)
if (_state != ST_DONE) if (_state != ST_DONE)
{ {
bool establish = _pSocket->getBlocking(); if (_pSocket->getBlocking())
if (establish)
{ {
while (_state != ST_DONE) performClientHandshake();
{
stateMachine();
}
} }
else else
{ {
stateMachine(); while (_state != ST_DONE && stateMachine())
{
// no-op
}
if (_state != ST_DONE) return -1; 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_ERROR) return 0;
if (_state != ST_DONE) if (_state != ST_DONE)
{ {
bool establish = _pSocket->getBlocking(); if (_pSocket->getBlocking())
if (establish)
{ {
while (_state != ST_DONE) performClientHandshake();
{
stateMachine();
}
} }
else else
{ {
stateMachine(); while (_state != ST_DONE && stateMachine())
{
// no-op
}
if (_state != ST_DONE) return -1; if (_state != ST_DONE) return -1;
} }
} }
@ -591,9 +589,9 @@ int SecureSocketImpl::receiveBytes(void* buffer, int length, int flags)
_needData = false; _needData = false;
setState(ST_CLIENT_HSK_LOOP_INIT); setState(ST_CLIENT_HSK_LOOP_INIT);
if (!_pSocket->getBlocking()) if (!_pSocket->getBlocking())
return -1; return bytesDecoded > 0 ? bytesDecoded : -1;
securityStatus = performClientHandshakeLoop(); securityStatus = performClientHandshake();
if (securityStatus != SEC_E_OK) if (securityStatus != SEC_E_OK)
break; break;
@ -725,9 +723,7 @@ SECURITY_STATUS SecureSocketImpl::decodeBufferFull(BYTE* pBuffer, DWORD bufSize,
if (securityStatus == SEC_I_RENEGOTIATE) if (securityStatus == SEC_I_RENEGOTIATE)
{ {
_needData = false; _needData = false;
securityStatus = performClientHandshakeLoop(); return securityStatus;
if (securityStatus != SEC_E_OK)
break;
} }
} }
while (securityStatus == SEC_E_OK && pBuffer); while (securityStatus == SEC_E_OK && pBuffer);
@ -782,7 +778,7 @@ void SecureSocketImpl::connectSSL(bool completeHandshake)
_peerHostName = _pSocket->peerAddress().host().toString(); _peerHostName = _pSocket->peerAddress().host().toString();
} }
initClientContext(); setState(ST_CONNECTING);
if (completeHandshake) if (completeHandshake)
{ {
performClientHandshake(); performClientHandshake();
@ -843,12 +839,13 @@ void SecureSocketImpl::initClientContext()
} }
void SecureSocketImpl::performClientHandshake() SECURITY_STATUS SecureSocketImpl::performClientHandshake()
{ {
performInitialClientHandshake(); while (_state != ST_DONE)
performClientHandshakeSendToken(); {
performClientHandshakeLoop(); stateMachine();
clientConnectVerify(); }
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() void SecureSocketImpl::performClientHandshakeSendError()
{ {
poco_assert_dbg (FAILED(_securityStatus)); 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() void SecureSocketImpl::performClientHandshakeLoopContinue()
{ {
performClientHandshakeExtraBuffer(); performClientHandshakeExtraBuffer();
@ -1682,9 +1615,9 @@ void SecureSocketImpl::performClientHandshakeStart()
} }
void SecureSocketImpl::stateMachine() bool SecureSocketImpl::stateMachine()
{ {
StateMachine::instance().execute(this); return StateMachine::instance().execute(this);
} }