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