问题
OpenSSL documents state that it can safely be used in multi-threaded applications provided that at least two callback functions are set, locking_function and threadid_func....
I've written programs which use OpenSSL API. Moreover, I know how to use pthreads. However, the OpenSSL documents are written in the form of a manual, and I can't see a step-by-step guide on what I have to do when using OpenSSL in a multi-threaded app.
Is there a tutorial on using OpenSSL with pthreads? (I searched the web, but no satisfactory result appeared.)
PS: I'm working in Debian Lenny & Ubuntu Lucid/Maverick.
PS2: OpenSSL includes a sample, but it's far too complicated to start with.
回答1:
Chapter 10 of the book The Definitive Guide to Linux Network Programming includes a section Thread-safe Programming with OpenSSL (on pages 255-259). This section details how OpenSSL and the pthreads library work. Specially, it tells how to setup the callback functions both in static allocation (where the number of threads are known a priori) and dynamic allocation (where threads are created and destroyed on the fly).
Another good source is Section 4.1 of the book Network Security with OpenSSL, titled Multithread Support. It provides static/dynamic allocation mechanisms in subsections 4.1.1 and 4.1.2, respectively.
Finally, there's the book Unix-Netzwerkprogrammierung mit Threads, Sockets und SSL, which is by far the most comprehensive one on the subject. Unfortunately, the English translation of this German book is not available.
Edit: The above references are now considered obsolete, as OpenSSL 1.1.0 changelog explains:
OpenSSL now uses a new threading API. It is no longer necessary to set locking callbacks to use OpenSSL in a multi-threaded environment. There are two supported threading models: pthreads and windows threads. It is also possible to configure OpenSSL at compile time for "no-threads". The old threading API should no longer be used. The functions have been replaced with "no-op" compatibility macros.
[Alessandro Ghedini, Matt Caswell]
This is further elaborated in OpenSSL blog post OpenSSL and Threads.
See also this issue on OpenSSL GitHub repository, which is open since 2017.
回答2:
Don't know about a tutorial, but here are two libcurl-based examples that might help:
http://curl.haxx.se/libcurl/c/opensslthreadlock.html
http://curl.haxx.se/libcurl/c/threaded-ssl.html
回答3:
openssl must be configured with threads option
./config thread -D_REENTRANTIt's a matter of copy & paste; the openssl tar ball includes a sample in file
crypto/threads/mttest.c
copy relevant platform specific implementation & call thread_setup for initialization and thread_cleanup for wrap up;
回答4:
Based on Wodin's answer using cURL references, all I did was copy these 4 functions
#include <openssl/crypto.h> //In addition to other ssl headers
...
/* we have this global to let the callback get easy access to it */
static pthread_mutex_t *lockarray;
static void lock_callback(int mode, int type, char *file, int line)
{
(void)file;
(void)line;
if (mode & CRYPTO_LOCK) {
pthread_mutex_lock(&(lockarray[type]));
}
else {
pthread_mutex_unlock(&(lockarray[type]));
}
}
static unsigned long thread_id(void)
{
unsigned long ret;
ret=(unsigned long)pthread_self();
return(ret);
}
static void init_locks(void)
{
int i;
lockarray=(pthread_mutex_t *)OPENSSL_malloc(CRYPTO_num_locks() *
sizeof(pthread_mutex_t));
for (i=0; i<CRYPTO_num_locks(); i++) {
pthread_mutex_init(&(lockarray[i]),NULL);
}
CRYPTO_set_id_callback((unsigned long (*)())thread_id);
CRYPTO_set_locking_callback((void (*)(int, int, const char*, int))lock_callback);
}
static void kill_locks(void)
{
int i;
CRYPTO_set_locking_callback(NULL);
for (i=0; i<CRYPTO_num_locks(); i++)
pthread_mutex_destroy(&(lockarray[i]));
OPENSSL_free(lockarray);
}
Then call these two functions as follows
int main(int argc, char **argv)
{
//pthread initialization goes here
init_locks();
//pthread stuff here (create, join, etc)
kill_locks();
return 0;
}
That got rid of all weird errors with SSL_load_error_strings(); segfaults and double free condition from glibc.
来源:https://stackoverflow.com/questions/3919420/tutorial-on-using-openssl-with-pthreads