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