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