Hello again,

Thank you very much for the quick response! You're quite right, using
select on the bio pair doesn`t make much sense if the application always
has to perform something to "unblock" it. I was under the impression that
a bio write to the filter (bio pair + BIO_f_ssl) could fail and ask for a
retry without requiring the application to do anything. If I understand
correctly this could happen with a normal ssl bio (when socket calls are
handled by the library) but not with the bio pair since the application
is in charge of the socket calls. Is there any circumstance under which
the "ssl filter" could be computing something in the background and
requiring read/write retries?

I've spent quite some time experimenting with bio pairs and I'd like to
share my conclusions with this mailing list to confirm what I think I
understand and possibly to help out (or confuse?) others who are trying
to figure out how they can use bio pairs. Just to be clear, I'm using a
BIO_f_ssl combined with a bio pair and I will call the SSL end the one
that receives the cleartext data and the IO end the one that spits out
the encrypted data. Keep in mind that I'm not an expert at this and I
might very well be doing something wrong! Any feedback would be greatly
appreciated!

The ssl handshake is not initiated until a BIO_read or a BIO_write to the
SSL end of the filter. In order to force the initialization of the
handshake without actually exchanging data it is possible to call those
functions with the buffer length set to 0. The calls to BIO_read and
BIO_write will return -1 until the handshake is completed.
BIO_should_retry(ssl_bio) will return 1, which means that we have to
retry the call with the same arguments later.

BIO_should_read(ssl_bio) will return the number of bytes that must be fed
into the IO end of the filter before the call to BIO_write/read can be
processed. BIO_ctrl_pending(io_bio) will return the number of bytes that
can be read from the IO end of the filter. The first call to
BIO_write/read on the client side will cause some data to appear on the
IO end of the filter: this data must be sent to your peer. In the case of
the server no data will be generated yet and the BIO_ctrl_pending(io_bio)
will indicate the number of bytes that the filter is waiting for.

SSL data will have to be exchanged a few times between the IO ends of the
peers before the handshake can be completed. SSL_in_init(ssl) will return
1 after the first successful write (and maybe read as well?) to the SSL
end of the filter. If I understand correclty here are the different
return values from BIO_read/write that we should handle:

1. Length of the data read / written: success.
2. BIO_write returns less than the number of bytes that were supposed to
be written: fatal error?
3. 0: fatal error?
4. -1: An error but it might not be fatal:
        - BIO_should_retry(bio) = 0: fatal error?
        - BIO_should_retry(bio) = 1: non-fatal...
                - BIO_should_read(bio) = 1: the filter is waiting to
receive data on the other end of the filter
                - BIO_ctrl_pending(other end) = 1: data is ready to be
read at the other end
                - none of the above: should retry later (can this
actually happen with bio pairs?)
5. -2: I've read that this could be returned but it doesn`t seem to be
taken into account in ssltest.c...

The buffer size in the bio pair seems to be a little tricky. If the
buffers are not large enough to contain all the ssl data that the
BIO_f_ssl has generated the data will be transfered in chunks. The tricky
thing is that a BIO_read on the IO end will not make the BIO_f_ssl
transfer the rest of the data into the bio pair buffers automatically. To
trigger this you have to do a BIO_read or a BIO_write to the SSL end.
Again you can trick the filter by using zero-length buffers in your
BIO_read/write calls.

Does this all seem correct? I've tested my assumptions and so far this
seems to work but I'm a bit worried about rarely occuring conditions that
could make this fail. I'm integrating openssl into an application that is
multithreaded and some threads will be blocking while the "ssl thread"
does its thing so I have to be careful not to cause any deadlocks...

I'm still unclear about a few things. Can BIO_ctrl_pending be used on the
SSL end (BIO_f_ssl)? It looks like you can't: when I do a
BIO_ctrl_pending(ssl_bio) during the handshake I get a non-zero value
even though there is nothing to be read there.

I've also had problems testing the behavior of my test programs when the
is no certificate or when the certificate is invalid. When I set both
communicating entities to verify certificates and I don't give a
certificate to the client it looks like the server is waiting forever for
the client cert. I thought the client would be sending something to tell
the server that it has no certificate. Am I right? Something similar
happens when I "disable" the trusted CA's certificate on the client side:
both the server and the client end up waiting for a message from its
peer. All this is happening in a relatively complex and very badly
written test program so I might very well be handling something
incorrectly.

I would greatly appreciate any feedback about all this! BTW if someone
who's more knowledgeable than me is willing to proofread it, I'd be happy
to write an howto guide about bio pairs... Openssl is a great library but
the lack of documentation make the learning curve a little steep. I'd be
happy to write about what I understand but I don't have enough experience
with openssl to consider myself a good reference...


Thanks in advance,

Vincent Levesque
[EMAIL PROTECTED]


Bodo Moeller wrote:

> On Fri, Jul 30, 1999 at 12:23:00AM +0200, Bodo Moeller wrote:
> > From: Vincent Levesque <[EMAIL PROTECTED]>:
>
> >> I'm using a bio pair combined with an ssl_f_bio, [...]
>
> > [...] SSL_ERROR_WANT_READ [...] SSL_ERROR_WANT_WRITE [...]
>
> As you said that you're using BIO_f_ssl (modulo case and sorting),
> SSL_ERROR_WANT_READ/WRITE is on a lower level than the one you're
> using -- I should have referred to BIO_should_read and
> BIO_should_write, applied to your SSL BIO.  Note that an SSL_read
> can result in BIO_should_write and an SSL_write result can result in
> BIO_should_read: it is not about what BIO call you should retry,
> but about what kind of I/O the lower level has to do so that the
> SSL library can proceed with the protocol.
> ______________________________________________________________________
> OpenSSL Project                                 http://www.openssl.org
> Development Mailing List                       [EMAIL PROTECTED]
> Automated List Manager                           [EMAIL PROTECTED]

______________________________________________________________________
OpenSSL Project                                 http://www.openssl.org
Development Mailing List                       [EMAIL PROTECTED]
Automated List Manager                           [EMAIL PROTECTED]

Reply via email to