1 /* $NetBSD: tlsa_52.c,v 1.9 2022/09/23 12:15:31 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
generic_fromtext_tlsa(ARGS_FROMTEXT)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
generic_totext_tlsa(ARGS_TOTEXT)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
generic_fromwire_tlsa(ARGS_FROMWIRE)125 generic_fromwire_tlsa(ARGS_FROMWIRE) {
126 isc_region_t sr;
127
128 UNUSED(type);
129 UNUSED(rdclass);
130 UNUSED(dctx);
131 UNUSED(options);
132
133 isc_buffer_activeregion(source, &sr);
134
135 /* Usage(1), Selector(1), Type(1), Data(1+) */
136 if (sr.length < 4) {
137 return (ISC_R_UNEXPECTEDEND);
138 }
139
140 isc_buffer_forward(source, sr.length);
141 return (mem_tobuffer(target, sr.base, sr.length));
142 }
143
144 static isc_result_t
fromtext_tlsa(ARGS_FROMTEXT)145 fromtext_tlsa(ARGS_FROMTEXT) {
146 REQUIRE(type == dns_rdatatype_tlsa);
147
148 return (generic_fromtext_tlsa(CALL_FROMTEXT));
149 }
150
151 static isc_result_t
totext_tlsa(ARGS_TOTEXT)152 totext_tlsa(ARGS_TOTEXT) {
153 REQUIRE(rdata->type == dns_rdatatype_tlsa);
154
155 return (generic_totext_tlsa(CALL_TOTEXT));
156 }
157
158 static isc_result_t
fromwire_tlsa(ARGS_FROMWIRE)159 fromwire_tlsa(ARGS_FROMWIRE) {
160 REQUIRE(type == dns_rdatatype_tlsa);
161
162 return (generic_fromwire_tlsa(CALL_FROMWIRE));
163 }
164
165 static isc_result_t
towire_tlsa(ARGS_TOWIRE)166 towire_tlsa(ARGS_TOWIRE) {
167 isc_region_t sr;
168
169 REQUIRE(rdata->type == dns_rdatatype_tlsa);
170 REQUIRE(rdata->length != 0);
171
172 UNUSED(cctx);
173
174 dns_rdata_toregion(rdata, &sr);
175 return (mem_tobuffer(target, sr.base, sr.length));
176 }
177
178 static int
compare_tlsa(ARGS_COMPARE)179 compare_tlsa(ARGS_COMPARE) {
180 isc_region_t r1;
181 isc_region_t r2;
182
183 REQUIRE(rdata1->type == rdata2->type);
184 REQUIRE(rdata1->rdclass == rdata2->rdclass);
185 REQUIRE(rdata1->type == dns_rdatatype_tlsa);
186 REQUIRE(rdata1->length != 0);
187 REQUIRE(rdata2->length != 0);
188
189 dns_rdata_toregion(rdata1, &r1);
190 dns_rdata_toregion(rdata2, &r2);
191 return (isc_region_compare(&r1, &r2));
192 }
193
194 static isc_result_t
generic_fromstruct_tlsa(ARGS_FROMSTRUCT)195 generic_fromstruct_tlsa(ARGS_FROMSTRUCT) {
196 dns_rdata_tlsa_t *tlsa = source;
197
198 REQUIRE(tlsa != NULL);
199 REQUIRE(tlsa->common.rdtype == type);
200 REQUIRE(tlsa->common.rdclass == rdclass);
201
202 UNUSED(type);
203 UNUSED(rdclass);
204
205 RETERR(uint8_tobuffer(tlsa->usage, target));
206 RETERR(uint8_tobuffer(tlsa->selector, target));
207 RETERR(uint8_tobuffer(tlsa->match, target));
208
209 return (mem_tobuffer(target, tlsa->data, tlsa->length));
210 }
211
212 static isc_result_t
generic_tostruct_tlsa(ARGS_TOSTRUCT)213 generic_tostruct_tlsa(ARGS_TOSTRUCT) {
214 dns_rdata_tlsa_t *tlsa = target;
215 isc_region_t region;
216
217 REQUIRE(tlsa != NULL);
218 REQUIRE(rdata->length != 0);
219
220 REQUIRE(tlsa != NULL);
221 REQUIRE(tlsa->common.rdclass == rdata->rdclass);
222 REQUIRE(tlsa->common.rdtype == rdata->type);
223 REQUIRE(!ISC_LINK_LINKED(&tlsa->common, link));
224
225 dns_rdata_toregion(rdata, ®ion);
226
227 tlsa->usage = uint8_fromregion(®ion);
228 isc_region_consume(®ion, 1);
229 tlsa->selector = uint8_fromregion(®ion);
230 isc_region_consume(®ion, 1);
231 tlsa->match = uint8_fromregion(®ion);
232 isc_region_consume(®ion, 1);
233 tlsa->length = region.length;
234
235 tlsa->data = mem_maybedup(mctx, region.base, region.length);
236 if (tlsa->data == NULL) {
237 return (ISC_R_NOMEMORY);
238 }
239
240 tlsa->mctx = mctx;
241 return (ISC_R_SUCCESS);
242 }
243
244 static void
generic_freestruct_tlsa(ARGS_FREESTRUCT)245 generic_freestruct_tlsa(ARGS_FREESTRUCT) {
246 dns_rdata_tlsa_t *tlsa = source;
247
248 REQUIRE(tlsa != NULL);
249
250 if (tlsa->mctx == NULL) {
251 return;
252 }
253
254 if (tlsa->data != NULL) {
255 isc_mem_free(tlsa->mctx, tlsa->data);
256 }
257 tlsa->mctx = NULL;
258 }
259
260 static isc_result_t
fromstruct_tlsa(ARGS_FROMSTRUCT)261 fromstruct_tlsa(ARGS_FROMSTRUCT) {
262 REQUIRE(type == dns_rdatatype_tlsa);
263
264 return (generic_fromstruct_tlsa(CALL_FROMSTRUCT));
265 }
266
267 static isc_result_t
tostruct_tlsa(ARGS_TOSTRUCT)268 tostruct_tlsa(ARGS_TOSTRUCT) {
269 dns_rdata_tlsa_t *tlsa = target;
270
271 REQUIRE(rdata->type == dns_rdatatype_tlsa);
272 REQUIRE(tlsa != NULL);
273
274 tlsa->common.rdclass = rdata->rdclass;
275 tlsa->common.rdtype = rdata->type;
276 ISC_LINK_INIT(&tlsa->common, link);
277
278 return (generic_tostruct_tlsa(CALL_TOSTRUCT));
279 }
280
281 static void
freestruct_tlsa(ARGS_FREESTRUCT)282 freestruct_tlsa(ARGS_FREESTRUCT) {
283 dns_rdata_tlsa_t *tlsa = source;
284
285 REQUIRE(tlsa != NULL);
286 REQUIRE(tlsa->common.rdtype == dns_rdatatype_tlsa);
287
288 generic_freestruct_tlsa(source);
289 }
290
291 static isc_result_t
additionaldata_tlsa(ARGS_ADDLDATA)292 additionaldata_tlsa(ARGS_ADDLDATA) {
293 REQUIRE(rdata->type == dns_rdatatype_tlsa);
294
295 UNUSED(rdata);
296 UNUSED(add);
297 UNUSED(arg);
298
299 return (ISC_R_SUCCESS);
300 }
301
302 static isc_result_t
digest_tlsa(ARGS_DIGEST)303 digest_tlsa(ARGS_DIGEST) {
304 isc_region_t r;
305
306 REQUIRE(rdata->type == dns_rdatatype_tlsa);
307
308 dns_rdata_toregion(rdata, &r);
309
310 return ((digest)(arg, &r));
311 }
312
313 static bool
checkowner_tlsa(ARGS_CHECKOWNER)314 checkowner_tlsa(ARGS_CHECKOWNER) {
315 REQUIRE(type == dns_rdatatype_tlsa);
316
317 UNUSED(name);
318 UNUSED(type);
319 UNUSED(rdclass);
320 UNUSED(wildcard);
321
322 return (true);
323 }
324
325 static bool
checknames_tlsa(ARGS_CHECKNAMES)326 checknames_tlsa(ARGS_CHECKNAMES) {
327 REQUIRE(rdata->type == dns_rdatatype_tlsa);
328
329 UNUSED(rdata);
330 UNUSED(owner);
331 UNUSED(bad);
332
333 return (true);
334 }
335
336 static int
casecompare_tlsa(ARGS_COMPARE)337 casecompare_tlsa(ARGS_COMPARE) {
338 return (compare_tlsa(rdata1, rdata2));
339 }
340
341 #endif /* RDATA_GENERIC_TLSA_52_C */
342