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