Home | History | Annotate | Line # | Download | only in generic
      1 /*	$NetBSD: tlsa_52.c,v 1.12 2026/01/29 18:37:53 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 /* rfc6698.txt */
     17 
     18 #ifndef RDATA_GENERIC_TLSA_52_C
     19 #define RDATA_GENERIC_TLSA_52_C
     20 
     21 #define RRTYPE_TLSA_ATTRIBUTES 0
     22 
     23 static isc_result_t
     24 generic_fromtext_tlsa(ARGS_FROMTEXT) {
     25 	isc_token_t token;
     26 
     27 	UNUSED(type);
     28 	UNUSED(rdclass);
     29 	UNUSED(origin);
     30 	UNUSED(options);
     31 	UNUSED(callbacks);
     32 
     33 	/*
     34 	 * Certificate Usage.
     35 	 */
     36 	RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_number,
     37 				      false));
     38 	if (token.value.as_ulong > 0xffU) {
     39 		RETTOK(ISC_R_RANGE);
     40 	}
     41 	RETERR(uint8_tobuffer(token.value.as_ulong, target));
     42 
     43 	/*
     44 	 * Selector.
     45 	 */
     46 	RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_number,
     47 				      false));
     48 	if (token.value.as_ulong > 0xffU) {
     49 		RETTOK(ISC_R_RANGE);
     50 	}
     51 	RETERR(uint8_tobuffer(token.value.as_ulong, target));
     52 
     53 	/*
     54 	 * Matching type.
     55 	 */
     56 	RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_number,
     57 				      false));
     58 	if (token.value.as_ulong > 0xffU) {
     59 		RETTOK(ISC_R_RANGE);
     60 	}
     61 	RETERR(uint8_tobuffer(token.value.as_ulong, target));
     62 
     63 	/*
     64 	 * Certificate Association Data.
     65 	 */
     66 	return isc_hex_tobuffer(lexer, target, -2);
     67 }
     68 
     69 static isc_result_t
     70 generic_totext_tlsa(ARGS_TOTEXT) {
     71 	isc_region_t sr;
     72 	char buf[sizeof("64000 ")];
     73 	unsigned int n;
     74 
     75 	REQUIRE(rdata->length != 0);
     76 
     77 	UNUSED(tctx);
     78 
     79 	dns_rdata_toregion(rdata, &sr);
     80 
     81 	/*
     82 	 * Certificate Usage.
     83 	 */
     84 	n = uint8_fromregion(&sr);
     85 	isc_region_consume(&sr, 1);
     86 	snprintf(buf, sizeof(buf), "%u ", n);
     87 	RETERR(str_totext(buf, target));
     88 
     89 	/*
     90 	 * Selector.
     91 	 */
     92 	n = uint8_fromregion(&sr);
     93 	isc_region_consume(&sr, 1);
     94 	snprintf(buf, sizeof(buf), "%u ", n);
     95 	RETERR(str_totext(buf, target));
     96 
     97 	/*
     98 	 * Matching type.
     99 	 */
    100 	n = uint8_fromregion(&sr);
    101 	isc_region_consume(&sr, 1);
    102 	snprintf(buf, sizeof(buf), "%u", n);
    103 	RETERR(str_totext(buf, target));
    104 
    105 	/*
    106 	 * Certificate Association Data.
    107 	 */
    108 	if ((tctx->flags & DNS_STYLEFLAG_MULTILINE) != 0) {
    109 		RETERR(str_totext(" (", target));
    110 	}
    111 	RETERR(str_totext(tctx->linebreak, target));
    112 	if (tctx->width == 0) { /* No splitting */
    113 		RETERR(isc_hex_totext(&sr, 0, "", target));
    114 	} else {
    115 		RETERR(isc_hex_totext(&sr, tctx->width - 2, tctx->linebreak,
    116 				      target));
    117 	}
    118 	if ((tctx->flags & DNS_STYLEFLAG_MULTILINE) != 0) {
    119 		RETERR(str_totext(" )", target));
    120 	}
    121 	return ISC_R_SUCCESS;
    122 }
    123 
    124 static isc_result_t
    125 generic_fromwire_tlsa(ARGS_FROMWIRE) {
    126 	isc_region_t sr;
    127 
    128 	UNUSED(type);
    129 	UNUSED(rdclass);
    130 	UNUSED(dctx);
    131 
    132 	isc_buffer_activeregion(source, &sr);
    133 
    134 	/* Usage(1), Selector(1), Type(1), Data(1+) */
    135 	if (sr.length < 4) {
    136 		return ISC_R_UNEXPECTEDEND;
    137 	}
    138 
    139 	isc_buffer_forward(source, sr.length);
    140 	return mem_tobuffer(target, sr.base, sr.length);
    141 }
    142 
    143 static isc_result_t
    144 fromtext_tlsa(ARGS_FROMTEXT) {
    145 	REQUIRE(type == dns_rdatatype_tlsa);
    146 
    147 	return generic_fromtext_tlsa(CALL_FROMTEXT);
    148 }
    149 
    150 static isc_result_t
    151 totext_tlsa(ARGS_TOTEXT) {
    152 	REQUIRE(rdata->type == dns_rdatatype_tlsa);
    153 
    154 	return generic_totext_tlsa(CALL_TOTEXT);
    155 }
    156 
    157 static isc_result_t
    158 fromwire_tlsa(ARGS_FROMWIRE) {
    159 	REQUIRE(type == dns_rdatatype_tlsa);
    160 
    161 	return generic_fromwire_tlsa(CALL_FROMWIRE);
    162 }
    163 
    164 static isc_result_t
    165 towire_tlsa(ARGS_TOWIRE) {
    166 	isc_region_t sr;
    167 
    168 	REQUIRE(rdata->type == dns_rdatatype_tlsa);
    169 	REQUIRE(rdata->length != 0);
    170 
    171 	UNUSED(cctx);
    172 
    173 	dns_rdata_toregion(rdata, &sr);
    174 	return mem_tobuffer(target, sr.base, sr.length);
    175 }
    176 
    177 static int
    178 compare_tlsa(ARGS_COMPARE) {
    179 	isc_region_t r1;
    180 	isc_region_t r2;
    181 
    182 	REQUIRE(rdata1->type == rdata2->type);
    183 	REQUIRE(rdata1->rdclass == rdata2->rdclass);
    184 	REQUIRE(rdata1->type == dns_rdatatype_tlsa);
    185 	REQUIRE(rdata1->length != 0);
    186 	REQUIRE(rdata2->length != 0);
    187 
    188 	dns_rdata_toregion(rdata1, &r1);
    189 	dns_rdata_toregion(rdata2, &r2);
    190 	return isc_region_compare(&r1, &r2);
    191 }
    192 
    193 static isc_result_t
    194 generic_fromstruct_tlsa(ARGS_FROMSTRUCT) {
    195 	dns_rdata_tlsa_t *tlsa = source;
    196 
    197 	REQUIRE(tlsa != NULL);
    198 	REQUIRE(tlsa->common.rdtype == type);
    199 	REQUIRE(tlsa->common.rdclass == rdclass);
    200 
    201 	UNUSED(type);
    202 	UNUSED(rdclass);
    203 
    204 	RETERR(uint8_tobuffer(tlsa->usage, target));
    205 	RETERR(uint8_tobuffer(tlsa->selector, target));
    206 	RETERR(uint8_tobuffer(tlsa->match, target));
    207 
    208 	return mem_tobuffer(target, tlsa->data, tlsa->length);
    209 }
    210 
    211 static isc_result_t
    212 generic_tostruct_tlsa(ARGS_TOSTRUCT) {
    213 	dns_rdata_tlsa_t *tlsa = target;
    214 	isc_region_t region;
    215 
    216 	REQUIRE(tlsa != NULL);
    217 	REQUIRE(rdata->length != 0);
    218 
    219 	REQUIRE(tlsa != NULL);
    220 	REQUIRE(tlsa->common.rdclass == rdata->rdclass);
    221 	REQUIRE(tlsa->common.rdtype == rdata->type);
    222 	REQUIRE(!ISC_LINK_LINKED(&tlsa->common, link));
    223 
    224 	dns_rdata_toregion(rdata, &region);
    225 
    226 	tlsa->usage = uint8_fromregion(&region);
    227 	isc_region_consume(&region, 1);
    228 	tlsa->selector = uint8_fromregion(&region);
    229 	isc_region_consume(&region, 1);
    230 	tlsa->match = uint8_fromregion(&region);
    231 	isc_region_consume(&region, 1);
    232 	tlsa->length = region.length;
    233 
    234 	tlsa->data = mem_maybedup(mctx, region.base, region.length);
    235 	tlsa->mctx = mctx;
    236 	return ISC_R_SUCCESS;
    237 }
    238 
    239 static void
    240 generic_freestruct_tlsa(ARGS_FREESTRUCT) {
    241 	dns_rdata_tlsa_t *tlsa = source;
    242 
    243 	REQUIRE(tlsa != NULL);
    244 
    245 	if (tlsa->mctx == NULL) {
    246 		return;
    247 	}
    248 
    249 	if (tlsa->data != NULL) {
    250 		isc_mem_free(tlsa->mctx, tlsa->data);
    251 	}
    252 	tlsa->mctx = NULL;
    253 }
    254 
    255 static isc_result_t
    256 fromstruct_tlsa(ARGS_FROMSTRUCT) {
    257 	REQUIRE(type == dns_rdatatype_tlsa);
    258 
    259 	return generic_fromstruct_tlsa(CALL_FROMSTRUCT);
    260 }
    261 
    262 static isc_result_t
    263 tostruct_tlsa(ARGS_TOSTRUCT) {
    264 	dns_rdata_tlsa_t *tlsa = target;
    265 
    266 	REQUIRE(rdata->type == dns_rdatatype_tlsa);
    267 	REQUIRE(tlsa != NULL);
    268 
    269 	DNS_RDATACOMMON_INIT(tlsa, rdata->type, rdata->rdclass);
    270 
    271 	return generic_tostruct_tlsa(CALL_TOSTRUCT);
    272 }
    273 
    274 static void
    275 freestruct_tlsa(ARGS_FREESTRUCT) {
    276 	dns_rdata_tlsa_t *tlsa = source;
    277 
    278 	REQUIRE(tlsa != NULL);
    279 	REQUIRE(tlsa->common.rdtype == dns_rdatatype_tlsa);
    280 
    281 	generic_freestruct_tlsa(source);
    282 }
    283 
    284 static isc_result_t
    285 additionaldata_tlsa(ARGS_ADDLDATA) {
    286 	REQUIRE(rdata->type == dns_rdatatype_tlsa);
    287 
    288 	UNUSED(rdata);
    289 	UNUSED(owner);
    290 	UNUSED(add);
    291 	UNUSED(arg);
    292 
    293 	return ISC_R_SUCCESS;
    294 }
    295 
    296 static isc_result_t
    297 digest_tlsa(ARGS_DIGEST) {
    298 	isc_region_t r;
    299 
    300 	REQUIRE(rdata->type == dns_rdatatype_tlsa);
    301 
    302 	dns_rdata_toregion(rdata, &r);
    303 
    304 	return (digest)(arg, &r);
    305 }
    306 
    307 static bool
    308 checkowner_tlsa(ARGS_CHECKOWNER) {
    309 	REQUIRE(type == dns_rdatatype_tlsa);
    310 
    311 	UNUSED(name);
    312 	UNUSED(type);
    313 	UNUSED(rdclass);
    314 	UNUSED(wildcard);
    315 
    316 	return true;
    317 }
    318 
    319 static bool
    320 checknames_tlsa(ARGS_CHECKNAMES) {
    321 	REQUIRE(rdata->type == dns_rdatatype_tlsa);
    322 
    323 	UNUSED(rdata);
    324 	UNUSED(owner);
    325 	UNUSED(bad);
    326 
    327 	return true;
    328 }
    329 
    330 static int
    331 casecompare_tlsa(ARGS_COMPARE) {
    332 	return compare_tlsa(rdata1, rdata2);
    333 }
    334 
    335 #endif /* RDATA_GENERIC_TLSA_52_C */
    336