Skip to content

Commit

Permalink
chore(NetSSL_Win): rewrite handshake logic to support non-blocking so…
Browse files Browse the repository at this point in the history
…ckets
  • Loading branch information
obiltschnig committed Nov 28, 2024
1 parent 0eb2e1b commit 663232b
Show file tree
Hide file tree
Showing 5 changed files with 443 additions and 297 deletions.
85 changes: 58 additions & 27 deletions NetSSL_Win/include/Poco/Net/SecureSocketImpl.h
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,10 @@
#define NetSSL_SecureSocketImpl_INCLUDED


// Temporary debugging aid, to be removed
// #define ENABLE_PRINT_STATE


#include "Poco/Net/SocketImpl.h"
#include "Poco/Net/NetSSL.h"
#include "Poco/Net/Context.h"
Expand All @@ -35,6 +39,14 @@
#include <sspi.h>



#ifdef ENABLE_PRINT_STATE
#define PRINT_STATE(m) printState(m)
#else
#define PRINT_STATE(m)
#endif


namespace Poco {
namespace Net {

Expand Down Expand Up @@ -224,20 +236,25 @@ class NetSSL_Win_API SecureSocketImpl
enum State
{
ST_INITIAL = 0,
// Client
ST_CONNECTING,
ST_CLIENT_HSK_START,
ST_CLIENT_HSK_SEND_TOKEN,
ST_CLIENT_HSK_LOOP_INIT,
ST_CLIENT_HSK_LOOP_RECV,
ST_CLIENT_HSK_LOOP_PROCESS,
ST_CLIENT_HSK_LOOP_CONTINUE,
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_ACCEPTING,
ST_SERVER_HSK_START,
ST_SERVER_HSK_LOOP_INIT,
ST_SERVER_HSK_LOOP_RECV,
ST_SERVER_HSK_LOOP_PROCESS,
ST_SERVER_HSK_LOOP_SEND,
ST_SERVER_HSK_LOOP_DONE,
ST_SERVER_VERIFY,
ST_DONE,
ST_ERROR,
ST_MAX
Expand All @@ -251,51 +268,64 @@ class NetSSL_Win_API SecureSocketImpl

int sendRawBytes(const void* buffer, int length, int flags = 0);
int receiveRawBytes(void* buffer, int length, int flags = 0);
void clientConnectVerify();
void performServerHandshake();
bool serverHandshakeLoop(PCtxtHandle phContext, PCredHandle phCred, bool requireClientAuth, bool doInitialRead, bool newContext);
void clientVerifyCertificate(const std::string& hostName);
void verifyCertificateChainClient(PCCERT_CONTEXT pServerCert);
void serverVerifyCertificate();
int serverShutdown(PCredHandle phCreds, CtxtHandle* phContext);
int clientShutdown(PCredHandle phCreds, CtxtHandle* phContext);
void initClientContext();
void initServerContext();
PCCERT_CONTEXT loadCertificate(bool mustFindCertificate);
void initCommon();
void cleanup();

void performClientHandshakeStart();
void performInitialClientHandshake();
void performClientHandshakeSendToken();
void performClientHandshakeLoopIncompleteMessage();
void performClientHandshakeLoopInit();
void performClientHandshakeLoopRecv();
void performClientHandshakeLoopProcess();
void performClientHandshakeLoopSend();
void performClientHandshakeLoopDone();
void performClientHandshakeSendFinal();
void performClientHandshakeExtraBuffer();
void performClientHandshakeLoopContinue();
void performClientHandshakeError();
void performClientHandshakeSendError();
void stateIllegal();
void stateError();

void stateClientConnected();
void stateClientHandshakeStart();
void stateClientHandshakeSendToken();
void stateClientHandshakeLoopInit();
void stateClientHandshakeLoopRecv();
void stateClientHandshakeLoopProcess();
void stateClientHandshakeLoopSend();
void stateClientHandshakeLoopDone();
void stateClientHandshakeSendFinal();
void stateClientHandshakeSendError();
void stateClientVerify();

void stateServerAccepted();
void stateServerHandshakeStart();
void stateServerHandshakeLoopInit();
void stateServerHandshakeLoopRecv();
void stateServerHandshakeLoopProcess();
void stateServerHandshakeLoopSend();
void stateServerHandshakeLoopDone();
void stateServerHandshakeVerify();

void sendOutSecBufferAndAdvanceState(State state);
void drainExtraBuffer();
static int getRecordLength(const BYTE* pBuffer, int length);
static bool bufferHasCompleteRecords(const BYTE* pBuffer, int length);

SECURITY_STATUS performClientHandshake();
void initClientCredentials();
void initServerCredentials();
SECURITY_STATUS doHandshake();
int completeHandshake();

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);
void stateIllegal();
void stateConnected();

void acceptSSL();
void connectSSL(bool completeHandshake);
void completeHandshake();
static int lastError();
bool stateMachine();
State getState() const;
void setState(State st);
static bool isLocalHost(const std::string& hostName);

#ifdef ENABLE_PRINT_STATE
void printState(const std::string& msg);
#endif

private:
SecureSocketImpl(const SecureSocketImpl&);
SecureSocketImpl& operator = (const SecureSocketImpl&);
Expand Down Expand Up @@ -331,9 +361,9 @@ class NetSSL_Win_API SecureSocketImpl
SecBuffer _extraSecBuffer;
SECURITY_STATUS _securityStatus;
State _state;
DWORD _outFlags;
bool _needData;
bool _needHandshake;
bool _initServerContext = false;

friend class SecureStreamSocketImpl;
friend class StateMachine;
Expand Down Expand Up @@ -376,6 +406,7 @@ inline SecureSocketImpl::State SecureSocketImpl::getState() const
inline void SecureSocketImpl::setState(SecureSocketImpl::State st)
{
_state = st;
PRINT_STATE("setState: ");
}


Expand Down
2 changes: 1 addition & 1 deletion NetSSL_Win/include/Poco/Net/Utility.h
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ class NetSSL_Win_API Utility
/// Non-case sensitive conversion of a string to a VerificationMode enum.
/// If verMode is illegal an OptionException is thrown.

static const std::string& formatError(long errCode);
static std::string formatError(long errCode);
/// Converts an winerror.h code into human readable form.

private:
Expand Down
Loading

0 comments on commit 663232b

Please sign in to comment.