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