chore(NetSSL_Win): refactored state machine (wip)

This commit is contained in:
Günter Obiltschnig 2024-11-24 15:22:17 +01:00
parent 5402032249
commit f1bb63a1f2
2 changed files with 219 additions and 144 deletions

View File

@ -224,16 +224,23 @@ protected:
enum State enum State
{ {
ST_INITIAL = 0, ST_INITIAL = 0,
// Client
ST_CONNECTING, ST_CONNECTING,
ST_CLIENTHANDSHAKESTART, ST_CLIENT_HSK_START,
ST_CLIENTHANDSHAKECONDREAD, ST_CLIENT_HSK_SEND_TOKEN,
ST_CLIENTHANDSHAKEINCOMPLETE, ST_CLIENT_HSK_LOOP_INIT,
ST_CLIENTHANDSHAKEOK, ST_CLIENT_HSK_LOOP_RECV,
ST_CLIENTHANDSHAKEEXTERROR, ST_CLIENT_HSK_LOOP_PROCESS,
ST_CLIENTHANDSHAKECONTINUE, ST_CLIENT_HSK_LOOP_CONTINUE,
ST_VERIFY, ST_CLIENT_HSK_LOOP_SEND,
ST_CLIENT_HSK_LOOP_INCOMPLETE,
ST_CLIENT_HSK_LOOP_DONE,
ST_CLIENT_HSK_SEND_FINAL,
ST_CLIENT_HSK_SEND_ERROR,
ST_CLIENT_VERIFY,
ST_DONE, ST_DONE,
ST_ERROR ST_ERROR,
ST_MAX
}; };
enum TLSShutdown enum TLSShutdown
@ -245,7 +252,6 @@ protected:
int sendRawBytes(const void* buffer, int length, int flags = 0); int sendRawBytes(const void* buffer, int length, int flags = 0);
int receiveRawBytes(void* buffer, int length, int flags = 0); int receiveRawBytes(void* buffer, int length, int flags = 0);
void clientConnectVerify(); void clientConnectVerify();
void sendInitialTokenOutBuffer();
void performServerHandshake(); void performServerHandshake();
bool serverHandshakeLoop(PCtxtHandle phContext, PCredHandle phCred, bool requireClientAuth, bool doInitialRead, bool newContext); bool serverHandshakeLoop(PCtxtHandle phContext, PCredHandle phCred, bool requireClientAuth, bool doInitialRead, bool newContext);
void clientVerifyCertificate(const std::string& hostName); void clientVerifyCertificate(const std::string& hostName);
@ -253,25 +259,32 @@ protected:
void serverVerifyCertificate(); void serverVerifyCertificate();
int serverShutdown(PCredHandle phCreds, CtxtHandle* phContext); int serverShutdown(PCredHandle phCreds, CtxtHandle* phContext);
int clientShutdown(PCredHandle phCreds, CtxtHandle* phContext); int clientShutdown(PCredHandle phCreds, CtxtHandle* phContext);
bool loadSecurityLibrary();
void initClientContext(); void initClientContext();
void initServerContext(); void initServerContext();
PCCERT_CONTEXT loadCertificate(bool mustFindCertificate); PCCERT_CONTEXT loadCertificate(bool mustFindCertificate);
void initCommon(); void initCommon();
void cleanup(); void cleanup();
void performClientHandshake();
void performClientHandshakeStart();
void performInitialClientHandshake(); void performInitialClientHandshake();
SECURITY_STATUS performClientHandshakeLoop(); void performClientHandshakeSendToken();
void performClientHandshakeLoopIncompleteMessage(); void performClientHandshakeLoopIncompleteMessage();
void performClientHandshakeLoopCondReceive();
void performClientHandshakeLoopReceive();
void performClientHandshakeLoopOK();
void performClientHandshakeLoopInit(); void performClientHandshakeLoopInit();
void performClientHandshakeLoopRecv();
void performClientHandshakeLoopProcess();
void performClientHandshakeLoopSend();
void performClientHandshakeLoopDone();
void performClientHandshakeSendFinal();
void performClientHandshakeExtraBuffer(); void performClientHandshakeExtraBuffer();
void performClientHandshakeSendOutBuffer(); void performClientHandshakeLoopContinue();
void performClientHandshakeLoopContinueNeeded(); void performClientHandshakeError();
void performClientHandshakeLoopError(); void performClientHandshakeSendError();
void performClientHandshakeLoopExtError(); void sendOutSecBufferAndAdvanceState(State state);
void 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);
void stateIllegal(); void stateIllegal();

