mirror of
https://github.com/pocoproject/poco.git
synced 2025-04-25 09:25:57 +02:00
NetSSL_Win: various bugfixes and improvements
This commit is contained in:
parent
ef34c21e91
commit
1d7d57a321
@ -184,8 +184,8 @@ protected:
|
|||||||
|
|
||||||
void clientConnectVerify();
|
void clientConnectVerify();
|
||||||
void sendInitialTokenOutBuffer();
|
void sendInitialTokenOutBuffer();
|
||||||
void serverConnect();
|
void performServerHandshake();
|
||||||
bool serverHandshakeLoop(PCtxtHandle phContext, PCredHandle phCred, BOOL requireClientAuth, BOOL fDoInitialRead, BOOL NewContext);
|
bool serverHandshakeLoop(PCtxtHandle phContext, PCredHandle phCred, bool requireClientAuth, bool doInitialRead, bool newContext);
|
||||||
void clientVerifyCertificate(PCCERT_CONTEXT pServerCert, const std::string& serverName, DWORD dwCertFlags);
|
void clientVerifyCertificate(PCCERT_CONTEXT pServerCert, const std::string& serverName, DWORD dwCertFlags);
|
||||||
void verifyCertificateChainClient(PCCERT_CONTEXT pServerCert, PCCERT_CHAIN_CONTEXT pChainContext);
|
void verifyCertificateChainClient(PCCERT_CONTEXT pServerCert, PCCERT_CHAIN_CONTEXT pChainContext);
|
||||||
void serverVerifyCertificate(PCCERT_CONTEXT pPeerCert, DWORD dwCertFlags);
|
void serverVerifyCertificate(PCCERT_CONTEXT pPeerCert, DWORD dwCertFlags);
|
||||||
@ -216,6 +216,7 @@ protected:
|
|||||||
void stateConnected();
|
void stateConnected();
|
||||||
void acceptSSL();
|
void acceptSSL();
|
||||||
void connectSSL(bool completeHandshake);
|
void connectSSL(bool completeHandshake);
|
||||||
|
void completeHandshake();
|
||||||
static int lastError();
|
static int lastError();
|
||||||
void stateMachine();
|
void stateMachine();
|
||||||
void setState(State st);
|
void setState(State st);
|
||||||
@ -250,16 +251,15 @@ private:
|
|||||||
SecPkgContext_StreamSizes _streamSizes;
|
SecPkgContext_StreamSizes _streamSizes;
|
||||||
AutoSecBufferDesc<1> _outSecBuffer;
|
AutoSecBufferDesc<1> _outSecBuffer;
|
||||||
AutoSecBufferDesc<2> _inSecBuffer;
|
AutoSecBufferDesc<2> _inSecBuffer;
|
||||||
Poco::Buffer<UCHAR> _ioCharBuffer;
|
|
||||||
Poco::SharedPtr<Poco::Buffer<BYTE> > _pSendBuffer;
|
Poco::SharedPtr<Poco::Buffer<BYTE> > _pSendBuffer;
|
||||||
SecBuffer _extraSecBuffer;
|
SecBuffer _extraSecBuffer;
|
||||||
bool _doReadFirst;
|
bool _doReadFirst;
|
||||||
DWORD _bytesRead;
|
DWORD _bytesRead;
|
||||||
DWORD _bytesReadSum;
|
|
||||||
SECURITY_STATUS _securityStatus;
|
SECURITY_STATUS _securityStatus;
|
||||||
State _state;
|
State _state;
|
||||||
DWORD _outFlags;
|
DWORD _outFlags;
|
||||||
std::string _hostName;
|
std::string _hostName;
|
||||||
|
bool _needHandshake;
|
||||||
|
|
||||||
friend class SecureStreamSocketImpl;
|
friend class SecureStreamSocketImpl;
|
||||||
friend class StateMachine;
|
friend class StateMachine;
|
||||||
|
@ -92,13 +92,12 @@ SecureSocketImpl::SecureSocketImpl(Poco::AutoPtr<SocketImpl> pSocketImpl, Contex
|
|||||||
_streamSizes(),
|
_streamSizes(),
|
||||||
_outSecBuffer(&_securityFunctions, true),
|
_outSecBuffer(&_securityFunctions, true),
|
||||||
_inSecBuffer(&_securityFunctions, false),
|
_inSecBuffer(&_securityFunctions, false),
|
||||||
_ioCharBuffer(IO_BUFFER_SIZE),
|
|
||||||
_extraSecBuffer(),
|
_extraSecBuffer(),
|
||||||
_doReadFirst(true),
|
_doReadFirst(true),
|
||||||
_bytesRead(0),
|
_bytesRead(0),
|
||||||
_bytesReadSum(0),
|
|
||||||
_securityStatus(SEC_E_INCOMPLETE_MESSAGE),
|
_securityStatus(SEC_E_INCOMPLETE_MESSAGE),
|
||||||
_state(ST_INITIAL)
|
_state(ST_INITIAL),
|
||||||
|
_needHandshake(false)
|
||||||
{
|
{
|
||||||
_hCreds.dwLower = 0;
|
_hCreds.dwLower = 0;
|
||||||
_hCreds.dwUpper = 0;
|
_hCreds.dwUpper = 0;
|
||||||
@ -151,11 +150,8 @@ void SecureSocketImpl::cleanup()
|
|||||||
{
|
{
|
||||||
_hostName.clear();
|
_hostName.clear();
|
||||||
|
|
||||||
if (_hCreds.dwLower != 0 && _hCreds.dwUpper != 0)
|
|
||||||
{
|
|
||||||
_hCreds.dwLower = 0;
|
_hCreds.dwLower = 0;
|
||||||
_hCreds.dwUpper = 0;
|
_hCreds.dwUpper = 0;
|
||||||
}
|
|
||||||
|
|
||||||
if (_hContext.dwLower != 0 && _hContext.dwUpper != 0)
|
if (_hContext.dwLower != 0 && _hContext.dwUpper != 0)
|
||||||
{
|
{
|
||||||
@ -250,7 +246,6 @@ void SecureSocketImpl::listen(int backlog)
|
|||||||
|
|
||||||
void SecureSocketImpl::shutdown()
|
void SecureSocketImpl::shutdown()
|
||||||
{
|
{
|
||||||
// TODO
|
|
||||||
if (_mode == MODE_SERVER)
|
if (_mode == MODE_SERVER)
|
||||||
serverDisconnect(&_hCreds, &_hContext);
|
serverDisconnect(&_hCreds, &_hContext);
|
||||||
else
|
else
|
||||||
@ -274,8 +269,8 @@ void SecureSocketImpl::close()
|
|||||||
|
|
||||||
void SecureSocketImpl::abort()
|
void SecureSocketImpl::abort()
|
||||||
{
|
{
|
||||||
// TODO
|
|
||||||
_pSocket->shutdown();
|
_pSocket->shutdown();
|
||||||
|
cleanup();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -283,12 +278,18 @@ void SecureSocketImpl::acceptSSL()
|
|||||||
{
|
{
|
||||||
_state = ST_DONE;
|
_state = ST_DONE;
|
||||||
initServerContext();
|
initServerContext();
|
||||||
serverConnect();
|
_needHandshake = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int SecureSocketImpl::sendBytes(const void* buffer, int length, int flags)
|
int SecureSocketImpl::sendBytes(const void* buffer, int length, int flags)
|
||||||
{
|
{
|
||||||
|
if (_needHandshake)
|
||||||
|
{
|
||||||
|
completeHandshake();
|
||||||
|
_needHandshake = false;
|
||||||
|
}
|
||||||
|
|
||||||
if (_state == ST_ERROR)
|
if (_state == ST_ERROR)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
@ -337,7 +338,7 @@ int SecureSocketImpl::sendBytes(const void* buffer, int length, int flags)
|
|||||||
|
|
||||||
int outBufferLen = msg[0].cbBuffer+msg[1].cbBuffer + msg[2].cbBuffer;
|
int outBufferLen = msg[0].cbBuffer+msg[1].cbBuffer + msg[2].cbBuffer;
|
||||||
|
|
||||||
int rcTmp = _pSocket->sendBytes(_pSendBuffer->begin(), outBufferLen, flags);
|
int rcTmp = sendRawBytes(_pSendBuffer->begin(), outBufferLen, flags);
|
||||||
if (_pSocket->getBlocking() && rcTmp == -1)
|
if (_pSocket->getBlocking() && rcTmp == -1)
|
||||||
{
|
{
|
||||||
if (dataSent == 0)
|
if (dataSent == 0)
|
||||||
@ -363,6 +364,12 @@ int SecureSocketImpl::sendRawBytes(const void* buffer, int length, int flags)
|
|||||||
|
|
||||||
int SecureSocketImpl::receiveBytes(void* buffer, int length, int flags)
|
int SecureSocketImpl::receiveBytes(void* buffer, int length, int flags)
|
||||||
{
|
{
|
||||||
|
if (_needHandshake)
|
||||||
|
{
|
||||||
|
completeHandshake();
|
||||||
|
_needHandshake = false;
|
||||||
|
}
|
||||||
|
|
||||||
if (_state == ST_ERROR)
|
if (_state == ST_ERROR)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
@ -372,8 +379,10 @@ int SecureSocketImpl::receiveBytes(void* buffer, int length, int flags)
|
|||||||
if (establish)
|
if (establish)
|
||||||
{
|
{
|
||||||
while (_state != ST_DONE)
|
while (_state != ST_DONE)
|
||||||
|
{
|
||||||
stateMachine();
|
stateMachine();
|
||||||
}
|
}
|
||||||
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
stateMachine();
|
stateMachine();
|
||||||
@ -405,12 +414,14 @@ int SecureSocketImpl::receiveBytes(void* buffer, int length, int flags)
|
|||||||
poco_assert (!_pReceiveBuffer);
|
poco_assert (!_pReceiveBuffer);
|
||||||
|
|
||||||
if (!_pIOBuffer)
|
if (!_pIOBuffer)
|
||||||
_pIOBuffer = new BYTE[_ioBufferSize];
|
_pIOBuffer = new BYTE[IO_BUFFER_SIZE];
|
||||||
|
bool mustReceive = _ioBufferOffset == 0;
|
||||||
bool cont = true;
|
bool cont = true;
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
int numBytes = _pSocket->receiveBytes(_pIOBuffer + _ioBufferOffset, _ioBufferSize - _ioBufferOffset);
|
if (mustReceive)
|
||||||
|
{
|
||||||
|
int numBytes = receiveRawBytes(_pIOBuffer + _ioBufferOffset, _ioBufferSize - _ioBufferOffset);
|
||||||
|
|
||||||
if (numBytes == -1)
|
if (numBytes == -1)
|
||||||
return -1;
|
return -1;
|
||||||
@ -418,11 +429,12 @@ int SecureSocketImpl::receiveBytes(void* buffer, int length, int flags)
|
|||||||
break;
|
break;
|
||||||
else
|
else
|
||||||
_ioBufferOffset += numBytes;
|
_ioBufferOffset += numBytes;
|
||||||
|
}
|
||||||
|
else mustReceive = true;
|
||||||
|
|
||||||
int bytesDecoded = 0;
|
int bytesDecoded = 0;
|
||||||
_extraSecBuffer = SecBuffer();
|
_extraSecBuffer = SecBuffer();
|
||||||
SECURITY_STATUS securityStatus = decodeBufferFull(_pIOBuffer, _ioBufferOffset, reinterpret_cast<char*>(buffer), length, bytesDecoded);
|
SECURITY_STATUS securityStatus = decodeBufferFull(_pIOBuffer, _ioBufferOffset, reinterpret_cast<char*>(buffer), length, bytesDecoded);
|
||||||
|
|
||||||
if (_extraSecBuffer.cbBuffer > 0)
|
if (_extraSecBuffer.cbBuffer > 0)
|
||||||
{
|
{
|
||||||
MoveMemory(_pIOBuffer, _extraSecBuffer.pvBuffer, _extraSecBuffer.cbBuffer);
|
MoveMemory(_pIOBuffer, _extraSecBuffer.pvBuffer, _extraSecBuffer.cbBuffer);
|
||||||
@ -485,6 +497,8 @@ int SecureSocketImpl::receiveBytes(void* buffer, int length, int flags)
|
|||||||
}
|
}
|
||||||
|
|
||||||
delete [] _extraSecBuffer.pvBuffer;
|
delete [] _extraSecBuffer.pvBuffer;
|
||||||
|
_extraSecBuffer.pvBuffer = 0;
|
||||||
|
_extraSecBuffer.cbBuffer = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
while (cont);
|
while (cont);
|
||||||
@ -676,8 +690,24 @@ void SecureSocketImpl::connectSSL(bool completeHandshake)
|
|||||||
_hostName = _pSocket->address().host().toString();
|
_hostName = _pSocket->address().host().toString();
|
||||||
|
|
||||||
initClientContext();
|
initClientContext();
|
||||||
|
if (completeHandshake)
|
||||||
|
{
|
||||||
|
performClientHandshake();
|
||||||
|
_needHandshake = false;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
_needHandshake = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void SecureSocketImpl::completeHandshake()
|
||||||
|
{
|
||||||
|
if (_mode == MODE_SERVER)
|
||||||
|
performServerHandshake();
|
||||||
|
else
|
||||||
performClientHandshake();
|
performClientHandshake();
|
||||||
clientConnectVerify();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -724,6 +754,7 @@ void SecureSocketImpl::performClientHandshake()
|
|||||||
{
|
{
|
||||||
performInitialClientHandshake();
|
performInitialClientHandshake();
|
||||||
performClientHandshakeLoop();
|
performClientHandshakeLoop();
|
||||||
|
clientConnectVerify();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -743,7 +774,7 @@ void SecureSocketImpl::performInitialClientHandshake()
|
|||||||
const_cast<SEC_WCHAR*>(whostName.c_str()),
|
const_cast<SEC_WCHAR*>(whostName.c_str()),
|
||||||
_clientFlags,
|
_clientFlags,
|
||||||
0,
|
0,
|
||||||
SECURITY_NATIVE_DREP,
|
0,
|
||||||
0,
|
0,
|
||||||
0,
|
0,
|
||||||
&_hContext, // init hContext
|
&_hContext, // init hContext
|
||||||
@ -803,7 +834,7 @@ void SecureSocketImpl::sendInitialTokenOutBuffer()
|
|||||||
SECURITY_STATUS SecureSocketImpl::performClientHandshakeLoop()
|
SECURITY_STATUS SecureSocketImpl::performClientHandshakeLoop()
|
||||||
{
|
{
|
||||||
_bytesRead = 0;
|
_bytesRead = 0;
|
||||||
_bytesReadSum = 0;
|
_ioBufferOffset = 0;
|
||||||
_securityStatus = SEC_E_INCOMPLETE_MESSAGE;
|
_securityStatus = SEC_E_INCOMPLETE_MESSAGE;
|
||||||
|
|
||||||
while (_securityStatus == SEC_I_CONTINUE_NEEDED || _securityStatus == SEC_E_INCOMPLETE_MESSAGE || _securityStatus == SEC_I_INCOMPLETE_CREDENTIALS)
|
while (_securityStatus == SEC_I_CONTINUE_NEEDED || _securityStatus == SEC_E_INCOMPLETE_MESSAGE || _securityStatus == SEC_I_INCOMPLETE_CREDENTIALS)
|
||||||
@ -862,7 +893,6 @@ void SecureSocketImpl::performClientHandshakeSendOutBuffer()
|
|||||||
{
|
{
|
||||||
throw SSLException("Socket error during handshake");
|
throw SSLException("Socket error during handshake");
|
||||||
}
|
}
|
||||||
_bytesReadSum = 0;
|
|
||||||
_outSecBuffer.release(0);
|
_outSecBuffer.release(0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -872,19 +902,10 @@ void SecureSocketImpl::performClientHandshakeExtraBuffer()
|
|||||||
{
|
{
|
||||||
if (_inSecBuffer[1].BufferType == SECBUFFER_EXTRA)
|
if (_inSecBuffer[1].BufferType == SECBUFFER_EXTRA)
|
||||||
{
|
{
|
||||||
_extraSecBuffer.pvBuffer = new BYTE[_inSecBuffer[1].cbBuffer];
|
MoveMemory(_pIOBuffer, _pIOBuffer + (_ioBufferOffset - _inSecBuffer[1].cbBuffer), _inSecBuffer[1].cbBuffer);
|
||||||
|
_ioBufferOffset = _inSecBuffer[1].cbBuffer;
|
||||||
MoveMemory(_extraSecBuffer.pvBuffer, _ioCharBuffer.begin() + (_bytesReadSum - _inSecBuffer[1].cbBuffer), _inSecBuffer[1].cbBuffer);
|
|
||||||
|
|
||||||
_extraSecBuffer.cbBuffer = _inSecBuffer[1].cbBuffer;
|
|
||||||
_extraSecBuffer.BufferType = SECBUFFER_TOKEN;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
_extraSecBuffer.pvBuffer = 0;
|
|
||||||
_extraSecBuffer.cbBuffer = 0;
|
|
||||||
_extraSecBuffer.BufferType = SECBUFFER_EMPTY;
|
|
||||||
}
|
}
|
||||||
|
else _ioBufferOffset = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -908,13 +929,16 @@ void SecureSocketImpl::performClientHandshakeLoopInit()
|
|||||||
void SecureSocketImpl::performClientHandshakeLoopRead()
|
void SecureSocketImpl::performClientHandshakeLoopRead()
|
||||||
{
|
{
|
||||||
poco_assert_dbg (_doReadFirst);
|
poco_assert_dbg (_doReadFirst);
|
||||||
|
poco_assert (IO_BUFFER_SIZE > _ioBufferOffset);
|
||||||
|
|
||||||
poco_assert (IO_BUFFER_SIZE > _bytesReadSum);
|
if (!_pIOBuffer)
|
||||||
_bytesRead = receiveRawBytes((void *)(_ioCharBuffer.begin() + _bytesReadSum), IO_BUFFER_SIZE - _bytesReadSum);
|
_pIOBuffer = new BYTE[IO_BUFFER_SIZE];
|
||||||
|
|
||||||
|
_bytesRead = receiveRawBytes(_pIOBuffer + _ioBufferOffset, IO_BUFFER_SIZE - _ioBufferOffset);
|
||||||
if (_bytesRead <= 0)
|
if (_bytesRead <= 0)
|
||||||
throw SSLException("Error during handshake: failed to read data");
|
throw SSLException("Error during handshake: failed to read data");
|
||||||
|
|
||||||
_bytesReadSum += _bytesRead;
|
_ioBufferOffset += _bytesRead;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -929,7 +953,7 @@ void SecureSocketImpl::performClientHandshakeLoopCondRead()
|
|||||||
}
|
}
|
||||||
else _doReadFirst = true;
|
else _doReadFirst = true;
|
||||||
|
|
||||||
_inSecBuffer.setSecBufferToken(0, _ioCharBuffer.begin(), _bytesReadSum);
|
_inSecBuffer.setSecBufferToken(0, _pIOBuffer, _ioBufferOffset);
|
||||||
// inbuffer 1 should be empty
|
// inbuffer 1 should be empty
|
||||||
_inSecBuffer.setSecBufferEmpty(1);
|
_inSecBuffer.setSecBufferEmpty(1);
|
||||||
|
|
||||||
@ -944,7 +968,7 @@ void SecureSocketImpl::performClientHandshakeLoopCondRead()
|
|||||||
0,
|
0,
|
||||||
_clientFlags,
|
_clientFlags,
|
||||||
0,
|
0,
|
||||||
SECURITY_NATIVE_DREP,
|
0,
|
||||||
&_inSecBuffer,
|
&_inSecBuffer,
|
||||||
0,
|
0,
|
||||||
0,
|
0,
|
||||||
@ -977,17 +1001,7 @@ void SecureSocketImpl::performClientHandshakeLoopCondRead()
|
|||||||
void SecureSocketImpl::performClientHandshakeLoopContinueNeeded()
|
void SecureSocketImpl::performClientHandshakeLoopContinueNeeded()
|
||||||
{
|
{
|
||||||
performClientHandshakeSendOutBuffer();
|
performClientHandshakeSendOutBuffer();
|
||||||
|
performClientHandshakeExtraBuffer();
|
||||||
if (_inSecBuffer[1].BufferType == SECBUFFER_EXTRA)
|
|
||||||
{
|
|
||||||
MoveMemory(_ioCharBuffer.begin(),
|
|
||||||
_ioCharBuffer.begin() + (_bytesReadSum - _inSecBuffer[1].cbBuffer),
|
|
||||||
_inSecBuffer[1].cbBuffer);
|
|
||||||
|
|
||||||
_bytesReadSum = _inSecBuffer[1].cbBuffer;
|
|
||||||
}
|
|
||||||
else _bytesReadSum = 0;
|
|
||||||
|
|
||||||
_state = ST_CLIENTHANDSHAKECONDREAD;
|
_state = ST_CLIENTHANDSHAKECONDREAD;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1006,9 +1020,9 @@ void SecureSocketImpl::initServerContext()
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void SecureSocketImpl::serverConnect()
|
void SecureSocketImpl::performServerHandshake()
|
||||||
{
|
{
|
||||||
serverHandshakeLoop(&_hContext, &_hCreds, _clientAuthRequired, TRUE, TRUE);
|
serverHandshakeLoop(&_hContext, &_hCreds, _clientAuthRequired, true, true);
|
||||||
|
|
||||||
SECURITY_STATUS securityStatus;
|
SECURITY_STATUS securityStatus;
|
||||||
if (_clientAuthRequired)
|
if (_clientAuthRequired)
|
||||||
@ -1041,15 +1055,13 @@ void SecureSocketImpl::serverConnect()
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool SecureSocketImpl::serverHandshakeLoop(PCtxtHandle phContext, PCredHandle phCred, BOOL requireClientAuth, BOOL fDoInitialRead, BOOL NewContext)
|
bool SecureSocketImpl::serverHandshakeLoop(PCtxtHandle phContext, PCredHandle phCred, bool requireClientAuth, bool doInitialRead, bool newContext)
|
||||||
{
|
{
|
||||||
TimeStamp tsExpiry;
|
TimeStamp tsExpiry;
|
||||||
DWORD err(0);
|
int n = 0;
|
||||||
BOOL doRead = fDoInitialRead;
|
bool doRead = doInitialRead;
|
||||||
BOOL initContext = NewContext;
|
bool initContext = newContext;
|
||||||
DWORD outFlags;
|
DWORD outFlags;
|
||||||
BYTE ioBuffer[IO_BUFFER_SIZE];
|
|
||||||
DWORD ioBufferIdx = 0;
|
|
||||||
SECURITY_STATUS securityStatus = SEC_E_INCOMPLETE_MESSAGE;
|
SECURITY_STATUS securityStatus = SEC_E_INCOMPLETE_MESSAGE;
|
||||||
|
|
||||||
while (securityStatus == SEC_I_CONTINUE_NEEDED || securityStatus == SEC_E_INCOMPLETE_MESSAGE || securityStatus == SEC_I_INCOMPLETE_CREDENTIALS)
|
while (securityStatus == SEC_I_CONTINUE_NEEDED || securityStatus == SEC_E_INCOMPLETE_MESSAGE || securityStatus == SEC_I_INCOMPLETE_CREDENTIALS)
|
||||||
@ -1058,19 +1070,23 @@ bool SecureSocketImpl::serverHandshakeLoop(PCtxtHandle phContext, PCredHandle ph
|
|||||||
{
|
{
|
||||||
if (doRead)
|
if (doRead)
|
||||||
{
|
{
|
||||||
err = receiveRawBytes(ioBuffer+ioBufferIdx, IO_BUFFER_SIZE-ioBufferIdx);
|
if (!_pIOBuffer)
|
||||||
|
{
|
||||||
|
_pIOBuffer = new BYTE[IO_BUFFER_SIZE];
|
||||||
|
}
|
||||||
|
n = receiveRawBytes(_pIOBuffer + _ioBufferOffset, IO_BUFFER_SIZE - _ioBufferOffset);
|
||||||
|
|
||||||
if (err == SOCKET_ERROR || err == 0)
|
if (n <= 0)
|
||||||
throw SSLException("Failed to receive data in handshake");
|
throw SSLException("Failed to receive data in handshake");
|
||||||
else
|
else
|
||||||
ioBufferIdx += err;
|
_ioBufferOffset += n;
|
||||||
}
|
}
|
||||||
else doRead = TRUE;
|
else doRead = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
AutoSecBufferDesc<2> inBuffer(&_securityFunctions, false);
|
AutoSecBufferDesc<2> inBuffer(&_securityFunctions, false);
|
||||||
AutoSecBufferDesc<1> outBuffer(&_securityFunctions, true);
|
AutoSecBufferDesc<1> outBuffer(&_securityFunctions, true);
|
||||||
inBuffer.setSecBufferToken(0, ioBuffer, ioBufferIdx);
|
inBuffer.setSecBufferToken(0, _pIOBuffer, _ioBufferOffset);
|
||||||
inBuffer.setSecBufferEmpty(1);
|
inBuffer.setSecBufferEmpty(1);
|
||||||
outBuffer.setSecBufferToken(0, 0, 0);
|
outBuffer.setSecBufferToken(0, 0, 0);
|
||||||
|
|
||||||
@ -1079,19 +1095,19 @@ bool SecureSocketImpl::serverHandshakeLoop(PCtxtHandle phContext, PCredHandle ph
|
|||||||
initContext ? NULL : phContext,
|
initContext ? NULL : phContext,
|
||||||
&inBuffer,
|
&inBuffer,
|
||||||
_serverFlags,
|
_serverFlags,
|
||||||
SECURITY_NATIVE_DREP,
|
0,
|
||||||
initContext ? phContext : NULL,
|
initContext ? phContext : NULL,
|
||||||
&outBuffer,
|
&outBuffer,
|
||||||
&outFlags,
|
&outFlags,
|
||||||
&tsExpiry);
|
&tsExpiry);
|
||||||
|
|
||||||
initContext = FALSE;
|
initContext = false;
|
||||||
|
|
||||||
if (securityStatus == SEC_E_OK || securityStatus == SEC_I_CONTINUE_NEEDED || (FAILED(securityStatus) && (0 != (outFlags & ISC_RET_EXTENDED_ERROR))))
|
if (securityStatus == SEC_E_OK || securityStatus == SEC_I_CONTINUE_NEEDED || (FAILED(securityStatus) && (0 != (outFlags & ISC_RET_EXTENDED_ERROR))))
|
||||||
{
|
{
|
||||||
if (outBuffer[0].cbBuffer != 0 && outBuffer[0].pvBuffer != 0)
|
if (outBuffer[0].cbBuffer != 0 && outBuffer[0].pvBuffer != 0)
|
||||||
{
|
{
|
||||||
err = sendRawBytes(outBuffer[0].pvBuffer, outBuffer[0].cbBuffer);
|
n = sendRawBytes(outBuffer[0].pvBuffer, outBuffer[0].cbBuffer);
|
||||||
outBuffer.release(0);
|
outBuffer.release(0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1100,13 +1116,16 @@ bool SecureSocketImpl::serverHandshakeLoop(PCtxtHandle phContext, PCredHandle ph
|
|||||||
{
|
{
|
||||||
if (inBuffer[1].BufferType == SECBUFFER_EXTRA)
|
if (inBuffer[1].BufferType == SECBUFFER_EXTRA)
|
||||||
{
|
{
|
||||||
memcpy(ioBuffer, ioBuffer + (ioBufferIdx - inBuffer[1].cbBuffer), inBuffer[1].cbBuffer);
|
memcpy(_pIOBuffer, _pIOBuffer + (_ioBufferOffset - inBuffer[1].cbBuffer), inBuffer[1].cbBuffer);
|
||||||
ioBufferIdx = inBuffer[1].cbBuffer;
|
_ioBufferOffset = inBuffer[1].cbBuffer;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
_ioBufferOffset = 0;
|
||||||
}
|
}
|
||||||
else ioBufferIdx = 0;
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
else if (FAILED(securityStatus) && (securityStatus != SEC_E_INCOMPLETE_MESSAGE))
|
else if (FAILED(securityStatus) && securityStatus != SEC_E_INCOMPLETE_MESSAGE)
|
||||||
{
|
{
|
||||||
throw SSLException("Handshake failure:", Utility::formatError(securityStatus));
|
throw SSLException("Handshake failure:", Utility::formatError(securityStatus));
|
||||||
}
|
}
|
||||||
@ -1115,14 +1134,17 @@ bool SecureSocketImpl::serverHandshakeLoop(PCtxtHandle phContext, PCredHandle ph
|
|||||||
{
|
{
|
||||||
if (inBuffer[1].BufferType == SECBUFFER_EXTRA)
|
if (inBuffer[1].BufferType == SECBUFFER_EXTRA)
|
||||||
{
|
{
|
||||||
memcpy(ioBuffer, ioBuffer + (ioBufferIdx - inBuffer[1].cbBuffer), inBuffer[1].cbBuffer);
|
memcpy(_pIOBuffer, _pIOBuffer + (_ioBufferOffset - inBuffer[1].cbBuffer), inBuffer[1].cbBuffer);
|
||||||
ioBufferIdx = inBuffer[1].cbBuffer;
|
_ioBufferOffset = inBuffer[1].cbBuffer;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
_ioBufferOffset = 0;
|
||||||
}
|
}
|
||||||
else ioBufferIdx = 0;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return FALSE;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -1258,7 +1280,7 @@ void SecureSocketImpl::verifyCertificateChainClient(PCCERT_CONTEXT pServerCert,
|
|||||||
NULL,
|
NULL,
|
||||||
&revStat);
|
&revStat);
|
||||||
|
|
||||||
if (FALSE == rc)
|
if (!rc)
|
||||||
{
|
{
|
||||||
VerificationErrorArgs args(cert, revStat.dwIndex, revStat.dwReason, Utility::formatError(revStat.dwError));
|
VerificationErrorArgs args(cert, revStat.dwIndex, revStat.dwReason, Utility::formatError(revStat.dwError));
|
||||||
SSLManager::instance().ClientVerificationError(this, args);
|
SSLManager::instance().ClientVerificationError(this, args);
|
||||||
@ -1401,6 +1423,13 @@ void SecureSocketImpl::serverVerifyCertificate(PCCERT_CONTEXT pPeerCert, DWORD d
|
|||||||
|
|
||||||
LONG SecureSocketImpl::clientDisconnect(PCredHandle phCreds, CtxtHandle* phContext)
|
LONG SecureSocketImpl::clientDisconnect(PCredHandle phCreds, CtxtHandle* phContext)
|
||||||
{
|
{
|
||||||
|
if (phContext->dwLower == 0 && phContext->dwUpper == 0)
|
||||||
|
{
|
||||||
|
// handshake has never been done
|
||||||
|
poco_assert_dbg (_needHandshake);
|
||||||
|
return SEC_E_OK;
|
||||||
|
}
|
||||||
|
|
||||||
AutoSecBufferDesc<1> tokBuffer(&_securityFunctions, false);
|
AutoSecBufferDesc<1> tokBuffer(&_securityFunctions, false);
|
||||||
|
|
||||||
DWORD dwType = SCHANNEL_SHUTDOWN;
|
DWORD dwType = SCHANNEL_SHUTDOWN;
|
||||||
@ -1427,7 +1456,7 @@ LONG SecureSocketImpl::clientDisconnect(PCredHandle phCreds, CtxtHandle *phConte
|
|||||||
NULL,
|
NULL,
|
||||||
dwSSPIFlags,
|
dwSSPIFlags,
|
||||||
0,
|
0,
|
||||||
SECURITY_NATIVE_DREP,
|
0,
|
||||||
NULL,
|
NULL,
|
||||||
0,
|
0,
|
||||||
phContext,
|
phContext,
|
||||||
@ -1441,6 +1470,13 @@ LONG SecureSocketImpl::clientDisconnect(PCredHandle phCreds, CtxtHandle *phConte
|
|||||||
|
|
||||||
LONG SecureSocketImpl::serverDisconnect(PCredHandle phCreds, CtxtHandle* phContext)
|
LONG SecureSocketImpl::serverDisconnect(PCredHandle phCreds, CtxtHandle* phContext)
|
||||||
{
|
{
|
||||||
|
if (phContext->dwLower == 0 && phContext->dwUpper == 0)
|
||||||
|
{
|
||||||
|
// handshake has never been done
|
||||||
|
poco_assert_dbg (_needHandshake);
|
||||||
|
return SEC_E_OK;
|
||||||
|
}
|
||||||
|
|
||||||
AutoSecBufferDesc<1> tokBuffer(&_securityFunctions, false);
|
AutoSecBufferDesc<1> tokBuffer(&_securityFunctions, false);
|
||||||
|
|
||||||
DWORD dwType = SCHANNEL_SHUTDOWN;
|
DWORD dwType = SCHANNEL_SHUTDOWN;
|
||||||
@ -1466,7 +1502,7 @@ LONG SecureSocketImpl::serverDisconnect(PCredHandle phCreds, CtxtHandle *phConte
|
|||||||
phContext,
|
phContext,
|
||||||
NULL,
|
NULL,
|
||||||
dwSSPIFlags,
|
dwSSPIFlags,
|
||||||
SECURITY_NATIVE_DREP,
|
0,
|
||||||
NULL,
|
NULL,
|
||||||
&outBuffer,
|
&outBuffer,
|
||||||
&dwSSPIOutFlags,
|
&dwSSPIOutFlags,
|
||||||
|
Loading…
x
Reference in New Issue
Block a user