[openssl-users] Root-Level queries while using SSL-connections wrapping "sockets"

Ajay Garg ajaygargnsit at gmail.com
Fri Oct 7 18:35:24 UTC 2016


Thanks Viktor.

On all our device-types, we are using blocking-sockets, but reads can
signal that no data is available (equivalent to SO_RCVTIMEO value set
as the socket-option on linux-like systems).

It seems you have provided me enough insight to get my hands dirty :)


Thanks and Regards,
Ajay

On Fri, Oct 7, 2016 at 11:17 PM, Viktor Dukhovni
<openssl-users at dukhovni.org> wrote:
> On Fri, Oct 07, 2016 at 10:30:06PM +0530, Ajay Garg wrote:
>
>> Ok, so for sending app-payload-bytes, we do a bio_write() to "bio1",
>> and if "bio1" requires reading from bio2/peer, bio_write() will return
>> SSL_ERROR_WANT_READ (even for blocking sockets). We then read-in some
>> app-payload-encrypted-bytes from device-socket,
>
> No, it will *usually* return SSL_ERROR_WANT_WRITE, that's when you
> write "some" (based on pending data amount from bio2) to the network
> that you read from bio2.  Those writes might be written via a buffer
> you interpose, however it is important to flush that buffer as
> much as possible before attempting any network reads (flush fully
> if the network reads are potentially blocking).
>
> However, it might sometimes return SSL_ERROR_WANT_READ, in which
> case, the SSL layer wants to read, even though the application
> wants to write.  Your job is to do the read on the SSL layer's
> behalf, and then retry the write.
>
> Where "some" is obtained by queried bio2 for the amount of pending
> data.  You can loop reading/sending smaller amounts that if the
> entire amount is too big to write to the target in one go without
> blocking.  Otherwise, you need a large enough write buffer downstream.
> If you can't fully drain bio2's output in one go, just keep the
> socket selected for write and try again later when more space is
> available.
>
>> put them into "bio2"
>> (thus internally fulfilling bio1's need for read), and then again try
>> bio_write() to "bio1" WITH IDENTICAL APP-PAYLOAD-BYTES. If it again
>> returns SSL_ERROR_WANT_READ, we repeat the cycle.
>
> Well, you may not fulfill that need, if you don't drain all the
> pending data, and so the SSL_ERROR_WANT_... may repeat.  What you
> do with bio2 has no direct relationship on the direction of the
> I/O in bio1.  Just keep track of whether the crypto wants to read
> or write, and whether either bio2 or any buffer you interpose
> downstream has pending data.  Then move data between the network
> and bio2 as appropriate.
>
>> For reading app-payload-bytes, we do a bio_read() from "bio1", and if
>> "bio1" requires writing bytes to bio2/peer, bio_read() will return
>> SSL_ERROR_WANT_WRITE (even for blocking sockets).
>
> No, it will *usually* return SSL_ERROR_WANT_READ, that's when you
> read "some" (based on desired read size from bio2) from the network
> and write the results to bio2.  Those reads might be satisfied from
> a buffer you interpose.
>
> However, it might sometimes return SSL_ERROR_WANT_WRITE, in which
> case, the SSL layer wants to write, even though the application wants
> to read.  Your job is to do the write on the SSL layer's behalf,
> and then retry the read.
>
>> We then pick up the
>> app-payload-encrypted-bytes from "bio2", transfer them over the wire
>> via device-specific-socket (thus fulfilling bio1's need to send bytes
>> to peer), and then again try bio_read() from "bio1" WITH IDENTICAL
>> APP-PAYLOAD-BYTES. If it again returns SSL_ERROR_WANT_WRITE, we repeat
>> the cycle.
>
> When retrying app-layer reads, you do not need to provide the same
> buffer or read request size on subsequent attempts.
>
>> Obviously, for the above two sub-plots, the only chance of failure if
>> reading/writing bytes fails over the wire.
>> But that is not the norm; if it does happen, then everything will be
>> restarted from scratch (at least by me).
>
>> If yes, then it seems everything can be done fully synchronously for
>> blocking-sockets,
>
> No, synchronous operation will not work.  The network may not be
> ready to receive more data when you're ready to write (network
> layer data), or have more data when you're ready to read.  Use of
> bio-pairs with blocking sockets is highly risky, you'll probably
> dead-lock with some regularity.
>
>> thus eliminating the need of multiple threads,
>
> You don't need threads, an event loop will do.  Indeed an event
> loop is generally better, don't know whether the same bio-pair is
> safe for use by multiple threads.
>
> You just need to be able to perform the equivalent of
>
>         select()/poll()/...
>
> on whatever interface you have for moving data to/from
> the network.
>
> --
>         Viktor.
> --
> openssl-users mailing list
> To unsubscribe: https://mta.openssl.org/mailman/listinfo/openssl-users



-- 
Regards,
Ajay


More information about the openssl-users mailing list