]> CyberLeo.Net >> Repos - FreeBSD/stable/9.git/blob - contrib/bind9/lib/dns/rdata/generic/ds_43.c
MFV r306384:
[FreeBSD/stable/9.git] / contrib / bind9 / lib / dns / rdata / generic / ds_43.c
1 /*
2  * Copyright (C) 2004, 2005, 2007, 2009-2012, 2015  Internet Systems Consortium, Inc. ("ISC")
3  * Copyright (C) 2002  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 /* draft-ietf-dnsext-delegation-signer-05.txt */
21
22 #ifndef RDATA_GENERIC_DS_43_C
23 #define RDATA_GENERIC_DS_43_C
24
25 #define RRTYPE_DS_ATTRIBUTES \
26         (DNS_RDATATYPEATTR_DNSSEC|DNS_RDATATYPEATTR_ATPARENT)
27
28 #include <isc/sha1.h>
29 #include <isc/sha2.h>
30
31 #include <dns/ds.h>
32
33 static inline isc_result_t
34 generic_fromtext_ds(ARGS_FROMTEXT) {
35         isc_token_t token;
36         unsigned char c;
37         int length;
38
39         UNUSED(type);
40         UNUSED(rdclass);
41         UNUSED(origin);
42         UNUSED(options);
43         UNUSED(callbacks);
44
45         /*
46          * Key tag.
47          */
48         RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_number,
49                                       ISC_FALSE));
50         if (token.value.as_ulong > 0xffffU)
51                 RETTOK(ISC_R_RANGE);
52         RETERR(uint16_tobuffer(token.value.as_ulong, target));
53
54         /*
55          * Algorithm.
56          */
57         RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_string,
58                                       ISC_FALSE));
59         RETTOK(dns_secalg_fromtext(&c, &token.value.as_textregion));
60         RETERR(mem_tobuffer(target, &c, 1));
61
62         /*
63          * Digest type.
64          */
65         RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_number,
66                                       ISC_FALSE));
67         if (token.value.as_ulong > 0xffU)
68                 RETTOK(ISC_R_RANGE);
69         RETERR(uint8_tobuffer(token.value.as_ulong, target));
70         c = (unsigned char) token.value.as_ulong;
71
72         /*
73          * Digest.
74          */
75         switch (c) {
76         case DNS_DSDIGEST_SHA1:
77                 length = ISC_SHA1_DIGESTLENGTH;
78                 break;
79         case DNS_DSDIGEST_SHA256:
80                 length = ISC_SHA256_DIGESTLENGTH;
81                 break;
82         case DNS_DSDIGEST_GOST:
83                 length = ISC_GOST_DIGESTLENGTH;
84                 break;
85         case DNS_DSDIGEST_SHA384:
86                 length = ISC_SHA384_DIGESTLENGTH;
87                 break;
88         default:
89                 length = -1;
90                 break;
91         }
92         return (isc_hex_tobuffer(lexer, target, length));
93 }
94
95 static inline isc_result_t
96 fromtext_ds(ARGS_FROMTEXT) {
97
98         REQUIRE(type == dns_rdatatype_ds);
99
100         return (generic_fromtext_ds(rdclass, type, lexer, origin, options,
101                                     target, callbacks));
102 }
103
104 static inline isc_result_t
105 generic_totext_ds(ARGS_TOTEXT) {
106         isc_region_t sr;
107         char buf[sizeof("64000 ")];
108         unsigned int n;
109
110         REQUIRE(rdata->length != 0);
111
112         UNUSED(tctx);
113
114         dns_rdata_toregion(rdata, &sr);
115
116         /*
117          * Key tag.
118          */
119         n = uint16_fromregion(&sr);
120         isc_region_consume(&sr, 2);
121         sprintf(buf, "%u ", n);
122         RETERR(str_totext(buf, target));
123
124         /*
125          * Algorithm.
126          */
127         n = uint8_fromregion(&sr);
128         isc_region_consume(&sr, 1);
129         sprintf(buf, "%u ", n);
130         RETERR(str_totext(buf, target));
131
132         /*
133          * Digest type.
134          */
135         n = uint8_fromregion(&sr);
136         isc_region_consume(&sr, 1);
137         sprintf(buf, "%u", n);
138         RETERR(str_totext(buf, target));
139
140         /*
141          * Digest.
142          */
143         if ((tctx->flags & DNS_STYLEFLAG_MULTILINE) != 0)
144                 RETERR(str_totext(" (", target));
145         RETERR(str_totext(tctx->linebreak, target));
146         if (tctx->width == 0) /* No splitting */
147                 RETERR(isc_hex_totext(&sr, 0, "", target));
148         else
149                 RETERR(isc_hex_totext(&sr, tctx->width - 2,
150                                       tctx->linebreak, target));
151         if ((tctx->flags & DNS_STYLEFLAG_MULTILINE) != 0)
152                 RETERR(str_totext(" )", target));
153         return (ISC_R_SUCCESS);
154 }
155
156 static inline isc_result_t
157 totext_ds(ARGS_TOTEXT) {
158
159         REQUIRE(rdata->type == dns_rdatatype_ds);
160
161         return (generic_totext_ds(rdata, tctx, target));
162 }
163
164 static inline isc_result_t
165 generic_fromwire_ds(ARGS_FROMWIRE) {
166         isc_region_t sr;
167
168         UNUSED(type);
169         UNUSED(rdclass);
170         UNUSED(dctx);
171         UNUSED(options);
172
173         isc_buffer_activeregion(source, &sr);
174
175         /*
176          * Check digest lengths if we know them.
177          */
178         if (sr.length < 4 ||
179             (sr.base[3] == DNS_DSDIGEST_SHA1 &&
180              sr.length < 4 + ISC_SHA1_DIGESTLENGTH) ||
181             (sr.base[3] == DNS_DSDIGEST_SHA256 &&
182              sr.length < 4 + ISC_SHA256_DIGESTLENGTH) ||
183             (sr.base[3] == DNS_DSDIGEST_GOST &&
184              sr.length < 4 + ISC_GOST_DIGESTLENGTH) ||
185             (sr.base[3] == DNS_DSDIGEST_SHA384 &&
186              sr.length < 4 + ISC_SHA384_DIGESTLENGTH))
187                 return (ISC_R_UNEXPECTEDEND);
188
189         /*
190          * Only copy digest lengths if we know them.
191          * If there is extra data dns_rdata_fromwire() will
192          * detect that.
193          */
194         if (sr.base[3] == DNS_DSDIGEST_SHA1)
195                 sr.length = 4 + ISC_SHA1_DIGESTLENGTH;
196         else if (sr.base[3] == DNS_DSDIGEST_SHA256)
197                 sr.length = 4 + ISC_SHA256_DIGESTLENGTH;
198         else if (sr.base[3] == DNS_DSDIGEST_GOST)
199                 sr.length = 4 + ISC_GOST_DIGESTLENGTH;
200         else if (sr.base[3] == DNS_DSDIGEST_SHA384)
201                 sr.length = 4 + ISC_SHA384_DIGESTLENGTH;
202
203         isc_buffer_forward(source, sr.length);
204         return (mem_tobuffer(target, sr.base, sr.length));
205 }
206
207 static inline isc_result_t
208 fromwire_ds(ARGS_FROMWIRE) {
209
210         REQUIRE(type == dns_rdatatype_ds);
211
212         return (generic_fromwire_ds(rdclass, type, source, dctx, options,
213                                     target));
214 }
215
216 static inline isc_result_t
217 towire_ds(ARGS_TOWIRE) {
218         isc_region_t sr;
219
220         REQUIRE(rdata->type == dns_rdatatype_ds);
221         REQUIRE(rdata->length != 0);
222
223         UNUSED(cctx);
224
225         dns_rdata_toregion(rdata, &sr);
226         return (mem_tobuffer(target, sr.base, sr.length));
227 }
228
229 static inline int
230 compare_ds(ARGS_COMPARE) {
231         isc_region_t r1;
232         isc_region_t r2;
233
234         REQUIRE(rdata1->type == rdata2->type);
235         REQUIRE(rdata1->rdclass == rdata2->rdclass);
236         REQUIRE(rdata1->type == dns_rdatatype_ds);
237         REQUIRE(rdata1->length != 0);
238         REQUIRE(rdata2->length != 0);
239
240         dns_rdata_toregion(rdata1, &r1);
241         dns_rdata_toregion(rdata2, &r2);
242         return (isc_region_compare(&r1, &r2));
243 }
244
245 static inline isc_result_t
246 generic_fromstruct_ds(ARGS_FROMSTRUCT) {
247         dns_rdata_ds_t *ds = source;
248
249         REQUIRE(source != NULL);
250         REQUIRE(ds->common.rdtype == type);
251         REQUIRE(ds->common.rdclass == rdclass);
252
253         UNUSED(type);
254         UNUSED(rdclass);
255
256         switch (ds->digest_type) {
257         case DNS_DSDIGEST_SHA1:
258                 REQUIRE(ds->length == ISC_SHA1_DIGESTLENGTH);
259                 break;
260         case DNS_DSDIGEST_SHA256:
261                 REQUIRE(ds->length == ISC_SHA256_DIGESTLENGTH);
262                 break;
263         case DNS_DSDIGEST_GOST:
264                 REQUIRE(ds->length == ISC_GOST_DIGESTLENGTH);
265                 break;
266         case DNS_DSDIGEST_SHA384:
267                 REQUIRE(ds->length == ISC_SHA384_DIGESTLENGTH);
268                 break;
269         }
270
271         RETERR(uint16_tobuffer(ds->key_tag, target));
272         RETERR(uint8_tobuffer(ds->algorithm, target));
273         RETERR(uint8_tobuffer(ds->digest_type, target));
274
275         return (mem_tobuffer(target, ds->digest, ds->length));
276 }
277
278 static inline isc_result_t
279 fromstruct_ds(ARGS_FROMSTRUCT) {
280
281         REQUIRE(type == dns_rdatatype_ds);
282
283         return (generic_fromstruct_ds(rdclass, type, source, target));
284 }
285
286 static inline isc_result_t
287 generic_tostruct_ds(ARGS_TOSTRUCT) {
288         dns_rdata_ds_t *ds = target;
289         isc_region_t region;
290
291         REQUIRE(target != NULL);
292         REQUIRE(rdata->length != 0);
293         REQUIRE(ds->common.rdtype == rdata->type);
294         REQUIRE(ds->common.rdclass == rdata->rdclass);
295         REQUIRE(!ISC_LINK_LINKED(&ds->common, link));
296
297         dns_rdata_toregion(rdata, &region);
298
299         ds->key_tag = uint16_fromregion(&region);
300         isc_region_consume(&region, 2);
301         ds->algorithm = uint8_fromregion(&region);
302         isc_region_consume(&region, 1);
303         ds->digest_type = uint8_fromregion(&region);
304         isc_region_consume(&region, 1);
305         ds->length = region.length;
306
307         ds->digest = mem_maybedup(mctx, region.base, region.length);
308         if (ds->digest == NULL)
309                 return (ISC_R_NOMEMORY);
310
311         ds->mctx = mctx;
312         return (ISC_R_SUCCESS);
313 }
314
315 static inline isc_result_t
316 tostruct_ds(ARGS_TOSTRUCT) {
317         dns_rdata_ds_t *ds = target;
318
319         REQUIRE(rdata->type == dns_rdatatype_ds);
320         REQUIRE(target != NULL);
321
322         ds->common.rdclass = rdata->rdclass;
323         ds->common.rdtype = rdata->type;
324         ISC_LINK_INIT(&ds->common, link);
325
326         return (generic_tostruct_ds(rdata, target, mctx));
327 }
328
329 static inline void
330 freestruct_ds(ARGS_FREESTRUCT) {
331         dns_rdata_ds_t *ds = source;
332
333         REQUIRE(ds != NULL);
334         REQUIRE(ds->common.rdtype == dns_rdatatype_ds);
335
336         if (ds->mctx == NULL)
337                 return;
338
339         if (ds->digest != NULL)
340                 isc_mem_free(ds->mctx, ds->digest);
341         ds->mctx = NULL;
342 }
343
344 static inline isc_result_t
345 additionaldata_ds(ARGS_ADDLDATA) {
346         REQUIRE(rdata->type == dns_rdatatype_ds);
347
348         UNUSED(rdata);
349         UNUSED(add);
350         UNUSED(arg);
351
352         return (ISC_R_SUCCESS);
353 }
354
355 static inline isc_result_t
356 digest_ds(ARGS_DIGEST) {
357         isc_region_t r;
358
359         REQUIRE(rdata->type == dns_rdatatype_ds);
360
361         dns_rdata_toregion(rdata, &r);
362
363         return ((digest)(arg, &r));
364 }
365
366 static inline isc_boolean_t
367 checkowner_ds(ARGS_CHECKOWNER) {
368
369         REQUIRE(type == dns_rdatatype_ds);
370
371         UNUSED(name);
372         UNUSED(type);
373         UNUSED(rdclass);
374         UNUSED(wildcard);
375
376         return (ISC_TRUE);
377 }
378
379 static inline isc_boolean_t
380 checknames_ds(ARGS_CHECKNAMES) {
381
382         REQUIRE(rdata->type == dns_rdatatype_ds);
383
384         UNUSED(rdata);
385         UNUSED(owner);
386         UNUSED(bad);
387
388         return (ISC_TRUE);
389 }
390
391 static inline int
392 casecompare_ds(ARGS_COMPARE) {
393         return (compare_ds(rdata1, rdata2));
394 }
395
396 #endif  /* RDATA_GENERIC_DS_43_C */