xref: /netbsd-src/external/mpl/bind/dist/lib/dns/rdata/generic/tlsa_52.c (revision bcda20f65a8566e103791ec395f7f499ef322704)
1 /*	$NetBSD: tlsa_52.c,v 1.11 2025/01/26 16:25:33 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 	tlsa->common.rdclass = rdata->rdclass;
270 	tlsa->common.rdtype = rdata->type;
271 	ISC_LINK_INIT(&tlsa->common, link);
272 
273 	return generic_tostruct_tlsa(CALL_TOSTRUCT);
274 }
275 
276 static void
277 freestruct_tlsa(ARGS_FREESTRUCT) {
278 	dns_rdata_tlsa_t *tlsa = source;
279 
280 	REQUIRE(tlsa != NULL);
281 	REQUIRE(tlsa->common.rdtype == dns_rdatatype_tlsa);
282 
283 	generic_freestruct_tlsa(source);
284 }
285 
286 static isc_result_t
287 additionaldata_tlsa(ARGS_ADDLDATA) {
288 	REQUIRE(rdata->type == dns_rdatatype_tlsa);
289 
290 	UNUSED(rdata);
291 	UNUSED(owner);
292 	UNUSED(add);
293 	UNUSED(arg);
294 
295 	return ISC_R_SUCCESS;
296 }
297 
298 static isc_result_t
299 digest_tlsa(ARGS_DIGEST) {
300 	isc_region_t r;
301 
302 	REQUIRE(rdata->type == dns_rdatatype_tlsa);
303 
304 	dns_rdata_toregion(rdata, &r);
305 
306 	return (digest)(arg, &r);
307 }
308 
309 static bool
310 checkowner_tlsa(ARGS_CHECKOWNER) {
311 	REQUIRE(type == dns_rdatatype_tlsa);
312 
313 	UNUSED(name);
314 	UNUSED(type);
315 	UNUSED(rdclass);
316 	UNUSED(wildcard);
317 
318 	return true;
319 }
320 
321 static bool
322 checknames_tlsa(ARGS_CHECKNAMES) {
323 	REQUIRE(rdata->type == dns_rdatatype_tlsa);
324 
325 	UNUSED(rdata);
326 	UNUSED(owner);
327 	UNUSED(bad);
328 
329 	return true;
330 }
331 
332 static int
333 casecompare_tlsa(ARGS_COMPARE) {
334 	return compare_tlsa(rdata1, rdata2);
335 }
336 
337 #endif /* RDATA_GENERIC_TLSA_52_C */
338