You're on the right track, but you have to consider how much data can be
written to the encrypted side of the bio pair before you read it from
the socket, and the fact that you might have to read from the encrypted
side of the bio pair and write to the socket to get things going (i.e.
send the initial client hello).

Furthermore, while you can tell how much data you can write to a BIO
before it will block, you can't really do this with a socket: you can
write and it will tell you how much was written. So, expect another
layer of buffering between the encrypted side of the BIO pair and the
network socket.

Finally, if you chose to wrap the SSL engine with a BIO as well, you
might run into the situation where you can't write network data to the
encrypted side for lack of room, and reading from the SSL decrypted side
yields nothing, but now makes it possible to write network data to the
encrypted side.

I've also found, that BIO_should_retry can be somewhat unreliable in
these circumstances.

-----Original Message-----
From: owner-openssl-us...@openssl.org
[mailto:owner-openssl-us...@openssl.org] On Behalf Of Aaron Wiebe
Sent: Thursday, May 28, 2009 11:49 AM
To: openssl-users@openssl.org
Subject: Re: nonblocking implementation question

On Tue, May 26, 2009 at 5:27 PM, Victor Duchovni
<victor.ducho...@morganstanley.com> wrote:
> On Tue, May 26, 2009 at 05:02:59PM -0400, Aaron Wiebe wrote:
>
>> >> You're looking for a BIO_s_mem.
>> >
>> > No, he is looking for BIO_new_bio_pair(3) and SSL_set_bio(3).

So, apologies for hammering this down, but I'm still a little fuzzy
and the documentation is lacking..

This would be in theory how to perform this work:

ctx = SSL_ctx_new();
myssl = SSL_new(ctx);
BIO_new_bio_pair(app_bio, 0, net_bio, 0);
SSL_set_bio(myssl, app_bio, app_bio);

Now, for a write sequence...

BIO_write(app_bio, buffer, len);   /* unencrypted */
BIO_read(net_bio, buf, size);  /* encrypted */
write(fd, buf, size);

and the same in reverse:

len = recv(fd, &buf, size);
BIO_write(net_bio, buf, len);
len = BIO_read(app_bio, buffer, size);


This is ignoring the obvious semantics involved in various other types
of situations, such as renegotiations or other state changes that
might be involved.  Am i on the right track?  If this makes my BIO
calls asynchronous, is the expectation that the other side of the BIO
pair will be ready immediately, assuming a clean response?

Thanks again all,
-Aaron
______________________________________________________________________
OpenSSL Project                                 http://www.openssl.org
User Support Mailing List                    openssl-users@openssl.org
Automated List Manager                           majord...@openssl.org
______________________________________________________________________
OpenSSL Project                                 http://www.openssl.org
User Support Mailing List                    openssl-users@openssl.org
Automated List Manager                           majord...@openssl.org

Reply via email to