1/* $NetBSD: tsig_250.c,v 1.9 2024/02/21 22:52:11 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#ifndef RDATA_ANY_255_TSIG_250_C 17#define RDATA_ANY_255_TSIG_250_C 18 19#define RRTYPE_TSIG_ATTRIBUTES \ 20 (DNS_RDATATYPEATTR_META | DNS_RDATATYPEATTR_NOTQUESTION) 21 22static isc_result_t 23fromtext_any_tsig(ARGS_FROMTEXT) { 24 isc_token_t token; 25 dns_name_t name; 26 uint64_t sigtime; 27 isc_buffer_t buffer; 28 dns_rcode_t rcode; 29 long i; 30 char *e; 31 32 REQUIRE(type == dns_rdatatype_tsig); 33 REQUIRE(rdclass == dns_rdataclass_any); 34 35 UNUSED(type); 36 UNUSED(rdclass); 37 UNUSED(callbacks); 38 39 /* 40 * Algorithm Name. 41 */ 42 RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_string, 43 false)); 44 dns_name_init(&name, NULL); 45 buffer_fromregion(&buffer, &token.value.as_region); 46 if (origin == NULL) { 47 origin = dns_rootname; 48 } 49 RETTOK(dns_name_fromtext(&name, &buffer, origin, options, target)); 50 51 /* 52 * Time Signed: 48 bits. 53 */ 54 RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_string, 55 false)); 56 sigtime = strtoull(DNS_AS_STR(token), &e, 10); 57 if (*e != 0) { 58 RETTOK(DNS_R_SYNTAX); 59 } 60 if ((sigtime >> 48) != 0) { 61 RETTOK(ISC_R_RANGE); 62 } 63 RETERR(uint16_tobuffer((uint16_t)(sigtime >> 32), target)); 64 RETERR(uint32_tobuffer((uint32_t)(sigtime & 0xffffffffU), target)); 65 66 /* 67 * Fudge. 68 */ 69 RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_number, 70 false)); 71 if (token.value.as_ulong > 0xffffU) { 72 RETTOK(ISC_R_RANGE); 73 } 74 RETERR(uint16_tobuffer(token.value.as_ulong, target)); 75 76 /* 77 * Signature Size. 78 */ 79 RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_number, 80 false)); 81 if (token.value.as_ulong > 0xffffU) { 82 RETTOK(ISC_R_RANGE); 83 } 84 RETERR(uint16_tobuffer(token.value.as_ulong, target)); 85 86 /* 87 * Signature. 88 */ 89 RETERR(isc_base64_tobuffer(lexer, target, (int)token.value.as_ulong)); 90 91 /* 92 * Original ID. 93 */ 94 RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_number, 95 false)); 96 if (token.value.as_ulong > 0xffffU) { 97 RETTOK(ISC_R_RANGE); 98 } 99 RETERR(uint16_tobuffer(token.value.as_ulong, target)); 100 101 /* 102 * Error. 103 */ 104 RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_string, 105 false)); 106 if (dns_tsigrcode_fromtext(&rcode, &token.value.as_textregion) != 107 ISC_R_SUCCESS) 108 { 109 i = strtol(DNS_AS_STR(token), &e, 10); 110 if (*e != 0) { 111 RETTOK(DNS_R_UNKNOWN); 112 } 113 if (i < 0 || i > 0xffff) { 114 RETTOK(ISC_R_RANGE); 115 } 116 rcode = (dns_rcode_t)i; 117 } 118 RETERR(uint16_tobuffer(rcode, target)); 119 120 /* 121 * Other Len. 122 */ 123 RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_number, 124 false)); 125 if (token.value.as_ulong > 0xffffU) { 126 RETTOK(ISC_R_RANGE); 127 } 128 RETERR(uint16_tobuffer(token.value.as_ulong, target)); 129 130 /* 131 * Other Data. 132 */ 133 return (isc_base64_tobuffer(lexer, target, (int)token.value.as_ulong)); 134} 135 136static isc_result_t 137totext_any_tsig(ARGS_TOTEXT) { 138 isc_region_t sr; 139 isc_region_t sigr; 140 char buf[sizeof(" 281474976710655 ")]; 141 char *bufp; 142 dns_name_t name; 143 dns_name_t prefix; 144 bool sub; 145 uint64_t sigtime; 146 unsigned short n; 147 148 REQUIRE(rdata->type == dns_rdatatype_tsig); 149 REQUIRE(rdata->rdclass == dns_rdataclass_any); 150 REQUIRE(rdata->length != 0); 151 152 dns_rdata_toregion(rdata, &sr); 153 /* 154 * Algorithm Name. 155 */ 156 dns_name_init(&name, NULL); 157 dns_name_init(&prefix, NULL); 158 dns_name_fromregion(&name, &sr); 159 sub = name_prefix(&name, tctx->origin, &prefix); 160 RETERR(dns_name_totext(&prefix, sub, target)); 161 RETERR(str_totext(" ", target)); 162 isc_region_consume(&sr, name_length(&name)); 163 164 /* 165 * Time Signed. 166 */ 167 sigtime = ((uint64_t)sr.base[0] << 40) | ((uint64_t)sr.base[1] << 32) | 168 ((uint64_t)sr.base[2] << 24) | ((uint64_t)sr.base[3] << 16) | 169 ((uint64_t)sr.base[4] << 8) | (uint64_t)sr.base[5]; 170 isc_region_consume(&sr, 6); 171 bufp = &buf[sizeof(buf) - 1]; 172 *bufp-- = 0; 173 *bufp-- = ' '; 174 do { 175 *bufp-- = decdigits[sigtime % 10]; 176 sigtime /= 10; 177 } while (sigtime != 0); 178 bufp++; 179 RETERR(str_totext(bufp, target)); 180 181 /* 182 * Fudge. 183 */ 184 n = uint16_fromregion(&sr); 185 isc_region_consume(&sr, 2); 186 snprintf(buf, sizeof(buf), "%u ", n); 187 RETERR(str_totext(buf, target)); 188 189 /* 190 * Signature Size. 191 */ 192 n = uint16_fromregion(&sr); 193 isc_region_consume(&sr, 2); 194 snprintf(buf, sizeof(buf), "%u", n); 195 RETERR(str_totext(buf, target)); 196 197 /* 198 * Signature. 199 */ 200 if (n != 0U) { 201 REQUIRE(n <= sr.length); 202 sigr = sr; 203 sigr.length = n; 204 if ((tctx->flags & DNS_STYLEFLAG_MULTILINE) != 0) { 205 RETERR(str_totext(" (", target)); 206 } 207 RETERR(str_totext(tctx->linebreak, target)); 208 if (tctx->width == 0) { /* No splitting */ 209 RETERR(isc_base64_totext(&sigr, 60, "", target)); 210 } else { 211 RETERR(isc_base64_totext(&sigr, tctx->width - 2, 212 tctx->linebreak, target)); 213 } 214 if ((tctx->flags & DNS_STYLEFLAG_MULTILINE) != 0) { 215 RETERR(str_totext(" ) ", target)); 216 } else { 217 RETERR(str_totext(" ", target)); 218 } 219 isc_region_consume(&sr, n); 220 } else { 221 RETERR(str_totext(" ", target)); 222 } 223 224 /* 225 * Original ID. 226 */ 227 n = uint16_fromregion(&sr); 228 isc_region_consume(&sr, 2); 229 snprintf(buf, sizeof(buf), "%u ", n); 230 RETERR(str_totext(buf, target)); 231 232 /* 233 * Error. 234 */ 235 n = uint16_fromregion(&sr); 236 isc_region_consume(&sr, 2); 237 RETERR(dns_tsigrcode_totext((dns_rcode_t)n, target)); 238 239 /* 240 * Other Size. 241 */ 242 n = uint16_fromregion(&sr); 243 isc_region_consume(&sr, 2); 244 snprintf(buf, sizeof(buf), " %u ", n); 245 RETERR(str_totext(buf, target)); 246 247 /* 248 * Other. 249 */ 250 if (tctx->width == 0) { /* No splitting */ 251 return (isc_base64_totext(&sr, 60, "", target)); 252 } else { 253 return (isc_base64_totext(&sr, 60, " ", target)); 254 } 255} 256 257static isc_result_t 258fromwire_any_tsig(ARGS_FROMWIRE) { 259 isc_region_t sr; 260 dns_name_t name; 261 unsigned long n; 262 263 REQUIRE(type == dns_rdatatype_tsig); 264 REQUIRE(rdclass == dns_rdataclass_any); 265 266 UNUSED(type); 267 UNUSED(rdclass); 268 269 dns_decompress_setmethods(dctx, DNS_COMPRESS_NONE); 270 271 /* 272 * Algorithm Name. 273 */ 274 dns_name_init(&name, NULL); 275 RETERR(dns_name_fromwire(&name, source, dctx, options, target)); 276 277 isc_buffer_activeregion(source, &sr); 278 /* 279 * Time Signed + Fudge. 280 */ 281 if (sr.length < 8) { 282 return (ISC_R_UNEXPECTEDEND); 283 } 284 RETERR(mem_tobuffer(target, sr.base, 8)); 285 isc_region_consume(&sr, 8); 286 isc_buffer_forward(source, 8); 287 288 /* 289 * Signature Length + Signature. 290 */ 291 if (sr.length < 2) { 292 return (ISC_R_UNEXPECTEDEND); 293 } 294 n = uint16_fromregion(&sr); 295 if (sr.length < n + 2) { 296 return (ISC_R_UNEXPECTEDEND); 297 } 298 RETERR(mem_tobuffer(target, sr.base, n + 2)); 299 isc_region_consume(&sr, n + 2); 300 isc_buffer_forward(source, n + 2); 301 302 /* 303 * Original ID + Error. 304 */ 305 if (sr.length < 4) { 306 return (ISC_R_UNEXPECTEDEND); 307 } 308 RETERR(mem_tobuffer(target, sr.base, 4)); 309 isc_region_consume(&sr, 4); 310 isc_buffer_forward(source, 4); 311 312 /* 313 * Other Length + Other. 314 */ 315 if (sr.length < 2) { 316 return (ISC_R_UNEXPECTEDEND); 317 } 318 n = uint16_fromregion(&sr); 319 if (sr.length < n + 2) { 320 return (ISC_R_UNEXPECTEDEND); 321 } 322 isc_buffer_forward(source, n + 2); 323 return (mem_tobuffer(target, sr.base, n + 2)); 324} 325 326static isc_result_t 327towire_any_tsig(ARGS_TOWIRE) { 328 isc_region_t sr; 329 dns_name_t name; 330 dns_offsets_t offsets; 331 332 REQUIRE(rdata->type == dns_rdatatype_tsig); 333 REQUIRE(rdata->rdclass == dns_rdataclass_any); 334 REQUIRE(rdata->length != 0); 335 336 dns_compress_setmethods(cctx, DNS_COMPRESS_NONE); 337 dns_rdata_toregion(rdata, &sr); 338 dns_name_init(&name, offsets); 339 dns_name_fromregion(&name, &sr); 340 RETERR(dns_name_towire(&name, cctx, target)); 341 isc_region_consume(&sr, name_length(&name)); 342 return (mem_tobuffer(target, sr.base, sr.length)); 343} 344 345static int 346compare_any_tsig(ARGS_COMPARE) { 347 isc_region_t r1; 348 isc_region_t r2; 349 dns_name_t name1; 350 dns_name_t name2; 351 int order; 352 353 REQUIRE(rdata1->type == rdata2->type); 354 REQUIRE(rdata1->rdclass == rdata2->rdclass); 355 REQUIRE(rdata1->type == dns_rdatatype_tsig); 356 REQUIRE(rdata1->rdclass == dns_rdataclass_any); 357 REQUIRE(rdata1->length != 0); 358 REQUIRE(rdata2->length != 0); 359 360 dns_rdata_toregion(rdata1, &r1); 361 dns_rdata_toregion(rdata2, &r2); 362 dns_name_init(&name1, NULL); 363 dns_name_init(&name2, NULL); 364 dns_name_fromregion(&name1, &r1); 365 dns_name_fromregion(&name2, &r2); 366 order = dns_name_rdatacompare(&name1, &name2); 367 if (order != 0) { 368 return (order); 369 } 370 isc_region_consume(&r1, name_length(&name1)); 371 isc_region_consume(&r2, name_length(&name2)); 372 return (isc_region_compare(&r1, &r2)); 373} 374 375static isc_result_t 376fromstruct_any_tsig(ARGS_FROMSTRUCT) { 377 dns_rdata_any_tsig_t *tsig = source; 378 isc_region_t tr; 379 380 REQUIRE(type == dns_rdatatype_tsig); 381 REQUIRE(rdclass == dns_rdataclass_any); 382 REQUIRE(tsig != NULL); 383 REQUIRE(tsig->common.rdclass == rdclass); 384 REQUIRE(tsig->common.rdtype == type); 385 386 UNUSED(type); 387 UNUSED(rdclass); 388 389 /* 390 * Algorithm Name. 391 */ 392 RETERR(name_tobuffer(&tsig->algorithm, target)); 393 394 isc_buffer_availableregion(target, &tr); 395 if (tr.length < 6 + 2 + 2) { 396 return (ISC_R_NOSPACE); 397 } 398 399 /* 400 * Time Signed: 48 bits. 401 */ 402 RETERR(uint16_tobuffer((uint16_t)(tsig->timesigned >> 32), target)); 403 RETERR(uint32_tobuffer((uint32_t)(tsig->timesigned & 0xffffffffU), 404 target)); 405 406 /* 407 * Fudge. 408 */ 409 RETERR(uint16_tobuffer(tsig->fudge, target)); 410 411 /* 412 * Signature Size. 413 */ 414 RETERR(uint16_tobuffer(tsig->siglen, target)); 415 416 /* 417 * Signature. 418 */ 419 RETERR(mem_tobuffer(target, tsig->signature, tsig->siglen)); 420 421 isc_buffer_availableregion(target, &tr); 422 if (tr.length < 2 + 2 + 2) { 423 return (ISC_R_NOSPACE); 424 } 425 426 /* 427 * Original ID. 428 */ 429 RETERR(uint16_tobuffer(tsig->originalid, target)); 430 431 /* 432 * Error. 433 */ 434 RETERR(uint16_tobuffer(tsig->error, target)); 435 436 /* 437 * Other Len. 438 */ 439 RETERR(uint16_tobuffer(tsig->otherlen, target)); 440 441 /* 442 * Other Data. 443 */ 444 return (mem_tobuffer(target, tsig->other, tsig->otherlen)); 445} 446 447static isc_result_t 448tostruct_any_tsig(ARGS_TOSTRUCT) { 449 dns_rdata_any_tsig_t *tsig; 450 dns_name_t alg; 451 isc_region_t sr; 452 453 REQUIRE(rdata->type == dns_rdatatype_tsig); 454 REQUIRE(rdata->rdclass == dns_rdataclass_any); 455 REQUIRE(rdata->length != 0); 456 457 tsig = (dns_rdata_any_tsig_t *)target; 458 tsig->common.rdclass = rdata->rdclass; 459 tsig->common.rdtype = rdata->type; 460 ISC_LINK_INIT(&tsig->common, link); 461 462 dns_rdata_toregion(rdata, &sr); 463 464 /* 465 * Algorithm Name. 466 */ 467 dns_name_init(&alg, NULL); 468 dns_name_fromregion(&alg, &sr); 469 dns_name_init(&tsig->algorithm, NULL); 470 name_duporclone(&alg, mctx, &tsig->algorithm); 471 472 isc_region_consume(&sr, name_length(&tsig->algorithm)); 473 474 /* 475 * Time Signed. 476 */ 477 INSIST(sr.length >= 6); 478 tsig->timesigned = ((uint64_t)sr.base[0] << 40) | 479 ((uint64_t)sr.base[1] << 32) | 480 ((uint64_t)sr.base[2] << 24) | 481 ((uint64_t)sr.base[3] << 16) | 482 ((uint64_t)sr.base[4] << 8) | (uint64_t)sr.base[5]; 483 isc_region_consume(&sr, 6); 484 485 /* 486 * Fudge. 487 */ 488 tsig->fudge = uint16_fromregion(&sr); 489 isc_region_consume(&sr, 2); 490 491 /* 492 * Signature Size. 493 */ 494 tsig->siglen = uint16_fromregion(&sr); 495 isc_region_consume(&sr, 2); 496 497 /* 498 * Signature. 499 */ 500 INSIST(sr.length >= tsig->siglen); 501 tsig->signature = mem_maybedup(mctx, sr.base, tsig->siglen); 502 if (tsig->signature == NULL) { 503 goto cleanup; 504 } 505 isc_region_consume(&sr, tsig->siglen); 506 507 /* 508 * Original ID. 509 */ 510 tsig->originalid = uint16_fromregion(&sr); 511 isc_region_consume(&sr, 2); 512 513 /* 514 * Error. 515 */ 516 tsig->error = uint16_fromregion(&sr); 517 isc_region_consume(&sr, 2); 518 519 /* 520 * Other Size. 521 */ 522 tsig->otherlen = uint16_fromregion(&sr); 523 isc_region_consume(&sr, 2); 524 525 /* 526 * Other. 527 */ 528 INSIST(sr.length == tsig->otherlen); 529 tsig->other = mem_maybedup(mctx, sr.base, tsig->otherlen); 530 if (tsig->other == NULL) { 531 goto cleanup; 532 } 533 534 tsig->mctx = mctx; 535 return (ISC_R_SUCCESS); 536 537cleanup: 538 if (mctx != NULL) { 539 dns_name_free(&tsig->algorithm, tsig->mctx); 540 } 541 if (mctx != NULL && tsig->signature != NULL) { 542 isc_mem_free(mctx, tsig->signature); 543 } 544 return (ISC_R_NOMEMORY); 545} 546 547static void 548freestruct_any_tsig(ARGS_FREESTRUCT) { 549 dns_rdata_any_tsig_t *tsig = (dns_rdata_any_tsig_t *)source; 550 551 REQUIRE(tsig != NULL); 552 REQUIRE(tsig->common.rdtype == dns_rdatatype_tsig); 553 REQUIRE(tsig->common.rdclass == dns_rdataclass_any); 554 555 if (tsig->mctx == NULL) { 556 return; 557 } 558 559 dns_name_free(&tsig->algorithm, tsig->mctx); 560 if (tsig->signature != NULL) { 561 isc_mem_free(tsig->mctx, tsig->signature); 562 } 563 if (tsig->other != NULL) { 564 isc_mem_free(tsig->mctx, tsig->other); 565 } 566 tsig->mctx = NULL; 567} 568 569static isc_result_t 570additionaldata_any_tsig(ARGS_ADDLDATA) { 571 REQUIRE(rdata->type == dns_rdatatype_tsig); 572 REQUIRE(rdata->rdclass == dns_rdataclass_any); 573 574 UNUSED(rdata); 575 UNUSED(owner); 576 UNUSED(add); 577 UNUSED(arg); 578 579 return (ISC_R_SUCCESS); 580} 581 582static isc_result_t 583digest_any_tsig(ARGS_DIGEST) { 584 REQUIRE(rdata->type == dns_rdatatype_tsig); 585 REQUIRE(rdata->rdclass == dns_rdataclass_any); 586 587 UNUSED(rdata); 588 UNUSED(digest); 589 UNUSED(arg); 590 591 return (ISC_R_NOTIMPLEMENTED); 592} 593 594static bool 595checkowner_any_tsig(ARGS_CHECKOWNER) { 596 REQUIRE(type == dns_rdatatype_tsig); 597 REQUIRE(rdclass == dns_rdataclass_any); 598 599 UNUSED(name); 600 UNUSED(type); 601 UNUSED(rdclass); 602 UNUSED(wildcard); 603 604 return (true); 605} 606 607static bool 608checknames_any_tsig(ARGS_CHECKNAMES) { 609 REQUIRE(rdata->type == dns_rdatatype_tsig); 610 REQUIRE(rdata->rdclass == dns_rdataclass_any); 611 612 UNUSED(rdata); 613 UNUSED(owner); 614 UNUSED(bad); 615 616 return (true); 617} 618 619static int 620casecompare_any_tsig(ARGS_COMPARE) { 621 return (compare_any_tsig(rdata1, rdata2)); 622} 623 624#endif /* RDATA_ANY_255_TSIG_250_C */ 625