Hi,
some time ago I described an annoying problem I have with the usage of
OpenSSLs crypto-functions in a multi-threaded environment on the
Apache-mailinglist. Because the problem cannot be solved with the now
available instruments I was given the advice to discus this problem on
the APR-mailinglist, so that the APR-OpenSSL-guys are aware of that
problem and might build the needed wrappers/functionalities. :-) (For
the discussion see:
http://marc.theaimsgroup.com/?l=apache-httpd-dev&m=116535180024531&w=2)
And now my problem:
The OpenSSL-library offers more than just SSL and TLS: It is also a
general purpose cryptography library! But there is a problem with the
usage in a multi-threaded environment, because the OpenSSL-library is
not thread-safe per se. Fortunately there is a 'trick' to make it
thread-safe as stated in
http://www.openssl.org/docs/crypto/threads.html#DESCRIPTION (and also
noted on
http://httpd.apache.org/docs/2.2/developer/thread_safety.html#liblist):
"OpenSSL can safely be used in multi-threaded applications provided that
at least two callback functions are set."
This means two functions: 'CRYPTO_set_locking_callback' and
'CRYPTO_set_id_callback'. And here starts my problem: It might be that
another module already might have done this and there is no way to find
it out! OK, there are functions like 'CRYPTO_get_locking_callback' and
'CRYPTO_get_id_callback' to retrieve the information whether these
callbacks have already been set or not, but that won't help (and
additionally is a bad programming style)! See this scenario:
Currently the Apache-module mod_ssl is setting these two callbacks (in
modules/ssl/ssl_util.c)! If that module is loaded and inited before mine
it works, because the callbacks are set and I am able to determine this.
If my module is loaded before mod_ssl is inited I have a problem! When I
set the two callbacks and afterwards mod_ssl is doing this too, bad
things might happen! (This is only one trivial example.)
OK, you might say that mod_ssl is wrong and it should first determine if
the callbacks have been set before setting them, but then I (and
possibly others) would argue, why everyone unnecessarily has to
duplicate code? Why is there no API-call for
'make-this-library-thread-safe-if-not-already-done'? Or why doesn't this
happen magically/automatically when I use the
'start-to-use-library'-call (e.g. inside apu_ssl_init)? (Especially as
it might be not that trivial for every module-writer to set the
callbacks with the correct thread-safe-making function-values for all
availbale platforms!!)
What do you think?
Frank
P.S.: And in case you wonder what crypto-functions I want to use in
OpenSSL: EVP_EncryptInit, EVP_EncryptUpdate, EVP_EncryptFinal, and
especially EVP_CIPHER_CTX_init!