|
Programming
Asynchronous SSL Clients
by Eddie Zaremba
Programming
blocking sockets, those sockets that wait until data has been
read or written, are actually quite easy to write, especially
when writing OpenSSL Clients; however, writing Asynchronous clients
can prove a little more challenging. Why is there hardly any documentation
on the subject?
First off,
OpenSSL was made to be compiled with ANSI compilers, not just
Windows Operating Systems which means keeping OpenSSL as generic
as possible. Secondly, the implementation in OpenSSL is rather
poor when it comes to targeting Asynchronous platforms such as
Windows, specifically the handshaking protocol.
When targeting
Asynchronous Sockets, an existing non-blocking asynchronous socket
must first be created. This will will have at its core the AsyncSelect()
function call that will establish the windows handle to receive
the FD_READ, FD_WRITE, FD_CONNECT, FD_CLOSE commands. This all
works very normal as described in the OpenSSL documentation.
After the
socket (file descriptor for unix) has been successfully assigned
to a BIO using the SSL_set_bio() function it is time to connect
to the host and this is the part that needs some more work. The
OpenSSL documentation describes the following process regarding
SSL_connect():
"The
behaviour of SSL_connect() depends on the underlying BIO.
If
the underlying BIO is B<blocking>, SSL_connect() will only
return once the handshake has been finished or an error occurred.
If
the underlying BIO is B<non-blocking>, SSL_connect() will
also return when the underlying BIO could not satisfy the needs
of SSL_connect() to continue the handshake. In this case a call
to SSL_get_error() with the return value of SSL_connect() will
yield B<SSL_ERROR_WANT_READ> or B<SSL_ERROR_WANT_WRITE>.
The calling process then must repeat the call after taking appropriate
action to satisfy the needs of SSL_connect(). The action depends
on the underlying BIO. When using a non-blocking socket, nothing
is to be done, but select() can be used to check for the required
condition. When using a buffering BIO, like a BIO pair, data must
be written into or retrieved out of the BIO before being able
to continue."
In the above
description you should pay special attention to the item underlined.
All that is needed if a return value is -1 is to repeat the call.
This is largely in part because in the background the client and
server are processing their handshake and upon completion the
server will accept the connection. For more information, please
review the source code to Visual SSL's TSSLClientSocket.
|