Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

SSL_read/SSL_write and select

2,358 views
Skip to first unread message

Luiz Rafael Culik Guimaraes

unread,
Aug 3, 2009, 9:06:15 AM8/3/09
to
Dear Friends

How to use properly SSL_read/SSL_write with select?
my default code with use standart api, make an call to select before call to
recv/send api


my code to read is like this


to Read i use
do
{
if( iPos == iAllocated - 1 )
{
iAllocated += iBufferSize;
Buffer = ( char * ) hb_xrealloc( Buffer, iAllocated );
}

if( hb_selectReadSocket( Socket ) )
{
iLen = SSL_read( Socket->pSSL, &cChar, 1 );
iRet = SSL_get_error( Socket->pSSL, iLen) ;
Socket->errorCode = iRet;
}
else
{
iTimeElapsed += Socket->timeout;


/* this signals timeout */
iLen = -2;
}

if( iLen > 0 )
{
/* verify endsequence recognition automata status */
if( cChar == szPattern[ ulPatPos ] )
{
ulPatPos ++;
if( ! szPattern[ ulPatPos ] )
{
break;
}
}
else
{
ulPatPos = 0;
}

Buffer[ iPos++ ] = cChar;
}
else
{
break;
}
}
while( iMax == 0 || iPos < iMax );

static int hb_selectReadSocket( HB_SSL_SOCKET_STRUCT *Socket )
{
fd_set set;
struct timeval tv;

FD_ZERO( &set );
FD_SET(Socket->com, &set);

if( Socket->timeout == -1 )
{
if( select( Socket->com + 1, &set, NULL, NULL, NULL ) < 0 )
return 0;
}
else
{
tv.tv_sec = Socket->timeout/ 1000;
tv.tv_usec = (Socket->timeout % 1000) * 1000;
if( select( Socket->com + 1, &set, NULL, NULL, &tv ) < 0 )
return 0;
}

return FD_ISSET( Socket->com, &set );
}

So , how can i change so can work correctly with openssl SSL_read/SSL_write
api

Thanks in advance

Regards
Luiz Rafael

______________________________________________________________________
OpenSSL Project http://www.openssl.org
User Support Mailing List openss...@openssl.org
Automated List Manager majo...@openssl.org

David Schwartz

unread,
Aug 3, 2009, 8:01:14 PM8/3/09
to

Luiz Rafael Culik Guimaraes wrote:

> How to use properly SSL_read/SSL_write with select?

Make sure to set the socket/BIO non-blocking. Call SSL_read or SSL_write
when you want to read or write plaintext to/from the SSL connection. *Only*
call 'select' on the underlying socket if OpenSSL specifically tells you to.

> my default code with use standart api, make an call to select
> before call to
> recv/send api

That won't work. Just because you want to receive unencrypted data, you
cannot assume that OpenSSL needs to receive encrypted data to do it. For
example, it may already have received the data from the socket. Don't try to
"look into" or "look through" the OpenSSL state machine. Treat it like a
black box with an encrypted side and a plaintext side.


> if( hb_selectReadSocket( Socket ) )
> {
> iLen = SSL_read( Socket->pSSL, &cChar, 1 );
> iRet = SSL_get_error( Socket->pSSL, iLen) ;
> Socket->errorCode = iRet;
> }

Here you are "looking through" the OpenSSL black box. You are saying if
encrypted data has been received by the black box, then I'll ask it for
plaintext. But this is an unecessary assumption that will not always be
correrct. So don't make it. Just call SSL_read if you want to read
plaintext. *Don't* call 'select' first because you have no idea whether or
not OpenSSL needs to read encrypted data.

> So , how can i change so can work correctly with openssl
> SSL_read/SSL_write
> api

When you want to read plaintext, call SSL_read. When you want to write
plaintext, call SSL_write. If OpenSSL cannot make forward progress because
it needs to read or write to or from the socket, it will tell you with a
WANT_READ/WANT_WRITE indication. *Then* you can call 'select'.

Note that the two directions of an OpenSSL connection are not independent.
Any forward progress in either direction invalidates a previous WANT_*
indication in the other direction.

DS

cul...@gmail.com

unread,
Aug 5, 2009, 6:55:13 AM8/5/09
to
Hi DS

Thanks for the explanation.

Regards
Luiz

> User Support Mailing List                    openssl-us...@openssl.org
> Automated List Manager                           majord...@openssl.org

0 new messages