]> CyberLeo.Net >> Repos - FreeBSD/stable/9.git/blob - contrib/bind9/lib/dns/rdata/generic/cds_59.c
Update BIND to 9.9.8
[FreeBSD/stable/9.git] / contrib / bind9 / lib / dns / rdata / generic / cds_59.c
1 /*
2  * Copyright (C) 2014, 2015  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 0
25
26 #include <isc/sha1.h>
27 #include <isc/sha2.h>
28
29 #include <dns/ds.h>
30
31 static inline isc_result_t
32 fromtext_cds(ARGS_FROMTEXT) {
33         isc_token_t token;
34         unsigned char c;
35         int length;
36
37         REQUIRE(type == dns_rdatatype_cds);
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 totext_cds(ARGS_TOTEXT) {
97         isc_region_t sr;
98         char buf[sizeof("64000 ")];
99         unsigned int n;
100
101         REQUIRE(rdata->type == dns_rdatatype_cds);
102         REQUIRE(rdata->length != 0);
103
104         UNUSED(tctx);
105
106         dns_rdata_toregion(rdata, &sr);
107
108         /*
109          * Key tag.
110          */
111         n = uint16_fromregion(&sr);
112         isc_region_consume(&sr, 2);
113         sprintf(buf, "%u ", n);
114         RETERR(str_totext(buf, target));
115
116         /*
117          * Algorithm.
118          */
119         n = uint8_fromregion(&sr);
120         isc_region_consume(&sr, 1);
121         sprintf(buf, "%u ", n);
122         RETERR(str_totext(buf, target));
123
124         /*
125          * Digest type.
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.
134          */
135         if ((tctx->flags & DNS_STYLEFLAG_MULTILINE) != 0)
136                 RETERR(str_totext(" (", target));
137         RETERR(str_totext(tctx->linebreak, target));
138         if (tctx->width == 0) /* No splitting */
139                 RETERR(isc_hex_totext(&sr, 0, "", target));
140         else
141                 RETERR(isc_hex_totext(&sr, tctx->width - 2,
142                                       tctx->linebreak, target));
143         if ((tctx->flags & DNS_STYLEFLAG_MULTILINE) != 0)
144                 RETERR(str_totext(" )", target));
145         return (ISC_R_SUCCESS);
146 }
147
148 static inline isc_result_t
149 fromwire_cds(ARGS_FROMWIRE) {
150         isc_region_t sr;
151
152         REQUIRE(type == dns_rdatatype_cds);
153
154         UNUSED(type);
155         UNUSED(rdclass);
156         UNUSED(dctx);
157         UNUSED(options);
158
159         isc_buffer_activeregion(source, &sr);
160
161         /*
162          * Check digest lengths if we know them.
163          */
164         if (sr.length < 4 ||
165             (sr.base[3] == DNS_DSDIGEST_SHA1 &&
166              sr.length < 4 + ISC_SHA1_DIGESTLENGTH) ||
167             (sr.base[3] == DNS_DSDIGEST_SHA256 &&
168              sr.length < 4 + ISC_SHA256_DIGESTLENGTH) ||
169             (sr.base[3] == DNS_DSDIGEST_GOST &&
170              sr.length < 4 + ISC_GOST_DIGESTLENGTH) ||
171             (sr.base[3] == DNS_DSDIGEST_SHA384 &&
172              sr.length < 4 + ISC_SHA384_DIGESTLENGTH))
173                 return (ISC_R_UNEXPECTEDEND);
174
175         /*
176          * Only copy digest lengths if we know them.
177          * If there is extra data dns_rdata_fromwire() will
178          * detect that.
179          */
180         if (sr.base[3] == DNS_DSDIGEST_SHA1)
181                 sr.length = 4 + ISC_SHA1_DIGESTLENGTH;
182         else if (sr.base[3] == DNS_DSDIGEST_SHA256)
183                 sr.length = 4 + ISC_SHA256_DIGESTLENGTH;
184         else if (sr.base[3] == DNS_DSDIGEST_GOST)
185                 sr.length = 4 + ISC_GOST_DIGESTLENGTH;
186         else if (sr.base[3] == DNS_DSDIGEST_SHA384)
187                 sr.length = 4 + ISC_SHA384_DIGESTLENGTH;
188
189         isc_buffer_forward(source, sr.length);
190         return (mem_tobuffer(target, sr.base, sr.length));
191 }
192
193 static inline isc_result_t
194 towire_cds(ARGS_TOWIRE) {
195         isc_region_t sr;
196
197         REQUIRE(rdata->type == dns_rdatatype_cds);
198         REQUIRE(rdata->length != 0);
199
200         UNUSED(cctx);
201
202         dns_rdata_toregion(rdata, &sr);
203         return (mem_tobuffer(target, sr.base, sr.length));
204 }
205
206 static inline int
207 compare_cds(ARGS_COMPARE) {
208         isc_region_t r1;
209         isc_region_t r2;
210
211         REQUIRE(rdata1->type == rdata2->type);
212         REQUIRE(rdata1->rdclass == rdata2->rdclass);
213         REQUIRE(rdata1->type == dns_rdatatype_cds);
214         REQUIRE(rdata1->length != 0);
215         REQUIRE(rdata2->length != 0);
216
217         dns_rdata_toregion(rdata1, &r1);
218         dns_rdata_toregion(rdata2, &r2);
219         return (isc_region_compare(&r1, &r2));
220 }
221
222 static inline isc_result_t
223 fromstruct_cds(ARGS_FROMSTRUCT) {
224         dns_rdata_cds_t *ds = source;
225
226         REQUIRE(type == dns_rdatatype_cds);
227         REQUIRE(source != NULL);
228         REQUIRE(ds->common.rdtype == type);
229         REQUIRE(ds->common.rdclass == rdclass);
230         switch (ds->digest_type) {
231         case DNS_DSDIGEST_SHA1:
232                 REQUIRE(ds->length == ISC_SHA1_DIGESTLENGTH);
233                 break;
234         case DNS_DSDIGEST_SHA256:
235                 REQUIRE(ds->length == ISC_SHA256_DIGESTLENGTH);
236                 break;
237         case DNS_DSDIGEST_GOST:
238                 REQUIRE(ds->length == ISC_GOST_DIGESTLENGTH);
239                 break;
240         case DNS_DSDIGEST_SHA384:
241                 REQUIRE(ds->length == ISC_SHA384_DIGESTLENGTH);
242                 break;
243         }
244
245         UNUSED(type);
246         UNUSED(rdclass);
247
248         RETERR(uint16_tobuffer(ds->key_tag, target));
249         RETERR(uint8_tobuffer(ds->algorithm, target));
250         RETERR(uint8_tobuffer(ds->digest_type, target));
251
252         return (mem_tobuffer(target, ds->digest, ds->length));
253 }
254
255 static inline isc_result_t
256 tostruct_cds(ARGS_TOSTRUCT) {
257         dns_rdata_cds_t *ds = target;
258         isc_region_t region;
259
260         REQUIRE(rdata->type == dns_rdatatype_cds);
261         REQUIRE(target != NULL);
262         REQUIRE(rdata->length != 0);
263
264         ds->common.rdclass = rdata->rdclass;
265         ds->common.rdtype = rdata->type;
266         ISC_LINK_INIT(&ds->common, link);
267
268         dns_rdata_toregion(rdata, &region);
269
270         ds->key_tag = uint16_fromregion(&region);
271         isc_region_consume(&region, 2);
272         ds->algorithm = uint8_fromregion(&region);
273         isc_region_consume(&region, 1);
274         ds->digest_type = uint8_fromregion(&region);
275         isc_region_consume(&region, 1);
276         ds->length = region.length;
277
278         ds->digest = mem_maybedup(mctx, region.base, region.length);
279         if (ds->digest == NULL)
280                 return (ISC_R_NOMEMORY);
281
282         ds->mctx = mctx;
283         return (ISC_R_SUCCESS);
284 }
285
286 static inline void
287 freestruct_cds(ARGS_FREESTRUCT) {
288         dns_rdata_cds_t *ds = source;
289
290         REQUIRE(ds != NULL);
291         REQUIRE(ds->common.rdtype == dns_rdatatype_cds);
292
293         if (ds->mctx == NULL)
294                 return;
295
296         if (ds->digest != NULL)
297                 isc_mem_free(ds->mctx, ds->digest);
298         ds->mctx = NULL;
299 }
300
301 static inline isc_result_t
302 additionaldata_cds(ARGS_ADDLDATA) {
303         REQUIRE(rdata->type == dns_rdatatype_cds);
304
305         UNUSED(rdata);
306         UNUSED(add);
307         UNUSED(arg);
308
309         return (ISC_R_SUCCESS);
310 }
311
312 static inline isc_result_t
313 digest_cds(ARGS_DIGEST) {
314         isc_region_t r;
315
316         REQUIRE(rdata->type == dns_rdatatype_cds);
317
318         dns_rdata_toregion(rdata, &r);
319
320         return ((digest)(arg, &r));
321 }
322
323 static inline isc_boolean_t
324 checkowner_cds(ARGS_CHECKOWNER) {
325
326         REQUIRE(type == dns_rdatatype_cds);
327
328         UNUSED(name);
329         UNUSED(type);
330         UNUSED(rdclass);
331         UNUSED(wildcard);
332
333         return (ISC_TRUE);
334 }
335
336 static inline isc_boolean_t
337 checknames_cds(ARGS_CHECKNAMES) {
338
339         REQUIRE(rdata->type == dns_rdatatype_cds);
340
341         UNUSED(rdata);
342         UNUSED(owner);
343         UNUSED(bad);
344
345         return (ISC_TRUE);
346 }
347
348 static inline int
349 casecompare_cds(ARGS_COMPARE) {
350         return (compare_cds(rdata1, rdata2));
351 }
352
353 #endif  /* RDATA_GENERIC_CDS_59_C */