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