On Mon, 2008-03-10 at 17:23 -0600, Bryan Sutula wrote: > My questions: > 1. What I understand from this is that OpenSSL can be thread safe. > In order for it to be safely used in multi-threaded > applications, it needs: > A. to be built with multi-threaded versions of the standard > libraries, > B. to have the application provide the two callback > functions, and > C. the application must avoid using the same SSL connection > by two different threads. > All of the above are necessary. In other words, it isn't > sufficient that OpenSSL was built with the multi-threaded > versions of the standard libraries. The application must also > set up the callbacks. (True or False, please?)
True. OpenSSL's role is not to be a threads implementation, nor a wrapper around all known or conceivable threads implementations, it's role is to allow you to glue it to the thread implementation you intend to use. Hence the callbacks. > 2. Related to question 1, the thread-safe requirements (A and B > above) are needed even if the different threads are not sharing > an SSL connection. (My understanding is that connections can't > ever be shared, and that the library still needs A and B in > order to be thread-safe.) (True or false?) True. The different SSL contexts operating in different threads will still be using shared structures that need to be synchronised. Eg. the SSL_CTX that the SSL objects were derived from, certificates and certificate-stores, public-keys, some global data specific to some other corners of the libcrypto and/or libssl implementations, etc. > 3. Instead of B (implementing the two callback functions), is it > sufficient for the application to provide it's own locking > around all SSL library calls? In other words, if the > application guarantees that only one thread will be in the > library at a time, is that sufficient? Sure, but you'd have to mutex all accesses to *any* openssl interface. Eg. see my answer to 2. If time spent in openssl is a miniscule percentage of your run-time profile, then this may be tolerable. But otherwise, you really don't want to be serialising all threads for any use of openssl interfaces. The locking callbacks allow you to implement the minimum required locking at the appropriate granularities (there are CRYPTO_num_locks() different locks). The contention is likely to be a lot less than if you lock your own code before it calls into openssl ... > 4. I'm guessing from the semantics of CRYPTO_set_locking_callback() > and CRYPTO_set_id_callback(), that they are not to be called > more than once from an application. It seems like they have to > be called only at the beginning of the program, and not ever > again. (True or False?) Is there a way to know if they have > already been called later on? True, I think. I guess if you have some guarantee that the process is quiesced (ie. "everyone please shut up for a moment while I change the locking"), then you could conceivably change these. But not "on the fly", if you get my point. There may also be some "fail if they've already been set" checking in openssl, in which case this would fail. As always, you have access to the source code - feel free to dig. Finally, yes, you can call CRYPTO_get_locking_callback() and CRYPTO_get_id_callback() to see if they've already been called. > 5. There are some other "dynlock" functions described in the > threads(3) man page. The wording on that page implies that they > are only needed for performance, or maybe in a future version. > In my current application, they don't seem to be called. Is it > necessary to implement these? Will they only be for > performance? If I don't implement them, will my application > break in some future version of OpenSSL, or will it just run > slower? (The confusion results because the current man page has > wording: "Multi-threaded applications might crash at random if > it is not set", but also says "dynamic locks are currently not > used internally by OpenSSL, but may do so in the future" and > "some parts of OpenSSL need it for better performance".) What's > the real situation here? I agree that this is fuzzy. It should be fine not to provide dynlock functionality for now, but of course be aware that if you maintain your code going forward there may come a time where functionality within openssl (or more likely, run-time/loadable extensions to openssl, such as hardware/enhancement support) will fail due to its inability to create new locks on the fly. Only you can judge whether this is or will be an issue. > 6. Question 4 applies to the dynlock setup functions as well. Same > answer about calling them multiple times? Any user-callable API > to know whether they've already been called? Yes, they all have s/set/get/ counterparts you can call to retrieve the currently registered callbacks. They should be NULLs until set otherwise by the user of the API. BTW, please correct me if you find this not to be the case (eg. if there is an internal lazy-initialisation to a non-NULL callback) because any "falling back to a default implementation" should be done without needing to internally set callbacks non-NULL. > 7. Not specifically concerning threads, but is it safe to call > SSL_library_init() more than once? (Does the library protect > against that, returning immediately if the initialization is > already done? Many libraries do this.) How about > SSL_load_error_strings()? ERR_load_BIO_strings()? AFAICT no, you should avoid calling these multiple times from the same address space. But as you're the guy providing the locking callbacks, I'm sure you can find some mechanism on "your side" to make sure the initialisation only happens once? :-) Cheers, Geoff ______________________________________________________________________ OpenSSL Project http://www.openssl.org User Support Mailing List openssl-users@openssl.org Automated List Manager [EMAIL PROTECTED]