]> CyberLeo.Net >> Repos - FreeBSD/releng/9.3.git/blob - contrib/bind9/lib/dns/rdata/generic/dnskey_48.c
Copy stable/9 to releng/9.3 as part of the 9.3-RELEASE cycle.
[FreeBSD/releng/9.3.git] / contrib / bind9 / lib / dns / rdata / generic / dnskey_48.c
1 /*
2  * Copyright (C) 2004, 2005, 2007, 2009, 2011-2013  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 /*
21  * Reviewed: Wed Mar 15 16:47:10 PST 2000 by halley.
22  */
23
24 /* RFC2535 */
25
26 #ifndef RDATA_GENERIC_DNSKEY_48_C
27 #define RDATA_GENERIC_DNSKEY_48_C
28
29 #include <dst/dst.h>
30
31 #define RRTYPE_DNSKEY_ATTRIBUTES (DNS_RDATATYPEATTR_DNSSEC)
32
33 static inline isc_result_t
34 fromtext_dnskey(ARGS_FROMTEXT) {
35         isc_result_t result;
36         isc_token_t token;
37         dns_secalg_t alg;
38         dns_secproto_t proto;
39         dns_keyflags_t flags;
40
41         REQUIRE(type == 48);
42
43         UNUSED(type);
44         UNUSED(rdclass);
45         UNUSED(origin);
46         UNUSED(options);
47         UNUSED(callbacks);
48
49         /* flags */
50         RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_string,
51                                       ISC_FALSE));
52         RETTOK(dns_keyflags_fromtext(&flags, &token.value.as_textregion));
53         RETERR(uint16_tobuffer(flags, target));
54
55         /* protocol */
56         RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_string,
57                                       ISC_FALSE));
58         RETTOK(dns_secproto_fromtext(&proto, &token.value.as_textregion));
59         RETERR(mem_tobuffer(target, &proto, 1));
60
61         /* algorithm */
62         RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_string,
63                                       ISC_FALSE));
64         RETTOK(dns_secalg_fromtext(&alg, &token.value.as_textregion));
65         RETERR(mem_tobuffer(target, &alg, 1));
66
67         /* No Key? */
68         if ((flags & 0xc000) == 0xc000)
69                 return (ISC_R_SUCCESS);
70
71         result = isc_base64_tobuffer(lexer, target, -1);
72         if (result != ISC_R_SUCCESS)
73                 return (result);
74
75         /* Ensure there's at least enough data to compute a key ID for MD5 */
76         if (alg == DST_ALG_RSAMD5 && isc_buffer_usedlength(target) < 7)
77                 return (ISC_R_UNEXPECTEDEND);
78
79         return (ISC_R_SUCCESS);
80 }
81
82 static inline isc_result_t
83 totext_dnskey(ARGS_TOTEXT) {
84         isc_region_t sr;
85         char buf[sizeof("64000")];
86         unsigned int flags;
87         unsigned char algorithm;
88         char algbuf[DNS_NAME_FORMATSIZE];
89         const char *keyinfo;
90
91         REQUIRE(rdata->type == 48);
92         REQUIRE(rdata->length != 0);
93
94         dns_rdata_toregion(rdata, &sr);
95
96         /* flags */
97         flags = uint16_fromregion(&sr);
98         isc_region_consume(&sr, 2);
99         sprintf(buf, "%u", flags);
100         RETERR(str_totext(buf, target));
101         RETERR(str_totext(" ", target));
102         if ((flags & DNS_KEYFLAG_KSK) != 0) {
103                 if (flags & DNS_KEYFLAG_REVOKE)
104                         keyinfo = "revoked KSK";
105                 else
106                         keyinfo = "KSK";
107         } else
108                 keyinfo = "ZSK";
109
110         /* protocol */
111         sprintf(buf, "%u", sr.base[0]);
112         isc_region_consume(&sr, 1);
113         RETERR(str_totext(buf, target));
114         RETERR(str_totext(" ", target));
115
116         /* algorithm */
117         algorithm = sr.base[0];
118         sprintf(buf, "%u", algorithm);
119         isc_region_consume(&sr, 1);
120         RETERR(str_totext(buf, target));
121
122         /* No Key? */
123         if ((flags & 0xc000) == 0xc000)
124                 return (ISC_R_SUCCESS);
125
126         if ((tctx->flags & DNS_STYLEFLAG_RRCOMMENT) != 0 &&
127              algorithm == DNS_KEYALG_PRIVATEDNS) {
128                 dns_name_t name;
129                 dns_name_init(&name, NULL);
130                 dns_name_fromregion(&name, &sr);
131                 dns_name_format(&name, algbuf, sizeof(algbuf));
132         } else {
133                 dns_secalg_format((dns_secalg_t) algorithm, algbuf,
134                                   sizeof(algbuf));
135         }
136
137         /* key */
138         if ((tctx->flags & DNS_STYLEFLAG_MULTILINE) != 0)
139                 RETERR(str_totext(" (", target));
140         RETERR(str_totext(tctx->linebreak, target));
141         if (tctx->width == 0)   /* No splitting */
142                 RETERR(isc_base64_totext(&sr, 0, "", target));
143         else
144                 RETERR(isc_base64_totext(&sr, tctx->width - 2,
145                                          tctx->linebreak, target));
146
147         if ((tctx->flags & DNS_STYLEFLAG_RRCOMMENT) != 0)
148                 RETERR(str_totext(tctx->linebreak, target));
149         else if ((tctx->flags & DNS_STYLEFLAG_MULTILINE) != 0)
150                 RETERR(str_totext(" ", target));
151
152         if ((tctx->flags & DNS_STYLEFLAG_MULTILINE) != 0)
153                 RETERR(str_totext(")", target));
154
155         if ((tctx->flags & DNS_STYLEFLAG_RRCOMMENT) != 0) {
156                 isc_region_t tmpr;
157
158                 RETERR(str_totext(" ; ", target));
159                 RETERR(str_totext(keyinfo, target));
160                 RETERR(str_totext("; alg = ", target));
161                 RETERR(str_totext(algbuf, target));
162                 RETERR(str_totext("; key id = ", target));
163                 dns_rdata_toregion(rdata, &tmpr);
164                 sprintf(buf, "%u", dst_region_computeid(&tmpr, algorithm));
165                 RETERR(str_totext(buf, target));
166         }
167         return (ISC_R_SUCCESS);
168 }
169
170 static inline isc_result_t
171 fromwire_dnskey(ARGS_FROMWIRE) {
172         unsigned char algorithm;
173         isc_region_t sr;
174
175         REQUIRE(type == 48);
176
177         UNUSED(type);
178         UNUSED(rdclass);
179         UNUSED(dctx);
180         UNUSED(options);
181
182         isc_buffer_activeregion(source, &sr);
183         if (sr.length < 4)
184                 return (ISC_R_UNEXPECTEDEND);
185
186         algorithm = sr.base[3];
187         RETERR(mem_tobuffer(target, sr.base, 4));
188         isc_region_consume(&sr, 4);
189         isc_buffer_forward(source, 4);
190
191         if (algorithm == DNS_KEYALG_PRIVATEDNS) {
192                 dns_name_t name;
193                 dns_decompress_setmethods(dctx, DNS_COMPRESS_NONE);
194                 dns_name_init(&name, NULL);
195                 RETERR(dns_name_fromwire(&name, source, dctx, options, target));
196         }
197
198         /*
199          * RSAMD5 computes key ID differently from other
200          * algorithms: we need to ensure there's enough data
201          * present for the computation
202          */
203         if (algorithm == DST_ALG_RSAMD5 && sr.length < 3)
204                 return (ISC_R_UNEXPECTEDEND);
205
206         isc_buffer_activeregion(source, &sr);
207         isc_buffer_forward(source, sr.length);
208         return (mem_tobuffer(target, sr.base, sr.length));
209 }
210
211 static inline isc_result_t
212 towire_dnskey(ARGS_TOWIRE) {
213         isc_region_t sr;
214
215         REQUIRE(rdata->type == 48);
216         REQUIRE(rdata->length != 0);
217
218         UNUSED(cctx);
219
220         dns_rdata_toregion(rdata, &sr);
221         return (mem_tobuffer(target, sr.base, sr.length));
222 }
223
224 static inline int
225 compare_dnskey(ARGS_COMPARE) {
226         isc_region_t r1;
227         isc_region_t r2;
228
229         REQUIRE(rdata1->type == rdata2->type);
230         REQUIRE(rdata1->rdclass == rdata2->rdclass);
231         REQUIRE(rdata1->type == 48);
232         REQUIRE(rdata1->length != 0);
233         REQUIRE(rdata2->length != 0);
234
235         dns_rdata_toregion(rdata1, &r1);
236         dns_rdata_toregion(rdata2, &r2);
237         return (isc_region_compare(&r1, &r2));
238 }
239
240 static inline isc_result_t
241 fromstruct_dnskey(ARGS_FROMSTRUCT) {
242         dns_rdata_dnskey_t *dnskey = source;
243
244         REQUIRE(type == 48);
245         REQUIRE(source != NULL);
246         REQUIRE(dnskey->common.rdtype == type);
247         REQUIRE(dnskey->common.rdclass == rdclass);
248
249         UNUSED(type);
250         UNUSED(rdclass);
251
252         /* Flags */
253         RETERR(uint16_tobuffer(dnskey->flags, target));
254
255         /* Protocol */
256         RETERR(uint8_tobuffer(dnskey->protocol, target));
257
258         /* Algorithm */
259         RETERR(uint8_tobuffer(dnskey->algorithm, target));
260
261         /* Data */
262         return (mem_tobuffer(target, dnskey->data, dnskey->datalen));
263 }
264
265 static inline isc_result_t
266 tostruct_dnskey(ARGS_TOSTRUCT) {
267         dns_rdata_dnskey_t *dnskey = target;
268         isc_region_t sr;
269
270         REQUIRE(rdata->type == 48);
271         REQUIRE(target != NULL);
272         REQUIRE(rdata->length != 0);
273
274         dnskey->common.rdclass = rdata->rdclass;
275         dnskey->common.rdtype = rdata->type;
276         ISC_LINK_INIT(&dnskey->common, link);
277
278         dns_rdata_toregion(rdata, &sr);
279
280         /* Flags */
281         if (sr.length < 2)
282                 return (ISC_R_UNEXPECTEDEND);
283         dnskey->flags = uint16_fromregion(&sr);
284         isc_region_consume(&sr, 2);
285
286         /* Protocol */
287         if (sr.length < 1)
288                 return (ISC_R_UNEXPECTEDEND);
289         dnskey->protocol = uint8_fromregion(&sr);
290         isc_region_consume(&sr, 1);
291
292         /* Algorithm */
293         if (sr.length < 1)
294                 return (ISC_R_UNEXPECTEDEND);
295         dnskey->algorithm = uint8_fromregion(&sr);
296         isc_region_consume(&sr, 1);
297
298         /* Data */
299         dnskey->datalen = sr.length;
300         dnskey->data = mem_maybedup(mctx, sr.base, dnskey->datalen);
301         if (dnskey->data == NULL)
302                 return (ISC_R_NOMEMORY);
303
304         dnskey->mctx = mctx;
305         return (ISC_R_SUCCESS);
306 }
307
308 static inline void
309 freestruct_dnskey(ARGS_FREESTRUCT) {
310         dns_rdata_dnskey_t *dnskey = (dns_rdata_dnskey_t *) source;
311
312         REQUIRE(source != NULL);
313         REQUIRE(dnskey->common.rdtype == 48);
314
315         if (dnskey->mctx == NULL)
316                 return;
317
318         if (dnskey->data != NULL)
319                 isc_mem_free(dnskey->mctx, dnskey->data);
320         dnskey->mctx = NULL;
321 }
322
323 static inline isc_result_t
324 additionaldata_dnskey(ARGS_ADDLDATA) {
325         REQUIRE(rdata->type == 48);
326
327         UNUSED(rdata);
328         UNUSED(add);
329         UNUSED(arg);
330
331         return (ISC_R_SUCCESS);
332 }
333
334 static inline isc_result_t
335 digest_dnskey(ARGS_DIGEST) {
336         isc_region_t r;
337
338         REQUIRE(rdata->type == 48);
339
340         dns_rdata_toregion(rdata, &r);
341
342         return ((digest)(arg, &r));
343 }
344
345 static inline isc_boolean_t
346 checkowner_dnskey(ARGS_CHECKOWNER) {
347
348         REQUIRE(type == 48);
349
350         UNUSED(name);
351         UNUSED(type);
352         UNUSED(rdclass);
353         UNUSED(wildcard);
354
355         return (ISC_TRUE);
356 }
357
358 static inline isc_boolean_t
359 checknames_dnskey(ARGS_CHECKNAMES) {
360
361         REQUIRE(rdata->type == 48);
362
363         UNUSED(rdata);
364         UNUSED(owner);
365         UNUSED(bad);
366
367         return (ISC_TRUE);
368 }
369
370 static inline int
371 casecompare_dnskey(ARGS_COMPARE) {
372
373         /*
374          * Treat ALG 253 (private DNS) subtype name case sensistively.
375          */
376         return (compare_dnskey(rdata1, rdata2));
377 }
378
379 #endif  /* RDATA_GENERIC_DNSKEY_48_C */