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!