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