1 /*
2 * Part of DNS zone file validator `validns`.
3 *
4 * Copyright 2011-2014 Anton Berezin <tobez@tobez.org>
5 * Modified BSD license.
6 * (See LICENSE file in the distribution.)
7 *
8 */
9 #include <sys/types.h>
10 #include <string.h>
11 #include <stdlib.h>
12 #include <stdio.h>
13 #include <time.h>
14 #include <pthread.h>
15 #include <netinet/in.h>
16 #include <arpa/inet.h>
17 #include <openssl/evp.h>
18 #include <openssl/err.h>
19
20 #include "common.h"
21 #include "textparse.h"
22 #include "mempool.h"
23 #include "carp.h"
24 #include "rr.h"
25
26 struct verification_data
27 {
28 struct verification_data *next;
29 EVP_MD_CTX *ctx;
30 struct rr_dnskey *key;
31 struct rr_rrsig *rr;
32 int ok;
33 unsigned long openssl_error;
34 };
35
36 struct keys_to_verify
37 {
38 struct keys_to_verify *next;
39 struct rr_rrsig *rr;
40 struct rr_set *signed_set;
41 int n_keys;
42 struct verification_data to_verify[1];
43 };
44
45 static struct keys_to_verify *all_keys_to_verify = NULL;
46
rrsig_parse(char * name,long ttl,int type,char * s)47 static struct rr* rrsig_parse(char *name, long ttl, int type, char *s)
48 {
49 struct rr_rrsig *rr = getmem(sizeof(*rr));
50 int type_covered, key_tag;
51 char *str_type_covered;
52 struct binary_data sig;
53 long long ts;
54
55 str_type_covered = extract_label(&s, "type covered", "temporary");
56 if (!str_type_covered) return NULL;
57 type_covered = str2rdtype(str_type_covered, NULL);
58 if (type_covered <= 0 || type_covered > 65535) return NULL;
59 rr->type_covered = type_covered;
60
61 rr->algorithm = extract_algorithm(&s, "algorithm");
62 if (rr->algorithm == ALG_UNSUPPORTED) return NULL;
63 if (rr->algorithm == ALG_PRIVATEDNS || rr->algorithm == ALG_PRIVATEOID) {
64 return bitch("private algorithms are not supported in RRSIG");
65 }
66
67 rr->labels = extract_integer(&s, "labels");
68 if (rr->labels < 0) return NULL;
69 /* TODO validate labels, see http://tools.ietf.org/html/rfc4034#section-3.1.3 */
70
71 rr->orig_ttl = extract_timevalue(&s, "original TTL");
72 if (rr->orig_ttl < 0) return NULL;
73
74 ts = extract_timestamp(&s, "signature expiration");
75 if (ts < 0) return NULL;
76 rr->sig_expiration = ts;
77
78 ts = extract_timestamp(&s, "signature inception");
79 if (ts < 0) return NULL;
80 rr->sig_inception = ts;
81
82 key_tag = extract_integer(&s, "key tag");
83 if (key_tag < 0) return NULL;
84 rr->key_tag = key_tag;
85
86 rr->signer = extract_name(&s, "signer name", 0);
87 if (!rr->signer) return NULL;
88 /* TODO validate signer name, http://tools.ietf.org/html/rfc4034#section-3.1.7 */
89
90 sig = extract_base64_binary_data(&s, "signature");
91 if (sig.length < 0) return NULL;
92 /* TODO validate signature length based on algorithm */
93 rr->signature = sig;
94
95 if (*s) {
96 return bitch("garbage after valid RRSIG data");
97 }
98 G.dnssec_active = 1;
99 return store_record(type, name, ttl, rr);
100 }
101
rrsig_human(struct rr * rrv)102 static char* rrsig_human(struct rr *rrv)
103 {
104 // RRCAST(rrsig);
105 // char s[1024];
106
107 //snprintf(s, 1024, "SOA %s %s %d %d %d %d %d",
108 // rr->mname, rr->rname, rr->serial,
109 // rr->refresh, rr->retry, rr->expire, rr->minimum);
110 //return quickstrdup_temp(s);
111 return NULL;
112 }
113
rrsig_wirerdata_ex(struct rr * rrv,int with_signature)114 static struct binary_data rrsig_wirerdata_ex(struct rr *rrv, int with_signature)
115 {
116 RRCAST(rrsig);
117 struct binary_data bd;
118
119 bd = compose_binary_data("2114442d", 1,
120 rr->type_covered, rr->algorithm, rr->labels,
121 rr->orig_ttl, rr->sig_expiration, rr->sig_inception,
122 rr->key_tag, name2wire_name(rr->signer));
123 if (with_signature) {
124 return compose_binary_data("dd", 1, bd, rr->signature);
125 }
126 return bd;
127 }
128
rrsig_wirerdata(struct rr * rrv)129 static struct binary_data rrsig_wirerdata(struct rr *rrv)
130 {
131 return rrsig_wirerdata_ex(rrv, 1);
132 }
133
134 struct rr_with_wired
135 {
136 struct rr *rr;
137 struct binary_data wired;
138 };
139
compare_rr_with_wired(const void * va,const void * vb)140 static int compare_rr_with_wired(const void *va, const void *vb)
141 {
142 const struct rr_with_wired *a = va;
143 const struct rr_with_wired *b = vb;
144 int r;
145
146 if (a->wired.length == b->wired.length) {
147 return memcmp(a->wired.data, b->wired.data, a->wired.length);
148 } else if (a->wired.length < b->wired.length) {
149 r = memcmp(a->wired.data, b->wired.data, a->wired.length);
150 if (r != 0) return r;
151 return -1;
152 } else {
153 r = memcmp(a->wired.data, b->wired.data, b->wired.length);
154 if (r != 0) return r;
155 return 1;
156 }
157 }
158
159 static struct verification_data *verification_queue = NULL;
160 static int verification_queue_size = 0;
161 static pthread_mutex_t queue_lock;
162 static int workers_started = 0;
163 static pthread_t *workers;
164
verification_thread(void * dummy)165 void *verification_thread(void *dummy)
166 {
167 struct verification_data *d;
168 struct timespec sleep_time;
169
170 while (1) {
171 if (pthread_mutex_lock(&queue_lock) != 0)
172 croak(1, "pthread_mutex_lock");
173 d = verification_queue;
174 if (d) {
175 verification_queue = d->next;
176 G.stats.signatures_verified++;
177 }
178 if (pthread_mutex_unlock(&queue_lock) != 0)
179 croak(1, "pthread_mutex_unlock");
180 if (d) {
181 int r;
182 d->next = NULL;
183 r = EVP_VerifyFinal(d->ctx, (unsigned char *)d->rr->signature.data, d->rr->signature.length, d->key->pkey);
184 EVP_MD_CTX_destroy(d->ctx);
185 if (r == 1) {
186 d->ok = 1;
187 } else {
188 d->openssl_error = ERR_peek_last_error();
189 }
190 if (pthread_mutex_lock(&queue_lock) != 0)
191 croak(1, "pthread_mutex_lock");
192 verification_queue_size--;
193 if (pthread_mutex_unlock(&queue_lock) != 0)
194 croak(1, "pthread_mutex_unlock");
195 } else {
196 sleep_time.tv_sec = 0;
197 sleep_time.tv_nsec = 10000000;
198 nanosleep(&sleep_time, NULL);
199 }
200 }
201 }
202
start_workers(void)203 static void start_workers(void)
204 {
205 int i;
206
207 if (workers_started)
208 return;
209 if (G.opt.verbose)
210 fprintf(stderr, "starting workers for signature verification\n");
211 workers = getmem(sizeof(*workers)*G.opt.n_threads);
212 for (i = 0; i < G.opt.n_threads; i++) {
213 if (pthread_create(&workers[i], NULL, verification_thread, NULL) != 0)
214 croak(1, "pthread_create");
215 }
216 workers_started = 1;
217 }
218
schedule_verification(struct verification_data * d)219 static void schedule_verification(struct verification_data *d)
220 {
221 int cur_size;
222 if (G.opt.n_threads > 1) {
223 if (pthread_mutex_lock(&queue_lock) != 0)
224 croak(1, "pthread_mutex_lock");
225 d->next = verification_queue;
226 verification_queue = d;
227 verification_queue_size++;
228 cur_size = verification_queue_size;
229 if (pthread_mutex_unlock(&queue_lock) != 0)
230 croak(1, "pthread_mutex_unlock");
231 if (!workers_started && cur_size >= G.opt.n_threads)
232 start_workers();
233 } else {
234 int r;
235 G.stats.signatures_verified++;
236 r = EVP_VerifyFinal(d->ctx, (unsigned char *)d->rr->signature.data, d->rr->signature.length, d->key->pkey);
237 EVP_MD_CTX_destroy(d->ctx);
238 if (r == 1) {
239 d->ok = 1;
240 } else {
241 d->openssl_error = ERR_peek_last_error();
242 }
243 }
244 }
245
verify_signature(struct verification_data * d,struct rr_set * signed_set)246 static int verify_signature(struct verification_data *d, struct rr_set *signed_set)
247 {
248 uint16_t b2;
249 uint32_t b4;
250 struct binary_data chunk;
251 struct rr_with_wired *set;
252 struct rr *signed_rr;
253 int i;
254
255 d->ctx = EVP_MD_CTX_create();
256 switch (d->rr->algorithm) {
257 case ALG_DSA:
258 case ALG_RSASHA1:
259 case ALG_DSA_NSEC3_SHA1:
260 case ALG_RSASHA1_NSEC3_SHA1:
261 if (EVP_VerifyInit(d->ctx, EVP_sha1()) != 1)
262 return 0;
263 break;
264 case ALG_RSASHA256:
265 if (EVP_VerifyInit(d->ctx, EVP_sha256()) != 1)
266 return 0;
267 break;
268 case ALG_RSASHA512:
269 if (EVP_VerifyInit(d->ctx, EVP_sha512()) != 1)
270 return 0;
271 break;
272 default:
273 return 0;
274 }
275
276 chunk = rrsig_wirerdata_ex(&d->rr->rr, 0);
277 if (chunk.length < 0)
278 return 0;
279 EVP_VerifyUpdate(d->ctx, chunk.data, chunk.length);
280
281 set = getmem_temp(sizeof(*set) * signed_set->count);
282
283 signed_rr = signed_set->tail;
284 i = 0;
285 while (signed_rr) {
286 set[i].rr = signed_rr;
287 set[i].wired = call_get_wired(signed_rr);
288 if (set[i].wired.length < 0)
289 return 0;
290 i++;
291 signed_rr = signed_rr->next;
292 }
293 qsort(set, signed_set->count, sizeof(*set), compare_rr_with_wired);
294
295 for (i = 0; i < signed_set->count; i++) {
296 chunk = name2wire_name(signed_set->named_rr->name);
297 if (chunk.length < 0)
298 return 0;
299 EVP_VerifyUpdate(d->ctx, chunk.data, chunk.length);
300 b2 = htons(set[i].rr->rdtype); EVP_VerifyUpdate(d->ctx, &b2, 2);
301 b2 = htons(1); /* class IN */ EVP_VerifyUpdate(d->ctx, &b2, 2);
302 b4 = htonl(set[i].rr->ttl); EVP_VerifyUpdate(d->ctx, &b4, 4);
303 b2 = htons(set[i].wired.length); EVP_VerifyUpdate(d->ctx, &b2, 2);
304 EVP_VerifyUpdate(d->ctx, set[i].wired.data, set[i].wired.length);
305 }
306
307 schedule_verification(d);
308 return 1;
309 }
310
rrsig_validate(struct rr * rrv)311 static void *rrsig_validate(struct rr *rrv)
312 {
313 RRCAST(rrsig);
314 struct named_rr *named_rr;
315 struct rr_set *signed_set;
316 struct rr_dnskey *key = NULL;
317 struct rr_set *dnskey_rr_set;
318 int candidate_keys = 0;
319 struct keys_to_verify *candidates;
320 int i = 0;
321 int t;
322
323 named_rr = rr->rr.rr_set->named_rr;
324 for (t = 0; t < G.opt.n_times_to_check; t++) {
325 if (G.opt.times_to_check[t] < rr->sig_inception) {
326 return moan(rr->rr.file_name, rr->rr.line, "%s signature is too new", named_rr->name);
327 }
328 if (G.opt.times_to_check[t] > rr->sig_expiration) {
329 return moan(rr->rr.file_name, rr->rr.line, "%s signature is too old", named_rr->name);
330 }
331 }
332 signed_set = find_rr_set_in_named_rr(named_rr, rr->type_covered);
333 if (!signed_set) {
334 return moan(rr->rr.file_name, rr->rr.line, "%s RRSIG exists for non-existing type %s", named_rr->name, rdtype2str(rr->type_covered));
335 }
336 if (signed_set->tail->ttl != rr->orig_ttl) {
337 return moan(rr->rr.file_name, rr->rr.line, "%s RRSIG's original TTL differs from corresponding record's", named_rr->name);
338 }
339 dnskey_rr_set = find_rr_set(T_DNSKEY, rr->signer);
340 if (!dnskey_rr_set) {
341 return moan(rr->rr.file_name, rr->rr.line, "%s RRSIG(%s): cannot find a signer key (%s)", named_rr->name, rdtype2str(rr->type_covered), rr->signer);
342 }
343 key = (struct rr_dnskey *)dnskey_rr_set->tail;
344 while (key) {
345 if (key->algorithm == rr->algorithm && key->key_tag == rr->key_tag) {
346 candidate_keys++;
347 dnskey_build_pkey(key);
348 }
349 key = (struct rr_dnskey *)key->rr.next;
350 }
351 if (candidate_keys == 0)
352 return moan(rr->rr.file_name, rr->rr.line, "%s RRSIG(%s): cannot find the right signer key (%s)", named_rr->name, rdtype2str(rr->type_covered), rr->signer);
353
354 candidates = getmem(sizeof(struct keys_to_verify) + (candidate_keys-1) * sizeof(struct verification_data));
355 candidates->next = all_keys_to_verify;
356 candidates->rr = rr;
357 candidates->signed_set = signed_set;
358 candidates->n_keys = candidate_keys;
359 all_keys_to_verify = candidates;
360 key = (struct rr_dnskey *)dnskey_rr_set->tail;
361 while (key) {
362 if (key->algorithm == rr->algorithm && key->key_tag == rr->key_tag) {
363 candidates->to_verify[i].key = key;
364 candidates->to_verify[i].rr = rr;
365 candidates->to_verify[i].ok = 0;
366 candidates->to_verify[i].openssl_error = 0;
367 candidates->to_verify[i].next = NULL;
368 i++;
369 }
370 key = (struct rr_dnskey *)key->rr.next;
371 }
372
373 return rr;
374 }
375
376 static pthread_mutex_t *lock_cs;
377 static long *lock_count;
378
pthreads_thread_id(void)379 static unsigned long pthreads_thread_id(void)
380 {
381 unsigned long ret;
382
383 ret=(unsigned long)pthread_self();
384 return(ret);
385 }
386
pthreads_locking_callback(int mode,int type,char * file,int line)387 static void pthreads_locking_callback(int mode, int type, char *file, int line)
388 {
389 if (mode & CRYPTO_LOCK) {
390 pthread_mutex_lock(&(lock_cs[type]));
391 lock_count[type]++;
392 } else {
393 pthread_mutex_unlock(&(lock_cs[type]));
394 }
395 }
396
verify_all_keys(void)397 void verify_all_keys(void)
398 {
399 struct keys_to_verify *k = all_keys_to_verify;
400 int i;
401 struct timespec sleep_time;
402
403 ERR_load_crypto_strings();
404 if (G.opt.n_threads > 1) {
405 lock_cs = OPENSSL_malloc(CRYPTO_num_locks() * sizeof(pthread_mutex_t));
406 lock_count = OPENSSL_malloc(CRYPTO_num_locks() * sizeof(long));
407 for (i = 0; i < CRYPTO_num_locks(); i++) {
408 lock_count[i] = 0;
409 pthread_mutex_init(&lock_cs[i],NULL);
410 }
411
412 CRYPTO_set_id_callback((unsigned long (*)())pthreads_thread_id);
413 CRYPTO_set_locking_callback((void (*)())pthreads_locking_callback);
414
415 if (pthread_mutex_init(&queue_lock, NULL) != 0)
416 croak(1, "pthread_mutex_init");
417 }
418
419 while (k) {
420 freeall_temp();
421 for (i = 0; i < k->n_keys; i++) {
422 if (dnskey_build_pkey(k->to_verify[i].key))
423 verify_signature(&k->to_verify[i], k->signed_set);
424 }
425 k = k->next;
426 }
427 start_workers(); /* this is needed in case n_threads is greater than the number of signatures to verify */
428 while (verification_queue_size > 0) {
429 sleep_time.tv_sec = 0;
430 sleep_time.tv_nsec = 10000000;
431 nanosleep(&sleep_time, NULL);
432 }
433 k = all_keys_to_verify;
434 while (k) {
435 int ok = 0;
436 unsigned long e = 0;
437 for (i = 0; i < k->n_keys; i++) {
438 if (k->to_verify[i].ok) {
439 ok = 1;
440 break;
441 } else {
442 if (k->to_verify[i].openssl_error != 0)
443 e = k->to_verify[i].openssl_error;
444 }
445 }
446 if (!ok) {
447 struct named_rr *named_rr;
448 named_rr = k->rr->rr.rr_set->named_rr;
449 moan(k->rr->rr.file_name, k->rr->rr.line, "%s RRSIG(%s): %s",
450 named_rr->name, rdtype2str(k->rr->type_covered),
451 e ? ERR_reason_error_string(e) : "cannot verify signature, reason unknown");
452 }
453 k = k->next;
454 }
455 }
456
457 struct rr_methods rrsig_methods = { rrsig_parse, rrsig_human, rrsig_wirerdata, NULL, rrsig_validate };
458