xref: /netbsd-src/external/mpl/bind/dist/lib/dns/rdata/generic/tkey_249.c (revision bcda20f65a8566e103791ec395f7f499ef322704)
1 /*	$NetBSD: tkey_249.c,v 1.10 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 /* draft-ietf-dnsext-tkey-01.txt */
17 
18 #ifndef RDATA_GENERIC_TKEY_249_C
19 #define RDATA_GENERIC_TKEY_249_C
20 
21 #define RRTYPE_TKEY_ATTRIBUTES (DNS_RDATATYPEATTR_META)
22 
23 static isc_result_t
24 fromtext_tkey(ARGS_FROMTEXT) {
25 	isc_token_t token;
26 	dns_rcode_t rcode;
27 	dns_name_t name;
28 	isc_buffer_t buffer;
29 	long i;
30 	char *e;
31 
32 	REQUIRE(type == dns_rdatatype_tkey);
33 
34 	UNUSED(type);
35 	UNUSED(rdclass);
36 	UNUSED(callbacks);
37 
38 	/*
39 	 * Algorithm.
40 	 */
41 	RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_string,
42 				      false));
43 	dns_name_init(&name, NULL);
44 	buffer_fromregion(&buffer, &token.value.as_region);
45 	if (origin == NULL) {
46 		origin = dns_rootname;
47 	}
48 	RETTOK(dns_name_fromtext(&name, &buffer, origin, options, target));
49 
50 	/*
51 	 * Inception.
52 	 */
53 	RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_number,
54 				      false));
55 	RETERR(uint32_tobuffer(token.value.as_ulong, target));
56 
57 	/*
58 	 * Expiration.
59 	 */
60 	RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_number,
61 				      false));
62 	RETERR(uint32_tobuffer(token.value.as_ulong, target));
63 
64 	/*
65 	 * Mode.
66 	 */
67 	RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_number,
68 				      false));
69 	if (token.value.as_ulong > 0xffffU) {
70 		RETTOK(ISC_R_RANGE);
71 	}
72 	RETERR(uint16_tobuffer(token.value.as_ulong, target));
73 
74 	/*
75 	 * Error.
76 	 */
77 	RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_string,
78 				      false));
79 	if (dns_tsigrcode_fromtext(&rcode, &token.value.as_textregion) !=
80 	    ISC_R_SUCCESS)
81 	{
82 		i = strtol(DNS_AS_STR(token), &e, 10);
83 		if (*e != 0) {
84 			RETTOK(DNS_R_UNKNOWN);
85 		}
86 		if (i < 0 || i > 0xffff) {
87 			RETTOK(ISC_R_RANGE);
88 		}
89 		rcode = (dns_rcode_t)i;
90 	}
91 	RETERR(uint16_tobuffer(rcode, target));
92 
93 	/*
94 	 * Key Size.
95 	 */
96 	RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_number,
97 				      false));
98 	if (token.value.as_ulong > 0xffffU) {
99 		RETTOK(ISC_R_RANGE);
100 	}
101 	RETERR(uint16_tobuffer(token.value.as_ulong, target));
102 
103 	/*
104 	 * Key Data.
105 	 */
106 	RETERR(isc_base64_tobuffer(lexer, target, (int)token.value.as_ulong));
107 
108 	/*
109 	 * Other Size.
110 	 */
111 	RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_number,
112 				      false));
113 	if (token.value.as_ulong > 0xffffU) {
114 		RETTOK(ISC_R_RANGE);
115 	}
116 	RETERR(uint16_tobuffer(token.value.as_ulong, target));
117 
118 	/*
119 	 * Other Data.
120 	 */
121 	return isc_base64_tobuffer(lexer, target, (int)token.value.as_ulong);
122 }
123 
124 static isc_result_t
125 totext_tkey(ARGS_TOTEXT) {
126 	isc_region_t sr, dr;
127 	char buf[sizeof("4294967295 ")];
128 	unsigned long n;
129 	dns_name_t name;
130 	dns_name_t prefix;
131 	unsigned int opts;
132 
133 	REQUIRE(rdata->type == dns_rdatatype_tkey);
134 	REQUIRE(rdata->length != 0);
135 
136 	dns_rdata_toregion(rdata, &sr);
137 
138 	/*
139 	 * Algorithm.
140 	 */
141 	dns_name_init(&name, NULL);
142 	dns_name_init(&prefix, NULL);
143 	dns_name_fromregion(&name, &sr);
144 	opts = name_prefix(&name, tctx->origin, &prefix) ? DNS_NAME_OMITFINALDOT
145 							 : 0;
146 	RETERR(dns_name_totext(&prefix, opts, target));
147 	RETERR(str_totext(" ", target));
148 	isc_region_consume(&sr, name_length(&name));
149 
150 	/*
151 	 * Inception.
152 	 */
153 	n = uint32_fromregion(&sr);
154 	isc_region_consume(&sr, 4);
155 	snprintf(buf, sizeof(buf), "%lu ", n);
156 	RETERR(str_totext(buf, target));
157 
158 	/*
159 	 * Expiration.
160 	 */
161 	n = uint32_fromregion(&sr);
162 	isc_region_consume(&sr, 4);
163 	snprintf(buf, sizeof(buf), "%lu ", n);
164 	RETERR(str_totext(buf, target));
165 
166 	/*
167 	 * Mode.
168 	 */
169 	n = uint16_fromregion(&sr);
170 	isc_region_consume(&sr, 2);
171 	snprintf(buf, sizeof(buf), "%lu ", n);
172 	RETERR(str_totext(buf, target));
173 
174 	/*
175 	 * Error.
176 	 */
177 	n = uint16_fromregion(&sr);
178 	isc_region_consume(&sr, 2);
179 	if (dns_tsigrcode_totext((dns_rcode_t)n, target) == ISC_R_SUCCESS) {
180 		RETERR(str_totext(" ", target));
181 	} else {
182 		snprintf(buf, sizeof(buf), "%lu ", n);
183 		RETERR(str_totext(buf, target));
184 	}
185 
186 	/*
187 	 * Key Size.
188 	 */
189 	n = uint16_fromregion(&sr);
190 	isc_region_consume(&sr, 2);
191 	snprintf(buf, sizeof(buf), "%lu", n);
192 	RETERR(str_totext(buf, target));
193 
194 	/*
195 	 * Key Data.
196 	 */
197 	REQUIRE(n <= sr.length);
198 	dr = sr;
199 	dr.length = n;
200 	if ((tctx->flags & DNS_STYLEFLAG_MULTILINE) != 0) {
201 		RETERR(str_totext(" (", target));
202 	}
203 	RETERR(str_totext(tctx->linebreak, target));
204 	if (tctx->width == 0) { /* No splitting */
205 		RETERR(isc_base64_totext(&dr, 60, "", target));
206 	} else {
207 		RETERR(isc_base64_totext(&dr, tctx->width - 2, tctx->linebreak,
208 					 target));
209 	}
210 	if ((tctx->flags & DNS_STYLEFLAG_MULTILINE) != 0) {
211 		RETERR(str_totext(" ) ", target));
212 	} else {
213 		RETERR(str_totext(" ", target));
214 	}
215 	isc_region_consume(&sr, n);
216 
217 	/*
218 	 * Other Size.
219 	 */
220 	n = uint16_fromregion(&sr);
221 	isc_region_consume(&sr, 2);
222 	snprintf(buf, sizeof(buf), "%lu", n);
223 	RETERR(str_totext(buf, target));
224 
225 	/*
226 	 * Other Data.
227 	 */
228 	REQUIRE(n <= sr.length);
229 	if (n != 0U) {
230 		dr = sr;
231 		dr.length = n;
232 		if ((tctx->flags & DNS_STYLEFLAG_MULTILINE) != 0) {
233 			RETERR(str_totext(" (", target));
234 		}
235 		RETERR(str_totext(tctx->linebreak, target));
236 		if (tctx->width == 0) { /* No splitting */
237 			RETERR(isc_base64_totext(&dr, 60, "", target));
238 		} else {
239 			RETERR(isc_base64_totext(&dr, tctx->width - 2,
240 						 tctx->linebreak, target));
241 		}
242 		if ((tctx->flags & DNS_STYLEFLAG_MULTILINE) != 0) {
243 			RETERR(str_totext(" )", target));
244 		}
245 	}
246 	return ISC_R_SUCCESS;
247 }
248 
249 static isc_result_t
250 fromwire_tkey(ARGS_FROMWIRE) {
251 	isc_region_t sr;
252 	unsigned long n;
253 	dns_name_t name;
254 
255 	REQUIRE(type == dns_rdatatype_tkey);
256 
257 	UNUSED(type);
258 	UNUSED(rdclass);
259 
260 	dctx = dns_decompress_setpermitted(dctx, false);
261 
262 	/*
263 	 * Algorithm.
264 	 */
265 	dns_name_init(&name, NULL);
266 	RETERR(dns_name_fromwire(&name, source, dctx, target));
267 
268 	/*
269 	 * Inception: 4
270 	 * Expiration: 4
271 	 * Mode: 2
272 	 * Error: 2
273 	 */
274 	isc_buffer_activeregion(source, &sr);
275 	if (sr.length < 12) {
276 		return ISC_R_UNEXPECTEDEND;
277 	}
278 	RETERR(mem_tobuffer(target, sr.base, 12));
279 	isc_region_consume(&sr, 12);
280 	isc_buffer_forward(source, 12);
281 
282 	/*
283 	 * Key Length + Key Data.
284 	 */
285 	if (sr.length < 2) {
286 		return ISC_R_UNEXPECTEDEND;
287 	}
288 	n = uint16_fromregion(&sr);
289 	if (sr.length < n + 2) {
290 		return ISC_R_UNEXPECTEDEND;
291 	}
292 	RETERR(mem_tobuffer(target, sr.base, n + 2));
293 	isc_region_consume(&sr, n + 2);
294 	isc_buffer_forward(source, n + 2);
295 
296 	/*
297 	 * Other Length + Other Data.
298 	 */
299 	if (sr.length < 2) {
300 		return ISC_R_UNEXPECTEDEND;
301 	}
302 	n = uint16_fromregion(&sr);
303 	if (sr.length < n + 2) {
304 		return ISC_R_UNEXPECTEDEND;
305 	}
306 	isc_buffer_forward(source, n + 2);
307 	return mem_tobuffer(target, sr.base, n + 2);
308 }
309 
310 static isc_result_t
311 towire_tkey(ARGS_TOWIRE) {
312 	isc_region_t sr;
313 	dns_name_t name;
314 	dns_offsets_t offsets;
315 
316 	REQUIRE(rdata->type == dns_rdatatype_tkey);
317 	REQUIRE(rdata->length != 0);
318 
319 	dns_compress_setpermitted(cctx, false);
320 	/*
321 	 * Algorithm.
322 	 */
323 	dns_rdata_toregion(rdata, &sr);
324 	dns_name_init(&name, offsets);
325 	dns_name_fromregion(&name, &sr);
326 	RETERR(dns_name_towire(&name, cctx, target, NULL));
327 	isc_region_consume(&sr, name_length(&name));
328 
329 	return mem_tobuffer(target, sr.base, sr.length);
330 }
331 
332 static int
333 compare_tkey(ARGS_COMPARE) {
334 	isc_region_t r1;
335 	isc_region_t r2;
336 	dns_name_t name1;
337 	dns_name_t name2;
338 	int order;
339 
340 	REQUIRE(rdata1->type == rdata2->type);
341 	REQUIRE(rdata1->rdclass == rdata2->rdclass);
342 	REQUIRE(rdata1->type == dns_rdatatype_tkey);
343 	REQUIRE(rdata1->length != 0);
344 	REQUIRE(rdata2->length != 0);
345 
346 	/*
347 	 * Algorithm.
348 	 */
349 	dns_rdata_toregion(rdata1, &r1);
350 	dns_rdata_toregion(rdata2, &r2);
351 	dns_name_init(&name1, NULL);
352 	dns_name_init(&name2, NULL);
353 	dns_name_fromregion(&name1, &r1);
354 	dns_name_fromregion(&name2, &r2);
355 	if ((order = dns_name_rdatacompare(&name1, &name2)) != 0) {
356 		return order;
357 	}
358 	isc_region_consume(&r1, name_length(&name1));
359 	isc_region_consume(&r2, name_length(&name2));
360 	return isc_region_compare(&r1, &r2);
361 }
362 
363 static isc_result_t
364 fromstruct_tkey(ARGS_FROMSTRUCT) {
365 	dns_rdata_tkey_t *tkey = source;
366 
367 	REQUIRE(type == dns_rdatatype_tkey);
368 	REQUIRE(tkey != NULL);
369 	REQUIRE(tkey->common.rdtype == type);
370 	REQUIRE(tkey->common.rdclass == rdclass);
371 
372 	UNUSED(type);
373 	UNUSED(rdclass);
374 
375 	/*
376 	 * Algorithm Name.
377 	 */
378 	RETERR(name_tobuffer(&tkey->algorithm, target));
379 
380 	/*
381 	 * Inception: 32 bits.
382 	 */
383 	RETERR(uint32_tobuffer(tkey->inception, target));
384 
385 	/*
386 	 * Expire: 32 bits.
387 	 */
388 	RETERR(uint32_tobuffer(tkey->expire, target));
389 
390 	/*
391 	 * Mode: 16 bits.
392 	 */
393 	RETERR(uint16_tobuffer(tkey->mode, target));
394 
395 	/*
396 	 * Error: 16 bits.
397 	 */
398 	RETERR(uint16_tobuffer(tkey->error, target));
399 
400 	/*
401 	 * Key size: 16 bits.
402 	 */
403 	RETERR(uint16_tobuffer(tkey->keylen, target));
404 
405 	/*
406 	 * Key.
407 	 */
408 	RETERR(mem_tobuffer(target, tkey->key, tkey->keylen));
409 
410 	/*
411 	 * Other size: 16 bits.
412 	 */
413 	RETERR(uint16_tobuffer(tkey->otherlen, target));
414 
415 	/*
416 	 * Other data.
417 	 */
418 	return mem_tobuffer(target, tkey->other, tkey->otherlen);
419 }
420 
421 static isc_result_t
422 tostruct_tkey(ARGS_TOSTRUCT) {
423 	dns_rdata_tkey_t *tkey = target;
424 	dns_name_t alg;
425 	isc_region_t sr;
426 
427 	REQUIRE(rdata->type == dns_rdatatype_tkey);
428 	REQUIRE(tkey != NULL);
429 	REQUIRE(rdata->length != 0);
430 
431 	tkey->common.rdclass = rdata->rdclass;
432 	tkey->common.rdtype = rdata->type;
433 	ISC_LINK_INIT(&tkey->common, link);
434 
435 	dns_rdata_toregion(rdata, &sr);
436 
437 	/*
438 	 * Algorithm Name.
439 	 */
440 	dns_name_init(&alg, NULL);
441 	dns_name_fromregion(&alg, &sr);
442 	dns_name_init(&tkey->algorithm, NULL);
443 	name_duporclone(&alg, mctx, &tkey->algorithm);
444 	isc_region_consume(&sr, name_length(&tkey->algorithm));
445 
446 	/*
447 	 * Inception.
448 	 */
449 	tkey->inception = uint32_fromregion(&sr);
450 	isc_region_consume(&sr, 4);
451 
452 	/*
453 	 * Expire.
454 	 */
455 	tkey->expire = uint32_fromregion(&sr);
456 	isc_region_consume(&sr, 4);
457 
458 	/*
459 	 * Mode.
460 	 */
461 	tkey->mode = uint16_fromregion(&sr);
462 	isc_region_consume(&sr, 2);
463 
464 	/*
465 	 * Error.
466 	 */
467 	tkey->error = uint16_fromregion(&sr);
468 	isc_region_consume(&sr, 2);
469 
470 	/*
471 	 * Key size.
472 	 */
473 	tkey->keylen = uint16_fromregion(&sr);
474 	isc_region_consume(&sr, 2);
475 
476 	/*
477 	 * Key.
478 	 */
479 	INSIST(tkey->keylen + 2U <= sr.length);
480 	tkey->key = mem_maybedup(mctx, sr.base, tkey->keylen);
481 	isc_region_consume(&sr, tkey->keylen);
482 
483 	/*
484 	 * Other size.
485 	 */
486 	tkey->otherlen = uint16_fromregion(&sr);
487 	isc_region_consume(&sr, 2);
488 
489 	/*
490 	 * Other.
491 	 */
492 	INSIST(tkey->otherlen <= sr.length);
493 	tkey->other = mem_maybedup(mctx, sr.base, tkey->otherlen);
494 	tkey->mctx = mctx;
495 	return ISC_R_SUCCESS;
496 }
497 
498 static void
499 freestruct_tkey(ARGS_FREESTRUCT) {
500 	dns_rdata_tkey_t *tkey = (dns_rdata_tkey_t *)source;
501 
502 	REQUIRE(tkey != NULL);
503 
504 	if (tkey->mctx == NULL) {
505 		return;
506 	}
507 
508 	dns_name_free(&tkey->algorithm, tkey->mctx);
509 	if (tkey->key != NULL) {
510 		isc_mem_free(tkey->mctx, tkey->key);
511 	}
512 	if (tkey->other != NULL) {
513 		isc_mem_free(tkey->mctx, tkey->other);
514 	}
515 	tkey->mctx = NULL;
516 }
517 
518 static isc_result_t
519 additionaldata_tkey(ARGS_ADDLDATA) {
520 	REQUIRE(rdata->type == dns_rdatatype_tkey);
521 
522 	UNUSED(rdata);
523 	UNUSED(owner);
524 	UNUSED(add);
525 	UNUSED(arg);
526 
527 	return ISC_R_SUCCESS;
528 }
529 
530 static isc_result_t
531 digest_tkey(ARGS_DIGEST) {
532 	UNUSED(rdata);
533 	UNUSED(digest);
534 	UNUSED(arg);
535 
536 	REQUIRE(rdata->type == dns_rdatatype_tkey);
537 
538 	return ISC_R_NOTIMPLEMENTED;
539 }
540 
541 static bool
542 checkowner_tkey(ARGS_CHECKOWNER) {
543 	REQUIRE(type == dns_rdatatype_tkey);
544 
545 	UNUSED(name);
546 	UNUSED(type);
547 	UNUSED(rdclass);
548 	UNUSED(wildcard);
549 
550 	return true;
551 }
552 
553 static bool
554 checknames_tkey(ARGS_CHECKNAMES) {
555 	REQUIRE(rdata->type == dns_rdatatype_tkey);
556 
557 	UNUSED(rdata);
558 	UNUSED(owner);
559 	UNUSED(bad);
560 
561 	return true;
562 }
563 
564 static int
565 casecompare_tkey(ARGS_COMPARE) {
566 	return compare_tkey(rdata1, rdata2);
567 }
568 #endif /* RDATA_GENERIC_TKEY_249_C */
569