Hi, all!



How can i do handshake before using BIO pairs for encrypt/decrypt, if as

transport i use Winsock(WSASend and WSARecv)?



some example



this is send function:
DWORD CSSLTLSLayer::Send(IN OVERLAPPED *pOverlapped,
IN WSABUF *pBuffer,
OUT PDWORD pdwWasSend)
{
size_t iBuffered = BIO_write(m_pSSLBIO, pBuffer->buf, pBuffer->len);

BIO_flush(m_pSSLBIO);
iBuffered = (int)BIO_ctrl_pending(m_pNetworkBIO);

if (iBuffered <= 0){
return(WSA_IO_PENDING);
}

m_vcLayeredBuffer.clear();
m_vcLayeredBuffer.resize(iBuffered);

iBuffered = BIO_read(m_pNetworkBIO,
&m_vcLayeredBuffer.front(),
(int)iBuffered);

pBuffer->buf = &m_vcLayeredBuffer.front();
pBuffer->len = (u_long)m_vcLayeredBuffer.size();

//Method of parent class which only send message as WSASend()
DWORD dwStatus = __super::Send(pOverlapped, pBuffer, pdwWasSend);

return(dwStatus);
}
DWORD CSSLTLSLayer::Send(IN OVERLAPPED *pOverlapped,
IN WSABUF *pBuffer,
OUT PDWORD pdwWasSend)
{
size_t iBuffered = BIO_write(m_pSSLBIO, pBuffer->buf, pBuffer->len);

BIO_flush(m_pSSLBIO);
iBuffered = (int)BIO_ctrl_pending(m_pNetworkBIO);

if (iBuffered <= 0){
return(WSA_IO_PENDING);
}

m_vcLayeredBuffer.clear();
m_vcLayeredBuffer.resize(iBuffered);

iBuffered = BIO_read(m_pNetworkBIO,
&m_vcLayeredBuffer.front(),
(int)iBuffered);

pBuffer->buf = &m_vcLayeredBuffer.front();
pBuffer->len = (u_long)m_vcLayeredBuffer.size();

//Method of parent class which only send message as WSASend()
DWORD dwStatus = __super::Send(pOverlapped, pBuffer, pdwWasSend);

return(dwStatus);
}


this is receive function (common problem, because DWORD Send() work
correctly):


DWORD CSSLTLSLayer::Receive(IN OVERLAPPED *pOverlapped,
IN WSABUF *pBuffer,
OUT PDWORD pdwWasRecv)
{
if (!m_bKEXed){
this->Handshake();
this->InitBIOAbstractions();
return 0;
}

//Receive method in parent class only do WSARecv()
DWORD dwRet = __super::Receive(pOverlapped, pBuffer, pdwWasRecv);

BIO_write(m_pNetworkBIO, pBuffer->buf, *pdwWasRecv);
BIO_flush(m_pNetworkBIO);

size_t iBuffered = BIO_ctrl_pending(m_pSSLBIO);

if (iBuffered <= 0){
return(WSA_IO_PENDING);
}

m_vcLayeredBuffer.clear();
m_vcLayeredBuffer.resize(iBuffered);
iBuffered = BIO_read(m_pSSLBIO, &m_vcLayeredBuffer.front(),
(int)iBuffered);

pBuffer->buf = &m_vcLayeredBuffer.front();
pBuffer->len = (u_long)m_vcLayeredBuffer.size();

return(dwRet);
}
DWORD CSSLTLSLayer::Receive(IN OVERLAPPED *pOverlapped,
IN WSABUF *pBuffer,
OUT PDWORD pdwWasRecv)
{
if (!m_bKEXed){
this->Handshake();
this->InitBIOAbstractions();
return 0;
}

//Receive method in parent class only do WSARecv()
DWORD dwRet = __super::Receive(pOverlapped, pBuffer, pdwWasRecv);

BIO_write(m_pNetworkBIO, pBuffer->buf, *pdwWasRecv);
BIO_flush(m_pNetworkBIO);

size_t iBuffered = BIO_ctrl_pending(m_pSSLBIO);

if (iBuffered <= 0){
return(WSA_IO_PENDING);
}

m_vcLayeredBuffer.clear();
m_vcLayeredBuffer.resize(iBuffered);
iBuffered = BIO_read(m_pSSLBIO, &m_vcLayeredBuffer.front(),
(int)iBuffered);

pBuffer->buf = &m_vcLayeredBuffer.front();
pBuffer->len = (u_long)m_vcLayeredBuffer.size();

return(dwRet);
}


and Handshake() method:


void CSSLTLSLayer::Handshake(void){

if (!m_bKEXed && m_pSSL){
SSL_set_fd(m_pSSL, (int)m_Socket);
SSL_set_accept_state(m_pSSL);
SSL_do_handshake(m_pSSL);
m_bKEXed = true;
}

return;
}
void CSSLTLSLayer::Handshake(void){

if (!m_bKEXed && m_pSSL){
SSL_set_fd(m_pSSL, (int)m_Socket);
SSL_set_accept_state(m_pSSL);
SSL_do_handshake(m_pSSL);
m_bKEXed = true;
}

return;
}


after Handshake() calling in Receive() i always request 0 bytes and empty
buffer... why?

maybe i can do handshake without using SSL_set_fd(), SSL_set_accept_state()
and SSL_do_handshake()?

Thanks for support!