]> CyberLeo.Net >> Repos - FreeBSD/stable/9.git/blob - contrib/bind9/lib/dns/rdata/generic/cds_59.c
Update BIND to 9.9.6-P1
[FreeBSD/stable/9.git] / contrib / bind9 / lib / dns / rdata / generic / cds_59.c
1 /*
2  * Copyright (C) 2014  Internet Systems Consortium, Inc. ("ISC")
3  *
4  * Permission to use, copy, modify, and/or distribute this software for any
5  * purpose with or without fee is hereby granted, provided that the above
6  * copyright notice and this permission notice appear in all copies.
7  *
8  * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
9  * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
10  * AND FITNESS.  IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
11  * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
12  * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
13  * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
14  * PERFORMANCE OF THIS SOFTWARE.
15  */
16
17 /* $Id$ */
18
19 /* draft-ietf-dnsext-delegation-signer-05.txt */
20
21 #ifndef RDATA_GENERIC_CDS_59_C
22 #define RDATA_GENERIC_CDS_59_C
23
24 #define RRTYPE_CDS_ATTRIBUTES \
25         (DNS_RDATATYPEATTR_DNSSEC|DNS_RDATATYPEATTR_ATPARENT)
26
27 #include <isc/sha1.h>
28 #include <isc/sha2.h>
29
30 #include <dns/ds.h>
31
32 static inline isc_result_t
33 fromtext_cds(ARGS_FROMTEXT) {
34         isc_token_t token;
35         unsigned char c;
36         int length;
37
38         REQUIRE(type == 59);
39
40         UNUSED(type);
41         UNUSED(rdclass);
42         UNUSED(origin);
43         UNUSED(options);
44         UNUSED(callbacks);
45
46         /*
47          * Key tag.
48          */
49         RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_number,
50                                       ISC_FALSE));
51         if (token.value.as_ulong > 0xffffU)
52                 RETTOK(ISC_R_RANGE);
53         RETERR(uint16_tobuffer(token.value.as_ulong, target));
54
55         /*
56          * Algorithm.
57          */
58         RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_string,
59                                       ISC_FALSE));
60         RETTOK(dns_secalg_fromtext(&c, &token.value.as_textregion));
61         RETERR(mem_tobuffer(target, &c, 1));
62
63         /*
64          * Digest type.
65          */
66         RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_number,
67                                       ISC_FALSE));
68         if (token.value.as_ulong > 0xffU)
69                 RETTOK(ISC_R_RANGE);
70         RETERR(uint8_tobuffer(token.value.as_ulong, target));
71         c = (unsigned char) token.value.as_ulong;
72
73         /*
74          * Digest.
75          */
76         switch (c) {
77         case DNS_DSDIGEST_SHA1:
78                 length = ISC_SHA1_DIGESTLENGTH;
79                 break;
80         case DNS_DSDIGEST_SHA256:
81                 length = ISC_SHA256_DIGESTLENGTH;
82                 break;
83         case DNS_DSDIGEST_GOST:
84                 length = ISC_GOST_DIGESTLENGTH;
85                 break;
86         case DNS_DSDIGEST_SHA384:
87                 length = ISC_SHA384_DIGESTLENGTH;
88                 break;
89         default:
90                 length = -1;
91                 break;
92         }
93         return (isc_hex_tobuffer(lexer, target, length));
94 }
95
96 static inline isc_result_t
97 totext_cds(ARGS_TOTEXT) {
98         isc_region_t sr;
99         char buf[sizeof("64000 ")];
100         unsigned int n;
101
102         REQUIRE(rdata->type == 59);
103         REQUIRE(rdata->length != 0);
104
105         UNUSED(tctx);
106
107         dns_rdata_toregion(rdata, &sr);
108
109         /*
110          * Key tag.
111          */
112         n = uint16_fromregion(&sr);
113         isc_region_consume(&sr, 2);
114         sprintf(buf, "%u ", n);
115         RETERR(str_totext(buf, target));
116
117         /*
118          * Algorithm.
119          */
120         n = uint8_fromregion(&sr);
121         isc_region_consume(&sr, 1);
122         sprintf(buf, "%u ", n);
123         RETERR(str_totext(buf, target));
124
125         /*
126          * Digest type.
127          */
128         n = uint8_fromregion(&sr);
129         isc_region_consume(&sr, 1);
130         sprintf(buf, "%u", n);
131         RETERR(str_totext(buf, target));
132
133         /*
134          * Digest.
135          */
136         if ((tctx->flags & DNS_STYLEFLAG_MULTILINE) != 0)
137                 RETERR(str_totext(" (", target));
138         RETERR(str_totext(tctx->linebreak, target));
139         if (tctx->width == 0) /* No splitting */
140                 RETERR(isc_hex_totext(&sr, 0, "", target));
141         else
142                 RETERR(isc_hex_totext(&sr, tctx->width - 2,
143                                       tctx->linebreak, target));
144         if ((tctx->flags & DNS_STYLEFLAG_MULTILINE) != 0)
145                 RETERR(str_totext(" )", target));
146         return (ISC_R_SUCCESS);
147 }
148
149 static inline isc_result_t
150 fromwire_cds(ARGS_FROMWIRE) {
151         isc_region_t sr;
152
153         REQUIRE(type == 59);
154
155         UNUSED(type);
156         UNUSED(rdclass);
157         UNUSED(dctx);
158         UNUSED(options);
159
160         isc_buffer_activeregion(source, &sr);
161
162         /*
163          * Check digest lengths if we know them.
164          */
165         if (sr.length < 4 ||
166             (sr.base[3] == DNS_DSDIGEST_SHA1 &&
167              sr.length < 4 + ISC_SHA1_DIGESTLENGTH) ||
168             (sr.base[3] == DNS_DSDIGEST_SHA256 &&
169              sr.length < 4 + ISC_SHA256_DIGESTLENGTH) ||
170             (sr.base[3] == DNS_DSDIGEST_GOST &&
171              sr.length < 4 + ISC_GOST_DIGESTLENGTH) ||
172             (sr.base[3] == DNS_DSDIGEST_SHA384 &&
173              sr.length < 4 + ISC_SHA384_DIGESTLENGTH))
174                 return (ISC_R_UNEXPECTEDEND);
175
176         /*
177          * Only copy digest lengths if we know them.
178          * If there is extra data dns_rdata_fromwire() will
179          * detect that.
180          */
181         if (sr.base[3] == DNS_DSDIGEST_SHA1)
182                 sr.length = 4 + ISC_SHA1_DIGESTLENGTH;
183         else if (sr.base[3] == DNS_DSDIGEST_SHA256)
184                 sr.length = 4 + ISC_SHA256_DIGESTLENGTH;
185         else if (sr.base[3] == DNS_DSDIGEST_GOST)
186                 sr.length = 4 + ISC_GOST_DIGESTLENGTH;
187         else if (sr.base[3] == DNS_DSDIGEST_SHA384)
188                 sr.length = 4 + ISC_SHA384_DIGESTLENGTH;
189
190         isc_buffer_forward(source, sr.length);
191         return (mem_tobuffer(target, sr.base, sr.length));
192 }
193
194 static inline isc_result_t
195 towire_cds(ARGS_TOWIRE) {
196         isc_region_t sr;
197
198         REQUIRE(rdata->type == 59);
199         REQUIRE(rdata->length != 0);
200
201         UNUSED(cctx);
202
203         dns_rdata_toregion(rdata, &sr);
204         return (mem_tobuffer(target, sr.base, sr.length));
205 }
206
207 static inline int
208 compare_cds(ARGS_COMPARE) {
209         isc_region_t r1;
210         isc_region_t r2;
211
212         REQUIRE(rdata1->type == rdata2->type);
213         REQUIRE(rdata1->rdclass == rdata2->rdclass);
214         REQUIRE(rdata1->type == 59);
215         REQUIRE(rdata1->length != 0);
216         REQUIRE(rdata2->length != 0);
217
218         dns_rdata_toregion(rdata1, &r1);
219         dns_rdata_toregion(rdata2, &r2);
220         return (isc_region_compare(&r1, &r2));
221 }
222
223 static inline isc_result_t
224 fromstruct_cds(ARGS_FROMSTRUCT) {
225         dns_rdata_cds_t *ds = source;
226
227         REQUIRE(type == 59);
228         REQUIRE(source != NULL);
229         REQUIRE(ds->common.rdtype == type);
230         REQUIRE(ds->common.rdclass == rdclass);
231         switch (ds->digest_type) {
232         case DNS_DSDIGEST_SHA1:
233                 REQUIRE(ds->length == ISC_SHA1_DIGESTLENGTH);
234                 break;
235         case DNS_DSDIGEST_SHA256:
236                 REQUIRE(ds->length == ISC_SHA256_DIGESTLENGTH);
237                 break;
238         case DNS_DSDIGEST_GOST:
239                 REQUIRE(ds->length == ISC_GOST_DIGESTLENGTH);
240                 break;
241         case DNS_DSDIGEST_SHA384:
242                 REQUIRE(ds->length == ISC_SHA384_DIGESTLENGTH);
243                 break;
244         }
245
246         UNUSED(type);
247         UNUSED(rdclass);
248
249         RETERR(uint16_tobuffer(ds->key_tag, target));
250         RETERR(uint8_tobuffer(ds->algorithm, target));
251         RETERR(uint8_tobuffer(ds->digest_type, target));
252
253         return (mem_tobuffer(target, ds->digest, ds->length));
254 }
255
256 static inline isc_result_t
257 tostruct_cds(ARGS_TOSTRUCT) {
258         dns_rdata_cds_t *ds = target;
259         isc_region_t region;
260
261         REQUIRE(rdata->type == 59);
262         REQUIRE(target != NULL);
263         REQUIRE(rdata->length != 0);
264
265         ds->common.rdclass = rdata->rdclass;
266         ds->common.rdtype = rdata->type;
267         ISC_LINK_INIT(&ds->common, link);
268
269         dns_rdata_toregion(rdata, &region);
270
271         ds->key_tag = uint16_fromregion(&region);
272         isc_region_consume(&region, 2);
273         ds->algorithm = uint8_fromregion(&region);
274         isc_region_consume(&region, 1);
275         ds->digest_type = uint8_fromregion(&region);
276         isc_region_consume(&region, 1);
277         ds->length = region.length;
278
279         ds->digest = mem_maybedup(mctx, region.base, region.length);
280         if (ds->digest == NULL)
281                 return (ISC_R_NOMEMORY);
282
283         ds->mctx = mctx;
284         return (ISC_R_SUCCESS);
285 }
286
287 static inline void
288 freestruct_cds(ARGS_FREESTRUCT) {
289         dns_rdata_cds_t *ds = source;
290
291         REQUIRE(ds != NULL);
292         REQUIRE(ds->common.rdtype == 59);
293
294         if (ds->mctx == NULL)
295                 return;
296
297         if (ds->digest != NULL)
298                 isc_mem_free(ds->mctx, ds->digest);
299         ds->mctx = NULL;
300 }
301
302 static inline isc_result_t
303 additionaldata_cds(ARGS_ADDLDATA) {
304         REQUIRE(rdata->type == 59);
305
306         UNUSED(rdata);
307         UNUSED(add);
308         UNUSED(arg);
309
310         return (ISC_R_SUCCESS);
311 }
312
313 static inline isc_result_t
314 digest_cds(ARGS_DIGEST) {
315         isc_region_t r;
316
317         REQUIRE(rdata->type == 59);
318
319         dns_rdata_toregion(rdata, &r);
320
321         return ((digest)(arg, &r));
322 }
323
324 static inline isc_boolean_t
325 checkowner_cds(ARGS_CHECKOWNER) {
326
327         REQUIRE(type == 59);
328
329         UNUSED(name);
330         UNUSED(type);
331         UNUSED(rdclass);
332         UNUSED(wildcard);
333
334         return (ISC_TRUE);
335 }
336
337 static inline isc_boolean_t
338 checknames_cds(ARGS_CHECKNAMES) {
339
340         REQUIRE(rdata->type == 59);
341
342         UNUSED(rdata);
343         UNUSED(owner);
344         UNUSED(bad);
345
346         return (ISC_TRUE);
347 }
348
349 static inline int
350 casecompare_cds(ARGS_COMPARE) {
351         return (compare_cds(rdata1, rdata2));
352 }
353
354 #endif  /* RDATA_GENERIC_CDS_59_C */