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