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_type node; /* by dname */ 27 tsig_key_type *key; 28 }; 29 typedef struct tsig_key_table tsig_key_table_type; 30 static rbtree_type *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 if(strncmp("hmac-", algorithm_entry->algorithm->short_name, 5) == 0 && tsig_strlowercmp(name, algorithm_entry->algorithm->short_name+5) == 0) { 196 return algorithm_entry->algorithm; 197 } 198 } 199 200 return NULL; 201 } 202 203 204 const char * 205 tsig_error(int error_code) 206 { 207 static char message[1000]; 208 209 switch (error_code) { 210 case TSIG_ERROR_NOERROR: 211 return "No Error"; 212 break; 213 case TSIG_ERROR_BADSIG: 214 return "Bad Signature"; 215 break; 216 case TSIG_ERROR_BADKEY: 217 return "Bad Key"; 218 break; 219 case TSIG_ERROR_BADTIME: 220 return "Bad Time"; 221 break; 222 default: 223 if(error_code < 16) /* DNS rcodes */ 224 return rcode2str(error_code); 225 226 snprintf(message, sizeof(message), 227 "Unknown Error %d", error_code); 228 break; 229 } 230 return message; 231 } 232 233 static void 234 tsig_cleanup(void *data) 235 { 236 tsig_record_type *tsig = (tsig_record_type *) data; 237 region_destroy(tsig->rr_region); 238 region_destroy(tsig->context_region); 239 } 240 241 void 242 tsig_create_record(tsig_record_type *tsig, region_type *region) 243 { 244 tsig_create_record_custom(tsig, region, DEFAULT_CHUNK_SIZE, 245 DEFAULT_LARGE_OBJECT_SIZE, DEFAULT_INITIAL_CLEANUP_SIZE); 246 } 247 248 void 249 tsig_create_record_custom(tsig_record_type *tsig, region_type *region, 250 size_t chunk_size, size_t large_object_size, size_t initial_cleanup_size) 251 { 252 tsig->rr_region = region_create_custom(xalloc, free, chunk_size, 253 large_object_size, initial_cleanup_size, 0); 254 tsig->context_region = region_create_custom(xalloc, free, chunk_size, 255 large_object_size, initial_cleanup_size, 0); 256 if(region) 257 region_add_cleanup(region, tsig_cleanup, tsig); 258 tsig_init_record(tsig, NULL, NULL); 259 } 260 261 void 262 tsig_delete_record(tsig_record_type* tsig, region_type* region) 263 { 264 if(region) 265 region_remove_cleanup(region, tsig_cleanup, tsig); 266 region_destroy(tsig->rr_region); 267 region_destroy(tsig->context_region); 268 } 269 270 void 271 tsig_init_record(tsig_record_type *tsig, 272 tsig_algorithm_type *algorithm, 273 tsig_key_type *key) 274 { 275 tsig->status = TSIG_NOT_PRESENT; 276 tsig->error_code = TSIG_ERROR_NOERROR; 277 tsig->position = 0; 278 tsig->response_count = 0; 279 tsig->context = NULL; 280 tsig->algorithm = algorithm; 281 tsig->key = key; 282 tsig->prior_mac_size = 0; 283 tsig->prior_mac_data = NULL; 284 region_free_all(tsig->context_region); 285 } 286 287 int 288 tsig_from_query(tsig_record_type *tsig) 289 { 290 tsig_key_type *key = NULL; 291 tsig_algorithm_table_type *algorithm_entry; 292 tsig_algorithm_type *algorithm = NULL; 293 uint64_t current_time; 294 uint64_t signed_time; 295 296 assert(tsig->status == TSIG_OK); 297 assert(!tsig->algorithm); 298 assert(!tsig->key); 299 300 key = (tsig_key_type*)tsig_find_key(tsig->key_name); 301 302 for (algorithm_entry = tsig_algorithm_table; 303 algorithm_entry; 304 algorithm_entry = algorithm_entry->next) 305 { 306 if (dname_compare( 307 tsig->algorithm_name, 308 algorithm_entry->algorithm->wireformat_name) == 0) 309 { 310 algorithm = algorithm_entry->algorithm; 311 break; 312 } 313 } 314 315 if (!algorithm || !key) { 316 /* Algorithm or key is unknown, cannot authenticate. */ 317 tsig->error_code = TSIG_ERROR_BADKEY; 318 return 0; 319 } 320 321 if ((tsig->algorithm && algorithm != tsig->algorithm) 322 || (tsig->key && key != tsig->key)) 323 { 324 /* 325 * Algorithm or key changed during a single connection, 326 * return error. 327 */ 328 tsig->error_code = TSIG_ERROR_BADKEY; 329 return 0; 330 } 331 332 signed_time = ((((uint64_t) tsig->signed_time_high) << 32) | 333 ((uint64_t) tsig->signed_time_low)); 334 335 current_time = (uint64_t) time(NULL); 336 if ((current_time < signed_time - tsig->signed_time_fudge) 337 || (current_time > signed_time + tsig->signed_time_fudge)) 338 { 339 uint16_t current_time_high; 340 uint32_t current_time_low; 341 342 #if 0 /* debug */ 343 char current_time_text[26]; 344 char signed_time_text[26]; 345 time_t clock; 346 347 clock = (time_t) current_time; 348 ctime_r(&clock, current_time_text); 349 current_time_text[24] = '\0'; 350 351 clock = (time_t) signed_time; 352 ctime_r(&clock, signed_time_text); 353 signed_time_text[24] = '\0'; 354 355 log_msg(LOG_ERR, 356 "current server time %s is outside the range of TSIG" 357 " signed time %s with fudge %u", 358 current_time_text, 359 signed_time_text, 360 (unsigned) tsig->signed_time_fudge); 361 #endif 362 363 tsig->error_code = TSIG_ERROR_BADTIME; 364 current_time_high = (uint16_t) (current_time >> 32); 365 current_time_low = (uint32_t) current_time; 366 tsig->other_size = 6; 367 tsig->other_data = (uint8_t *) region_alloc( 368 tsig->rr_region, sizeof(uint16_t) + sizeof(uint32_t)); 369 write_uint16(tsig->other_data, current_time_high); 370 write_uint32(tsig->other_data + 2, current_time_low); 371 return 0; 372 } 373 374 tsig->algorithm = algorithm; 375 tsig->key = key; 376 tsig->response_count = 0; 377 tsig->prior_mac_size = 0; 378 379 return 1; 380 } 381 382 void 383 tsig_init_query(tsig_record_type *tsig, uint16_t original_query_id) 384 { 385 assert(tsig); 386 assert(tsig->algorithm); 387 assert(tsig->key); 388 389 tsig->response_count = 0; 390 tsig->prior_mac_size = 0; 391 tsig->algorithm_name = tsig->algorithm->wireformat_name; 392 tsig->key_name = tsig->key->name; 393 tsig->mac_size = 0; 394 tsig->mac_data = NULL; 395 tsig->original_query_id = original_query_id; 396 tsig->error_code = TSIG_ERROR_NOERROR; 397 tsig->other_size = 0; 398 tsig->other_data = NULL; 399 } 400 401 void 402 tsig_prepare(tsig_record_type *tsig) 403 { 404 if (!tsig->context) { 405 assert(tsig->algorithm); 406 tsig->context = tsig->algorithm->hmac_create_context( 407 tsig->context_region); 408 tsig->prior_mac_data = (uint8_t *) region_alloc( 409 tsig->context_region, 410 tsig->algorithm->maximum_digest_size); 411 } 412 tsig->algorithm->hmac_init_context(tsig->context, 413 tsig->algorithm, 414 tsig->key); 415 416 if (tsig->prior_mac_size > 0) { 417 uint16_t mac_size = htons(tsig->prior_mac_size); 418 tsig->algorithm->hmac_update(tsig->context, 419 &mac_size, 420 sizeof(mac_size)); 421 tsig->algorithm->hmac_update(tsig->context, 422 tsig->prior_mac_data, 423 tsig->prior_mac_size); 424 } 425 426 tsig->updates_since_last_prepare = 0; 427 } 428 429 void 430 tsig_update(tsig_record_type *tsig, buffer_type *packet, size_t length) 431 { 432 uint16_t original_query_id = htons(tsig->original_query_id); 433 434 assert(length <= buffer_limit(packet)); 435 436 tsig->algorithm->hmac_update(tsig->context, 437 &original_query_id, 438 sizeof(original_query_id)); 439 tsig->algorithm->hmac_update( 440 tsig->context, 441 buffer_at(packet, sizeof(original_query_id)), 442 length - sizeof(original_query_id)); 443 if (QR(packet)) { 444 ++tsig->response_count; 445 } 446 447 ++tsig->updates_since_last_prepare; 448 } 449 450 void 451 tsig_sign(tsig_record_type *tsig) 452 { 453 uint64_t current_time = (uint64_t) time(NULL); 454 tsig->signed_time_high = (uint16_t) (current_time >> 32); 455 tsig->signed_time_low = (uint32_t) current_time; 456 tsig->signed_time_fudge = 300; /* XXX; hardcoded value */ 457 458 tsig_digest_variables(tsig, tsig->response_count > 1); 459 460 tsig->algorithm->hmac_final(tsig->context, 461 tsig->prior_mac_data, 462 &tsig->prior_mac_size); 463 464 tsig->mac_size = tsig->prior_mac_size; 465 tsig->mac_data = tsig->prior_mac_data; 466 } 467 468 int 469 tsig_verify(tsig_record_type *tsig) 470 { 471 tsig_digest_variables(tsig, tsig->response_count > 1); 472 473 tsig->algorithm->hmac_final(tsig->context, 474 tsig->prior_mac_data, 475 &tsig->prior_mac_size); 476 477 if (tsig->mac_size != tsig->prior_mac_size 478 || memcmp(tsig->mac_data, 479 tsig->prior_mac_data, 480 tsig->mac_size) != 0) 481 { 482 /* Digest is incorrect, cannot authenticate. */ 483 tsig->error_code = TSIG_ERROR_BADSIG; 484 return 0; 485 } else { 486 return 1; 487 } 488 } 489 490 int 491 tsig_find_rr(tsig_record_type *tsig, buffer_type *packet) 492 { 493 size_t saved_position = buffer_position(packet); 494 size_t rrcount = (QDCOUNT(packet) 495 + ANCOUNT(packet) 496 + NSCOUNT(packet) 497 + ARCOUNT(packet)); 498 size_t i; 499 int result; 500 501 if (ARCOUNT(packet) == 0) { 502 tsig->status = TSIG_NOT_PRESENT; 503 return 1; 504 } 505 506 buffer_set_position(packet, QHEADERSZ); 507 508 /* TSIG must be the last record, so skip all others. */ 509 for (i = 0; i < rrcount - 1; ++i) { 510 if (!packet_skip_rr(packet, i < QDCOUNT(packet))) { 511 buffer_set_position(packet, saved_position); 512 return 0; 513 } 514 } 515 516 result = tsig_parse_rr(tsig, packet); 517 buffer_set_position(packet, saved_position); 518 return result; 519 } 520 521 int 522 tsig_parse_rr(tsig_record_type *tsig, buffer_type *packet) 523 { 524 uint16_t type; 525 uint16_t klass; 526 uint32_t ttl; 527 uint16_t rdlen; 528 529 tsig->status = TSIG_NOT_PRESENT; 530 tsig->position = buffer_position(packet); 531 tsig->key_name = NULL; 532 tsig->algorithm_name = NULL; 533 tsig->mac_data = NULL; 534 tsig->other_data = NULL; 535 region_free_all(tsig->rr_region); 536 537 tsig->key_name = dname_make_from_packet(tsig->rr_region, packet, 1, 1); 538 if (!tsig->key_name) { 539 buffer_set_position(packet, tsig->position); 540 return 0; 541 } 542 543 if (!buffer_available(packet, 10)) { 544 buffer_set_position(packet, tsig->position); 545 return 0; 546 } 547 548 type = buffer_read_u16(packet); 549 klass = buffer_read_u16(packet); 550 551 /* TSIG not present */ 552 if (type != TYPE_TSIG || klass != CLASS_ANY) { 553 buffer_set_position(packet, tsig->position); 554 return 1; 555 } 556 557 ttl = buffer_read_u32(packet); 558 rdlen = buffer_read_u16(packet); 559 560 tsig->status = TSIG_ERROR; 561 tsig->error_code = RCODE_FORMAT; 562 if (ttl != 0 || !buffer_available(packet, rdlen)) { 563 buffer_set_position(packet, tsig->position); 564 return 0; 565 } 566 567 tsig->algorithm_name = dname_make_from_packet( 568 tsig->rr_region, packet, 1, 1); 569 if (!tsig->algorithm_name || !buffer_available(packet, 10)) { 570 buffer_set_position(packet, tsig->position); 571 return 0; 572 } 573 574 tsig->signed_time_high = buffer_read_u16(packet); 575 tsig->signed_time_low = buffer_read_u32(packet); 576 tsig->signed_time_fudge = buffer_read_u16(packet); 577 tsig->mac_size = buffer_read_u16(packet); 578 if (!buffer_available(packet, tsig->mac_size)) { 579 buffer_set_position(packet, tsig->position); 580 tsig->mac_size = 0; 581 return 0; 582 } 583 tsig->mac_data = (uint8_t *) region_alloc_init( 584 tsig->rr_region, buffer_current(packet), tsig->mac_size); 585 buffer_skip(packet, tsig->mac_size); 586 if (!buffer_available(packet, 6)) { 587 buffer_set_position(packet, tsig->position); 588 return 0; 589 } 590 tsig->original_query_id = buffer_read_u16(packet); 591 tsig->error_code = buffer_read_u16(packet); 592 tsig->other_size = buffer_read_u16(packet); 593 if (!buffer_available(packet, tsig->other_size) || tsig->other_size > 16) { 594 tsig->other_size = 0; 595 buffer_set_position(packet, tsig->position); 596 return 0; 597 } 598 tsig->other_data = (uint8_t *) region_alloc_init( 599 tsig->rr_region, buffer_current(packet), tsig->other_size); 600 buffer_skip(packet, tsig->other_size); 601 tsig->status = TSIG_OK; 602 return 1; 603 } 604 605 void 606 tsig_append_rr(tsig_record_type *tsig, buffer_type *packet) 607 { 608 size_t rdlength_pos; 609 610 /* XXX: TODO key name compression? */ 611 if(tsig->key_name) 612 buffer_write(packet, dname_name(tsig->key_name), 613 tsig->key_name->name_size); 614 else buffer_write_u8(packet, 0); 615 buffer_write_u16(packet, TYPE_TSIG); 616 buffer_write_u16(packet, CLASS_ANY); 617 buffer_write_u32(packet, 0); /* TTL */ 618 rdlength_pos = buffer_position(packet); 619 buffer_skip(packet, sizeof(uint16_t)); 620 if(tsig->algorithm_name) 621 buffer_write(packet, dname_name(tsig->algorithm_name), 622 tsig->algorithm_name->name_size); 623 else buffer_write_u8(packet, 0); 624 buffer_write_u16(packet, tsig->signed_time_high); 625 buffer_write_u32(packet, tsig->signed_time_low); 626 buffer_write_u16(packet, tsig->signed_time_fudge); 627 buffer_write_u16(packet, tsig->mac_size); 628 buffer_write(packet, tsig->mac_data, tsig->mac_size); 629 buffer_write_u16(packet, tsig->original_query_id); 630 buffer_write_u16(packet, tsig->error_code); 631 buffer_write_u16(packet, tsig->other_size); 632 buffer_write(packet, tsig->other_data, tsig->other_size); 633 634 buffer_write_u16_at(packet, rdlength_pos, 635 buffer_position(packet) - rdlength_pos 636 - sizeof(uint16_t)); 637 } 638 639 size_t 640 tsig_reserved_space(tsig_record_type *tsig) 641 { 642 if (tsig->status == TSIG_NOT_PRESENT) 643 return 0; 644 645 return ( 646 (tsig->key_name?tsig->key_name->name_size:1) /* Owner */ 647 + sizeof(uint16_t) /* Type */ 648 + sizeof(uint16_t) /* Class */ 649 + sizeof(uint32_t) /* TTL */ 650 + sizeof(uint16_t) /* RDATA length */ 651 + (tsig->algorithm_name?tsig->algorithm_name->name_size:1) 652 + sizeof(uint16_t) /* Signed time (high) */ 653 + sizeof(uint32_t) /* Signed time (low) */ 654 + sizeof(uint16_t) /* Signed time fudge */ 655 + sizeof(uint16_t) /* MAC size */ 656 + max_algo_digest_size /* MAC data */ 657 + sizeof(uint16_t) /* Original query ID */ 658 + sizeof(uint16_t) /* Error code */ 659 + sizeof(uint16_t) /* Other size */ 660 + tsig->other_size); /* Other data */ 661 } 662 663 void 664 tsig_error_reply(tsig_record_type *tsig) 665 { 666 if(tsig->mac_data) 667 memset(tsig->mac_data, 0, tsig->mac_size); 668 tsig->mac_size = 0; 669 } 670 671 void 672 tsig_finalize() 673 { 674 #if defined(HAVE_SSL) 675 tsig_openssl_finalize(); 676 #endif /* defined(HAVE_SSL) */ 677 } 678