1 /* $NetBSD: sig_24.c,v 1.7 2021/02/19 16:42:17 christos Exp $ */ 2 3 /* 4 * Copyright (C) Internet Systems Consortium, Inc. ("ISC") 5 * 6 * This Source Code Form is subject to the terms of the Mozilla Public 7 * License, v. 2.0. If a copy of the MPL was not distributed with this 8 * file, you can obtain one at https://mozilla.org/MPL/2.0/. 9 * 10 * See the COPYRIGHT file distributed with this work for additional 11 * information regarding copyright ownership. 12 */ 13 14 /* RFC2535 */ 15 16 #ifndef RDATA_GENERIC_SIG_24_C 17 #define RDATA_GENERIC_SIG_24_C 18 19 #define RRTYPE_SIG_ATTRIBUTES (0) 20 21 static inline isc_result_t 22 fromtext_sig(ARGS_FROMTEXT) { 23 isc_token_t token; 24 unsigned char c; 25 long i; 26 dns_rdatatype_t covered; 27 char *e; 28 isc_result_t result; 29 dns_name_t name; 30 isc_buffer_t buffer; 31 uint32_t time_signed, time_expire; 32 33 REQUIRE(type == dns_rdatatype_sig); 34 35 UNUSED(type); 36 UNUSED(rdclass); 37 UNUSED(callbacks); 38 39 /* 40 * Type covered. 41 */ 42 RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_string, 43 false)); 44 result = dns_rdatatype_fromtext(&covered, &token.value.as_textregion); 45 if (result != ISC_R_SUCCESS && result != ISC_R_NOTIMPLEMENTED) { 46 i = strtol(DNS_AS_STR(token), &e, 10); 47 if (i < 0 || i > 65535) { 48 RETTOK(ISC_R_RANGE); 49 } 50 if (*e != 0) { 51 RETTOK(result); 52 } 53 covered = (dns_rdatatype_t)i; 54 } 55 RETERR(uint16_tobuffer(covered, target)); 56 57 /* 58 * Algorithm. 59 */ 60 RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_string, 61 false)); 62 RETTOK(dns_secalg_fromtext(&c, &token.value.as_textregion)); 63 RETERR(mem_tobuffer(target, &c, 1)); 64 65 /* 66 * Labels. 67 */ 68 RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_number, 69 false)); 70 if (token.value.as_ulong > 0xffU) { 71 RETTOK(ISC_R_RANGE); 72 } 73 c = (unsigned char)token.value.as_ulong; 74 RETERR(mem_tobuffer(target, &c, 1)); 75 76 /* 77 * Original ttl. 78 */ 79 RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_number, 80 false)); 81 RETERR(uint32_tobuffer(token.value.as_ulong, target)); 82 83 /* 84 * Signature expiration. 85 */ 86 RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_string, 87 false)); 88 RETTOK(dns_time32_fromtext(DNS_AS_STR(token), &time_expire)); 89 RETERR(uint32_tobuffer(time_expire, target)); 90 91 /* 92 * Time signed. 93 */ 94 RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_string, 95 false)); 96 RETTOK(dns_time32_fromtext(DNS_AS_STR(token), &time_signed)); 97 RETERR(uint32_tobuffer(time_signed, target)); 98 99 /* 100 * Key footprint. 101 */ 102 RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_number, 103 false)); 104 RETERR(uint16_tobuffer(token.value.as_ulong, target)); 105 106 /* 107 * Signer. 108 */ 109 RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_string, 110 false)); 111 dns_name_init(&name, NULL); 112 buffer_fromregion(&buffer, &token.value.as_region); 113 if (origin == NULL) { 114 origin = dns_rootname; 115 } 116 RETTOK(dns_name_fromtext(&name, &buffer, origin, options, target)); 117 118 /* 119 * Sig. 120 */ 121 return (isc_base64_tobuffer(lexer, target, -2)); 122 } 123 124 static inline isc_result_t 125 totext_sig(ARGS_TOTEXT) { 126 isc_region_t sr; 127 char buf[sizeof("4294967295")]; 128 dns_rdatatype_t covered; 129 unsigned long ttl; 130 unsigned long when; 131 unsigned long exp; 132 unsigned long foot; 133 dns_name_t name; 134 dns_name_t prefix; 135 bool sub; 136 137 REQUIRE(rdata->type == dns_rdatatype_sig); 138 REQUIRE(rdata->length != 0); 139 140 dns_rdata_toregion(rdata, &sr); 141 142 /* 143 * Type covered. 144 */ 145 covered = uint16_fromregion(&sr); 146 isc_region_consume(&sr, 2); 147 /* 148 * XXXAG We should have something like dns_rdatatype_isknown() 149 * that does the right thing with type 0. 150 */ 151 if (dns_rdatatype_isknown(covered) && covered != 0) { 152 RETERR(dns_rdatatype_totext(covered, target)); 153 } else { 154 snprintf(buf, sizeof(buf), "%u", covered); 155 RETERR(str_totext(buf, target)); 156 } 157 RETERR(str_totext(" ", target)); 158 159 /* 160 * Algorithm. 161 */ 162 snprintf(buf, sizeof(buf), "%u", sr.base[0]); 163 isc_region_consume(&sr, 1); 164 RETERR(str_totext(buf, target)); 165 RETERR(str_totext(" ", target)); 166 167 /* 168 * Labels. 169 */ 170 snprintf(buf, sizeof(buf), "%u", sr.base[0]); 171 isc_region_consume(&sr, 1); 172 RETERR(str_totext(buf, target)); 173 RETERR(str_totext(" ", target)); 174 175 /* 176 * Ttl. 177 */ 178 ttl = uint32_fromregion(&sr); 179 isc_region_consume(&sr, 4); 180 snprintf(buf, sizeof(buf), "%lu", ttl); 181 RETERR(str_totext(buf, target)); 182 RETERR(str_totext(" ", target)); 183 184 /* 185 * Sig exp. 186 */ 187 exp = uint32_fromregion(&sr); 188 isc_region_consume(&sr, 4); 189 RETERR(dns_time32_totext(exp, target)); 190 191 if ((tctx->flags & DNS_STYLEFLAG_MULTILINE) != 0) { 192 RETERR(str_totext(" (", target)); 193 } 194 RETERR(str_totext(tctx->linebreak, target)); 195 196 /* 197 * Time signed. 198 */ 199 when = uint32_fromregion(&sr); 200 isc_region_consume(&sr, 4); 201 RETERR(dns_time32_totext(when, target)); 202 RETERR(str_totext(" ", target)); 203 204 /* 205 * Footprint. 206 */ 207 foot = uint16_fromregion(&sr); 208 isc_region_consume(&sr, 2); 209 snprintf(buf, sizeof(buf), "%lu", foot); 210 RETERR(str_totext(buf, target)); 211 RETERR(str_totext(" ", target)); 212 213 /* 214 * Signer. 215 */ 216 dns_name_init(&name, NULL); 217 dns_name_init(&prefix, NULL); 218 dns_name_fromregion(&name, &sr); 219 isc_region_consume(&sr, name_length(&name)); 220 sub = name_prefix(&name, tctx->origin, &prefix); 221 RETERR(dns_name_totext(&prefix, sub, target)); 222 223 /* 224 * Sig. 225 */ 226 RETERR(str_totext(tctx->linebreak, target)); 227 if (tctx->width == 0) { /* No splitting */ 228 RETERR(isc_base64_totext(&sr, 60, "", target)); 229 } else { 230 RETERR(isc_base64_totext(&sr, tctx->width - 2, tctx->linebreak, 231 target)); 232 } 233 if ((tctx->flags & DNS_STYLEFLAG_MULTILINE) != 0) { 234 RETERR(str_totext(" )", target)); 235 } 236 237 return (ISC_R_SUCCESS); 238 } 239 240 static inline isc_result_t 241 fromwire_sig(ARGS_FROMWIRE) { 242 isc_region_t sr; 243 dns_name_t name; 244 245 REQUIRE(type == dns_rdatatype_sig); 246 247 UNUSED(type); 248 UNUSED(rdclass); 249 250 dns_decompress_setmethods(dctx, DNS_COMPRESS_NONE); 251 252 isc_buffer_activeregion(source, &sr); 253 /* 254 * type covered: 2 255 * algorithm: 1 256 * labels: 1 257 * original ttl: 4 258 * signature expiration: 4 259 * time signed: 4 260 * key footprint: 2 261 */ 262 if (sr.length < 18) { 263 return (ISC_R_UNEXPECTEDEND); 264 } 265 266 isc_buffer_forward(source, 18); 267 RETERR(mem_tobuffer(target, sr.base, 18)); 268 269 /* 270 * Signer. 271 */ 272 dns_name_init(&name, NULL); 273 RETERR(dns_name_fromwire(&name, source, dctx, options, target)); 274 275 /* 276 * Sig. 277 */ 278 isc_buffer_activeregion(source, &sr); 279 if (sr.length == 0) { 280 return (ISC_R_UNEXPECTEDEND); 281 } 282 isc_buffer_forward(source, sr.length); 283 return (mem_tobuffer(target, sr.base, sr.length)); 284 } 285 286 static inline isc_result_t 287 towire_sig(ARGS_TOWIRE) { 288 isc_region_t sr; 289 dns_name_t name; 290 dns_offsets_t offsets; 291 292 REQUIRE(rdata->type == dns_rdatatype_sig); 293 REQUIRE(rdata->length != 0); 294 295 dns_compress_setmethods(cctx, DNS_COMPRESS_NONE); 296 dns_rdata_toregion(rdata, &sr); 297 /* 298 * type covered: 2 299 * algorithm: 1 300 * labels: 1 301 * original ttl: 4 302 * signature expiration: 4 303 * time signed: 4 304 * key footprint: 2 305 */ 306 RETERR(mem_tobuffer(target, sr.base, 18)); 307 isc_region_consume(&sr, 18); 308 309 /* 310 * Signer. 311 */ 312 dns_name_init(&name, offsets); 313 dns_name_fromregion(&name, &sr); 314 isc_region_consume(&sr, name_length(&name)); 315 RETERR(dns_name_towire(&name, cctx, target)); 316 317 /* 318 * Signature. 319 */ 320 return (mem_tobuffer(target, sr.base, sr.length)); 321 } 322 323 static inline int 324 compare_sig(ARGS_COMPARE) { 325 isc_region_t r1; 326 isc_region_t r2; 327 dns_name_t name1; 328 dns_name_t name2; 329 int order; 330 331 REQUIRE(rdata1->type == rdata2->type); 332 REQUIRE(rdata1->rdclass == rdata2->rdclass); 333 REQUIRE(rdata1->type == dns_rdatatype_sig); 334 REQUIRE(rdata1->length != 0); 335 REQUIRE(rdata2->length != 0); 336 337 dns_rdata_toregion(rdata1, &r1); 338 dns_rdata_toregion(rdata2, &r2); 339 340 INSIST(r1.length > 18); 341 INSIST(r2.length > 18); 342 r1.length = 18; 343 r2.length = 18; 344 order = isc_region_compare(&r1, &r2); 345 if (order != 0) { 346 return (order); 347 } 348 349 dns_name_init(&name1, NULL); 350 dns_name_init(&name2, NULL); 351 dns_rdata_toregion(rdata1, &r1); 352 dns_rdata_toregion(rdata2, &r2); 353 isc_region_consume(&r1, 18); 354 isc_region_consume(&r2, 18); 355 dns_name_fromregion(&name1, &r1); 356 dns_name_fromregion(&name2, &r2); 357 order = dns_name_rdatacompare(&name1, &name2); 358 if (order != 0) { 359 return (order); 360 } 361 362 isc_region_consume(&r1, name_length(&name1)); 363 isc_region_consume(&r2, name_length(&name2)); 364 365 return (isc_region_compare(&r1, &r2)); 366 } 367 368 static inline isc_result_t 369 fromstruct_sig(ARGS_FROMSTRUCT) { 370 dns_rdata_sig_t *sig = source; 371 372 REQUIRE(type == dns_rdatatype_sig); 373 REQUIRE(sig != NULL); 374 REQUIRE(sig->common.rdtype == type); 375 REQUIRE(sig->common.rdclass == rdclass); 376 REQUIRE(sig->signature != NULL || sig->siglen == 0); 377 378 UNUSED(type); 379 UNUSED(rdclass); 380 381 /* 382 * Type covered. 383 */ 384 RETERR(uint16_tobuffer(sig->covered, target)); 385 386 /* 387 * Algorithm. 388 */ 389 RETERR(uint8_tobuffer(sig->algorithm, target)); 390 391 /* 392 * Labels. 393 */ 394 RETERR(uint8_tobuffer(sig->labels, target)); 395 396 /* 397 * Original TTL. 398 */ 399 RETERR(uint32_tobuffer(sig->originalttl, target)); 400 401 /* 402 * Expire time. 403 */ 404 RETERR(uint32_tobuffer(sig->timeexpire, target)); 405 406 /* 407 * Time signed. 408 */ 409 RETERR(uint32_tobuffer(sig->timesigned, target)); 410 411 /* 412 * Key ID. 413 */ 414 RETERR(uint16_tobuffer(sig->keyid, target)); 415 416 /* 417 * Signer name. 418 */ 419 RETERR(name_tobuffer(&sig->signer, target)); 420 421 /* 422 * Signature. 423 */ 424 return (mem_tobuffer(target, sig->signature, sig->siglen)); 425 } 426 427 static inline isc_result_t 428 tostruct_sig(ARGS_TOSTRUCT) { 429 isc_region_t sr; 430 dns_rdata_sig_t *sig = target; 431 dns_name_t signer; 432 433 REQUIRE(rdata->type == dns_rdatatype_sig); 434 REQUIRE(sig != NULL); 435 REQUIRE(rdata->length != 0); 436 437 sig->common.rdclass = rdata->rdclass; 438 sig->common.rdtype = rdata->type; 439 ISC_LINK_INIT(&sig->common, link); 440 441 dns_rdata_toregion(rdata, &sr); 442 443 /* 444 * Type covered. 445 */ 446 sig->covered = uint16_fromregion(&sr); 447 isc_region_consume(&sr, 2); 448 449 /* 450 * Algorithm. 451 */ 452 sig->algorithm = uint8_fromregion(&sr); 453 isc_region_consume(&sr, 1); 454 455 /* 456 * Labels. 457 */ 458 sig->labels = uint8_fromregion(&sr); 459 isc_region_consume(&sr, 1); 460 461 /* 462 * Original TTL. 463 */ 464 sig->originalttl = uint32_fromregion(&sr); 465 isc_region_consume(&sr, 4); 466 467 /* 468 * Expire time. 469 */ 470 sig->timeexpire = uint32_fromregion(&sr); 471 isc_region_consume(&sr, 4); 472 473 /* 474 * Time signed. 475 */ 476 sig->timesigned = uint32_fromregion(&sr); 477 isc_region_consume(&sr, 4); 478 479 /* 480 * Key ID. 481 */ 482 sig->keyid = uint16_fromregion(&sr); 483 isc_region_consume(&sr, 2); 484 485 dns_name_init(&signer, NULL); 486 dns_name_fromregion(&signer, &sr); 487 dns_name_init(&sig->signer, NULL); 488 RETERR(name_duporclone(&signer, mctx, &sig->signer)); 489 isc_region_consume(&sr, name_length(&sig->signer)); 490 491 /* 492 * Signature. 493 */ 494 sig->siglen = sr.length; 495 sig->signature = mem_maybedup(mctx, sr.base, sig->siglen); 496 if (sig->signature == NULL) { 497 goto cleanup; 498 } 499 500 sig->mctx = mctx; 501 return (ISC_R_SUCCESS); 502 503 cleanup: 504 if (mctx != NULL) { 505 dns_name_free(&sig->signer, mctx); 506 } 507 return (ISC_R_NOMEMORY); 508 } 509 510 static inline void 511 freestruct_sig(ARGS_FREESTRUCT) { 512 dns_rdata_sig_t *sig = (dns_rdata_sig_t *)source; 513 514 REQUIRE(sig != NULL); 515 REQUIRE(sig->common.rdtype == dns_rdatatype_sig); 516 517 if (sig->mctx == NULL) { 518 return; 519 } 520 521 dns_name_free(&sig->signer, sig->mctx); 522 if (sig->signature != NULL) { 523 isc_mem_free(sig->mctx, sig->signature); 524 } 525 sig->mctx = NULL; 526 } 527 528 static inline isc_result_t 529 additionaldata_sig(ARGS_ADDLDATA) { 530 REQUIRE(rdata->type == dns_rdatatype_sig); 531 532 UNUSED(rdata); 533 UNUSED(add); 534 UNUSED(arg); 535 536 return (ISC_R_SUCCESS); 537 } 538 539 static inline isc_result_t 540 digest_sig(ARGS_DIGEST) { 541 REQUIRE(rdata->type == dns_rdatatype_sig); 542 543 UNUSED(rdata); 544 UNUSED(digest); 545 UNUSED(arg); 546 547 return (ISC_R_NOTIMPLEMENTED); 548 } 549 550 static inline dns_rdatatype_t 551 covers_sig(dns_rdata_t *rdata) { 552 dns_rdatatype_t type; 553 isc_region_t r; 554 555 REQUIRE(rdata->type == dns_rdatatype_sig); 556 557 dns_rdata_toregion(rdata, &r); 558 type = uint16_fromregion(&r); 559 560 return (type); 561 } 562 563 static inline bool 564 checkowner_sig(ARGS_CHECKOWNER) { 565 REQUIRE(type == dns_rdatatype_sig); 566 567 UNUSED(name); 568 UNUSED(type); 569 UNUSED(rdclass); 570 UNUSED(wildcard); 571 572 return (true); 573 } 574 575 static inline bool 576 checknames_sig(ARGS_CHECKNAMES) { 577 REQUIRE(rdata->type == dns_rdatatype_sig); 578 579 UNUSED(rdata); 580 UNUSED(owner); 581 UNUSED(bad); 582 583 return (true); 584 } 585 586 static inline int 587 casecompare_sig(ARGS_COMPARE) { 588 return (compare_sig(rdata1, rdata2)); 589 } 590 #endif /* RDATA_GENERIC_SIG_24_C */ 591