xref: /openbsd-src/usr.sbin/nsd/tsig.c (revision 4c1e55dc91edd6e69ccc60ce855900fbc12cf34f)
1 /*
2  * tsig.h -- TSIG definitions (RFC 2845).
3  *
4  * Copyright (c) 2001-2011, NLnet Labs. All rights reserved.
5  *
6  * See LICENSE for the license.
7  *
8  */
9 
10 
11 #include "config.h"
12 #include <stdlib.h>
13 #include <ctype.h>
14 
15 #include "tsig.h"
16 #include "tsig-openssl.h"
17 #include "dns.h"
18 #include "packet.h"
19 #include "query.h"
20 
21 static region_type *tsig_region;
22 
23 struct tsig_key_table
24 {
25 	struct tsig_key_table *next;
26 	tsig_key_type *key;
27 };
28 typedef struct tsig_key_table tsig_key_table_type;
29 static tsig_key_table_type *tsig_key_table;
30 
31 struct tsig_algorithm_table
32 {
33 	struct tsig_algorithm_table *next;
34 	tsig_algorithm_type *algorithm;
35 };
36 typedef struct tsig_algorithm_table tsig_algorithm_table_type;
37 static tsig_algorithm_table_type *tsig_algorithm_table;
38 static size_t max_algo_digest_size = 0;
39 
40 tsig_lookup_algorithm_table tsig_supported_algorithms[] = {
41 	{ TSIG_HMAC_MD5, "hmac-md5" },
42 #ifdef HAVE_EVP_SHA1
43 	{ TSIG_HMAC_SHA1, "hmac-sha1" },
44 #endif /* HAVE_EVP_SHA1 */
45 
46 #ifdef HAVE_EVP_SHA256
47 	{ TSIG_HMAC_SHA256, "hmac-sha256" },
48 #endif /* HAVE_EVP_SHA256 */
49         { 0, NULL }
50 };
51 
52 static void
53 tsig_digest_variables(tsig_record_type *tsig, int tsig_timers_only)
54 {
55 	uint16_t klass = htons(CLASS_ANY);
56 	uint32_t ttl = htonl(0);
57 	uint16_t signed_time_high = htons(tsig->signed_time_high);
58 	uint32_t signed_time_low = htonl(tsig->signed_time_low);
59 	uint16_t signed_time_fudge = htons(tsig->signed_time_fudge);
60 	uint16_t error_code = htons(tsig->error_code);
61 	uint16_t other_size = htons(tsig->other_size);
62 
63 	if (!tsig_timers_only) {
64 		tsig->algorithm->hmac_update(tsig->context,
65 					     dname_name(tsig->key_name),
66 					     tsig->key_name->name_size);
67 		tsig->algorithm->hmac_update(tsig->context,
68 					     &klass,
69 					     sizeof(klass));
70 		tsig->algorithm->hmac_update(tsig->context,
71 					     &ttl,
72 					     sizeof(ttl));
73 		tsig->algorithm->hmac_update(tsig->context,
74 					     dname_name(tsig->algorithm_name),
75 					     tsig->algorithm_name->name_size);
76 	}
77 	tsig->algorithm->hmac_update(tsig->context,
78 				     &signed_time_high,
79 				     sizeof(signed_time_high));
80 	tsig->algorithm->hmac_update(tsig->context,
81 				     &signed_time_low,
82 				     sizeof(signed_time_low));
83 	tsig->algorithm->hmac_update(tsig->context,
84 				     &signed_time_fudge,
85 				     sizeof(signed_time_fudge));
86 	if (!tsig_timers_only) {
87 		tsig->algorithm->hmac_update(tsig->context,
88 					     &error_code,
89 					     sizeof(error_code));
90 		tsig->algorithm->hmac_update(tsig->context,
91 					     &other_size,
92 					     sizeof(other_size));
93 		tsig->algorithm->hmac_update(tsig->context,
94 					     tsig->other_data,
95 					     tsig->other_size);
96 	}
97 }
98 
99 int
100 tsig_init(region_type *region)
101 {
102 	tsig_region = region;
103 	tsig_key_table = NULL;
104 	tsig_algorithm_table = NULL;
105 
106 #if defined(HAVE_SSL)
107 	return tsig_openssl_init(region);
108 #endif /* defined(HAVE_SSL) */
109 	return 1;
110 }
111 
112 void
113 tsig_add_key(tsig_key_type *key)
114 {
115 	tsig_key_table_type *entry = (tsig_key_table_type *) region_alloc(
116 		tsig_region, sizeof(tsig_key_table_type));
117 	entry->key = key;
118 	entry->next = tsig_key_table;
119 	tsig_key_table = entry;
120 }
121 
122 void
123 tsig_add_algorithm(tsig_algorithm_type *algorithm)
124 {
125 	tsig_algorithm_table_type *entry
126 		= (tsig_algorithm_table_type *) region_alloc(
127 			tsig_region, sizeof(tsig_algorithm_table_type));
128 	entry->algorithm = algorithm;
129 	entry->next = tsig_algorithm_table;
130 	tsig_algorithm_table = entry;
131 	if(algorithm->maximum_digest_size > max_algo_digest_size)
132 		max_algo_digest_size = algorithm->maximum_digest_size;
133 }
134 
135 /**
136  * compare a tsig algorithm string lowercased
137  */
138 int
139 tsig_strlowercmp(const char* str1, const char* str2)
140 {
141 	while (str1 && str2 && *str1 != '\0' && *str2 != '\0') {
142 		if(tolower((int)*str1) != tolower((int)*str2)) {
143 			if(tolower((int)*str1) < tolower((int)*str2))
144 				return -1;
145 			return 1;
146 		}
147 		str1++;
148 		str2++;
149 	}
150 	if (str1 && str2) {
151 		if (*str1 == *str2)
152 			return 0;
153 		else if (*str1 == '\0')
154 			return -1;
155 	}
156 	else if (!str1 && !str2)
157 		return 0;
158 	else if (!str1 && str2)
159 		return -1;
160 	return 1;
161 }
162 
163 
164 /*
165  * Find an HMAC algorithm based on its short name.
166  */
167 tsig_algorithm_type *
168 tsig_get_algorithm_by_name(const char *name)
169 {
170 	tsig_algorithm_table_type *algorithm_entry;
171 
172 	for (algorithm_entry = tsig_algorithm_table;
173 	     algorithm_entry;
174 	     algorithm_entry = algorithm_entry->next)
175 	{
176 		if (tsig_strlowercmp(name, algorithm_entry->algorithm->short_name) == 0)
177 		{
178 			return algorithm_entry->algorithm;
179 		}
180 	}
181 
182 	return NULL;
183 }
184 
185 /*
186  * Find an HMAC algorithm based on its id.
187  */
188 tsig_algorithm_type *
189 tsig_get_algorithm_by_id(uint8_t alg)
190 {
191 	int i=0;
192 	for (/*empty*/; tsig_supported_algorithms[i].id > 0; i++) {
193 		if (tsig_supported_algorithms[i].id == alg)
194 			return tsig_get_algorithm_by_name(tsig_supported_algorithms[i].short_name);
195 	}
196 	return NULL;
197 }
198 
199 const char *
200 tsig_error(int error_code)
201 {
202 	static char message[1000];
203 
204 	switch (error_code) {
205 	case TSIG_ERROR_NOERROR:
206 		return "No Error";
207 		break;
208 	case TSIG_ERROR_BADSIG:
209 		return "Bad Signature";
210 		break;
211 	case TSIG_ERROR_BADKEY:
212 		return "Bad Key";
213 		break;
214 	case TSIG_ERROR_BADTIME:
215 		return "Bad Time";
216 		break;
217 	default:
218 		if(error_code < 16) /* DNS rcodes */
219 			return rcode2str(error_code);
220 
221 		snprintf(message, sizeof(message),
222 			 "Unknown Error %d", error_code);
223 		break;
224 	}
225 	return message;
226 }
227 
228 static void
229 tsig_cleanup(void *data)
230 {
231 	tsig_record_type *tsig = (tsig_record_type *) data;
232 	region_destroy(tsig->rr_region);
233 	region_destroy(tsig->context_region);
234 }
235 
236 void
237 tsig_create_record(tsig_record_type *tsig, region_type *region)
238 {
239 	tsig_create_record_custom(tsig, region, DEFAULT_CHUNK_SIZE,
240 		DEFAULT_LARGE_OBJECT_SIZE, DEFAULT_INITIAL_CLEANUP_SIZE);
241 }
242 
243 void
244 tsig_create_record_custom(tsig_record_type *tsig, region_type *region,
245 	size_t chunk_size, size_t large_object_size, size_t initial_cleanup_size)
246 {
247 	tsig->rr_region = region_create_custom(xalloc, free, chunk_size,
248 		large_object_size, initial_cleanup_size, 0);
249 	tsig->context_region = region_create_custom(xalloc, free, chunk_size,
250 		large_object_size, initial_cleanup_size, 0);
251 	region_add_cleanup(region, tsig_cleanup, tsig);
252 	tsig_init_record(tsig, NULL, NULL);
253 }
254 
255 void
256 tsig_init_record(tsig_record_type *tsig,
257 		 tsig_algorithm_type *algorithm,
258 		 tsig_key_type *key)
259 {
260 	tsig->status = TSIG_NOT_PRESENT;
261 	tsig->error_code = TSIG_ERROR_NOERROR;
262 	tsig->position = 0;
263 	tsig->response_count = 0;
264 	tsig->context = NULL;
265 	tsig->algorithm = algorithm;
266 	tsig->key = key;
267 	tsig->prior_mac_size = 0;
268 	tsig->prior_mac_data = NULL;
269 	region_free_all(tsig->context_region);
270 }
271 
272 int
273 tsig_from_query(tsig_record_type *tsig)
274 {
275 	tsig_key_table_type *key_entry;
276 	tsig_key_type *key = NULL;
277 	tsig_algorithm_table_type *algorithm_entry;
278 	tsig_algorithm_type *algorithm = NULL;
279 	uint64_t current_time;
280 	uint64_t signed_time;
281 
282 	assert(tsig->status == TSIG_OK);
283 	assert(!tsig->algorithm);
284 	assert(!tsig->key);
285 
286 	/* XXX: TODO: slow linear check for keyname */
287 	for (key_entry = tsig_key_table;
288 	     key_entry;
289 	     key_entry = key_entry->next)
290 	{
291 		if (dname_compare(tsig->key_name, key_entry->key->name) == 0) {
292 			key = key_entry->key;
293 			break;
294 		}
295 	}
296 
297 	for (algorithm_entry = tsig_algorithm_table;
298 	     algorithm_entry;
299 	     algorithm_entry = algorithm_entry->next)
300 	{
301 		if (dname_compare(
302 			    tsig->algorithm_name,
303 			    algorithm_entry->algorithm->wireformat_name) == 0)
304 		{
305 			algorithm = algorithm_entry->algorithm;
306 			break;
307 		}
308 	}
309 
310 	if (!algorithm || !key) {
311 		/* Algorithm or key is unknown, cannot authenticate.  */
312 		tsig->error_code = TSIG_ERROR_BADKEY;
313 		return 0;
314 	}
315 
316 	if ((tsig->algorithm && algorithm != tsig->algorithm)
317 	    || (tsig->key && key != tsig->key))
318 	{
319 		/*
320 		 * Algorithm or key changed during a single connection,
321 		 * return error.
322 		 */
323 		tsig->error_code = TSIG_ERROR_BADKEY;
324 		return 0;
325 	}
326 
327 	signed_time = ((((uint64_t) tsig->signed_time_high) << 32) |
328 		       ((uint64_t) tsig->signed_time_low));
329 
330 	current_time = (uint64_t) time(NULL);
331 	if ((current_time < signed_time - tsig->signed_time_fudge)
332 	    || (current_time > signed_time + tsig->signed_time_fudge))
333 	{
334 		uint16_t current_time_high;
335 		uint32_t current_time_low;
336 
337 #if 0 /* debug */
338 		char current_time_text[26];
339 		char signed_time_text[26];
340 		time_t clock;
341 
342 		clock = (time_t) current_time;
343 		ctime_r(&clock, current_time_text);
344 		current_time_text[24] = '\0';
345 
346 		clock = (time_t) signed_time;
347 		ctime_r(&clock, signed_time_text);
348 		signed_time_text[24] = '\0';
349 
350 		log_msg(LOG_ERR,
351 			"current server time %s is outside the range of TSIG"
352 			" signed time %s with fudge %u",
353 			current_time_text,
354 			signed_time_text,
355 			(unsigned) tsig->signed_time_fudge);
356 #endif
357 
358 		tsig->error_code = TSIG_ERROR_BADTIME;
359 		current_time_high = (uint16_t) (current_time >> 32);
360 		current_time_low = (uint32_t) current_time;
361 		tsig->other_size = 6;
362 		tsig->other_data = (uint8_t *) region_alloc(
363 			tsig->rr_region, sizeof(uint16_t) + sizeof(uint32_t));
364 		write_uint16(tsig->other_data, current_time_high);
365 		write_uint32(tsig->other_data + 2, current_time_low);
366 		return 0;
367 	}
368 
369 	tsig->algorithm = algorithm;
370 	tsig->key = key;
371 	tsig->response_count = 0;
372 	tsig->prior_mac_size = 0;
373 
374 	return 1;
375 }
376 
377 void
378 tsig_init_query(tsig_record_type *tsig, uint16_t original_query_id)
379 {
380 	assert(tsig);
381 	assert(tsig->algorithm);
382 	assert(tsig->key);
383 
384 	tsig->response_count = 0;
385 	tsig->prior_mac_size = 0;
386 	tsig->algorithm_name = tsig->algorithm->wireformat_name;
387 	tsig->key_name = tsig->key->name;
388 	tsig->mac_size = 0;
389 	tsig->mac_data = NULL;
390 	tsig->original_query_id = original_query_id;
391 	tsig->error_code = TSIG_ERROR_NOERROR;
392 	tsig->other_size = 0;
393 	tsig->other_data = NULL;
394 }
395 
396 void
397 tsig_prepare(tsig_record_type *tsig)
398 {
399 	if (!tsig->context) {
400 		assert(tsig->algorithm);
401 		tsig->context = tsig->algorithm->hmac_create_context(
402 			tsig->context_region);
403 		tsig->prior_mac_data = (uint8_t *) region_alloc(
404 			tsig->context_region,
405 			tsig->algorithm->maximum_digest_size);
406 	}
407 	tsig->algorithm->hmac_init_context(tsig->context,
408 					   tsig->algorithm,
409 					   tsig->key);
410 
411 	if (tsig->prior_mac_size > 0) {
412 		uint16_t mac_size = htons(tsig->prior_mac_size);
413 		tsig->algorithm->hmac_update(tsig->context,
414 					     &mac_size,
415 					     sizeof(mac_size));
416 		tsig->algorithm->hmac_update(tsig->context,
417 					     tsig->prior_mac_data,
418 					     tsig->prior_mac_size);
419 	}
420 
421 	tsig->updates_since_last_prepare = 0;
422 }
423 
424 void
425 tsig_update(tsig_record_type *tsig, buffer_type *packet, size_t length)
426 {
427 	uint16_t original_query_id = htons(tsig->original_query_id);
428 
429 	assert(length <= buffer_limit(packet));
430 
431 	tsig->algorithm->hmac_update(tsig->context,
432 				     &original_query_id,
433 				     sizeof(original_query_id));
434 	tsig->algorithm->hmac_update(
435 		tsig->context,
436 		buffer_at(packet, sizeof(original_query_id)),
437 		length - sizeof(original_query_id));
438 	if (QR(packet)) {
439 		++tsig->response_count;
440 	}
441 
442 	++tsig->updates_since_last_prepare;
443 }
444 
445 void
446 tsig_sign(tsig_record_type *tsig)
447 {
448 	uint64_t current_time = (uint64_t) time(NULL);
449 	tsig->signed_time_high = (uint16_t) (current_time >> 32);
450 	tsig->signed_time_low = (uint32_t) current_time;
451 	tsig->signed_time_fudge = 300; /* XXX; hardcoded value */
452 
453 	tsig_digest_variables(tsig, tsig->response_count > 1);
454 
455 	tsig->algorithm->hmac_final(tsig->context,
456 				    tsig->prior_mac_data,
457 				    &tsig->prior_mac_size);
458 
459 	tsig->mac_size = tsig->prior_mac_size;
460 	tsig->mac_data = tsig->prior_mac_data;
461 }
462 
463 int
464 tsig_verify(tsig_record_type *tsig)
465 {
466 	tsig_digest_variables(tsig, tsig->response_count > 1);
467 
468 	tsig->algorithm->hmac_final(tsig->context,
469 				    tsig->prior_mac_data,
470 				    &tsig->prior_mac_size);
471 
472 	if (tsig->mac_size != tsig->prior_mac_size
473 	    || memcmp(tsig->mac_data,
474 		      tsig->prior_mac_data,
475 		      tsig->mac_size) != 0)
476 	{
477 		/* Digest is incorrect, cannot authenticate.  */
478 		tsig->error_code = TSIG_ERROR_BADSIG;
479 		return 0;
480 	} else {
481 		return 1;
482 	}
483 }
484 
485 int
486 tsig_find_rr(tsig_record_type *tsig, buffer_type *packet)
487 {
488 	size_t saved_position = buffer_position(packet);
489 	size_t rrcount = (QDCOUNT(packet)
490 			  + ANCOUNT(packet)
491 			  + NSCOUNT(packet)
492 			  + ARCOUNT(packet));
493 	size_t i;
494 	int result;
495 
496 	if (ARCOUNT(packet) == 0) {
497 		tsig->status = TSIG_NOT_PRESENT;
498 		return 1;
499 	}
500 
501 	buffer_set_position(packet, QHEADERSZ);
502 
503 	/* TSIG must be the last record, so skip all others. */
504 	for (i = 0; i < rrcount - 1; ++i) {
505 		if (!packet_skip_rr(packet, i < QDCOUNT(packet))) {
506 			buffer_set_position(packet, saved_position);
507 			return 0;
508 		}
509 	}
510 
511 	result = tsig_parse_rr(tsig, packet);
512 	buffer_set_position(packet, saved_position);
513 	return result;
514 }
515 
516 int
517 tsig_parse_rr(tsig_record_type *tsig, buffer_type *packet)
518 {
519 	uint16_t type;
520 	uint16_t klass;
521 	uint32_t ttl;
522 	uint16_t rdlen;
523 
524 	tsig->status = TSIG_NOT_PRESENT;
525 	tsig->position = buffer_position(packet);
526 	tsig->key_name = NULL;
527 	tsig->algorithm_name = NULL;
528 	tsig->mac_data = NULL;
529 	tsig->other_data = NULL;
530 	region_free_all(tsig->rr_region);
531 
532 	tsig->key_name = dname_make_from_packet(tsig->rr_region, packet, 1, 1);
533 	if (!tsig->key_name) {
534 		buffer_set_position(packet, tsig->position);
535 		return 0;
536 	}
537 
538 	if (!buffer_available(packet, 10)) {
539 		buffer_set_position(packet, tsig->position);
540 		return 0;
541 	}
542 
543 	type = buffer_read_u16(packet);
544 	klass = buffer_read_u16(packet);
545 
546 	/* TSIG not present */
547 	if (type != TYPE_TSIG || klass != CLASS_ANY) {
548 		buffer_set_position(packet, tsig->position);
549 		return 1;
550 	}
551 
552 	ttl = buffer_read_u32(packet);
553 	rdlen = buffer_read_u16(packet);
554 
555 	tsig->status = TSIG_ERROR;
556 	tsig->error_code = RCODE_FORMAT;
557 	if (ttl != 0 || !buffer_available(packet, rdlen)) {
558 		buffer_set_position(packet, tsig->position);
559 		return 0;
560 	}
561 
562 	tsig->algorithm_name = dname_make_from_packet(
563 		tsig->rr_region, packet, 1, 1);
564 	if (!tsig->algorithm_name || !buffer_available(packet, 10)) {
565 		buffer_set_position(packet, tsig->position);
566 		return 0;
567 	}
568 
569 	tsig->signed_time_high = buffer_read_u16(packet);
570 	tsig->signed_time_low = buffer_read_u32(packet);
571 	tsig->signed_time_fudge = buffer_read_u16(packet);
572 	tsig->mac_size = buffer_read_u16(packet);
573 	if (!buffer_available(packet, tsig->mac_size)) {
574 		buffer_set_position(packet, tsig->position);
575 		tsig->mac_size = 0;
576 		return 0;
577 	}
578 	tsig->mac_data = (uint8_t *) region_alloc_init(
579 		tsig->rr_region, buffer_current(packet), tsig->mac_size);
580 	buffer_skip(packet, tsig->mac_size);
581 	if (!buffer_available(packet, 6)) {
582 		buffer_set_position(packet, tsig->position);
583 		return 0;
584 	}
585 	tsig->original_query_id = buffer_read_u16(packet);
586 	tsig->error_code = buffer_read_u16(packet);
587 	tsig->other_size = buffer_read_u16(packet);
588 	if (!buffer_available(packet, tsig->other_size) || tsig->other_size > 16) {
589 		tsig->other_size = 0;
590 		buffer_set_position(packet, tsig->position);
591 		return 0;
592 	}
593 	tsig->other_data = (uint8_t *) region_alloc_init(
594 		tsig->rr_region, buffer_current(packet), tsig->other_size);
595 	buffer_skip(packet, tsig->other_size);
596 	tsig->status = TSIG_OK;
597 	tsig->error_code = TSIG_ERROR_NOERROR;
598 
599 	return 1;
600 }
601 
602 void
603 tsig_append_rr(tsig_record_type *tsig, buffer_type *packet)
604 {
605 	size_t rdlength_pos;
606 
607 	/* XXX: TODO key name compression? */
608 	if(tsig->key_name)
609 		buffer_write(packet, dname_name(tsig->key_name),
610 		     tsig->key_name->name_size);
611 	else	buffer_write_u8(packet, 0);
612 	buffer_write_u16(packet, TYPE_TSIG);
613 	buffer_write_u16(packet, CLASS_ANY);
614 	buffer_write_u32(packet, 0); /* TTL */
615 	rdlength_pos = buffer_position(packet);
616 	buffer_skip(packet, sizeof(uint16_t));
617 	if(tsig->algorithm_name)
618 		buffer_write(packet, dname_name(tsig->algorithm_name),
619 		     tsig->algorithm_name->name_size);
620 	else 	buffer_write_u8(packet, 0);
621 	buffer_write_u16(packet, tsig->signed_time_high);
622 	buffer_write_u32(packet, tsig->signed_time_low);
623 	buffer_write_u16(packet, tsig->signed_time_fudge);
624 	buffer_write_u16(packet, tsig->mac_size);
625 	buffer_write(packet, tsig->mac_data, tsig->mac_size);
626 	buffer_write_u16(packet, tsig->original_query_id);
627 	buffer_write_u16(packet, tsig->error_code);
628 	buffer_write_u16(packet, tsig->other_size);
629 	buffer_write(packet, tsig->other_data, tsig->other_size);
630 
631 	buffer_write_u16_at(packet, rdlength_pos,
632 			    buffer_position(packet) - rdlength_pos
633 			    - sizeof(uint16_t));
634 }
635 
636 size_t
637 tsig_reserved_space(tsig_record_type *tsig)
638 {
639 	if (tsig->status == TSIG_NOT_PRESENT)
640 		return 0;
641 
642 	return (
643 		(tsig->key_name?tsig->key_name->name_size:1)   /* Owner */
644 		+ sizeof(uint16_t)	    /* Type */
645 		+ sizeof(uint16_t)	    /* Class */
646 		+ sizeof(uint32_t)	    /* TTL */
647 		+ sizeof(uint16_t)	    /* RDATA length */
648 		+ (tsig->algorithm_name?tsig->algorithm_name->name_size:1)
649 		+ sizeof(uint16_t)	    /* Signed time (high) */
650 		+ sizeof(uint32_t)	    /* Signed time (low) */
651 		+ sizeof(uint16_t)	    /* Signed time fudge */
652 		+ sizeof(uint16_t)	    /* MAC size */
653 		+ max_algo_digest_size 	    /* MAC data */
654 		+ sizeof(uint16_t)	    /* Original query ID */
655 		+ sizeof(uint16_t)	    /* Error code */
656 		+ sizeof(uint16_t)	    /* Other size */
657 		+ tsig->other_size);	    /* Other data */
658 }
659 
660 void
661 tsig_error_reply(tsig_record_type *tsig)
662 {
663 	if(tsig->mac_data)
664 		memset(tsig->mac_data, 0, tsig->mac_size);
665 	tsig->mac_size = 0;
666 }
667 
668 void
669 tsig_finalize()
670 {
671 #if defined(HAVE_SSL)
672 	tsig_openssl_finalize();
673 #endif /* defined(HAVE_SSL) */
674 }
675