1 /* $NetBSD: tsig.c,v 1.11 2022/09/23 12:15:30 christos Exp $ */ 2 3 /* 4 * Copyright (C) Internet Systems Consortium, Inc. ("ISC") 5 * 6 * SPDX-License-Identifier: MPL-2.0 7 * 8 * This Source Code Form is subject to the terms of the Mozilla Public 9 * License, v. 2.0. If a copy of the MPL was not distributed with this 10 * file, you can obtain one at https://mozilla.org/MPL/2.0/. 11 * 12 * See the COPYRIGHT file distributed with this work for additional 13 * information regarding copyright ownership. 14 */ 15 16 /*! \file */ 17 18 #include <inttypes.h> 19 #include <stdbool.h> 20 #include <stdlib.h> 21 22 #include <isc/buffer.h> 23 #include <isc/mem.h> 24 #include <isc/print.h> 25 #include <isc/refcount.h> 26 #include <isc/serial.h> 27 #include <isc/string.h> /* Required for HP/UX (and others?) */ 28 #include <isc/time.h> 29 #include <isc/util.h> 30 31 #include <pk11/site.h> 32 33 #include <dns/fixedname.h> 34 #include <dns/keyvalues.h> 35 #include <dns/log.h> 36 #include <dns/message.h> 37 #include <dns/rbt.h> 38 #include <dns/rdata.h> 39 #include <dns/rdatalist.h> 40 #include <dns/rdataset.h> 41 #include <dns/rdatastruct.h> 42 #include <dns/result.h> 43 #include <dns/tsig.h> 44 45 #include <dst/result.h> 46 47 #include "tsig_p.h" 48 49 #define TSIG_MAGIC ISC_MAGIC('T', 'S', 'I', 'G') 50 #define VALID_TSIG_KEY(x) ISC_MAGIC_VALID(x, TSIG_MAGIC) 51 52 #ifndef DNS_TSIG_MAXGENERATEDKEYS 53 #define DNS_TSIG_MAXGENERATEDKEYS 4096 54 #endif /* ifndef DNS_TSIG_MAXGENERATEDKEYS */ 55 56 #define is_response(msg) ((msg->flags & DNS_MESSAGEFLAG_QR) != 0) 57 58 #define BADTIMELEN 6 59 60 static unsigned char hmacmd5_ndata[] = "\010hmac-md5\007sig-alg\003reg\003int"; 61 static unsigned char hmacmd5_offsets[] = { 0, 9, 17, 21, 25 }; 62 63 static dns_name_t const hmacmd5 = DNS_NAME_INITABSOLUTE(hmacmd5_ndata, 64 hmacmd5_offsets); 65 LIBDNS_EXTERNAL_DATA const dns_name_t *dns_tsig_hmacmd5_name = &hmacmd5; 66 67 static unsigned char gsstsig_ndata[] = "\010gss-tsig"; 68 static unsigned char gsstsig_offsets[] = { 0, 9 }; 69 static dns_name_t const gsstsig = DNS_NAME_INITABSOLUTE(gsstsig_ndata, 70 gsstsig_offsets); 71 LIBDNS_EXTERNAL_DATA const dns_name_t *dns_tsig_gssapi_name = &gsstsig; 72 73 /* 74 * Since Microsoft doesn't follow its own standard, we will use this 75 * alternate name as a second guess. 76 */ 77 static unsigned char gsstsigms_ndata[] = "\003gss\011microsoft\003com"; 78 static unsigned char gsstsigms_offsets[] = { 0, 4, 14, 18 }; 79 static dns_name_t const gsstsigms = DNS_NAME_INITABSOLUTE(gsstsigms_ndata, 80 gsstsigms_offsets); 81 LIBDNS_EXTERNAL_DATA const dns_name_t *dns_tsig_gssapims_name = &gsstsigms; 82 83 static unsigned char hmacsha1_ndata[] = "\011hmac-sha1"; 84 static unsigned char hmacsha1_offsets[] = { 0, 10 }; 85 static dns_name_t const hmacsha1 = DNS_NAME_INITABSOLUTE(hmacsha1_ndata, 86 hmacsha1_offsets); 87 LIBDNS_EXTERNAL_DATA const dns_name_t *dns_tsig_hmacsha1_name = &hmacsha1; 88 89 static unsigned char hmacsha224_ndata[] = "\013hmac-sha224"; 90 static unsigned char hmacsha224_offsets[] = { 0, 12 }; 91 static dns_name_t const hmacsha224 = DNS_NAME_INITABSOLUTE(hmacsha224_ndata, 92 hmacsha224_offsets); 93 LIBDNS_EXTERNAL_DATA const dns_name_t *dns_tsig_hmacsha224_name = &hmacsha224; 94 95 static unsigned char hmacsha256_ndata[] = "\013hmac-sha256"; 96 static unsigned char hmacsha256_offsets[] = { 0, 12 }; 97 static dns_name_t const hmacsha256 = DNS_NAME_INITABSOLUTE(hmacsha256_ndata, 98 hmacsha256_offsets); 99 LIBDNS_EXTERNAL_DATA const dns_name_t *dns_tsig_hmacsha256_name = &hmacsha256; 100 101 static unsigned char hmacsha384_ndata[] = "\013hmac-sha384"; 102 static unsigned char hmacsha384_offsets[] = { 0, 12 }; 103 static dns_name_t const hmacsha384 = DNS_NAME_INITABSOLUTE(hmacsha384_ndata, 104 hmacsha384_offsets); 105 LIBDNS_EXTERNAL_DATA const dns_name_t *dns_tsig_hmacsha384_name = &hmacsha384; 106 107 static unsigned char hmacsha512_ndata[] = "\013hmac-sha512"; 108 static unsigned char hmacsha512_offsets[] = { 0, 12 }; 109 static dns_name_t const hmacsha512 = DNS_NAME_INITABSOLUTE(hmacsha512_ndata, 110 hmacsha512_offsets); 111 LIBDNS_EXTERNAL_DATA const dns_name_t *dns_tsig_hmacsha512_name = &hmacsha512; 112 113 static const struct { 114 const dns_name_t *name; 115 unsigned int dstalg; 116 } known_algs[] = { { &hmacmd5, DST_ALG_HMACMD5 }, 117 { &gsstsig, DST_ALG_GSSAPI }, 118 { &gsstsigms, DST_ALG_GSSAPI }, 119 { &hmacsha1, DST_ALG_HMACSHA1 }, 120 { &hmacsha224, DST_ALG_HMACSHA224 }, 121 { &hmacsha256, DST_ALG_HMACSHA256 }, 122 { &hmacsha384, DST_ALG_HMACSHA384 }, 123 { &hmacsha512, DST_ALG_HMACSHA512 } }; 124 125 static isc_result_t 126 tsig_verify_tcp(isc_buffer_t *source, dns_message_t *msg); 127 128 static void 129 tsig_log(dns_tsigkey_t *key, int level, const char *fmt, ...) 130 ISC_FORMAT_PRINTF(3, 4); 131 132 static void 133 cleanup_ring(dns_tsig_keyring_t *ring); 134 static void 135 tsigkey_free(dns_tsigkey_t *key); 136 137 bool 138 dns__tsig_algvalid(unsigned int alg) { 139 return (alg == DST_ALG_HMACMD5 || alg == DST_ALG_HMACSHA1 || 140 alg == DST_ALG_HMACSHA224 || alg == DST_ALG_HMACSHA256 || 141 alg == DST_ALG_HMACSHA384 || alg == DST_ALG_HMACSHA512); 142 } 143 144 static void 145 tsig_log(dns_tsigkey_t *key, int level, const char *fmt, ...) { 146 va_list ap; 147 char message[4096]; 148 char namestr[DNS_NAME_FORMATSIZE]; 149 char creatorstr[DNS_NAME_FORMATSIZE]; 150 151 if (!isc_log_wouldlog(dns_lctx, level)) { 152 return; 153 } 154 if (key != NULL) { 155 dns_name_format(&key->name, namestr, sizeof(namestr)); 156 } else { 157 strlcpy(namestr, "<null>", sizeof(namestr)); 158 } 159 160 if (key != NULL && key->generated && key->creator) { 161 dns_name_format(key->creator, creatorstr, sizeof(creatorstr)); 162 } else { 163 strlcpy(creatorstr, "<null>", sizeof(creatorstr)); 164 } 165 166 va_start(ap, fmt); 167 vsnprintf(message, sizeof(message), fmt, ap); 168 va_end(ap); 169 if (key != NULL && key->generated) { 170 isc_log_write(dns_lctx, DNS_LOGCATEGORY_DNSSEC, 171 DNS_LOGMODULE_TSIG, level, 172 "tsig key '%s' (%s): %s", namestr, creatorstr, 173 message); 174 } else { 175 isc_log_write(dns_lctx, DNS_LOGCATEGORY_DNSSEC, 176 DNS_LOGMODULE_TSIG, level, "tsig key '%s': %s", 177 namestr, message); 178 } 179 } 180 181 static void 182 remove_fromring(dns_tsigkey_t *tkey) { 183 if (tkey->generated) { 184 ISC_LIST_UNLINK(tkey->ring->lru, tkey, link); 185 tkey->ring->generated--; 186 } 187 (void)dns_rbt_deletename(tkey->ring->keys, &tkey->name, false); 188 } 189 190 static void 191 adjust_lru(dns_tsigkey_t *tkey) { 192 if (tkey->generated) { 193 RWLOCK(&tkey->ring->lock, isc_rwlocktype_write); 194 /* 195 * We may have been removed from the LRU list between 196 * removing the read lock and acquiring the write lock. 197 */ 198 if (ISC_LINK_LINKED(tkey, link) && tkey->ring->lru.tail != tkey) 199 { 200 ISC_LIST_UNLINK(tkey->ring->lru, tkey, link); 201 ISC_LIST_APPEND(tkey->ring->lru, tkey, link); 202 } 203 RWUNLOCK(&tkey->ring->lock, isc_rwlocktype_write); 204 } 205 } 206 207 /* 208 * A supplemental routine just to add a key to ring. Note that reference 209 * counter should be counted separately because we may be adding the key 210 * as part of creation of the key, in which case the reference counter was 211 * already initialized. Also note we don't need RWLOCK for the reference 212 * counter: it's protected by a separate lock. 213 */ 214 static isc_result_t 215 keyring_add(dns_tsig_keyring_t *ring, const dns_name_t *name, 216 dns_tsigkey_t *tkey) { 217 isc_result_t result; 218 219 RWLOCK(&ring->lock, isc_rwlocktype_write); 220 ring->writecount++; 221 222 /* 223 * Do on the fly cleaning. Find some nodes we might not 224 * want around any more. 225 */ 226 if (ring->writecount > 10) { 227 cleanup_ring(ring); 228 ring->writecount = 0; 229 } 230 231 result = dns_rbt_addname(ring->keys, name, tkey); 232 if (result == ISC_R_SUCCESS && tkey->generated) { 233 /* 234 * Add the new key to the LRU list and remove the least 235 * recently used key if there are too many keys on the list. 236 */ 237 ISC_LIST_APPEND(ring->lru, tkey, link); 238 if (ring->generated++ > ring->maxgenerated) { 239 remove_fromring(ISC_LIST_HEAD(ring->lru)); 240 } 241 } 242 RWUNLOCK(&ring->lock, isc_rwlocktype_write); 243 244 return (result); 245 } 246 247 isc_result_t 248 dns_tsigkey_createfromkey(const dns_name_t *name, const dns_name_t *algorithm, 249 dst_key_t *dstkey, bool generated, 250 const dns_name_t *creator, isc_stdtime_t inception, 251 isc_stdtime_t expire, isc_mem_t *mctx, 252 dns_tsig_keyring_t *ring, dns_tsigkey_t **key) { 253 dns_tsigkey_t *tkey; 254 isc_result_t ret; 255 unsigned int refs = 0; 256 unsigned int dstalg = 0; 257 258 REQUIRE(key == NULL || *key == NULL); 259 REQUIRE(name != NULL); 260 REQUIRE(algorithm != NULL); 261 REQUIRE(mctx != NULL); 262 REQUIRE(key != NULL || ring != NULL); 263 264 tkey = isc_mem_get(mctx, sizeof(dns_tsigkey_t)); 265 266 dns_name_init(&tkey->name, NULL); 267 dns_name_dup(name, mctx, &tkey->name); 268 (void)dns_name_downcase(&tkey->name, &tkey->name, NULL); 269 270 /* Check against known algorithm names */ 271 dstalg = dns__tsig_algfromname(algorithm); 272 if (dstalg != 0) { 273 /* 274 * 'algorithm' must be set to a static pointer 275 * so that dns__tsig_algallocated() can compare them. 276 */ 277 tkey->algorithm = dns__tsig_algnamefromname(algorithm); 278 if (dstkey != NULL && dst_key_alg(dstkey) != dstalg) { 279 ret = DNS_R_BADALG; 280 goto cleanup_name; 281 } 282 } else { 283 dns_name_t *tmpname; 284 if (dstkey != NULL) { 285 ret = DNS_R_BADALG; 286 goto cleanup_name; 287 } 288 tmpname = isc_mem_get(mctx, sizeof(dns_name_t)); 289 dns_name_init(tmpname, NULL); 290 dns_name_dup(algorithm, mctx, tmpname); 291 (void)dns_name_downcase(tmpname, tmpname, NULL); 292 tkey->algorithm = tmpname; 293 } 294 295 if (creator != NULL) { 296 tkey->creator = isc_mem_get(mctx, sizeof(dns_name_t)); 297 dns_name_init(tkey->creator, NULL); 298 dns_name_dup(creator, mctx, tkey->creator); 299 } else { 300 tkey->creator = NULL; 301 } 302 303 tkey->key = NULL; 304 if (dstkey != NULL) { 305 dst_key_attach(dstkey, &tkey->key); 306 } 307 tkey->ring = ring; 308 309 if (key != NULL) { 310 refs = 1; 311 } 312 if (ring != NULL) { 313 refs++; 314 } 315 316 isc_refcount_init(&tkey->refs, refs); 317 318 tkey->generated = generated; 319 tkey->inception = inception; 320 tkey->expire = expire; 321 tkey->mctx = NULL; 322 isc_mem_attach(mctx, &tkey->mctx); 323 ISC_LINK_INIT(tkey, link); 324 325 tkey->magic = TSIG_MAGIC; 326 327 if (ring != NULL) { 328 ret = keyring_add(ring, name, tkey); 329 if (ret != ISC_R_SUCCESS) { 330 goto cleanup_refs; 331 } 332 } 333 334 /* 335 * Ignore this if it's a GSS key, since the key size is meaningless. 336 */ 337 if (dstkey != NULL && dst_key_size(dstkey) < 64 && 338 dstalg != DST_ALG_GSSAPI) { 339 char namestr[DNS_NAME_FORMATSIZE]; 340 dns_name_format(name, namestr, sizeof(namestr)); 341 isc_log_write(dns_lctx, DNS_LOGCATEGORY_DNSSEC, 342 DNS_LOGMODULE_TSIG, ISC_LOG_INFO, 343 "the key '%s' is too short to be secure", 344 namestr); 345 } 346 347 if (key != NULL) { 348 *key = tkey; 349 } 350 351 return (ISC_R_SUCCESS); 352 353 cleanup_refs: 354 tkey->magic = 0; 355 while (refs-- > 0) { 356 isc_refcount_decrement0(&tkey->refs); 357 } 358 isc_refcount_destroy(&tkey->refs); 359 360 if (tkey->key != NULL) { 361 dst_key_free(&tkey->key); 362 } 363 if (tkey->creator != NULL) { 364 dns_name_free(tkey->creator, mctx); 365 isc_mem_put(mctx, tkey->creator, sizeof(dns_name_t)); 366 } 367 if (dns__tsig_algallocated(tkey->algorithm)) { 368 dns_name_t *tmpname; 369 DE_CONST(tkey->algorithm, tmpname); 370 if (dns_name_dynamic(tmpname)) { 371 dns_name_free(tmpname, mctx); 372 } 373 isc_mem_put(mctx, tmpname, sizeof(dns_name_t)); 374 } 375 cleanup_name: 376 dns_name_free(&tkey->name, mctx); 377 isc_mem_put(mctx, tkey, sizeof(dns_tsigkey_t)); 378 379 return (ret); 380 } 381 382 /* 383 * Find a few nodes to destroy if possible. 384 */ 385 static void 386 cleanup_ring(dns_tsig_keyring_t *ring) { 387 isc_result_t result; 388 dns_rbtnodechain_t chain; 389 dns_name_t foundname; 390 dns_fixedname_t fixedorigin; 391 dns_name_t *origin; 392 isc_stdtime_t now; 393 dns_rbtnode_t *node; 394 dns_tsigkey_t *tkey; 395 396 /* 397 * Start up a new iterator each time. 398 */ 399 isc_stdtime_get(&now); 400 dns_name_init(&foundname, NULL); 401 origin = dns_fixedname_initname(&fixedorigin); 402 403 again: 404 dns_rbtnodechain_init(&chain); 405 result = dns_rbtnodechain_first(&chain, ring->keys, &foundname, origin); 406 if (result != ISC_R_SUCCESS && result != DNS_R_NEWORIGIN) { 407 dns_rbtnodechain_invalidate(&chain); 408 return; 409 } 410 411 for (;;) { 412 node = NULL; 413 dns_rbtnodechain_current(&chain, &foundname, origin, &node); 414 tkey = node->data; 415 if (tkey != NULL) { 416 if (tkey->generated && 417 isc_refcount_current(&tkey->refs) == 1 && 418 tkey->inception != tkey->expire && 419 tkey->expire < now) 420 { 421 tsig_log(tkey, 2, "tsig expire: deleting"); 422 /* delete the key */ 423 dns_rbtnodechain_invalidate(&chain); 424 remove_fromring(tkey); 425 goto again; 426 } 427 } 428 result = dns_rbtnodechain_next(&chain, &foundname, origin); 429 if (result != ISC_R_SUCCESS && result != DNS_R_NEWORIGIN) { 430 dns_rbtnodechain_invalidate(&chain); 431 return; 432 } 433 } 434 } 435 436 static void 437 destroyring(dns_tsig_keyring_t *ring) { 438 isc_refcount_destroy(&ring->references); 439 dns_rbt_destroy(&ring->keys); 440 isc_rwlock_destroy(&ring->lock); 441 isc_mem_putanddetach(&ring->mctx, ring, sizeof(dns_tsig_keyring_t)); 442 } 443 444 /* 445 * Look up the DST_ALG_ constant for a given name. 446 */ 447 unsigned int 448 dns__tsig_algfromname(const dns_name_t *algorithm) { 449 int i; 450 int n = sizeof(known_algs) / sizeof(*known_algs); 451 for (i = 0; i < n; ++i) { 452 const dns_name_t *name = known_algs[i].name; 453 if (algorithm == name || dns_name_equal(algorithm, name)) { 454 return (known_algs[i].dstalg); 455 } 456 } 457 return (0); 458 } 459 460 /* 461 * Convert an algorithm name into a pointer to the 462 * corresponding pre-defined dns_name_t structure. 463 */ 464 const dns_name_t * 465 dns__tsig_algnamefromname(const dns_name_t *algorithm) { 466 int i; 467 int n = sizeof(known_algs) / sizeof(*known_algs); 468 for (i = 0; i < n; ++i) { 469 const dns_name_t *name = known_algs[i].name; 470 if (algorithm == name || dns_name_equal(algorithm, name)) { 471 return (name); 472 } 473 } 474 return (NULL); 475 } 476 477 /* 478 * Test whether the passed algorithm is NOT a pointer to one of the 479 * pre-defined known algorithms (and therefore one that has been 480 * dynamically allocated). 481 * 482 * This will return an incorrect result if passed a dynamically allocated 483 * dns_name_t that happens to match one of the pre-defined names. 484 */ 485 bool 486 dns__tsig_algallocated(const dns_name_t *algorithm) { 487 int i; 488 int n = sizeof(known_algs) / sizeof(*known_algs); 489 for (i = 0; i < n; ++i) { 490 const dns_name_t *name = known_algs[i].name; 491 if (algorithm == name) { 492 return (false); 493 } 494 } 495 return (true); 496 } 497 498 static isc_result_t 499 restore_key(dns_tsig_keyring_t *ring, isc_stdtime_t now, FILE *fp) { 500 dst_key_t *dstkey = NULL; 501 char namestr[1024]; 502 char creatorstr[1024]; 503 char algorithmstr[1024]; 504 char keystr[4096]; 505 unsigned int inception, expire; 506 int n; 507 isc_buffer_t b; 508 dns_name_t *name, *creator, *algorithm; 509 dns_fixedname_t fname, fcreator, falgorithm; 510 isc_result_t result; 511 unsigned int dstalg; 512 513 n = fscanf(fp, "%1023s %1023s %u %u %1023s %4095s\n", namestr, 514 creatorstr, &inception, &expire, algorithmstr, keystr); 515 if (n == EOF) { 516 return (ISC_R_NOMORE); 517 } 518 if (n != 6) { 519 return (ISC_R_FAILURE); 520 } 521 522 if (isc_serial_lt(expire, now)) { 523 return (DNS_R_EXPIRED); 524 } 525 526 name = dns_fixedname_initname(&fname); 527 isc_buffer_init(&b, namestr, strlen(namestr)); 528 isc_buffer_add(&b, strlen(namestr)); 529 result = dns_name_fromtext(name, &b, dns_rootname, 0, NULL); 530 if (result != ISC_R_SUCCESS) { 531 return (result); 532 } 533 534 creator = dns_fixedname_initname(&fcreator); 535 isc_buffer_init(&b, creatorstr, strlen(creatorstr)); 536 isc_buffer_add(&b, strlen(creatorstr)); 537 result = dns_name_fromtext(creator, &b, dns_rootname, 0, NULL); 538 if (result != ISC_R_SUCCESS) { 539 return (result); 540 } 541 542 algorithm = dns_fixedname_initname(&falgorithm); 543 isc_buffer_init(&b, algorithmstr, strlen(algorithmstr)); 544 isc_buffer_add(&b, strlen(algorithmstr)); 545 result = dns_name_fromtext(algorithm, &b, dns_rootname, 0, NULL); 546 if (result != ISC_R_SUCCESS) { 547 return (result); 548 } 549 550 dstalg = dns__tsig_algfromname(algorithm); 551 if (dstalg == 0) { 552 return (DNS_R_BADALG); 553 } 554 555 result = dst_key_restore(name, dstalg, DNS_KEYOWNER_ENTITY, 556 DNS_KEYPROTO_DNSSEC, dns_rdataclass_in, 557 ring->mctx, keystr, &dstkey); 558 if (result != ISC_R_SUCCESS) { 559 return (result); 560 } 561 562 result = dns_tsigkey_createfromkey(name, algorithm, dstkey, true, 563 creator, inception, expire, 564 ring->mctx, ring, NULL); 565 if (dstkey != NULL) { 566 dst_key_free(&dstkey); 567 } 568 return (result); 569 } 570 571 static void 572 dump_key(dns_tsigkey_t *tkey, FILE *fp) { 573 char *buffer = NULL; 574 int length = 0; 575 char namestr[DNS_NAME_FORMATSIZE]; 576 char creatorstr[DNS_NAME_FORMATSIZE]; 577 char algorithmstr[DNS_NAME_FORMATSIZE]; 578 isc_result_t result; 579 580 REQUIRE(tkey != NULL); 581 REQUIRE(fp != NULL); 582 583 dns_name_format(&tkey->name, namestr, sizeof(namestr)); 584 dns_name_format(tkey->creator, creatorstr, sizeof(creatorstr)); 585 dns_name_format(tkey->algorithm, algorithmstr, sizeof(algorithmstr)); 586 result = dst_key_dump(tkey->key, tkey->mctx, &buffer, &length); 587 if (result == ISC_R_SUCCESS) { 588 fprintf(fp, "%s %s %u %u %s %.*s\n", namestr, creatorstr, 589 tkey->inception, tkey->expire, algorithmstr, length, 590 buffer); 591 } 592 if (buffer != NULL) { 593 isc_mem_put(tkey->mctx, buffer, length); 594 } 595 } 596 597 isc_result_t 598 dns_tsigkeyring_dumpanddetach(dns_tsig_keyring_t **ringp, FILE *fp) { 599 isc_result_t result; 600 dns_rbtnodechain_t chain; 601 dns_name_t foundname; 602 dns_fixedname_t fixedorigin; 603 dns_name_t *origin; 604 isc_stdtime_t now; 605 dns_rbtnode_t *node; 606 dns_tsigkey_t *tkey; 607 dns_tsig_keyring_t *ring; 608 609 REQUIRE(ringp != NULL && *ringp != NULL); 610 611 ring = *ringp; 612 *ringp = NULL; 613 614 if (isc_refcount_decrement(&ring->references) > 1) { 615 return (DNS_R_CONTINUE); 616 } 617 618 isc_stdtime_get(&now); 619 dns_name_init(&foundname, NULL); 620 origin = dns_fixedname_initname(&fixedorigin); 621 dns_rbtnodechain_init(&chain); 622 result = dns_rbtnodechain_first(&chain, ring->keys, &foundname, origin); 623 if (result != ISC_R_SUCCESS && result != DNS_R_NEWORIGIN) { 624 dns_rbtnodechain_invalidate(&chain); 625 goto destroy; 626 } 627 628 for (;;) { 629 node = NULL; 630 dns_rbtnodechain_current(&chain, &foundname, origin, &node); 631 tkey = node->data; 632 if (tkey != NULL && tkey->generated && tkey->expire >= now) { 633 dump_key(tkey, fp); 634 } 635 result = dns_rbtnodechain_next(&chain, &foundname, origin); 636 if (result != ISC_R_SUCCESS && result != DNS_R_NEWORIGIN) { 637 dns_rbtnodechain_invalidate(&chain); 638 if (result == ISC_R_NOMORE) { 639 result = ISC_R_SUCCESS; 640 } 641 goto destroy; 642 } 643 } 644 645 destroy: 646 destroyring(ring); 647 return (result); 648 } 649 650 const dns_name_t * 651 dns_tsigkey_identity(const dns_tsigkey_t *tsigkey) { 652 REQUIRE(tsigkey == NULL || VALID_TSIG_KEY(tsigkey)); 653 654 if (tsigkey == NULL) { 655 return (NULL); 656 } 657 if (tsigkey->generated) { 658 return (tsigkey->creator); 659 } else { 660 return (&tsigkey->name); 661 } 662 } 663 664 isc_result_t 665 dns_tsigkey_create(const dns_name_t *name, const dns_name_t *algorithm, 666 unsigned char *secret, int length, bool generated, 667 const dns_name_t *creator, isc_stdtime_t inception, 668 isc_stdtime_t expire, isc_mem_t *mctx, 669 dns_tsig_keyring_t *ring, dns_tsigkey_t **key) { 670 dst_key_t *dstkey = NULL; 671 isc_result_t result; 672 unsigned int dstalg = 0; 673 674 REQUIRE(length >= 0); 675 if (length > 0) { 676 REQUIRE(secret != NULL); 677 } 678 679 dstalg = dns__tsig_algfromname(algorithm); 680 if (dns__tsig_algvalid(dstalg)) { 681 if (secret != NULL) { 682 isc_buffer_t b; 683 684 isc_buffer_init(&b, secret, length); 685 isc_buffer_add(&b, length); 686 result = dst_key_frombuffer( 687 name, dstalg, DNS_KEYOWNER_ENTITY, 688 DNS_KEYPROTO_DNSSEC, dns_rdataclass_in, &b, 689 mctx, &dstkey); 690 if (result != ISC_R_SUCCESS) { 691 return (result); 692 } 693 } 694 } else if (length > 0) { 695 return (DNS_R_BADALG); 696 } 697 698 result = dns_tsigkey_createfromkey(name, algorithm, dstkey, generated, 699 creator, inception, expire, mctx, 700 ring, key); 701 if (dstkey != NULL) { 702 dst_key_free(&dstkey); 703 } 704 return (result); 705 } 706 707 void 708 dns_tsigkey_attach(dns_tsigkey_t *source, dns_tsigkey_t **targetp) { 709 REQUIRE(VALID_TSIG_KEY(source)); 710 REQUIRE(targetp != NULL && *targetp == NULL); 711 712 isc_refcount_increment(&source->refs); 713 *targetp = source; 714 } 715 716 static void 717 tsigkey_free(dns_tsigkey_t *key) { 718 REQUIRE(VALID_TSIG_KEY(key)); 719 720 key->magic = 0; 721 dns_name_free(&key->name, key->mctx); 722 if (dns__tsig_algallocated(key->algorithm)) { 723 dns_name_t *name; 724 DE_CONST(key->algorithm, name); 725 dns_name_free(name, key->mctx); 726 isc_mem_put(key->mctx, name, sizeof(dns_name_t)); 727 } 728 if (key->key != NULL) { 729 dst_key_free(&key->key); 730 } 731 if (key->creator != NULL) { 732 dns_name_free(key->creator, key->mctx); 733 isc_mem_put(key->mctx, key->creator, sizeof(dns_name_t)); 734 } 735 isc_mem_putanddetach(&key->mctx, key, sizeof(dns_tsigkey_t)); 736 } 737 738 void 739 dns_tsigkey_detach(dns_tsigkey_t **keyp) { 740 REQUIRE(keyp != NULL && VALID_TSIG_KEY(*keyp)); 741 dns_tsigkey_t *key = *keyp; 742 *keyp = NULL; 743 744 if (isc_refcount_decrement(&key->refs) == 1) { 745 isc_refcount_destroy(&key->refs); 746 tsigkey_free(key); 747 } 748 } 749 750 void 751 dns_tsigkey_setdeleted(dns_tsigkey_t *key) { 752 REQUIRE(VALID_TSIG_KEY(key)); 753 REQUIRE(key->ring != NULL); 754 755 RWLOCK(&key->ring->lock, isc_rwlocktype_write); 756 remove_fromring(key); 757 RWUNLOCK(&key->ring->lock, isc_rwlocktype_write); 758 } 759 760 isc_result_t 761 dns_tsig_sign(dns_message_t *msg) { 762 dns_tsigkey_t *key = NULL; 763 dns_rdata_any_tsig_t tsig, querytsig; 764 unsigned char data[128]; 765 isc_buffer_t databuf, sigbuf; 766 isc_buffer_t *dynbuf = NULL; 767 dns_name_t *owner = NULL; 768 dns_rdata_t *rdata = NULL; 769 dns_rdatalist_t *datalist = NULL; 770 dns_rdataset_t *dataset = NULL; 771 isc_region_t r; 772 isc_stdtime_t now; 773 isc_mem_t *mctx; 774 dst_context_t *ctx = NULL; 775 isc_result_t ret; 776 unsigned char badtimedata[BADTIMELEN]; 777 unsigned int sigsize = 0; 778 bool response; 779 780 REQUIRE(msg != NULL); 781 key = dns_message_gettsigkey(msg); 782 REQUIRE(VALID_TSIG_KEY(key)); 783 784 /* 785 * If this is a response, there should be a TSIG in the query with the 786 * the exception if this is a TKEY request (see RFC 3645, Section 2.2). 787 */ 788 response = is_response(msg); 789 if (response && msg->querytsig == NULL) { 790 if (msg->tkey != 1) { 791 return (DNS_R_EXPECTEDTSIG); 792 } 793 } 794 795 mctx = msg->mctx; 796 797 tsig.mctx = mctx; 798 tsig.common.rdclass = dns_rdataclass_any; 799 tsig.common.rdtype = dns_rdatatype_tsig; 800 ISC_LINK_INIT(&tsig.common, link); 801 dns_name_init(&tsig.algorithm, NULL); 802 dns_name_clone(key->algorithm, &tsig.algorithm); 803 804 isc_stdtime_get(&now); 805 tsig.timesigned = now + msg->timeadjust; 806 tsig.fudge = DNS_TSIG_FUDGE; 807 808 tsig.originalid = msg->id; 809 810 isc_buffer_init(&databuf, data, sizeof(data)); 811 812 if (response) { 813 tsig.error = msg->querytsigstatus; 814 } else { 815 tsig.error = dns_rcode_noerror; 816 } 817 818 if (tsig.error != dns_tsigerror_badtime) { 819 tsig.otherlen = 0; 820 tsig.other = NULL; 821 } else { 822 isc_buffer_t otherbuf; 823 824 tsig.otherlen = BADTIMELEN; 825 tsig.other = badtimedata; 826 isc_buffer_init(&otherbuf, tsig.other, tsig.otherlen); 827 isc_buffer_putuint48(&otherbuf, tsig.timesigned); 828 } 829 830 if ((key->key != NULL) && (tsig.error != dns_tsigerror_badsig) && 831 (tsig.error != dns_tsigerror_badkey)) 832 { 833 unsigned char header[DNS_MESSAGE_HEADERLEN]; 834 isc_buffer_t headerbuf; 835 uint16_t digestbits; 836 bool querytsig_ok = false; 837 838 /* 839 * If it is a response, we assume that the request MAC 840 * has validated at this point. This is why we include a 841 * MAC length > 0 in the reply. 842 */ 843 ret = dst_context_create(key->key, mctx, DNS_LOGCATEGORY_DNSSEC, 844 true, 0, &ctx); 845 if (ret != ISC_R_SUCCESS) { 846 return (ret); 847 } 848 849 /* 850 * If this is a response, and if there was a TSIG in 851 * the query, digest the request's MAC. 852 * 853 * (Note: querytsig should be non-NULL for all 854 * responses except TKEY responses. Those may be signed 855 * with the newly-negotiated TSIG key even if the query 856 * wasn't signed.) 857 */ 858 if (response && msg->querytsig != NULL) { 859 dns_rdata_t querytsigrdata = DNS_RDATA_INIT; 860 861 INSIST(msg->verified_sig); 862 863 ret = dns_rdataset_first(msg->querytsig); 864 if (ret != ISC_R_SUCCESS) { 865 goto cleanup_context; 866 } 867 dns_rdataset_current(msg->querytsig, &querytsigrdata); 868 ret = dns_rdata_tostruct(&querytsigrdata, &querytsig, 869 NULL); 870 if (ret != ISC_R_SUCCESS) { 871 goto cleanup_context; 872 } 873 isc_buffer_putuint16(&databuf, querytsig.siglen); 874 if (isc_buffer_availablelength(&databuf) < 875 querytsig.siglen) { 876 ret = ISC_R_NOSPACE; 877 goto cleanup_context; 878 } 879 isc_buffer_putmem(&databuf, querytsig.signature, 880 querytsig.siglen); 881 isc_buffer_usedregion(&databuf, &r); 882 ret = dst_context_adddata(ctx, &r); 883 if (ret != ISC_R_SUCCESS) { 884 goto cleanup_context; 885 } 886 querytsig_ok = true; 887 } 888 889 /* 890 * Digest the header. 891 */ 892 isc_buffer_init(&headerbuf, header, sizeof(header)); 893 dns_message_renderheader(msg, &headerbuf); 894 isc_buffer_usedregion(&headerbuf, &r); 895 ret = dst_context_adddata(ctx, &r); 896 if (ret != ISC_R_SUCCESS) { 897 goto cleanup_context; 898 } 899 900 /* 901 * Digest the remainder of the message. 902 */ 903 isc_buffer_usedregion(msg->buffer, &r); 904 isc_region_consume(&r, DNS_MESSAGE_HEADERLEN); 905 ret = dst_context_adddata(ctx, &r); 906 if (ret != ISC_R_SUCCESS) { 907 goto cleanup_context; 908 } 909 910 if (msg->tcp_continuation == 0) { 911 /* 912 * Digest the name, class, ttl, alg. 913 */ 914 dns_name_toregion(&key->name, &r); 915 ret = dst_context_adddata(ctx, &r); 916 if (ret != ISC_R_SUCCESS) { 917 goto cleanup_context; 918 } 919 920 isc_buffer_clear(&databuf); 921 isc_buffer_putuint16(&databuf, dns_rdataclass_any); 922 isc_buffer_putuint32(&databuf, 0); /* ttl */ 923 isc_buffer_usedregion(&databuf, &r); 924 ret = dst_context_adddata(ctx, &r); 925 if (ret != ISC_R_SUCCESS) { 926 goto cleanup_context; 927 } 928 929 dns_name_toregion(&tsig.algorithm, &r); 930 ret = dst_context_adddata(ctx, &r); 931 if (ret != ISC_R_SUCCESS) { 932 goto cleanup_context; 933 } 934 } 935 /* Digest the timesigned and fudge */ 936 isc_buffer_clear(&databuf); 937 if (tsig.error == dns_tsigerror_badtime && querytsig_ok) { 938 tsig.timesigned = querytsig.timesigned; 939 } 940 isc_buffer_putuint48(&databuf, tsig.timesigned); 941 isc_buffer_putuint16(&databuf, tsig.fudge); 942 isc_buffer_usedregion(&databuf, &r); 943 ret = dst_context_adddata(ctx, &r); 944 if (ret != ISC_R_SUCCESS) { 945 goto cleanup_context; 946 } 947 948 if (msg->tcp_continuation == 0) { 949 /* 950 * Digest the error and other data length. 951 */ 952 isc_buffer_clear(&databuf); 953 isc_buffer_putuint16(&databuf, tsig.error); 954 isc_buffer_putuint16(&databuf, tsig.otherlen); 955 956 isc_buffer_usedregion(&databuf, &r); 957 ret = dst_context_adddata(ctx, &r); 958 if (ret != ISC_R_SUCCESS) { 959 goto cleanup_context; 960 } 961 962 /* 963 * Digest other data. 964 */ 965 if (tsig.otherlen > 0) { 966 r.length = tsig.otherlen; 967 r.base = tsig.other; 968 ret = dst_context_adddata(ctx, &r); 969 if (ret != ISC_R_SUCCESS) { 970 goto cleanup_context; 971 } 972 } 973 } 974 975 ret = dst_key_sigsize(key->key, &sigsize); 976 if (ret != ISC_R_SUCCESS) { 977 goto cleanup_context; 978 } 979 tsig.signature = isc_mem_get(mctx, sigsize); 980 981 isc_buffer_init(&sigbuf, tsig.signature, sigsize); 982 ret = dst_context_sign(ctx, &sigbuf); 983 if (ret != ISC_R_SUCCESS) { 984 goto cleanup_signature; 985 } 986 dst_context_destroy(&ctx); 987 digestbits = dst_key_getbits(key->key); 988 if (digestbits != 0) { 989 unsigned int bytes = (digestbits + 7) / 8; 990 if (querytsig_ok && bytes < querytsig.siglen) { 991 bytes = querytsig.siglen; 992 } 993 if (bytes > isc_buffer_usedlength(&sigbuf)) { 994 bytes = isc_buffer_usedlength(&sigbuf); 995 } 996 tsig.siglen = bytes; 997 } else { 998 tsig.siglen = isc_buffer_usedlength(&sigbuf); 999 } 1000 } else { 1001 tsig.siglen = 0; 1002 tsig.signature = NULL; 1003 } 1004 1005 ret = dns_message_gettemprdata(msg, &rdata); 1006 if (ret != ISC_R_SUCCESS) { 1007 goto cleanup_signature; 1008 } 1009 isc_buffer_allocate(msg->mctx, &dynbuf, 512); 1010 ret = dns_rdata_fromstruct(rdata, dns_rdataclass_any, 1011 dns_rdatatype_tsig, &tsig, dynbuf); 1012 if (ret != ISC_R_SUCCESS) { 1013 goto cleanup_dynbuf; 1014 } 1015 1016 dns_message_takebuffer(msg, &dynbuf); 1017 1018 if (tsig.signature != NULL) { 1019 isc_mem_put(mctx, tsig.signature, sigsize); 1020 tsig.signature = NULL; 1021 } 1022 1023 ret = dns_message_gettempname(msg, &owner); 1024 if (ret != ISC_R_SUCCESS) { 1025 goto cleanup_rdata; 1026 } 1027 dns_name_copynf(&key->name, owner); 1028 1029 ret = dns_message_gettemprdatalist(msg, &datalist); 1030 if (ret != ISC_R_SUCCESS) { 1031 goto cleanup_owner; 1032 } 1033 1034 ret = dns_message_gettemprdataset(msg, &dataset); 1035 if (ret != ISC_R_SUCCESS) { 1036 goto cleanup_rdatalist; 1037 } 1038 datalist->rdclass = dns_rdataclass_any; 1039 datalist->type = dns_rdatatype_tsig; 1040 ISC_LIST_APPEND(datalist->rdata, rdata, link); 1041 RUNTIME_CHECK(dns_rdatalist_tordataset(datalist, dataset) == 1042 ISC_R_SUCCESS); 1043 msg->tsig = dataset; 1044 msg->tsigname = owner; 1045 1046 /* Windows does not like the tsig name being compressed. */ 1047 msg->tsigname->attributes |= DNS_NAMEATTR_NOCOMPRESS; 1048 1049 return (ISC_R_SUCCESS); 1050 1051 cleanup_rdatalist: 1052 dns_message_puttemprdatalist(msg, &datalist); 1053 cleanup_owner: 1054 dns_message_puttempname(msg, &owner); 1055 goto cleanup_rdata; 1056 cleanup_dynbuf: 1057 isc_buffer_free(&dynbuf); 1058 cleanup_rdata: 1059 dns_message_puttemprdata(msg, &rdata); 1060 cleanup_signature: 1061 if (tsig.signature != NULL) { 1062 isc_mem_put(mctx, tsig.signature, sigsize); 1063 } 1064 cleanup_context: 1065 if (ctx != NULL) { 1066 dst_context_destroy(&ctx); 1067 } 1068 return (ret); 1069 } 1070 1071 isc_result_t 1072 dns_tsig_verify(isc_buffer_t *source, dns_message_t *msg, 1073 dns_tsig_keyring_t *ring1, dns_tsig_keyring_t *ring2) { 1074 dns_rdata_any_tsig_t tsig, querytsig; 1075 isc_region_t r, source_r, header_r, sig_r; 1076 isc_buffer_t databuf; 1077 unsigned char data[32]; 1078 dns_name_t *keyname; 1079 dns_rdata_t rdata = DNS_RDATA_INIT; 1080 isc_stdtime_t now; 1081 isc_result_t ret; 1082 dns_tsigkey_t *tsigkey; 1083 dst_key_t *key = NULL; 1084 unsigned char header[DNS_MESSAGE_HEADERLEN]; 1085 dst_context_t *ctx = NULL; 1086 isc_mem_t *mctx; 1087 uint16_t addcount, id; 1088 unsigned int siglen; 1089 unsigned int alg; 1090 bool response; 1091 1092 REQUIRE(source != NULL); 1093 REQUIRE(DNS_MESSAGE_VALID(msg)); 1094 tsigkey = dns_message_gettsigkey(msg); 1095 response = is_response(msg); 1096 1097 REQUIRE(tsigkey == NULL || VALID_TSIG_KEY(tsigkey)); 1098 1099 msg->verify_attempted = 1; 1100 msg->verified_sig = 0; 1101 msg->tsigstatus = dns_tsigerror_badsig; 1102 1103 if (msg->tcp_continuation) { 1104 if (tsigkey == NULL || msg->querytsig == NULL) { 1105 return (DNS_R_UNEXPECTEDTSIG); 1106 } 1107 return (tsig_verify_tcp(source, msg)); 1108 } 1109 1110 /* 1111 * There should be a TSIG record... 1112 */ 1113 if (msg->tsig == NULL) { 1114 return (DNS_R_EXPECTEDTSIG); 1115 } 1116 1117 /* 1118 * If this is a response and there's no key or query TSIG, there 1119 * shouldn't be one on the response. 1120 */ 1121 if (response && (tsigkey == NULL || msg->querytsig == NULL)) { 1122 return (DNS_R_UNEXPECTEDTSIG); 1123 } 1124 1125 mctx = msg->mctx; 1126 1127 /* 1128 * If we're here, we know the message is well formed and contains a 1129 * TSIG record. 1130 */ 1131 1132 keyname = msg->tsigname; 1133 ret = dns_rdataset_first(msg->tsig); 1134 if (ret != ISC_R_SUCCESS) { 1135 return (ret); 1136 } 1137 dns_rdataset_current(msg->tsig, &rdata); 1138 ret = dns_rdata_tostruct(&rdata, &tsig, NULL); 1139 if (ret != ISC_R_SUCCESS) { 1140 return (ret); 1141 } 1142 dns_rdata_reset(&rdata); 1143 if (response) { 1144 ret = dns_rdataset_first(msg->querytsig); 1145 if (ret != ISC_R_SUCCESS) { 1146 return (ret); 1147 } 1148 dns_rdataset_current(msg->querytsig, &rdata); 1149 ret = dns_rdata_tostruct(&rdata, &querytsig, NULL); 1150 if (ret != ISC_R_SUCCESS) { 1151 return (ret); 1152 } 1153 } 1154 1155 /* 1156 * Do the key name and algorithm match that of the query? 1157 */ 1158 if (response && 1159 (!dns_name_equal(keyname, &tsigkey->name) || 1160 !dns_name_equal(&tsig.algorithm, &querytsig.algorithm))) 1161 { 1162 msg->tsigstatus = dns_tsigerror_badkey; 1163 tsig_log(msg->tsigkey, 2, 1164 "key name and algorithm do not match"); 1165 return (DNS_R_TSIGVERIFYFAILURE); 1166 } 1167 1168 /* 1169 * Get the current time. 1170 */ 1171 isc_stdtime_get(&now); 1172 1173 /* 1174 * Find dns_tsigkey_t based on keyname. 1175 */ 1176 if (tsigkey == NULL) { 1177 ret = ISC_R_NOTFOUND; 1178 if (ring1 != NULL) { 1179 ret = dns_tsigkey_find(&tsigkey, keyname, 1180 &tsig.algorithm, ring1); 1181 } 1182 if (ret == ISC_R_NOTFOUND && ring2 != NULL) { 1183 ret = dns_tsigkey_find(&tsigkey, keyname, 1184 &tsig.algorithm, ring2); 1185 } 1186 if (ret != ISC_R_SUCCESS) { 1187 msg->tsigstatus = dns_tsigerror_badkey; 1188 ret = dns_tsigkey_create(keyname, &tsig.algorithm, NULL, 1189 0, false, NULL, now, now, mctx, 1190 NULL, &msg->tsigkey); 1191 if (ret != ISC_R_SUCCESS) { 1192 return (ret); 1193 } 1194 tsig_log(msg->tsigkey, 2, "unknown key"); 1195 return (DNS_R_TSIGVERIFYFAILURE); 1196 } 1197 msg->tsigkey = tsigkey; 1198 } 1199 1200 key = tsigkey->key; 1201 1202 /* 1203 * Check digest length. 1204 */ 1205 alg = dst_key_alg(key); 1206 ret = dst_key_sigsize(key, &siglen); 1207 if (ret != ISC_R_SUCCESS) { 1208 return (ret); 1209 } 1210 if (dns__tsig_algvalid(alg)) { 1211 if (tsig.siglen > siglen) { 1212 tsig_log(msg->tsigkey, 2, "signature length too big"); 1213 return (DNS_R_FORMERR); 1214 } 1215 if (tsig.siglen > 0 && 1216 (tsig.siglen < 10 || tsig.siglen < ((siglen + 1) / 2))) { 1217 tsig_log(msg->tsigkey, 2, 1218 "signature length below minimum"); 1219 return (DNS_R_FORMERR); 1220 } 1221 } 1222 1223 if (tsig.siglen > 0) { 1224 uint16_t addcount_n; 1225 1226 sig_r.base = tsig.signature; 1227 sig_r.length = tsig.siglen; 1228 1229 ret = dst_context_create(key, mctx, DNS_LOGCATEGORY_DNSSEC, 1230 false, 0, &ctx); 1231 if (ret != ISC_R_SUCCESS) { 1232 return (ret); 1233 } 1234 1235 if (response) { 1236 isc_buffer_init(&databuf, data, sizeof(data)); 1237 isc_buffer_putuint16(&databuf, querytsig.siglen); 1238 isc_buffer_usedregion(&databuf, &r); 1239 ret = dst_context_adddata(ctx, &r); 1240 if (ret != ISC_R_SUCCESS) { 1241 goto cleanup_context; 1242 } 1243 if (querytsig.siglen > 0) { 1244 r.length = querytsig.siglen; 1245 r.base = querytsig.signature; 1246 ret = dst_context_adddata(ctx, &r); 1247 if (ret != ISC_R_SUCCESS) { 1248 goto cleanup_context; 1249 } 1250 } 1251 } 1252 1253 /* 1254 * Extract the header. 1255 */ 1256 isc_buffer_usedregion(source, &r); 1257 memmove(header, r.base, DNS_MESSAGE_HEADERLEN); 1258 isc_region_consume(&r, DNS_MESSAGE_HEADERLEN); 1259 1260 /* 1261 * Decrement the additional field counter. 1262 */ 1263 memmove(&addcount, &header[DNS_MESSAGE_HEADERLEN - 2], 2); 1264 addcount_n = ntohs(addcount); 1265 addcount = htons((uint16_t)(addcount_n - 1)); 1266 memmove(&header[DNS_MESSAGE_HEADERLEN - 2], &addcount, 2); 1267 1268 /* 1269 * Put in the original id. 1270 */ 1271 id = htons(tsig.originalid); 1272 memmove(&header[0], &id, 2); 1273 1274 /* 1275 * Digest the modified header. 1276 */ 1277 header_r.base = (unsigned char *)header; 1278 header_r.length = DNS_MESSAGE_HEADERLEN; 1279 ret = dst_context_adddata(ctx, &header_r); 1280 if (ret != ISC_R_SUCCESS) { 1281 goto cleanup_context; 1282 } 1283 1284 /* 1285 * Digest all non-TSIG records. 1286 */ 1287 isc_buffer_usedregion(source, &source_r); 1288 r.base = source_r.base + DNS_MESSAGE_HEADERLEN; 1289 r.length = msg->sigstart - DNS_MESSAGE_HEADERLEN; 1290 ret = dst_context_adddata(ctx, &r); 1291 if (ret != ISC_R_SUCCESS) { 1292 goto cleanup_context; 1293 } 1294 1295 /* 1296 * Digest the key name. 1297 */ 1298 dns_name_toregion(&tsigkey->name, &r); 1299 ret = dst_context_adddata(ctx, &r); 1300 if (ret != ISC_R_SUCCESS) { 1301 goto cleanup_context; 1302 } 1303 1304 isc_buffer_init(&databuf, data, sizeof(data)); 1305 isc_buffer_putuint16(&databuf, tsig.common.rdclass); 1306 isc_buffer_putuint32(&databuf, msg->tsig->ttl); 1307 isc_buffer_usedregion(&databuf, &r); 1308 ret = dst_context_adddata(ctx, &r); 1309 if (ret != ISC_R_SUCCESS) { 1310 goto cleanup_context; 1311 } 1312 1313 /* 1314 * Digest the key algorithm. 1315 */ 1316 dns_name_toregion(tsigkey->algorithm, &r); 1317 ret = dst_context_adddata(ctx, &r); 1318 if (ret != ISC_R_SUCCESS) { 1319 goto cleanup_context; 1320 } 1321 1322 isc_buffer_clear(&databuf); 1323 isc_buffer_putuint48(&databuf, tsig.timesigned); 1324 isc_buffer_putuint16(&databuf, tsig.fudge); 1325 isc_buffer_putuint16(&databuf, tsig.error); 1326 isc_buffer_putuint16(&databuf, tsig.otherlen); 1327 isc_buffer_usedregion(&databuf, &r); 1328 ret = dst_context_adddata(ctx, &r); 1329 if (ret != ISC_R_SUCCESS) { 1330 goto cleanup_context; 1331 } 1332 1333 if (tsig.otherlen > 0) { 1334 r.base = tsig.other; 1335 r.length = tsig.otherlen; 1336 ret = dst_context_adddata(ctx, &r); 1337 if (ret != ISC_R_SUCCESS) { 1338 goto cleanup_context; 1339 } 1340 } 1341 1342 ret = dst_context_verify(ctx, &sig_r); 1343 if (ret == DST_R_VERIFYFAILURE) { 1344 ret = DNS_R_TSIGVERIFYFAILURE; 1345 tsig_log(msg->tsigkey, 2, 1346 "signature failed to verify(1)"); 1347 goto cleanup_context; 1348 } else if (ret != ISC_R_SUCCESS) { 1349 goto cleanup_context; 1350 } 1351 msg->verified_sig = 1; 1352 } else if (!response || (tsig.error != dns_tsigerror_badsig && 1353 tsig.error != dns_tsigerror_badkey)) 1354 { 1355 tsig_log(msg->tsigkey, 2, "signature was empty"); 1356 return (DNS_R_TSIGVERIFYFAILURE); 1357 } 1358 1359 /* 1360 * Here at this point, the MAC has been verified. Even if any of 1361 * the following code returns a TSIG error, the reply will be 1362 * signed and WILL always include the request MAC in the digest 1363 * computation. 1364 */ 1365 1366 /* 1367 * Is the time ok? 1368 */ 1369 if (now + msg->timeadjust > tsig.timesigned + tsig.fudge) { 1370 msg->tsigstatus = dns_tsigerror_badtime; 1371 tsig_log(msg->tsigkey, 2, "signature has expired"); 1372 ret = DNS_R_CLOCKSKEW; 1373 goto cleanup_context; 1374 } else if (now + msg->timeadjust < tsig.timesigned - tsig.fudge) { 1375 msg->tsigstatus = dns_tsigerror_badtime; 1376 tsig_log(msg->tsigkey, 2, "signature is in the future"); 1377 ret = DNS_R_CLOCKSKEW; 1378 goto cleanup_context; 1379 } 1380 1381 if (dns__tsig_algvalid(alg)) { 1382 uint16_t digestbits = dst_key_getbits(key); 1383 1384 if (tsig.siglen > 0 && digestbits != 0 && 1385 tsig.siglen < ((digestbits + 7) / 8)) { 1386 msg->tsigstatus = dns_tsigerror_badtrunc; 1387 tsig_log(msg->tsigkey, 2, 1388 "truncated signature length too small"); 1389 ret = DNS_R_TSIGVERIFYFAILURE; 1390 goto cleanup_context; 1391 } 1392 if (tsig.siglen > 0 && digestbits == 0 && tsig.siglen < siglen) 1393 { 1394 msg->tsigstatus = dns_tsigerror_badtrunc; 1395 tsig_log(msg->tsigkey, 2, "signature length too small"); 1396 ret = DNS_R_TSIGVERIFYFAILURE; 1397 goto cleanup_context; 1398 } 1399 } 1400 1401 if (response && tsig.error != dns_rcode_noerror) { 1402 msg->tsigstatus = tsig.error; 1403 if (tsig.error == dns_tsigerror_badtime) { 1404 ret = DNS_R_CLOCKSKEW; 1405 } else { 1406 ret = DNS_R_TSIGERRORSET; 1407 } 1408 goto cleanup_context; 1409 } 1410 1411 msg->tsigstatus = dns_rcode_noerror; 1412 ret = ISC_R_SUCCESS; 1413 1414 cleanup_context: 1415 if (ctx != NULL) { 1416 dst_context_destroy(&ctx); 1417 } 1418 1419 return (ret); 1420 } 1421 1422 static isc_result_t 1423 tsig_verify_tcp(isc_buffer_t *source, dns_message_t *msg) { 1424 dns_rdata_any_tsig_t tsig, querytsig; 1425 isc_region_t r, source_r, header_r, sig_r; 1426 isc_buffer_t databuf; 1427 unsigned char data[32]; 1428 dns_name_t *keyname; 1429 dns_rdata_t rdata = DNS_RDATA_INIT; 1430 isc_stdtime_t now; 1431 isc_result_t ret; 1432 dns_tsigkey_t *tsigkey; 1433 dst_key_t *key = NULL; 1434 unsigned char header[DNS_MESSAGE_HEADERLEN]; 1435 uint16_t addcount, id; 1436 bool has_tsig = false; 1437 isc_mem_t *mctx; 1438 unsigned int siglen; 1439 unsigned int alg; 1440 1441 REQUIRE(source != NULL); 1442 REQUIRE(msg != NULL); 1443 REQUIRE(dns_message_gettsigkey(msg) != NULL); 1444 REQUIRE(msg->tcp_continuation == 1); 1445 REQUIRE(msg->querytsig != NULL); 1446 1447 msg->verified_sig = 0; 1448 msg->tsigstatus = dns_tsigerror_badsig; 1449 1450 if (!is_response(msg)) { 1451 return (DNS_R_EXPECTEDRESPONSE); 1452 } 1453 1454 mctx = msg->mctx; 1455 1456 tsigkey = dns_message_gettsigkey(msg); 1457 key = tsigkey->key; 1458 1459 /* 1460 * Extract and parse the previous TSIG 1461 */ 1462 ret = dns_rdataset_first(msg->querytsig); 1463 if (ret != ISC_R_SUCCESS) { 1464 return (ret); 1465 } 1466 dns_rdataset_current(msg->querytsig, &rdata); 1467 ret = dns_rdata_tostruct(&rdata, &querytsig, NULL); 1468 if (ret != ISC_R_SUCCESS) { 1469 return (ret); 1470 } 1471 dns_rdata_reset(&rdata); 1472 1473 /* 1474 * If there is a TSIG in this message, do some checks. 1475 */ 1476 if (msg->tsig != NULL) { 1477 has_tsig = true; 1478 1479 keyname = msg->tsigname; 1480 ret = dns_rdataset_first(msg->tsig); 1481 if (ret != ISC_R_SUCCESS) { 1482 goto cleanup_querystruct; 1483 } 1484 dns_rdataset_current(msg->tsig, &rdata); 1485 ret = dns_rdata_tostruct(&rdata, &tsig, NULL); 1486 if (ret != ISC_R_SUCCESS) { 1487 goto cleanup_querystruct; 1488 } 1489 1490 /* 1491 * Do the key name and algorithm match that of the query? 1492 */ 1493 if (!dns_name_equal(keyname, &tsigkey->name) || 1494 !dns_name_equal(&tsig.algorithm, &querytsig.algorithm)) 1495 { 1496 msg->tsigstatus = dns_tsigerror_badkey; 1497 ret = DNS_R_TSIGVERIFYFAILURE; 1498 tsig_log(msg->tsigkey, 2, 1499 "key name and algorithm do not match"); 1500 goto cleanup_querystruct; 1501 } 1502 1503 /* 1504 * Check digest length. 1505 */ 1506 alg = dst_key_alg(key); 1507 ret = dst_key_sigsize(key, &siglen); 1508 if (ret != ISC_R_SUCCESS) { 1509 goto cleanup_querystruct; 1510 } 1511 if (dns__tsig_algvalid(alg)) { 1512 if (tsig.siglen > siglen) { 1513 tsig_log(tsigkey, 2, 1514 "signature length too big"); 1515 ret = DNS_R_FORMERR; 1516 goto cleanup_querystruct; 1517 } 1518 if (tsig.siglen > 0 && 1519 (tsig.siglen < 10 || 1520 tsig.siglen < ((siglen + 1) / 2))) { 1521 tsig_log(tsigkey, 2, 1522 "signature length below minimum"); 1523 ret = DNS_R_FORMERR; 1524 goto cleanup_querystruct; 1525 } 1526 } 1527 } 1528 1529 if (msg->tsigctx == NULL) { 1530 ret = dst_context_create(key, mctx, DNS_LOGCATEGORY_DNSSEC, 1531 false, 0, &msg->tsigctx); 1532 if (ret != ISC_R_SUCCESS) { 1533 goto cleanup_querystruct; 1534 } 1535 1536 /* 1537 * Digest the length of the query signature 1538 */ 1539 isc_buffer_init(&databuf, data, sizeof(data)); 1540 isc_buffer_putuint16(&databuf, querytsig.siglen); 1541 isc_buffer_usedregion(&databuf, &r); 1542 ret = dst_context_adddata(msg->tsigctx, &r); 1543 if (ret != ISC_R_SUCCESS) { 1544 goto cleanup_context; 1545 } 1546 1547 /* 1548 * Digest the data of the query signature 1549 */ 1550 if (querytsig.siglen > 0) { 1551 r.length = querytsig.siglen; 1552 r.base = querytsig.signature; 1553 ret = dst_context_adddata(msg->tsigctx, &r); 1554 if (ret != ISC_R_SUCCESS) { 1555 goto cleanup_context; 1556 } 1557 } 1558 } 1559 1560 /* 1561 * Extract the header. 1562 */ 1563 isc_buffer_usedregion(source, &r); 1564 memmove(header, r.base, DNS_MESSAGE_HEADERLEN); 1565 isc_region_consume(&r, DNS_MESSAGE_HEADERLEN); 1566 1567 /* 1568 * Decrement the additional field counter if necessary. 1569 */ 1570 if (has_tsig) { 1571 uint16_t addcount_n; 1572 1573 memmove(&addcount, &header[DNS_MESSAGE_HEADERLEN - 2], 2); 1574 addcount_n = ntohs(addcount); 1575 addcount = htons((uint16_t)(addcount_n - 1)); 1576 memmove(&header[DNS_MESSAGE_HEADERLEN - 2], &addcount, 2); 1577 1578 /* 1579 * Put in the original id. 1580 * 1581 * XXX Can TCP transfers be forwarded? How would that 1582 * work? 1583 */ 1584 /* cppcheck-suppress uninitStructMember 1585 * symbolName=tsig.originalid */ 1586 id = htons(tsig.originalid); 1587 memmove(&header[0], &id, 2); 1588 } 1589 1590 /* 1591 * Digest the modified header. 1592 */ 1593 header_r.base = (unsigned char *)header; 1594 header_r.length = DNS_MESSAGE_HEADERLEN; 1595 ret = dst_context_adddata(msg->tsigctx, &header_r); 1596 if (ret != ISC_R_SUCCESS) { 1597 goto cleanup_context; 1598 } 1599 1600 /* 1601 * Digest all non-TSIG records. 1602 */ 1603 isc_buffer_usedregion(source, &source_r); 1604 r.base = source_r.base + DNS_MESSAGE_HEADERLEN; 1605 if (has_tsig) { 1606 r.length = msg->sigstart - DNS_MESSAGE_HEADERLEN; 1607 } else { 1608 r.length = source_r.length - DNS_MESSAGE_HEADERLEN; 1609 } 1610 ret = dst_context_adddata(msg->tsigctx, &r); 1611 if (ret != ISC_R_SUCCESS) { 1612 goto cleanup_context; 1613 } 1614 1615 /* 1616 * Digest the time signed and fudge. 1617 */ 1618 if (has_tsig) { 1619 isc_buffer_init(&databuf, data, sizeof(data)); 1620 isc_buffer_putuint48(&databuf, tsig.timesigned); 1621 isc_buffer_putuint16(&databuf, tsig.fudge); 1622 isc_buffer_usedregion(&databuf, &r); 1623 ret = dst_context_adddata(msg->tsigctx, &r); 1624 if (ret != ISC_R_SUCCESS) { 1625 goto cleanup_context; 1626 } 1627 1628 sig_r.base = tsig.signature; 1629 sig_r.length = tsig.siglen; 1630 if (tsig.siglen == 0) { 1631 if (tsig.error != dns_rcode_noerror) { 1632 msg->tsigstatus = tsig.error; 1633 if (tsig.error == dns_tsigerror_badtime) { 1634 ret = DNS_R_CLOCKSKEW; 1635 } else { 1636 ret = DNS_R_TSIGERRORSET; 1637 } 1638 } else { 1639 tsig_log(msg->tsigkey, 2, "signature is empty"); 1640 ret = DNS_R_TSIGVERIFYFAILURE; 1641 } 1642 goto cleanup_context; 1643 } 1644 1645 ret = dst_context_verify(msg->tsigctx, &sig_r); 1646 if (ret == DST_R_VERIFYFAILURE) { 1647 tsig_log(msg->tsigkey, 2, 1648 "signature failed to verify(2)"); 1649 ret = DNS_R_TSIGVERIFYFAILURE; 1650 goto cleanup_context; 1651 } else if (ret != ISC_R_SUCCESS) { 1652 goto cleanup_context; 1653 } 1654 msg->verified_sig = 1; 1655 1656 /* 1657 * Here at this point, the MAC has been verified. Even 1658 * if any of the following code returns a TSIG error, 1659 * the reply will be signed and WILL always include the 1660 * request MAC in the digest computation. 1661 */ 1662 1663 /* 1664 * Is the time ok? 1665 */ 1666 isc_stdtime_get(&now); 1667 1668 if (now + msg->timeadjust > tsig.timesigned + tsig.fudge) { 1669 msg->tsigstatus = dns_tsigerror_badtime; 1670 tsig_log(msg->tsigkey, 2, "signature has expired"); 1671 ret = DNS_R_CLOCKSKEW; 1672 goto cleanup_context; 1673 } else if (now + msg->timeadjust < tsig.timesigned - tsig.fudge) 1674 { 1675 msg->tsigstatus = dns_tsigerror_badtime; 1676 tsig_log(msg->tsigkey, 2, "signature is in the future"); 1677 ret = DNS_R_CLOCKSKEW; 1678 goto cleanup_context; 1679 } 1680 1681 alg = dst_key_alg(key); 1682 ret = dst_key_sigsize(key, &siglen); 1683 if (ret != ISC_R_SUCCESS) { 1684 goto cleanup_context; 1685 } 1686 if (dns__tsig_algvalid(alg)) { 1687 uint16_t digestbits = dst_key_getbits(key); 1688 1689 if (tsig.siglen > 0 && digestbits != 0 && 1690 tsig.siglen < ((digestbits + 7) / 8)) { 1691 msg->tsigstatus = dns_tsigerror_badtrunc; 1692 tsig_log(msg->tsigkey, 2, 1693 "truncated signature length " 1694 "too small"); 1695 ret = DNS_R_TSIGVERIFYFAILURE; 1696 goto cleanup_context; 1697 } 1698 if (tsig.siglen > 0 && digestbits == 0 && 1699 tsig.siglen < siglen) { 1700 msg->tsigstatus = dns_tsigerror_badtrunc; 1701 tsig_log(msg->tsigkey, 2, 1702 "signature length too small"); 1703 ret = DNS_R_TSIGVERIFYFAILURE; 1704 goto cleanup_context; 1705 } 1706 } 1707 1708 if (tsig.error != dns_rcode_noerror) { 1709 msg->tsigstatus = tsig.error; 1710 if (tsig.error == dns_tsigerror_badtime) { 1711 ret = DNS_R_CLOCKSKEW; 1712 } else { 1713 ret = DNS_R_TSIGERRORSET; 1714 } 1715 goto cleanup_context; 1716 } 1717 } 1718 1719 msg->tsigstatus = dns_rcode_noerror; 1720 ret = ISC_R_SUCCESS; 1721 1722 cleanup_context: 1723 /* 1724 * Except in error conditions, don't destroy the DST context 1725 * for unsigned messages; it is a running sum till the next 1726 * TSIG signed message. 1727 */ 1728 if ((ret != ISC_R_SUCCESS || has_tsig) && msg->tsigctx != NULL) { 1729 dst_context_destroy(&msg->tsigctx); 1730 } 1731 1732 cleanup_querystruct: 1733 dns_rdata_freestruct(&querytsig); 1734 1735 return (ret); 1736 } 1737 1738 isc_result_t 1739 dns_tsigkey_find(dns_tsigkey_t **tsigkey, const dns_name_t *name, 1740 const dns_name_t *algorithm, dns_tsig_keyring_t *ring) { 1741 dns_tsigkey_t *key; 1742 isc_stdtime_t now; 1743 isc_result_t result; 1744 1745 REQUIRE(tsigkey != NULL); 1746 REQUIRE(*tsigkey == NULL); 1747 REQUIRE(name != NULL); 1748 REQUIRE(ring != NULL); 1749 1750 RWLOCK(&ring->lock, isc_rwlocktype_write); 1751 cleanup_ring(ring); 1752 RWUNLOCK(&ring->lock, isc_rwlocktype_write); 1753 1754 isc_stdtime_get(&now); 1755 RWLOCK(&ring->lock, isc_rwlocktype_read); 1756 key = NULL; 1757 result = dns_rbt_findname(ring->keys, name, 0, NULL, (void *)&key); 1758 if (result == DNS_R_PARTIALMATCH || result == ISC_R_NOTFOUND) { 1759 RWUNLOCK(&ring->lock, isc_rwlocktype_read); 1760 return (ISC_R_NOTFOUND); 1761 } 1762 if (algorithm != NULL && !dns_name_equal(key->algorithm, algorithm)) { 1763 RWUNLOCK(&ring->lock, isc_rwlocktype_read); 1764 return (ISC_R_NOTFOUND); 1765 } 1766 if (key->inception != key->expire && isc_serial_lt(key->expire, now)) { 1767 /* 1768 * The key has expired. 1769 */ 1770 RWUNLOCK(&ring->lock, isc_rwlocktype_read); 1771 RWLOCK(&ring->lock, isc_rwlocktype_write); 1772 remove_fromring(key); 1773 RWUNLOCK(&ring->lock, isc_rwlocktype_write); 1774 return (ISC_R_NOTFOUND); 1775 } 1776 #if 0 1777 /* 1778 * MPAXXX We really should look at the inception time. 1779 */ 1780 if (key->inception != key->expire && 1781 isc_serial_lt(key->inception, now)) { 1782 RWUNLOCK(&ring->lock, isc_rwlocktype_read); 1783 adjust_lru(key); 1784 return (ISC_R_NOTFOUND); 1785 } 1786 #endif /* if 0 */ 1787 isc_refcount_increment(&key->refs); 1788 RWUNLOCK(&ring->lock, isc_rwlocktype_read); 1789 adjust_lru(key); 1790 *tsigkey = key; 1791 return (ISC_R_SUCCESS); 1792 } 1793 1794 static void 1795 free_tsignode(void *node, void *_unused) { 1796 dns_tsigkey_t *key; 1797 1798 REQUIRE(node != NULL); 1799 1800 UNUSED(_unused); 1801 1802 key = node; 1803 if (key->generated) { 1804 if (ISC_LINK_LINKED(key, link)) { 1805 ISC_LIST_UNLINK(key->ring->lru, key, link); 1806 } 1807 } 1808 dns_tsigkey_detach(&key); 1809 } 1810 1811 isc_result_t 1812 dns_tsigkeyring_create(isc_mem_t *mctx, dns_tsig_keyring_t **ringp) { 1813 isc_result_t result; 1814 dns_tsig_keyring_t *ring; 1815 1816 REQUIRE(mctx != NULL); 1817 REQUIRE(ringp != NULL); 1818 REQUIRE(*ringp == NULL); 1819 1820 ring = isc_mem_get(mctx, sizeof(dns_tsig_keyring_t)); 1821 1822 isc_rwlock_init(&ring->lock, 0, 0); 1823 ring->keys = NULL; 1824 result = dns_rbt_create(mctx, free_tsignode, NULL, &ring->keys); 1825 if (result != ISC_R_SUCCESS) { 1826 isc_rwlock_destroy(&ring->lock); 1827 isc_mem_put(mctx, ring, sizeof(dns_tsig_keyring_t)); 1828 return (result); 1829 } 1830 1831 ring->writecount = 0; 1832 ring->mctx = NULL; 1833 ring->generated = 0; 1834 ring->maxgenerated = DNS_TSIG_MAXGENERATEDKEYS; 1835 ISC_LIST_INIT(ring->lru); 1836 isc_mem_attach(mctx, &ring->mctx); 1837 isc_refcount_init(&ring->references, 1); 1838 1839 *ringp = ring; 1840 return (ISC_R_SUCCESS); 1841 } 1842 1843 isc_result_t 1844 dns_tsigkeyring_add(dns_tsig_keyring_t *ring, const dns_name_t *name, 1845 dns_tsigkey_t *tkey) { 1846 isc_result_t result; 1847 1848 result = keyring_add(ring, name, tkey); 1849 if (result == ISC_R_SUCCESS) { 1850 isc_refcount_increment(&tkey->refs); 1851 } 1852 1853 return (result); 1854 } 1855 1856 void 1857 dns_tsigkeyring_attach(dns_tsig_keyring_t *source, 1858 dns_tsig_keyring_t **target) { 1859 REQUIRE(source != NULL); 1860 REQUIRE(target != NULL && *target == NULL); 1861 1862 isc_refcount_increment(&source->references); 1863 1864 *target = source; 1865 } 1866 1867 void 1868 dns_tsigkeyring_detach(dns_tsig_keyring_t **ringp) { 1869 dns_tsig_keyring_t *ring; 1870 1871 REQUIRE(ringp != NULL); 1872 REQUIRE(*ringp != NULL); 1873 1874 ring = *ringp; 1875 *ringp = NULL; 1876 1877 if (isc_refcount_decrement(&ring->references) == 1) { 1878 destroyring(ring); 1879 } 1880 } 1881 1882 void 1883 dns_keyring_restore(dns_tsig_keyring_t *ring, FILE *fp) { 1884 isc_stdtime_t now; 1885 isc_result_t result; 1886 1887 isc_stdtime_get(&now); 1888 do { 1889 result = restore_key(ring, now, fp); 1890 if (result == ISC_R_NOMORE) { 1891 return; 1892 } 1893 if (result == DNS_R_BADALG || result == DNS_R_EXPIRED) { 1894 result = ISC_R_SUCCESS; 1895 } 1896 } while (result == ISC_R_SUCCESS); 1897 } 1898