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

Ajay Garg ajaygargnsit at gmail.com
Fri Oct 7 17:00:06 UTC 2016


Thanks for the reply Viktor.

On Fri, Oct 7, 2016 at 8:27 PM, Jakob Bohm <jb-openssl at wisemo.com> wrote:
> On 07/10/2016 16:35, Ajay Garg wrote:
>>
>> Hi Viktor.
>>
>> Thanks for your reply, and I am sorry for being idiotic, OpenSSL does
>> seem daunting, but I am learning :)
>>
>> Also, let's not bother too much about the APIs/methods as such.
>> I will be grateful if you could confirm/reject my
>> architectural-understanding so far.
>>
>> Let's say "bio1" is the SSL-BIO, and "bio2" is the In-Memory-BIO, and
>> they have been made a pair, with the architecture being ::
>>
>> App <=> bio1 <=> bio2 <=> device-specific-socket
>>
> One caveat for both scenarios below:
>
> RW2a: During step R2 or W2, the SSL/TLS protocol may need to
> transmit some data in the opposite direction in order to handle
> automatically setting or changing the encryption keys etc.  Thus
> during W2, some data may be read from bio2 and during R2, some
> data may be written to bio2.
>
> This doesn't happen every time, but it always happens for the
> first app-payload-bytes, and it may happen at any later time
> subject to changes as the protocol and/or library are improved.

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, 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.

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). 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.

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).


Is my understanding correct (especially for the case if
blocking-sockets are being used throughout)?

If yes, then it seems everything can be done fully synchronously for
blocking-sockets, thus eliminating the need of multiple threads, and
thus enabling us to integrate OpenSSL seamlessly in our already
existing framework across all devices that we have ported our
framework to (devices with/without operating-systems, with/without
GPRS/Wifi).

So, eagerly awaiting your reply :)



Thanks a ton for the lightning-quick help so far !!!!



Thanks and Regards,
Ajay


>
>
>> So, for writes, following steps can be made to happen synchronously
>> (even with blocking device-specific-sockets) ::
>>
>>     W1. App writes x app-payload-bytes to bio1.
>>
>>     W2. Internally, x app-payload-bytes (at bio1) become y
>> app-payload-encrypted-bytes (at bio2).
>>
>>     W3. Thereafter, the y app-payload-encrypted-bytes are transferred
>> over the wire via the device-specific-socket.
>>
>> I think W2 is the key-step architecturally.
>>
>>
>> For reads, following steps can be made to happen synchronously (even
>> with blocking device-specific-sockets, carrying read-timeout feature)
>> ::
>>
>>    R1. App wants x app-payload-bytes.
>>
>>    R2. If bio1 can produce at least x app-payload-bytes, then we are done.
>>
>>          Else, we read some (let's say n) app-payload-encrypted-bytes
>> from device-specific-socket, write them into bio2, and
>>          again enquire if bio1 can now produce at least x
>> app-payload-bytes.
>>
>>          If still not, we keep reading n app-payload-encrypted-bytes
>> from device-specific-socket and writing them into bio2, until
>>          bio1 can produce at least x app-payload-bytes.
>>
>>    R3. Finally, App reads x app-payload-bytes.
>>
>> Here too, I think R2 is the key-step architecturally.
>>
>>
>>
>> Is my above architectural-understanding of the workflow between App
>> and Device-Specific-Socket correct?
>>
>>
>> Anyway, thanks for your help so far.
>>
>>
>> Thanks and Regards,
>> Ajay
>>
>>
>>
>>
>> On Fri, Oct 7, 2016 at 3:25 PM, Viktor Dukhovni
>> <openssl-users at dukhovni.org> wrote:
>>>
>>> On Fri, Oct 07, 2016 at 12:28:46PM +0530, Ajay Garg wrote:
>>>
>>>> I realise I am still stuck with the original issue.
>>>
>>> Failure to read the documentation closely.
>>>
>>>> Also, how do "bio1" and "bio2" communicate in case of non-ideal
>>>> scenarios (timeouts, errors)?
>>>
>>> They don't, you move all the data.  All reads/writes by OpenSSL will
>>> return SSL_ERROR_WANT_READ/SSL_ERROR_WANT_WRITE when the requisite
>>> data is not already buffered.  At that point you do the requsite
>>> I/O and copy data into and out of the network bio.
>>>
>>> First, do all pending writes:
>>>
>>>      BIO_ctrl_pending(network_bio)
>>>      BIO_read(network_bio, ...)
>>>
>>>      ... write the opaque ciphertext to the underlying socket-like
>>>      ... thing when it is writable, take to not block or drop
>>>      ... the ciphertext on the floor if you do.
>>>
>>> then if SSL_ERROR_WANT_READ, find out how much OpenSSL wants to
>>> read, and read that much data from the underlying socket-like thing
>>> and copy its (opaque ciphertext) into the network bio:
>>>
>>>      BIO_ctrl_get_read_request(network_bio)
>>>      BIO_write(network_bio, ...)
>>>
>>> A double-buffer (separate read/write) between the socket and SSL
>>> may make the logic simpler, but the write side must be flushed
>>> whenever to the SSL network BIO becomes empty, to avoid deadlock.
>>> And of course avoid blocking on reads when it is OpenSSL's turn to
>>> write.  In general you have an event loop, a non-blocking socket
>>> thingy, and select/poll/... read/write or both depending on
>>> SSL_ERROR_WANT_READ/WRITE and the state of any intermediate buffers
>>> you're managing.
>>>
>>> A careful read of the manpage will expose all these facilities.
>
>
> Enjoy
>
> Jakob
> --
> Jakob Bohm, CIO, Partner, WiseMo A/S.  https://www.wisemo.com
> Transformervej 29, 2860 Søborg, Denmark.  Direct +45 31 13 16 10
> This public discussion message is non-binding and may contain errors.
> WiseMo - Remote Service Management for PCs, Phones and Embedded
>
>
> --
> openssl-users mailing list
> To unsubscribe: https://mta.openssl.org/mailman/listinfo/openssl-users



-- 
Regards,
Ajay


More information about the openssl-users mailing list