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