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