adamc@1268
|
1 #include "config.h"
|
adamc@1268
|
2
|
bbaren@2166
|
3 #include <assert.h>
|
adam@1368
|
4 #include <stdlib.h>
|
adam@1368
|
5 #include <unistd.h>
|
adam@1368
|
6 #include <sys/types.h>
|
adam@1368
|
7 #include <sys/stat.h>
|
adamc@1145
|
8 #include <fcntl.h>
|
adam@1368
|
9 #include <stdio.h>
|
adam@1368
|
10 #include <string.h>
|
bbaren@2166
|
11 #include <pthread.h>
|
adamc@1104
|
12
|
bbaren@2166
|
13 #include <openssl/crypto.h>
|
adam@1368
|
14 #include <openssl/sha.h>
|
adam@2105
|
15 #include <openssl/rand.h>
|
adam@1368
|
16
|
adamc@1104
|
17 #define PASSSIZE 4
|
adamc@1104
|
18
|
bbaren@2166
|
19 // OpenSSL locks array. See threads(3SSL).
|
bbaren@2166
|
20 static pthread_mutex_t *openssl_locks;
|
bbaren@2166
|
21
|
adam@1368
|
22 int uw_hash_blocksize = 32;
|
adamc@1104
|
23
|
adamc@1104
|
24 static int password[PASSSIZE];
|
adamc@1104
|
25
|
adamc@1145
|
26 char *uw_sig_file = NULL;
|
adamc@1145
|
27
|
adamc@1145
|
28 static void random_password() {
|
adam@2105
|
29 if (!RAND_bytes((unsigned char *)password, sizeof password)) {
|
adam@2105
|
30 fprintf(stderr, "Error generating random password\n");
|
adam@2105
|
31 perror("RAND_bytes");
|
adam@2105
|
32 exit(1);
|
adam@2105
|
33 }
|
adamc@1145
|
34 }
|
adamc@1145
|
35
|
bbaren@2166
|
36 // OpenSSL callbacks
|
bbaren@2174
|
37 #ifdef PTHREAD_T_IS_POINTER
|
bbaren@2174
|
38 # define CRYPTO_THREADID_SET CRYPTO_THREADID_set_pointer
|
bbaren@2174
|
39 #else
|
bbaren@2174
|
40 # define CRYPTO_THREADID_SET CRYPTO_THREADID_set_numeric
|
bbaren@2174
|
41 #endif
|
bbaren@2166
|
42 static void thread_id(CRYPTO_THREADID *const result) {
|
bbaren@2174
|
43 CRYPTO_THREADID_SET(result, pthread_self());
|
bbaren@2166
|
44 }
|
bbaren@2174
|
45 #undef CRYPTO_THREADID_SET
|
bbaren@2166
|
46 static void lock_or_unlock(const int mode, const int type, const char *file,
|
bbaren@2166
|
47 const int line) {
|
bbaren@2166
|
48 pthread_mutex_t *const lock = &openssl_locks[type];
|
bbaren@2166
|
49 if (mode & CRYPTO_LOCK) {
|
bbaren@2166
|
50 if (pthread_mutex_lock(lock)) {
|
bbaren@2166
|
51 fprintf(stderr, "Can't take lock at %s:%d\n", file, line);
|
bbaren@2166
|
52 exit(1);
|
bbaren@2166
|
53 }
|
bbaren@2166
|
54 } else {
|
bbaren@2166
|
55 if (pthread_mutex_unlock(lock)) {
|
bbaren@2166
|
56 fprintf(stderr, "Can't release lock at %s:%d\n", file, line);
|
bbaren@2166
|
57 exit(1);
|
bbaren@2166
|
58 }
|
bbaren@2166
|
59 }
|
bbaren@2166
|
60 }
|
bbaren@2166
|
61
|
adamc@1104
|
62 void uw_init_crypto() {
|
bbaren@2166
|
63 int i;
|
bbaren@2166
|
64 // Set up OpenSSL.
|
bbaren@2166
|
65 assert(openssl_locks == NULL);
|
bbaren@2166
|
66 openssl_locks = malloc(CRYPTO_num_locks() * sizeof(pthread_mutex_t));
|
bbaren@2166
|
67 if (!openssl_locks) {
|
bbaren@2166
|
68 perror("malloc");
|
bbaren@2166
|
69 exit(1);
|
bbaren@2166
|
70 }
|
bbaren@2166
|
71 for (i = 0; i < CRYPTO_num_locks(); ++i) {
|
bbaren@2166
|
72 pthread_mutex_init(&(openssl_locks[i]), NULL);
|
bbaren@2166
|
73 }
|
bbaren@2166
|
74 CRYPTO_THREADID_set_callback(thread_id);
|
bbaren@2166
|
75 CRYPTO_set_locking_callback(lock_or_unlock);
|
bbaren@2166
|
76 // Prepare signatures.
|
adamc@1145
|
77 if (uw_sig_file) {
|
adamc@1145
|
78 int fd;
|
adamc@1145
|
79
|
adamc@1155
|
80 if (access(uw_sig_file, F_OK)) {
|
adamc@1145
|
81 random_password();
|
adamc@1145
|
82
|
adamc@1145
|
83 if ((fd = open(uw_sig_file, O_WRONLY | O_CREAT, 0700)) < 0) {
|
adamc@1145
|
84 fprintf(stderr, "Can't open signature file %s\n", uw_sig_file);
|
adamc@1145
|
85 perror("open");
|
adamc@1145
|
86 exit(1);
|
adamc@1145
|
87 }
|
adamc@1145
|
88
|
adamc@1145
|
89 if (write(fd, &password, sizeof password) != sizeof password) {
|
adamc@1145
|
90 fprintf(stderr, "Error writing signature file\n");
|
adamc@1145
|
91 exit(1);
|
adamc@1145
|
92 }
|
adamc@1145
|
93
|
adamc@1145
|
94 close(fd);
|
adamc@1145
|
95 } else {
|
adamc@1145
|
96 if ((fd = open(uw_sig_file, O_RDONLY)) < 0) {
|
adamc@1145
|
97 fprintf(stderr, "Can't open signature file %s\n", uw_sig_file);
|
adamc@1145
|
98 perror("open");
|
adamc@1145
|
99 exit(1);
|
adamc@1145
|
100 }
|
adamc@1145
|
101
|
adamc@1145
|
102 if (read(fd, &password, sizeof password) != sizeof password) {
|
adamc@1145
|
103 fprintf(stderr, "Error reading signature file\n");
|
adamc@1145
|
104 exit(1);
|
adamc@1145
|
105 }
|
adamc@1145
|
106
|
adamc@1145
|
107 close(fd);
|
adamc@1145
|
108 }
|
adamc@1145
|
109 } else
|
adamc@1145
|
110 random_password();
|
adamc@1104
|
111 }
|
adamc@1104
|
112
|
adam@1368
|
113 void uw_sign(const char *in, unsigned char *out) {
|
adam@1368
|
114 SHA256_CTX c;
|
adamc@1104
|
115
|
adam@1368
|
116 SHA256_Init(&c);
|
adam@1368
|
117 SHA256_Update(&c, password, sizeof password);
|
adam@1368
|
118 SHA256_Update(&c, in, strlen(in));
|
adam@1368
|
119 SHA256_Final(out, &c);
|
adamc@1104
|
120 }
|