comparison src/c/openssl.c @ 2166:8a01e8f21de9

Make OpenSSL usage thread-safe (closes #206) Enable OpenSSL?s multithreading support by defining locking and thread-ID callbacks. Remove a lock obviated by this change.
author Benjamin Barenblat <bbaren@mit.edu>
date Thu, 06 Aug 2015 10:15:53 -0400
parents 882556b3029d
children ce312cad5ecd c275bbc41194
comparison
equal deleted inserted replaced
2165:7dfce558aca2 2166:8a01e8f21de9
1 #include "config.h" 1 #include "config.h"
2 2
3 #include <assert.h>
3 #include <stdlib.h> 4 #include <stdlib.h>
4 #include <unistd.h> 5 #include <unistd.h>
5 #include <sys/types.h> 6 #include <sys/types.h>
6 #include <sys/stat.h> 7 #include <sys/stat.h>
7 #include <fcntl.h> 8 #include <fcntl.h>
8 #include <stdio.h> 9 #include <stdio.h>
9 #include <string.h> 10 #include <string.h>
11 #include <pthread.h>
10 12
13 #include <openssl/crypto.h>
11 #include <openssl/sha.h> 14 #include <openssl/sha.h>
12 #include <openssl/rand.h> 15 #include <openssl/rand.h>
13 16
14 #define PASSSIZE 4 17 #define PASSSIZE 4
18
19 // OpenSSL locks array. See threads(3SSL).
20 static pthread_mutex_t *openssl_locks;
15 21
16 int uw_hash_blocksize = 32; 22 int uw_hash_blocksize = 32;
17 23
18 static int password[PASSSIZE]; 24 static int password[PASSSIZE];
19 25
25 perror("RAND_bytes"); 31 perror("RAND_bytes");
26 exit(1); 32 exit(1);
27 } 33 }
28 } 34 }
29 35
36 // OpenSSL callbacks
37 static void thread_id(CRYPTO_THREADID *const result) {
38 CRYPTO_THREADID_set_numeric(result, pthread_self());
39 }
40 static void lock_or_unlock(const int mode, const int type, const char *file,
41 const int line) {
42 pthread_mutex_t *const lock = &openssl_locks[type];
43 if (mode & CRYPTO_LOCK) {
44 if (pthread_mutex_lock(lock)) {
45 fprintf(stderr, "Can't take lock at %s:%d\n", file, line);
46 exit(1);
47 }
48 } else {
49 if (pthread_mutex_unlock(lock)) {
50 fprintf(stderr, "Can't release lock at %s:%d\n", file, line);
51 exit(1);
52 }
53 }
54 }
55
30 void uw_init_crypto() { 56 void uw_init_crypto() {
57 int i;
58 // Set up OpenSSL.
59 assert(openssl_locks == NULL);
60 openssl_locks = malloc(CRYPTO_num_locks() * sizeof(pthread_mutex_t));
61 if (!openssl_locks) {
62 perror("malloc");
63 exit(1);
64 }
65 for (i = 0; i < CRYPTO_num_locks(); ++i) {
66 pthread_mutex_init(&(openssl_locks[i]), NULL);
67 }
68 CRYPTO_THREADID_set_callback(thread_id);
69 CRYPTO_set_locking_callback(lock_or_unlock);
70 // Prepare signatures.
31 if (uw_sig_file) { 71 if (uw_sig_file) {
32 int fd; 72 int fd;
33 73
34 if (access(uw_sig_file, F_OK)) { 74 if (access(uw_sig_file, F_OK)) {
35 random_password(); 75 random_password();