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