]> CyberLeo.Net >> Repos - FreeBSD/releng/9.2.git/blob - contrib/bind9/lib/dns/rdata/generic/rrsig_46.c
- Copy stable/9 to releng/9.2 as part of the 9.2-RELEASE cycle.
[FreeBSD/releng/9.2.git] / contrib / bind9 / lib / dns / rdata / generic / rrsig_46.c
1 /*
2  * Copyright (C) 2004, 2005, 2007, 2009, 2011, 2012  Internet Systems Consortium, Inc. ("ISC")
3  * Copyright (C) 2003  Internet Software Consortium.
4  *
5  * Permission to use, copy, modify, and/or distribute this software for any
6  * purpose with or without fee is hereby granted, provided that the above
7  * copyright notice and this permission notice appear in all copies.
8  *
9  * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
10  * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
11  * AND FITNESS.  IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
12  * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
13  * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
14  * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
15  * PERFORMANCE OF THIS SOFTWARE.
16  */
17
18 /* $Id$ */
19
20 /* Reviewed: Fri Mar 17 09:05:02 PST 2000 by gson */
21
22 /* RFC2535 */
23
24 #ifndef RDATA_GENERIC_RRSIG_46_C
25 #define RDATA_GENERIC_RRSIG_46_C
26
27 #define RRTYPE_RRSIG_ATTRIBUTES (DNS_RDATATYPEATTR_DNSSEC)
28
29 static inline isc_result_t
30 fromtext_rrsig(ARGS_FROMTEXT) {
31         isc_token_t token;
32         unsigned char c;
33         long i;
34         dns_rdatatype_t covered;
35         char *e;
36         isc_result_t result;
37         dns_name_t name;
38         isc_buffer_t buffer;
39         isc_uint32_t time_signed, time_expire;
40
41         REQUIRE(type == 46);
42
43         UNUSED(type);
44         UNUSED(rdclass);
45         UNUSED(callbacks);
46
47         /*
48          * Type covered.
49          */
50         RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_string,
51                                       ISC_FALSE));
52         result = dns_rdatatype_fromtext(&covered, &token.value.as_textregion);
53         if (result != ISC_R_SUCCESS && result != ISC_R_NOTIMPLEMENTED) {
54                 i = strtol(DNS_AS_STR(token), &e, 10);
55                 if (i < 0 || i > 65535)
56                         RETTOK(ISC_R_RANGE);
57                 if (*e != 0)
58                         RETTOK(result);
59                 covered = (dns_rdatatype_t)i;
60         }
61         RETERR(uint16_tobuffer(covered, target));
62
63         /*
64          * Algorithm.
65          */
66         RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_string,
67                                       ISC_FALSE));
68         RETTOK(dns_secalg_fromtext(&c, &token.value.as_textregion));
69         RETERR(mem_tobuffer(target, &c, 1));
70
71         /*
72          * Labels.
73          */
74         RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_number,
75                                       ISC_FALSE));
76         if (token.value.as_ulong > 0xffU)
77                 RETTOK(ISC_R_RANGE);
78         c = (unsigned char)token.value.as_ulong;
79         RETERR(mem_tobuffer(target, &c, 1));
80
81         /*
82          * Original ttl.
83          */
84         RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_number,
85                                       ISC_FALSE));
86         RETERR(uint32_tobuffer(token.value.as_ulong, target));
87
88         /*
89          * Signature expiration.
90          */
91         RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_string,
92                                       ISC_FALSE));
93         RETTOK(dns_time32_fromtext(DNS_AS_STR(token), &time_expire));
94         RETERR(uint32_tobuffer(time_expire, target));
95
96         /*
97          * Time signed.
98          */
99         RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_string,
100                                       ISC_FALSE));
101         RETTOK(dns_time32_fromtext(DNS_AS_STR(token), &time_signed));
102         RETERR(uint32_tobuffer(time_signed, target));
103
104         /*
105          * Key footprint.
106          */
107         RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_number,
108                                       ISC_FALSE));
109         RETERR(uint16_tobuffer(token.value.as_ulong, target));
110
111         /*
112          * Signer.
113          */
114         RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_string,
115                                       ISC_FALSE));
116         dns_name_init(&name, NULL);
117         buffer_fromregion(&buffer, &token.value.as_region);
118         origin = (origin != NULL) ? origin : dns_rootname;
119         RETTOK(dns_name_fromtext(&name, &buffer, origin, options, target));
120
121         /*
122          * Sig.
123          */
124         return (isc_base64_tobuffer(lexer, target, -1));
125 }
126
127 static inline isc_result_t
128 totext_rrsig(ARGS_TOTEXT) {
129         isc_region_t sr;
130         char buf[sizeof("4294967295")];
131         dns_rdatatype_t covered;
132         unsigned long ttl;
133         unsigned long when;
134         unsigned long exp;
135         unsigned long foot;
136         dns_name_t name;
137
138         REQUIRE(rdata->type == 46);
139         REQUIRE(rdata->length != 0);
140
141         dns_rdata_toregion(rdata, &sr);
142
143         /*
144          * Type covered.
145          */
146         covered = uint16_fromregion(&sr);
147         isc_region_consume(&sr, 2);
148         /*
149          * XXXAG We should have something like dns_rdatatype_isknown()
150          * that does the right thing with type 0.
151          */
152         if (dns_rdatatype_isknown(covered) && covered != 0) {
153                 RETERR(dns_rdatatype_totext(covered, target));
154         } else {
155                 char buf[sizeof("TYPE65535")];
156                 sprintf(buf, "TYPE%u", covered);
157                 RETERR(str_totext(buf, target));
158         }
159         RETERR(str_totext(" ", target));
160
161         /*
162          * Algorithm.
163          */
164         sprintf(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         sprintf(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         sprintf(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         RETERR(str_totext(tctx->linebreak, target));
196
197         /*
198          * Time signed.
199          */
200         when = uint32_fromregion(&sr);
201         isc_region_consume(&sr, 4);
202         RETERR(dns_time32_totext(when, target));
203         RETERR(str_totext(" ", target));
204
205         /*
206          * Footprint.
207          */
208         foot = uint16_fromregion(&sr);
209         isc_region_consume(&sr, 2);
210         sprintf(buf, "%lu", foot);
211         RETERR(str_totext(buf, target));
212         RETERR(str_totext(" ", target));
213
214         /*
215          * Signer.
216          */
217         dns_name_init(&name, NULL);
218         dns_name_fromregion(&name, &sr);
219         isc_region_consume(&sr, name_length(&name));
220         RETERR(dns_name_totext(&name, ISC_FALSE, target));
221
222         /*
223          * Sig.
224          */
225         RETERR(str_totext(tctx->linebreak, target));
226         RETERR(isc_base64_totext(&sr, tctx->width - 2,
227                                     tctx->linebreak, target));
228         if ((tctx->flags & DNS_STYLEFLAG_MULTILINE) != 0)
229                 RETERR(str_totext(" )", target));
230
231         return (ISC_R_SUCCESS);
232 }
233
234 static inline isc_result_t
235 fromwire_rrsig(ARGS_FROMWIRE) {
236         isc_region_t sr;
237         dns_name_t name;
238
239         REQUIRE(type == 46);
240
241         UNUSED(type);
242         UNUSED(rdclass);
243
244         dns_decompress_setmethods(dctx, DNS_COMPRESS_NONE);
245
246         isc_buffer_activeregion(source, &sr);
247         /*
248          * type covered: 2
249          * algorithm: 1
250          * labels: 1
251          * original ttl: 4
252          * signature expiration: 4
253          * time signed: 4
254          * key footprint: 2
255          */
256         if (sr.length < 18)
257                 return (ISC_R_UNEXPECTEDEND);
258
259         isc_buffer_forward(source, 18);
260         RETERR(mem_tobuffer(target, sr.base, 18));
261
262         /*
263          * Signer.
264          */
265         dns_name_init(&name, NULL);
266         RETERR(dns_name_fromwire(&name, source, dctx, options, target));
267
268         /*
269          * Sig.
270          */
271         isc_buffer_activeregion(source, &sr);
272         isc_buffer_forward(source, sr.length);
273         return (mem_tobuffer(target, sr.base, sr.length));
274 }
275
276 static inline isc_result_t
277 towire_rrsig(ARGS_TOWIRE) {
278         isc_region_t sr;
279         dns_name_t name;
280         dns_offsets_t offsets;
281
282         REQUIRE(rdata->type == 46);
283         REQUIRE(rdata->length != 0);
284
285         dns_compress_setmethods(cctx, DNS_COMPRESS_NONE);
286         dns_rdata_toregion(rdata, &sr);
287         /*
288          * type covered: 2
289          * algorithm: 1
290          * labels: 1
291          * original ttl: 4
292          * signature expiration: 4
293          * time signed: 4
294          * key footprint: 2
295          */
296         RETERR(mem_tobuffer(target, sr.base, 18));
297         isc_region_consume(&sr, 18);
298
299         /*
300          * Signer.
301          */
302         dns_name_init(&name, offsets);
303         dns_name_fromregion(&name, &sr);
304         isc_region_consume(&sr, name_length(&name));
305         RETERR(dns_name_towire(&name, cctx, target));
306
307         /*
308          * Signature.
309          */
310         return (mem_tobuffer(target, sr.base, sr.length));
311 }
312
313 static inline int
314 compare_rrsig(ARGS_COMPARE) {
315         isc_region_t r1;
316         isc_region_t r2;
317
318         REQUIRE(rdata1->type == rdata2->type);
319         REQUIRE(rdata1->rdclass == rdata2->rdclass);
320         REQUIRE(rdata1->type == 46);
321         REQUIRE(rdata1->length != 0);
322         REQUIRE(rdata2->length != 0);
323
324         dns_rdata_toregion(rdata1, &r1);
325         dns_rdata_toregion(rdata2, &r2);
326         return (isc_region_compare(&r1, &r2));
327 }
328
329 static inline isc_result_t
330 fromstruct_rrsig(ARGS_FROMSTRUCT) {
331         dns_rdata_rrsig_t *sig = source;
332
333         REQUIRE(type == 46);
334         REQUIRE(source != NULL);
335         REQUIRE(sig->common.rdtype == type);
336         REQUIRE(sig->common.rdclass == rdclass);
337         REQUIRE(sig->signature != NULL || sig->siglen == 0);
338
339         UNUSED(type);
340         UNUSED(rdclass);
341
342         /*
343          * Type covered.
344          */
345         RETERR(uint16_tobuffer(sig->covered, target));
346
347         /*
348          * Algorithm.
349          */
350         RETERR(uint8_tobuffer(sig->algorithm, target));
351
352         /*
353          * Labels.
354          */
355         RETERR(uint8_tobuffer(sig->labels, target));
356
357         /*
358          * Original TTL.
359          */
360         RETERR(uint32_tobuffer(sig->originalttl, target));
361
362         /*
363          * Expire time.
364          */
365         RETERR(uint32_tobuffer(sig->timeexpire, target));
366
367         /*
368          * Time signed.
369          */
370         RETERR(uint32_tobuffer(sig->timesigned, target));
371
372         /*
373          * Key ID.
374          */
375         RETERR(uint16_tobuffer(sig->keyid, target));
376
377         /*
378          * Signer name.
379          */
380         RETERR(name_tobuffer(&sig->signer, target));
381
382         /*
383          * Signature.
384          */
385         return (mem_tobuffer(target, sig->signature, sig->siglen));
386 }
387
388 static inline isc_result_t
389 tostruct_rrsig(ARGS_TOSTRUCT) {
390         isc_region_t sr;
391         dns_rdata_rrsig_t *sig = target;
392         dns_name_t signer;
393
394         REQUIRE(rdata->type == 46);
395         REQUIRE(target != NULL);
396         REQUIRE(rdata->length != 0);
397
398         sig->common.rdclass = rdata->rdclass;
399         sig->common.rdtype = rdata->type;
400         ISC_LINK_INIT(&sig->common, link);
401
402         dns_rdata_toregion(rdata, &sr);
403
404         /*
405          * Type covered.
406          */
407         sig->covered = uint16_fromregion(&sr);
408         isc_region_consume(&sr, 2);
409
410         /*
411          * Algorithm.
412          */
413         sig->algorithm = uint8_fromregion(&sr);
414         isc_region_consume(&sr, 1);
415
416         /*
417          * Labels.
418          */
419         sig->labels = uint8_fromregion(&sr);
420         isc_region_consume(&sr, 1);
421
422         /*
423          * Original TTL.
424          */
425         sig->originalttl = uint32_fromregion(&sr);
426         isc_region_consume(&sr, 4);
427
428         /*
429          * Expire time.
430          */
431         sig->timeexpire = uint32_fromregion(&sr);
432         isc_region_consume(&sr, 4);
433
434         /*
435          * Time signed.
436          */
437         sig->timesigned = uint32_fromregion(&sr);
438         isc_region_consume(&sr, 4);
439
440         /*
441          * Key ID.
442          */
443         sig->keyid = uint16_fromregion(&sr);
444         isc_region_consume(&sr, 2);
445
446         dns_name_init(&signer, NULL);
447         dns_name_fromregion(&signer, &sr);
448         dns_name_init(&sig->signer, NULL);
449         RETERR(name_duporclone(&signer, mctx, &sig->signer));
450         isc_region_consume(&sr, name_length(&sig->signer));
451
452         /*
453          * Signature.
454          */
455         sig->siglen = sr.length;
456         sig->signature = mem_maybedup(mctx, sr.base, sig->siglen);
457         if (sig->signature == NULL)
458                 goto cleanup;
459
460
461         sig->mctx = mctx;
462         return (ISC_R_SUCCESS);
463
464  cleanup:
465         if (mctx != NULL)
466                 dns_name_free(&sig->signer, mctx);
467         return (ISC_R_NOMEMORY);
468 }
469
470 static inline void
471 freestruct_rrsig(ARGS_FREESTRUCT) {
472         dns_rdata_rrsig_t *sig = (dns_rdata_rrsig_t *) source;
473
474         REQUIRE(source != NULL);
475         REQUIRE(sig->common.rdtype == 46);
476
477         if (sig->mctx == NULL)
478                 return;
479
480         dns_name_free(&sig->signer, sig->mctx);
481         if (sig->signature != NULL)
482                 isc_mem_free(sig->mctx, sig->signature);
483         sig->mctx = NULL;
484 }
485
486 static inline isc_result_t
487 additionaldata_rrsig(ARGS_ADDLDATA) {
488         REQUIRE(rdata->type == 46);
489
490         UNUSED(rdata);
491         UNUSED(add);
492         UNUSED(arg);
493
494         return (ISC_R_SUCCESS);
495 }
496
497 static inline isc_result_t
498 digest_rrsig(ARGS_DIGEST) {
499
500         REQUIRE(rdata->type == 46);
501
502         UNUSED(rdata);
503         UNUSED(digest);
504         UNUSED(arg);
505
506         return (ISC_R_NOTIMPLEMENTED);
507 }
508
509 static inline dns_rdatatype_t
510 covers_rrsig(dns_rdata_t *rdata) {
511         dns_rdatatype_t type;
512         isc_region_t r;
513
514         REQUIRE(rdata->type == 46);
515
516         dns_rdata_toregion(rdata, &r);
517         type = uint16_fromregion(&r);
518
519         return (type);
520 }
521
522 static inline isc_boolean_t
523 checkowner_rrsig(ARGS_CHECKOWNER) {
524
525         REQUIRE(type == 46);
526
527         UNUSED(name);
528         UNUSED(type);
529         UNUSED(rdclass);
530         UNUSED(wildcard);
531
532         return (ISC_TRUE);
533 }
534
535 static inline isc_boolean_t
536 checknames_rrsig(ARGS_CHECKNAMES) {
537
538         REQUIRE(rdata->type == 46);
539
540         UNUSED(rdata);
541         UNUSED(owner);
542         UNUSED(bad);
543
544         return (ISC_TRUE);
545 }
546
547 static inline int
548 casecompare_rrsig(ARGS_COMPARE) {
549         isc_region_t r1;
550         isc_region_t r2;
551         dns_name_t name1;
552         dns_name_t name2;
553         int order;
554
555         REQUIRE(rdata1->type == rdata2->type);
556         REQUIRE(rdata1->rdclass == rdata2->rdclass);
557         REQUIRE(rdata1->type == 46);
558         REQUIRE(rdata1->length != 0);
559         REQUIRE(rdata2->length != 0);
560
561         dns_rdata_toregion(rdata1, &r1);
562         dns_rdata_toregion(rdata2, &r2);
563
564         INSIST(r1.length > 18);
565         INSIST(r2.length > 18);
566         r1.length = 18;
567         r2.length = 18;
568         order = isc_region_compare(&r1, &r2);
569         if (order != 0)
570                 return (order);
571
572         dns_name_init(&name1, NULL);
573         dns_name_init(&name2, NULL);
574         dns_rdata_toregion(rdata1, &r1);
575         dns_rdata_toregion(rdata2, &r2);
576         isc_region_consume(&r1, 18);
577         isc_region_consume(&r2, 18);
578         dns_name_fromregion(&name1, &r1);
579         dns_name_fromregion(&name2, &r2);
580         order = dns_name_rdatacompare(&name1, &name2);
581         if (order != 0)
582                 return (order);
583
584         isc_region_consume(&r1, name_length(&name1));
585         isc_region_consume(&r2, name_length(&name2));
586
587         return (isc_region_compare(&r1, &r2));
588 }
589
590 #endif  /* RDATA_GENERIC_RRSIG_46_C */