On Mon, Aug 09, 1999 at 10:48:54AM -0400, Vincent Levesque wrote:
[...]
> 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.
Yes. However most people seam to prefer not to use the SSL BIO
(implemented in ssl/bio_ssl.c), but to use the SSL_... API directly.
Then you can call SSL_connect or SSL_accept directly if you want to.
> 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.
No, it' just a flag. If you want to know how many bytes the SSL
implementation tried to read, you have to look at the IO BIO, i.e.
call BIO_ctrl_get_read_request(io_bio).
> 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?
In the case of an SSL BIO, unless you call SSL[_CTX]_set_mode with an
appropriate parameter, you won't see a return value the is positive
but less than the requested number of bytes. In other cases,
BIO_write may return less; then you should feed it the rest of the
data later (just as with the standard write/send functions). For a
BIO pair you have the guarantee that BIO_ctrl_get_read_request never
asks for more than the next BIO_write will accept, so you can avoid
these short writes.
> 3. 0: fatal error?
This can happen if the peer closed the connection. Whether this is an
error depends on the application protocol.
> 4. -1: An error but it might not be fatal:
> - BIO_should_retry(bio) = 0: fatal error?
Yes. Look at the error queue for details (see ERR_print_errors
in crypto/err/err_prn.c for an example for this).
> - 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
Yes. You don't have to use BIO_should_read if you call
BIO_ctrl_get_read_request(other_end) -- it tells you the number of
bytes requested, which may help for I/O (e.g. if you have to allocate
buffers for reading from the network).
> - none of the above: should retry later (can this
> actually happen with bio pairs?)
No, at least not directly after the incompleted I/O operation.
If you later feed data into the I/O end of the BIO pair,
BIO_ctrl_get_read_request will be reset.
> 5. -2: I've read that this could be returned but it doesn`t seem to be
> taken into account in ssltest.c...
This happens only in pathological cases (uninitialized BIOs),
but the code should take care of this possibility. I've now changed
it.
> 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.
If the write buffer fills up, writing to the SSL BIO will return -1
and BIO_should_retry_write(ssl_bio) will be true. After taking the
data from the I/O BIO, you have to call BIO_write for the SSL BIO
again with the same parameters. Repeat until BIO_write reports
success or a real error (and you've transferred the remaining data
over the network or wherever you want to send it to).
> 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...
The SSL library, when used with BIO pairs, never locks. Of course
your handling of the BIO pair can block (when sending data obtained
from the I/O BIO over a network, or when waiting for data from the
network that has to be fed into the I/O BIO).
> 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.
The problem with it is that it does not look at the block type of the
SSL records. This renders it largely useless. You can try to read a
byte or so from the SSL BIO -- your application will have to buffer it
internally if it is not immediately needed.
> 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.
They should not be waiting (i.e. BIO_should_retry should return 0) --
the calls to BIO_read/BIO_write return -1 because a real error
occured.
______________________________________________________________________
OpenSSL Project http://www.openssl.org
Development Mailing List [EMAIL PROTECTED]
Automated List Manager [EMAIL PROTECTED]