View File

@ -47,7 +47,7 @@ public:
bool none(SOCKET sockfd); bool none(SOCKET sockfd);
void select(fd_set* fdRead, fd_set* fdWrite, SOCKET sockfd); void select(fd_set* fdRead, fd_set* fdWrite, SOCKET sockfd);
void execute(SecureSocketImpl* pSock); bool execute(SecureSocketImpl* pSock);
private: private:
StateMachine(const StateMachine&); StateMachine(const StateMachine&);
@ -192,19 +192,19 @@ SocketImpl* SecureSocketImpl::acceptConnection(SocketAddress& clientAddr)
void SecureSocketImpl::connect(const SocketAddress& address, bool performHandshake) void SecureSocketImpl::connect(const SocketAddress& address, bool performHandshake)
{ {
_state = ST_ERROR; setState(ST_ERROR);
_pSocket->connect(address); _pSocket->connect(address);
connectSSL(performHandshake); connectSSL(performHandshake);
_state = ST_DONE; setState(ST_DONE);
} }
void SecureSocketImpl::connect(const SocketAddress& address, const Poco::Timespan& timeout, bool performHandshake) void SecureSocketImpl::connect(const SocketAddress& address, const Poco::Timespan& timeout, bool performHandshake)
{ {
_state = ST_ERROR; setState(ST_ERROR);
_pSocket->connect(address, timeout); _pSocket->connect(address, timeout);
connectSSL(performHandshake); connectSSL(performHandshake);
_state = ST_DONE; setState(ST_DONE);
} }
@ -212,12 +212,12 @@ void SecureSocketImpl::connectNB(const SocketAddress& address)
{ {
try try
{ {
_state = ST_CONNECTING; setState(ST_CONNECTING);
_pSocket->connectNB(address); _pSocket->connectNB(address);
} }
catch (...) catch (...)
{ {
_state = ST_ERROR; setState(ST_ERROR);
} }
} }
@ -318,7 +318,7 @@ int SecureSocketImpl::available() const
void SecureSocketImpl::acceptSSL() void SecureSocketImpl::acceptSSL()
{ {
_state = ST_DONE; setState(ST_DONE);
initServerContext(); initServerContext();
_needHandshake = true; _needHandshake = true;
} }
@ -379,17 +379,6 @@ int SecureSocketImpl::sendBytes(const void* buffer, int length, int flags)
if (_state == ST_ERROR) return 0; if (_state == ST_ERROR) return 0;
if (_sendBufferPending > 0)
{
int sent = sendRawBytes(_sendBuffer.begin() + _sendBufferOffset, _sendBufferPending, flags);
if (sent > 0)
{
_sendBufferOffset += sent;
_sendBufferPending -= sent;
}
return _sendBufferPending == 0 ? length : -1;
}
if (_state != ST_DONE) if (_state != ST_DONE)
{ {
bool establish = _pSocket->getBlocking(); bool establish = _pSocket->getBlocking();
@ -403,10 +392,21 @@ int SecureSocketImpl::sendBytes(const void* buffer, int length, int flags)
else else
{ {
stateMachine(); stateMachine();
return -1; if (_state != ST_DONE) return -1;
} }
} }
if (_sendBufferPending > 0)
{
int sent = sendRawBytes(_sendBuffer.begin() + _sendBufferOffset, _sendBufferPending, flags);
if (sent > 0)
{
_sendBufferOffset += sent;
_sendBufferPending -= sent;
}
return _sendBufferPending == 0 ? length : -1;
}
int dataToSend = length; int dataToSend = length;
int dataSent = 0; int dataSent = 0;
const char* pBuffer = reinterpret_cast<const char*>(buffer); const char* pBuffer = reinterpret_cast<const char*>(buffer);
@ -490,7 +490,7 @@ int SecureSocketImpl::receiveBytes(void* buffer, int length, int flags)
else else
{ {
stateMachine(); stateMachine();
return -1; if (_state != ST_DONE) return -1;
} }
} }
@ -598,7 +598,7 @@ int SecureSocketImpl::receiveBytes(void* buffer, int length, int flags)
if (securityStatus == SEC_I_RENEGOTIATE) if (securityStatus == SEC_I_RENEGOTIATE)
{ {
_needData = false; _needData = false;
_state = ST_CLIENTHANDSHAKECONDREAD; setState(ST_CLIENT_HSK_LOOP_INIT);
if (!_pSocket->getBlocking()) if (!_pSocket->getBlocking())
return -1; return -1;
@ -831,7 +831,7 @@ void SecureSocketImpl::clientConnectVerify()
throw SSLException("Failed to query stream sizes", Utility::formatError(securityStatus)); throw SSLException("Failed to query stream sizes", Utility::formatError(securityStatus));
_ioBufferSize = _streamSizes.cbHeader + _streamSizes.cbMaximumMessage + _streamSizes.cbTrailer; _ioBufferSize = _streamSizes.cbHeader + _streamSizes.cbMaximumMessage + _streamSizes.cbTrailer;
_state = ST_DONE; setState(ST_DONE);
} }
catch (...) catch (...)
{ {
@ -855,6 +855,7 @@ void SecureSocketImpl::initClientContext()
void SecureSocketImpl::performClientHandshake() void SecureSocketImpl::performClientHandshake()
{ {
performInitialClientHandshake(); performInitialClientHandshake();
performClientHandshakeSendToken();
performClientHandshakeLoop(); performClientHandshakeLoop();
clientConnectVerify(); clientConnectVerify();
} }
@ -897,38 +898,47 @@ void SecureSocketImpl::performInitialClientHandshake()
} }
} }
// incomplete credentials: more calls to InitializeSecurityContext needed _extraSecBuffer.pvBuffer = 0;
// send the token _extraSecBuffer.cbBuffer = 0;
sendInitialTokenOutBuffer(); _needData = true;
if (_outSecBuffer[0].cbBuffer && _outSecBuffer[0].pvBuffer)
{
setState(ST_CLIENT_HSK_SEND_TOKEN);
}
else if (_securityStatus == SEC_E_OK)
{
setState(ST_DONE);
}
}
void SecureSocketImpl::performClientHandshakeSendToken()
{
poco_assert_dbg (_outSecBuffer[0].cbBuffer && _outSecBuffer[0].pvBuffer);
int sent = sendRawBytes(_outSecBuffer[0].pvBuffer, _outSecBuffer[0].cbBuffer);
if (sent < 0)
{
return;
}
else if (sent < _outSecBuffer[0].cbBuffer)
{
_outSecBuffer[0].cbBuffer -= sent;
std::memmove(_outSecBuffer[0].pvBuffer, reinterpret_cast<char*>(_outSecBuffer[0].pvBuffer) + sent, _outSecBuffer[0].cbBuffer);
return;
}
if (_securityStatus == SEC_E_OK) if (_securityStatus == SEC_E_OK)
{ {
// The security context was successfully initialized. // The security context was successfully initialized.
// There is no need for another InitializeSecurityContext (Schannel) call. // There is no need for another InitializeSecurityContext (Schannel) call.
_state = ST_DONE; setState(ST_DONE);
return;
} }
else
//SEC_I_CONTINUE_NEEDED was returned:
// Wait for a return token. The returned token is then passed in
// another call to InitializeSecurityContext (Schannel). The output token can be empty.
_extraSecBuffer.pvBuffer = 0;
_extraSecBuffer.cbBuffer = 0;
_needData = true;
_state = ST_CLIENTHANDSHAKECONDREAD;
_securityStatus = SEC_E_INCOMPLETE_MESSAGE;
}
void SecureSocketImpl::sendInitialTokenOutBuffer()
{
// send the token
if (_outSecBuffer[0].cbBuffer && _outSecBuffer[0].pvBuffer)
{ {
int numBytes = sendRawBytes(_outSecBuffer[0].pvBuffer, _outSecBuffer[0].cbBuffer); setState(ST_CLIENT_HSK_LOOP_INIT);
if (numBytes != _outSecBuffer[0].cbBuffer) _securityStatus = SEC_E_INCOMPLETE_MESSAGE;
throw SSLException("Failed to send token to the server");
} }
} }
@ -944,11 +954,13 @@ SECURITY_STATUS SecureSocketImpl::performClientHandshakeLoop()
if (_securityStatus == SEC_E_OK) if (_securityStatus == SEC_E_OK)
{ {
performClientHandshakeLoopOK(); performClientHandshakeLoopDone();
performClientHandshakeSendFinal();
} }
else if (_securityStatus == SEC_I_CONTINUE_NEEDED) else if (_securityStatus == SEC_I_CONTINUE_NEEDED)
{ {
performClientHandshakeLoopContinueNeeded(); performClientHandshakeLoopContinue();
performClientHandshakeLoopSend();
} }
else if (_securityStatus == SEC_E_INCOMPLETE_MESSAGE) else if (_securityStatus == SEC_E_INCOMPLETE_MESSAGE)
{ {
@ -958,11 +970,11 @@ SECURITY_STATUS SecureSocketImpl::performClientHandshakeLoop()
{ {
if (_outFlags & ISC_RET_EXTENDED_ERROR) if (_outFlags & ISC_RET_EXTENDED_ERROR)
{ {
performClientHandshakeLoopExtError(); performClientHandshakeSendError();
} }
else else
{ {
performClientHandshakeLoopError(); performClientHandshakeError();
} }
} }
else else
@ -973,44 +985,30 @@ SECURITY_STATUS SecureSocketImpl::performClientHandshakeLoop()
if (FAILED(_securityStatus)) if (FAILED(_securityStatus))
{ {
performClientHandshakeLoopError(); performClientHandshakeError();
} }
return _securityStatus; return _securityStatus;
} }
void SecureSocketImpl::performClientHandshakeLoopExtError() void SecureSocketImpl::performClientHandshakeSendError()
{ {
poco_assert_dbg (FAILED(_securityStatus)); poco_assert_dbg (FAILED(_securityStatus));
performClientHandshakeSendOutBuffer(); sendOutSecBufferAndAdvanceState(ST_ERROR);
performClientHandshakeLoopError();
} }
void SecureSocketImpl::performClientHandshakeLoopError() void SecureSocketImpl::performClientHandshakeError()
{ {
poco_assert_dbg (FAILED(_securityStatus)); poco_assert_dbg (FAILED(_securityStatus));
cleanup(); cleanup();
_state = ST_ERROR; setState(ST_ERROR);
throw SSLException("Error during handshake", Utility::formatError(_securityStatus)); throw SSLException("Error during handshake", Utility::formatError(_securityStatus));
} }
void SecureSocketImpl::performClientHandshakeSendOutBuffer()
{
if (_outSecBuffer[0].cbBuffer && _outSecBuffer[0].pvBuffer)
{
int numBytes = sendRawBytes(static_cast<const void*>(_outSecBuffer[0].pvBuffer), _outSecBuffer[0].cbBuffer);
if (numBytes != _outSecBuffer[0].cbBuffer)
throw SSLException("Socket error during handshake");
_outSecBuffer.release(0);
}
}
void SecureSocketImpl::performClientHandshakeExtraBuffer() void SecureSocketImpl::performClientHandshakeExtraBuffer()
{ {
if (_inSecBuffer[1].BufferType == SECBUFFER_EXTRA) if (_inSecBuffer[1].BufferType == SECBUFFER_EXTRA)
@ -1022,48 +1020,67 @@ void SecureSocketImpl::performClientHandshakeExtraBuffer()
} }
void SecureSocketImpl::performClientHandshakeLoopOK() void SecureSocketImpl::performClientHandshakeLoopDone()
{ {
poco_assert_dbg(_securityStatus == SEC_E_OK); poco_assert_dbg(_securityStatus == SEC_E_OK);
performClientHandshakeSendOutBuffer();
performClientHandshakeExtraBuffer(); performClientHandshakeExtraBuffer();
_state = ST_VERIFY; if (_outSecBuffer[0].cbBuffer && _outSecBuffer[0].pvBuffer)
{
setState(ST_CLIENT_HSK_SEND_FINAL);
}
else
{
setState(ST_CLIENT_VERIFY);
}
}
void SecureSocketImpl::performClientHandshakeSendFinal()
{
sendOutSecBufferAndAdvanceState(ST_CLIENT_VERIFY);
} }
void SecureSocketImpl::performClientHandshakeLoopInit() void SecureSocketImpl::performClientHandshakeLoopInit()
{ {
poco_assert_dbg (_securityStatus == SEC_E_INCOMPLETE_MESSAGE || SEC_I_CONTINUE_NEEDED);
_inSecBuffer.reset(false); _inSecBuffer.reset(false);
_outSecBuffer.reset(true); _outSecBuffer.reset(true);
if (_needData)
{
if (_recvBuffer.capacity() != IO_BUFFER_SIZE)
{
_recvBuffer.setCapacity(IO_BUFFER_SIZE);
}
setState(ST_CLIENT_HSK_LOOP_RECV);
}
else
{
setState(ST_CLIENT_HSK_LOOP_PROCESS);
}
} }
void SecureSocketImpl::performClientHandshakeLoopReceive() void SecureSocketImpl::performClientHandshakeLoopRecv()
{ {
poco_assert_dbg (_needData); poco_assert_dbg (_needData);
poco_assert (IO_BUFFER_SIZE > _recvBufferOffset); poco_assert (IO_BUFFER_SIZE > _recvBufferOffset);
int n = receiveRawBytes(_recvBuffer.begin() + _recvBufferOffset, IO_BUFFER_SIZE - _recvBufferOffset); int n = receiveRawBytes(_recvBuffer.begin() + _recvBufferOffset, IO_BUFFER_SIZE - _recvBufferOffset);
if (n <= 0) throw SSLException("Error during handshake: failed to read data"); if (n == 0) throw SSLException("Connection unexpectedly closed during handshake");
if (n > 0)
_recvBufferOffset += n; {
_recvBufferOffset += n;
setState(ST_CLIENT_HSK_LOOP_PROCESS);
}
} }
void SecureSocketImpl::performClientHandshakeLoopCondReceive() void SecureSocketImpl::performClientHandshakeLoopProcess()
{ {
poco_assert_dbg (_securityStatus == SEC_E_INCOMPLETE_MESSAGE || SEC_I_CONTINUE_NEEDED);
performClientHandshakeLoopInit();
if (_needData)
{
if (_recvBuffer.capacity() != IO_BUFFER_SIZE)
_recvBuffer.setCapacity(IO_BUFFER_SIZE);
performClientHandshakeLoopReceive();
}
else _needData = true;
_inSecBuffer.setSecBufferToken(0, _recvBuffer.begin(), _recvBufferOffset); _inSecBuffer.setSecBufferToken(0, _recvBuffer.begin(), _recvBufferOffset);
// inbuffer 1 should be empty // inbuffer 1 should be empty
_inSecBuffer.setSecBufferEmpty(1); _inSecBuffer.setSecBufferEmpty(1);
@ -1089,38 +1106,82 @@ void SecureSocketImpl::performClientHandshakeLoopCondReceive()
if (_securityStatus == SEC_E_OK) if (_securityStatus == SEC_E_OK)
{ {
_state = ST_CLIENTHANDSHAKEOK; setState(ST_CLIENT_HSK_LOOP_DONE);
} }
else if (_securityStatus == SEC_I_CONTINUE_NEEDED) else if (_securityStatus == SEC_I_CONTINUE_NEEDED)
{ {
_state = ST_CLIENTHANDSHAKECONTINUE; setState(ST_CLIENT_HSK_LOOP_CONTINUE);
} }
else if (FAILED(_securityStatus)) else if (FAILED(_securityStatus))
{ {
if (_outFlags & ISC_RET_EXTENDED_ERROR) if (_outFlags & ISC_RET_EXTENDED_ERROR)
_state = ST_CLIENTHANDSHAKEEXTERROR; setState(ST_CLIENT_HSK_SEND_ERROR);
else else
_state = ST_ERROR; setState(ST_ERROR);
} }
else else
{ {
_state = ST_CLIENTHANDSHAKEINCOMPLETE; setState(ST_CLIENT_HSK_LOOP_INCOMPLETE);
} }
} }
void SecureSocketImpl::performClientHandshakeLoopContinueNeeded() 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()
{ {
performClientHandshakeSendOutBuffer();
performClientHandshakeExtraBuffer(); performClientHandshakeExtraBuffer();
_state = ST_CLIENTHANDSHAKECONDREAD; setState(ST_CLIENT_HSK_LOOP_SEND);
}
void SecureSocketImpl::performClientHandshakeLoopSend()
{
sendOutSecBufferAndAdvanceState(ST_CLIENT_HSK_LOOP_INIT);
}
void SecureSocketImpl::sendOutSecBufferAndAdvanceState(State state)
{
if (_outSecBuffer[0].cbBuffer && _outSecBuffer[0].pvBuffer)
{
int sent = sendRawBytes(_outSecBuffer[0].pvBuffer, _outSecBuffer[0].cbBuffer);
if (sent < 0) return;
if (sent < _outSecBuffer[0].cbBuffer)
{
_outSecBuffer[0].cbBuffer -= sent;
std::memmove(_outSecBuffer[0].pvBuffer, reinterpret_cast<char*>(_outSecBuffer[0].pvBuffer) + sent, _outSecBuffer[0].cbBuffer);
}
else
{
_outSecBuffer.release(0);
setState(state);
}
}
else
{
setState(state);
}
} }
void SecureSocketImpl::performClientHandshakeLoopIncompleteMessage() void SecureSocketImpl::performClientHandshakeLoopIncompleteMessage()
{ {
_needData = true; _needData = true;
_state = ST_CLIENTHANDSHAKECONDREAD; setState(ST_CLIENT_HSK_LOOP_INIT);
} }
@ -1619,6 +1680,12 @@ void SecureSocketImpl::stateIllegal()
void SecureSocketImpl::stateConnected() void SecureSocketImpl::stateConnected()
{ {
_peerHostName = _pSocket->peerAddress().host().toString(); _peerHostName = _pSocket->peerAddress().host().toString();
setState(ST_CLIENT_HSK_START);
}
void SecureSocketImpl::performClientHandshakeStart()
{
initClientContext(); initClientContext();
performInitialClientHandshake(); performInitialClientHandshake();
} }
@ -1700,34 +1767,28 @@ void StateMachine::select(fd_set* fdRead, fd_set* fdWrite, SOCKET sockfd)
StateMachine::StateMachine(): StateMachine::StateMachine():
_states() _states(SecureSocketImpl::ST_MAX)
{ {
//ST_INITIAL: 0, -> this one is illegal, you must call connectNB before _states[SecureSocketImpl::ST_INITIAL] = std::make_pair(&StateMachine::none, &SecureSocketImpl::stateIllegal);
_states.push_back(std::make_pair(&StateMachine::none, &SecureSocketImpl::stateIllegal)); _states[SecureSocketImpl::ST_CONNECTING] = std::make_pair(&StateMachine::writable, &SecureSocketImpl::stateConnected);
//ST_CONNECTING: connectNB was called, check if the socket is already available for writing _states[SecureSocketImpl::ST_CLIENT_HSK_START] = std::make_pair(&StateMachine::none, &SecureSocketImpl::performClientHandshakeStart);
_states.push_back(std::make_pair(&StateMachine::writable, &SecureSocketImpl::stateConnected)); _states[SecureSocketImpl::ST_CLIENT_HSK_SEND_TOKEN] = std::make_pair(&StateMachine::writable, &SecureSocketImpl::performClientHandshakeSendToken);
//ST_ESTABLISHTUNNELRECEIVED: we got the response, now start the handshake _states[SecureSocketImpl::ST_CLIENT_HSK_LOOP_INIT] = std::make_pair(&StateMachine::readable, &SecureSocketImpl::performClientHandshakeLoopInit);
_states.push_back(std::make_pair(&StateMachine::writable, &SecureSocketImpl::performInitialClientHandshake)); _states[SecureSocketImpl::ST_CLIENT_HSK_LOOP_RECV] = std::make_pair(&StateMachine::readable, &SecureSocketImpl::performClientHandshakeLoopRecv);
//ST_CLIENTHANDSHAKECONDREAD: condread _states[SecureSocketImpl::ST_CLIENT_HSK_LOOP_PROCESS] = std::make_pair(&StateMachine::none, &SecureSocketImpl::performClientHandshakeLoopProcess);
_states.push_back(std::make_pair(&StateMachine::readable, &SecureSocketImpl::performClientHandshakeLoopCondReceive)); _states[SecureSocketImpl::ST_CLIENT_HSK_LOOP_SEND] = std::make_pair(&StateMachine::writable, &SecureSocketImpl::performClientHandshakeLoopSend);
//ST_CLIENTHANDSHAKEINCOMPLETE, _states[SecureSocketImpl::ST_CLIENT_HSK_LOOP_INCOMPLETE] = std::make_pair(&StateMachine::none, &SecureSocketImpl::performClientHandshakeLoopIncompleteMessage);
_states.push_back(std::make_pair(&StateMachine::none, &SecureSocketImpl::performClientHandshakeLoopIncompleteMessage)); _states[SecureSocketImpl::ST_CLIENT_HSK_LOOP_CONTINUE] = std::make_pair(&StateMachine::none, &SecureSocketImpl::performClientHandshakeLoopContinue);
//ST_CLIENTHANDSHAKEOK, _states[SecureSocketImpl::ST_CLIENT_HSK_LOOP_DONE] = std::make_pair(&StateMachine::none, &SecureSocketImpl::performClientHandshakeLoopDone);
_states.push_back(std::make_pair(&StateMachine::writable, &SecureSocketImpl::performClientHandshakeLoopOK)); _states[SecureSocketImpl::ST_CLIENT_HSK_SEND_FINAL] = std::make_pair(&StateMachine::writable, &SecureSocketImpl::performClientHandshakeSendFinal);
//ST_CLIENTHANDSHAKEEXTERROR, _states[SecureSocketImpl::ST_CLIENT_HSK_SEND_ERROR] = std::make_pair(&StateMachine::writable, &SecureSocketImpl::performClientHandshakeSendError);
_states.push_back(std::make_pair(&StateMachine::writable, &SecureSocketImpl::performClientHandshakeLoopExtError)); _states[SecureSocketImpl::ST_CLIENT_VERIFY] = std::make_pair(&StateMachine::none, &SecureSocketImpl::clientConnectVerify);
//ST_CLIENTHANDSHAKECONTINUE, _states[SecureSocketImpl::ST_DONE] = std::make_pair(&StateMachine::none, &SecureSocketImpl::stateIllegal);
_states.push_back(std::make_pair(&StateMachine::writable, &SecureSocketImpl::performClientHandshakeLoopContinueNeeded)); _states[SecureSocketImpl::ST_ERROR] = std::make_pair(&StateMachine::none, &SecureSocketImpl::performClientHandshakeError);
//ST_VERIFY,
_states.push_back(std::make_pair(&StateMachine::none, &SecureSocketImpl::clientConnectVerify));
//ST_DONE,
_states.push_back(std::make_pair(&StateMachine::none, &SecureSocketImpl::stateIllegal));
//ST_ERROR
_states.push_back(std::make_pair(&StateMachine::none, &SecureSocketImpl::performClientHandshakeLoopError));
} }
void StateMachine::execute(SecureSocketImpl* pSock) bool StateMachine::execute(SecureSocketImpl* pSock)
{ {
try try
{ {
@ -1737,8 +1798,9 @@ void StateMachine::execute(SecureSocketImpl* pSock)
if ((this->*state.first)(pSock->sockfd())) if ((this->*state.first)(pSock->sockfd()))
{ {
(pSock->*(state.second))(); (pSock->*(state.second))();
(pSock->getState() == SecureSocketImpl::ST_DONE); return true;
} }
else return false;
} }
catch (...) catch (...)
{ {