I'm new to openSSL and I trying to figure out what the best / good solution is to create a https connection when using non blocking sockets, and libraries such as libevent, libev or libuv in combination with memory BIOs.
I'm trying to figure out how to manage openSSL calls/data and application data. In short my understanding of how a ssl client application should work is something like this:
As I'm using libuv (but this could be any other async/non-blocking library), I
have a read callback that gets called when data is received on the socket. When
I have data which must be written to the socket, I pass this data into a write
function of the library (in this uv_write()
), but in between this I need to put
the calls to SSL.
So after calling SSL_do_handshake(...), SSL stores some data into the writeBIO which I must read and pass into the socket. One question I was thinking about, how do I know that SSL stores data into this BIO, and secondly how do I know when I should send this over the socket.
After looking at some code, I figured out that I had to consume from the writeBIO
after calling SSL_do_handshake(). But the next steps are not clear to me. After s
ending the first bytes from the handshake the 'event' loop of libuv sets everything in motion; when new data arrives on the socket my 'onread()
callback is called. But
how do I handle this incoming data? (e.g. do I keep SSL state myself (<-- something
which some people have advised me not do to)).
Although I've seen lots of examples which use blocking sockets and the core SSL functions to make a connection I haven't found a good clean/minimalistic example which shows how to use memory BIOs as a client.
I've pasted some code I'm using to test openSSL here: https://gist.github.com/3989091
Someone around who can describe the process of using async/non-blocking sockets and memory BIOs with SSL?
Thanks R
I've also put together a basic example of using memory BIO's with non-blocking sockets and a poll based event loop.
ssl_server_nonblock.c
I don' think it makes sense to post all the source code of that example here. But here is the outline of what the example code does.
This diagram shows how the read and write memory BIO's (rbio & wbio) are associated with the socket read and write respectively. On the inbound flow (data into the program) bytes are read from the socket and copied into the rbio via BIO_write. This represents the the transfer of encrypted data into the SSL object. The unencrypted data is then obtained through calling SSL_read. The reverse happens on the outbound flow to convey unencrypted user data into a socket write of encrypted data.
+------+ +-----+
|......|--> read(fd) --> BIO_write(rbio) -->|.....|--> SSL_read(ssl) --> IN
|......| |.....|
|.sock.| |.SSL.|
|......| |.....|
|......|<-- write(fd) <-- BIO_read(wbio) <--|.....|<-- SSL_write(ssl) <-- OUT
+------+ +-----+
| | | |
|<-------------------------------->| |<------------------->|
| encrypted bytes | | unencrypted bytes |
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With