Rene Hollan wrote:

> Well, the BIO_write or BIO_read on the SSL BIO wrapping the 
> decrypted side of the SSL "black box" don't return WANT_* codes. 
> They return the number of chars transferred, or -1 in case of 
> error. At that point, one can get the SSL Error from the SSL session.

If you wrap the SSL decrypted streams in a bio, then you don't need 
WANT_READ/WANT_WRITE indications anyway. If data arrives at the socket, you're 
going to hand it to the BIO anyway. Deadlock should be impossible because you 
are servicing all four ports *independently*. You should never insist on "read 
before write" or "write before read".

Unless you have some already-received data the bio could not take, you should 
always be waiting for data from the socket to hand to the SSL engine. And you 
should always (any time you make forward progress on any port) be checking for 
data out from the SSL engine to go to the socket.
 
> The thing is, sometimes I don't get WANT_READ or WANT_WRITE in 
> that case, suggesting that something has to happen on one of the 
> other ports related to the SSL state machine.

Right, but you should be servicing those ports anyway.

> In particular I set up a bio pair on the network/encrypted side 
> (with 4096 byte buffers), and an SSL BIO on the decrypted side.

> I found that in one instance, I had what appeared to be 16384 
> (EXCACTLY 4 x 4K) byte encrypted SSL frames on the network side, 
> and got "stuck": I could not write to the network side of the BIO 
> pair to push received data through it (I can't wait until I can 
> do so and then select() in my app -- network data is pushed to me 
> as it arrives). The BIO write_guarantee was zero. If I tried to 
> read from the SSL bio, I DID NOT get WANT_READ, and no bytes were 
> returned. But, if I tried again to get the network side write 
> guarantee, low and behold, I got 4K! It looked like some kind of 
> state advance between the last decrypted buffer of four from the 
> last 16K encrypted SSL frame that did not provide data, but 
> consumed some to decrypt.

This is one of the irritations with OpenSSL. A read operation may make forward 
progress without telling you. For example, consider:

1) A renegotiation is in progress, we cannot write or read decrypted data until 
we receive renegotiation data from the socket. SSL_read and SSL_write will 
return WANT_READ. Our last SSL_read and SSL_write both returned WANT_READ.

2) The renegotiation data arrives on the socket, but we don't notice.

3) We call SSL_read. It reads the renegotiation data but not application data. 
It returns WANT_READ, since it cannot provide any application data until some 
arrives on the socket.

4) At this point, an SSL_write would succeed, but our last SSL_read and 
SSL_write both returned WANT_READ.

This is why it is very important to understand that any possible forward 
progress on any port (and a write operation that returns WANT_READ may have 
made forward progress!) requires you to retry all pending operations on all 
ports.

> I had to modify my app to see if I could write to the network 
> side of the BIO pair, read from the decrypted side, and if both 
> processed no data, try to write to the network side once more 
> IGNORING the WANT_READ/WRITE flag because it was not set. That 
> was a bit disconcerting.

Since you've wrapped everything in bios, you don't need the 
WANT_READ/WANT_WRITE flags. Just service all four ports. If data arrives, you 
will always try to give it to the encrypted bio, so why do you need a WANT_READ 
indication? If there's data on the encrypted out port, you're always going to 
send it over the socket, so why do you need a WANT_WRITE indication?
 
> So, I wonder if the WANT_READ/WANT_WRITE flags are consistent 
> when wrapping the decrypted side with SSL BIOs. I don't have to 
> use them -- it just seemed like a good idea at the time.

You can safely ignore them. You can also use them, but you have to remember 
that any possible forward progress on any port invalidates them.

DS


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

Reply via email to