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@2166
|
37 static void thread_id(CRYPTO_THREADID *const result) {
|
bbaren@2166
|
38 CRYPTO_THREADID_set_numeric(result, pthread_self());
|
bbaren@2166
|
39 }
|
bbaren@2166
|
40 static void lock_or_unlock(const int mode, const int type, const char *file,
|
bbaren@2166
|
41 const int line) {
|
bbaren@2166
|
42 pthread_mutex_t *const lock = &openssl_locks[type];
|
bbaren@2166
|
43 if (mode & CRYPTO_LOCK) {
|
bbaren@2166
|
44 if (pthread_mutex_lock(lock)) {
|
bbaren@2166
|
45 fprintf(stderr, "Can't take lock at %s:%d\n", file, line);
|
bbaren@2166
|
46 exit(1);
|
bbaren@2166
|
47 }
|
bbaren@2166
|
48 } else {
|
bbaren@2166
|
49 if (pthread_mutex_unlock(lock)) {
|
bbaren@2166
|
50 fprintf(stderr, "Can't release lock at %s:%d\n", file, line);
|
bbaren@2166
|
51 exit(1);
|
bbaren@2166
|
52 }
|
bbaren@2166
|
53 }
|
bbaren@2166
|
54 }
|
bbaren@2166
|
55
|
adamc@1104
|
56 void uw_init_crypto() {
|
bbaren@2166
|
57 int i;
|
bbaren@2166
|
58 // Set up OpenSSL.
|
bbaren@2166
|
59 assert(openssl_locks == NULL);
|
bbaren@2166
|
60 openssl_locks = malloc(CRYPTO_num_locks() * sizeof(pthread_mutex_t));
|
bbaren@2166
|
61 if (!openssl_locks) {
|
bbaren@2166
|
62 perror("malloc");
|
bbaren@2166
|
63 exit(1);
|
bbaren@2166
|
64 }
|
bbaren@2166
|
65 for (i = 0; i < CRYPTO_num_locks(); ++i) {
|
bbaren@2166
|
66 pthread_mutex_init(&(openssl_locks[i]), NULL);
|
bbaren@2166
|
67 }
|
bbaren@2166
|
68 CRYPTO_THREADID_set_callback(thread_id);
|
bbaren@2166
|
69 CRYPTO_set_locking_callback(lock_or_unlock);
|
bbaren@2166
|
70 // Prepare signatures.
|
adamc@1145
|
71 if (uw_sig_file) {
|
adamc@1145
|
72 int fd;
|
adamc@1145
|
73
|
adamc@1155
|
74 if (access(uw_sig_file, F_OK)) {
|
adamc@1145
|
75 random_password();
|
adamc@1145
|
76
|
adamc@1145
|
77 if ((fd = open(uw_sig_file, O_WRONLY | O_CREAT, 0700)) < 0) {
|
adamc@1145
|
78 fprintf(stderr, "Can't open signature file %s\n", uw_sig_file);
|
adamc@1145
|
79 perror("open");
|
adamc@1145
|
80 exit(1);
|
adamc@1145
|
81 }
|
adamc@1145
|
82
|
adamc@1145
|
83 if (write(fd, &password, sizeof password) != sizeof password) {
|
adamc@1145
|
84 fprintf(stderr, "Error writing signature file\n");
|
adamc@1145
|
85 exit(1);
|
adamc@1145
|
86 }
|
adamc@1145
|
87
|
adamc@1145
|
88 close(fd);
|
adamc@1145
|
89 } else {
|
adamc@1145
|
90 if ((fd = open(uw_sig_file, O_RDONLY)) < 0) {
|
adamc@1145
|
91 fprintf(stderr, "Can't open signature file %s\n", uw_sig_file);
|
adamc@1145
|
92 perror("open");
|
adamc@1145
|
93 exit(1);
|
adamc@1145
|
94 }
|
adamc@1145
|
95
|
adamc@1145
|
96 if (read(fd, &password, sizeof password) != sizeof password) {
|
adamc@1145
|
97 fprintf(stderr, "Error reading signature file\n");
|
adamc@1145
|
98 exit(1);
|
adamc@1145
|
99 }
|
adamc@1145
|
100
|
adamc@1145
|
101 close(fd);
|
adamc@1145
|
102 }
|
adamc@1145
|
103 } else
|
adamc@1145
|
104 random_password();
|
adamc@1104
|
105 }
|
adamc@1104
|
106
|
adam@1368
|
107 void uw_sign(const char *in, unsigned char *out) {
|
adam@1368
|
108 SHA256_CTX c;
|
adamc@1104
|
109
|
adam@1368
|
110 SHA256_Init(&c);
|
adam@1368
|
111 SHA256_Update(&c, password, sizeof password);
|
adam@1368
|
112 SHA256_Update(&c, in, strlen(in));
|
adam@1368
|
113 SHA256_Final(out, &c);
|
adamc@1104
|
114 }
|