]> CyberLeo.Net >> Repos - FreeBSD/stable/9.git/blob - contrib/bind9/lib/dns/rdata/generic/key_25.c
MFC r363988:
[FreeBSD/stable/9.git] / contrib / bind9 / lib / dns / rdata / generic / key_25.c
1 /*
2  * Copyright (C) 2004, 2005, 2007, 2009, 2011-2013, 2015  Internet Systems Consortium, Inc. ("ISC")
3  * Copyright (C) 1999-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_KEY_25_C
27 #define RDATA_GENERIC_KEY_25_C
28
29 #include <dst/dst.h>
30
31 #define RRTYPE_KEY_ATTRIBUTES (0)
32
33 static inline isc_result_t
34 generic_fromtext_key(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         UNUSED(type);
42         UNUSED(rdclass);
43         UNUSED(origin);
44         UNUSED(options);
45         UNUSED(callbacks);
46
47         /* flags */
48         RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_string,
49                                       ISC_FALSE));
50         RETTOK(dns_keyflags_fromtext(&flags, &token.value.as_textregion));
51         RETERR(uint16_tobuffer(flags, target));
52
53         /* protocol */
54         RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_string,
55                                       ISC_FALSE));
56         RETTOK(dns_secproto_fromtext(&proto, &token.value.as_textregion));
57         RETERR(mem_tobuffer(target, &proto, 1));
58
59         /* algorithm */
60         RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_string,
61                                       ISC_FALSE));
62         RETTOK(dns_secalg_fromtext(&alg, &token.value.as_textregion));
63         RETERR(mem_tobuffer(target, &alg, 1));
64
65         /* No Key? */
66         if ((flags & 0xc000) == 0xc000)
67                 return (ISC_R_SUCCESS);
68
69         result = isc_base64_tobuffer(lexer, target, -1);
70         if (result != ISC_R_SUCCESS)
71                 return (result);
72
73         /* Ensure there's at least enough data to compute a key ID for MD5 */
74         if (alg == DST_ALG_RSAMD5 && isc_buffer_usedlength(target) < 7)
75                 return (ISC_R_UNEXPECTEDEND);
76
77         return (ISC_R_SUCCESS);
78 }
79
80 static inline isc_result_t
81 generic_totext_key(ARGS_TOTEXT) {
82         isc_region_t sr;
83         char buf[sizeof("[key id = 64000]")];
84         unsigned int flags;
85         unsigned char algorithm;
86         char algbuf[DNS_NAME_FORMATSIZE];
87         const char *keyinfo;
88         isc_region_t tmpr;
89
90         REQUIRE(rdata->length != 0);
91
92         dns_rdata_toregion(rdata, &sr);
93
94         /* flags */
95         flags = uint16_fromregion(&sr);
96         isc_region_consume(&sr, 2);
97         sprintf(buf, "%u", flags);
98         RETERR(str_totext(buf, target));
99         RETERR(str_totext(" ", target));
100         if ((flags & DNS_KEYFLAG_KSK) != 0) {
101                 if (flags & DNS_KEYFLAG_REVOKE)
102                         keyinfo = "revoked KSK";
103                 else
104                         keyinfo = "KSK";
105         } else
106                 keyinfo = "ZSK";
107
108
109         /* protocol */
110         sprintf(buf, "%u", sr.base[0]);
111         isc_region_consume(&sr, 1);
112         RETERR(str_totext(buf, target));
113         RETERR(str_totext(" ", target));
114
115         /* algorithm */
116         algorithm = sr.base[0];
117         sprintf(buf, "%u", algorithm);
118         isc_region_consume(&sr, 1);
119         RETERR(str_totext(buf, target));
120
121         /* No Key? */
122         if ((flags & 0xc000) == 0xc000)
123                 return (ISC_R_SUCCESS);
124
125         if ((tctx->flags & DNS_STYLEFLAG_RRCOMMENT) != 0 &&
126              algorithm == DNS_KEYALG_PRIVATEDNS) {
127                 dns_name_t name;
128                 dns_name_init(&name, NULL);
129                 dns_name_fromregion(&name, &sr);
130                 dns_name_format(&name, algbuf, sizeof(algbuf));
131         } else {
132                 dns_secalg_format((dns_secalg_t) algorithm, algbuf,
133                                   sizeof(algbuf));
134         }
135
136         /* key */
137         if ((tctx->flags & DNS_STYLEFLAG_MULTILINE) != 0)
138                 RETERR(str_totext(" (", target));
139         RETERR(str_totext(tctx->linebreak, target));
140
141         if (tctx->width == 0)   /* No splitting */
142                 RETERR(isc_base64_totext(&sr, 60, "", 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
157                 if (rdata->type == dns_rdatatype_dnskey ||
158                     rdata->type == dns_rdatatype_cdnskey) {
159                         RETERR(str_totext(" ; ", target));
160                         RETERR(str_totext(keyinfo, target));
161                 }
162                 RETERR(str_totext("; alg = ", target));
163                 RETERR(str_totext(algbuf, target));
164                 RETERR(str_totext(" ; key id = ", target));
165                 dns_rdata_toregion(rdata, &tmpr);
166                 sprintf(buf, "%u", dst_region_computeid(&tmpr, algorithm));
167                 RETERR(str_totext(buf, target));
168         }
169         return (ISC_R_SUCCESS);
170 }
171
172 static inline isc_result_t
173 generic_fromwire_key(ARGS_FROMWIRE) {
174         unsigned char algorithm;
175         isc_region_t sr;
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 fromtext_key(ARGS_FROMTEXT) {
213
214         REQUIRE(type == dns_rdatatype_key);
215
216         return (generic_fromtext_key(rdclass, type, lexer, origin,
217                                      options, target, callbacks));
218 }
219
220 static inline isc_result_t
221 totext_key(ARGS_TOTEXT) {
222
223         REQUIRE(rdata != NULL);
224         REQUIRE(rdata->type == dns_rdatatype_key);
225
226         return (generic_totext_key(rdata, tctx, target));
227 }
228
229 static inline isc_result_t
230 fromwire_key(ARGS_FROMWIRE) {
231
232         REQUIRE(type == dns_rdatatype_key);
233
234         return (generic_fromwire_key(rdclass, type, source, dctx,
235                                      options, target));
236 }
237
238 static inline isc_result_t
239 towire_key(ARGS_TOWIRE) {
240         isc_region_t sr;
241
242         REQUIRE(rdata != NULL);
243         REQUIRE(rdata->type == dns_rdatatype_key);
244         REQUIRE(rdata->length != 0);
245
246         UNUSED(cctx);
247
248         dns_rdata_toregion(rdata, &sr);
249         return (mem_tobuffer(target, sr.base, sr.length));
250 }
251
252 static inline int
253 compare_key(ARGS_COMPARE) {
254         isc_region_t r1;
255         isc_region_t r2;
256
257         REQUIRE(rdata1 != NULL);
258         REQUIRE(rdata2 != NULL);
259         REQUIRE(rdata1->type == rdata2->type);
260         REQUIRE(rdata1->rdclass == rdata2->rdclass);
261         REQUIRE(rdata1->type == dns_rdatatype_key);
262         REQUIRE(rdata1->length != 0);
263         REQUIRE(rdata2->length != 0);
264
265         dns_rdata_toregion(rdata1, &r1);
266         dns_rdata_toregion(rdata2, &r2);
267         return (isc_region_compare(&r1, &r2));
268 }
269
270 static inline isc_result_t
271 generic_fromstruct_key(ARGS_FROMSTRUCT) {
272         dns_rdata_key_t *key = source;
273
274         REQUIRE(key != NULL);
275         REQUIRE(key->common.rdtype == type);
276         REQUIRE(key->common.rdclass == rdclass);
277
278         UNUSED(type);
279         UNUSED(rdclass);
280
281         /* Flags */
282         RETERR(uint16_tobuffer(key->flags, target));
283
284         /* Protocol */
285         RETERR(uint8_tobuffer(key->protocol, target));
286
287         /* Algorithm */
288         RETERR(uint8_tobuffer(key->algorithm, target));
289
290         /* Data */
291         return (mem_tobuffer(target, key->data, key->datalen));
292 }
293
294 static inline isc_result_t
295 generic_tostruct_key(ARGS_TOSTRUCT) {
296         dns_rdata_key_t *key = target;
297         isc_region_t sr;
298
299         REQUIRE(rdata != NULL);
300         REQUIRE(rdata->length != 0);
301
302         REQUIRE(key != NULL);
303         REQUIRE(key->common.rdclass == rdata->rdclass);
304         REQUIRE(key->common.rdtype == rdata->type);
305         REQUIRE(!ISC_LINK_LINKED(&key->common, link));
306
307         dns_rdata_toregion(rdata, &sr);
308
309         /* Flags */
310         if (sr.length < 2)
311                 return (ISC_R_UNEXPECTEDEND);
312         key->flags = uint16_fromregion(&sr);
313         isc_region_consume(&sr, 2);
314
315         /* Protocol */
316         if (sr.length < 1)
317                 return (ISC_R_UNEXPECTEDEND);
318         key->protocol = uint8_fromregion(&sr);
319         isc_region_consume(&sr, 1);
320
321         /* Algorithm */
322         if (sr.length < 1)
323                 return (ISC_R_UNEXPECTEDEND);
324         key->algorithm = uint8_fromregion(&sr);
325         isc_region_consume(&sr, 1);
326
327         /* Data */
328         key->datalen = sr.length;
329         key->data = mem_maybedup(mctx, sr.base, key->datalen);
330         if (key->data == NULL)
331                 return (ISC_R_NOMEMORY);
332
333         key->mctx = mctx;
334         return (ISC_R_SUCCESS);
335 }
336
337 static inline void
338 generic_freestruct_key(ARGS_FREESTRUCT) {
339         dns_rdata_key_t *key = (dns_rdata_key_t *) source;
340
341         REQUIRE(key != NULL);
342
343         if (key->mctx == NULL)
344                 return;
345
346         if (key->data != NULL)
347                 isc_mem_free(key->mctx, key->data);
348         key->mctx = NULL;
349 }
350
351 static inline isc_result_t
352 fromstruct_key(ARGS_FROMSTRUCT) {
353
354         REQUIRE(type == dns_rdatatype_key);
355
356         return (generic_fromstruct_key(rdclass, type, source, target));
357 }
358
359 static inline isc_result_t
360 tostruct_key(ARGS_TOSTRUCT) {
361         dns_rdata_key_t *key = target;
362
363         REQUIRE(key != NULL);
364         REQUIRE(rdata != NULL);
365         REQUIRE(rdata->type == dns_rdatatype_key);
366
367         key->common.rdclass = rdata->rdclass;
368         key->common.rdtype = rdata->type;
369         ISC_LINK_INIT(&key->common, link);
370
371         return (generic_tostruct_key(rdata, target, mctx));
372 }
373
374 static inline void
375 freestruct_key(ARGS_FREESTRUCT) {
376         dns_rdata_key_t *key = (dns_rdata_key_t *) source;
377
378         REQUIRE(key != NULL);
379         REQUIRE(key->common.rdtype == dns_rdatatype_key);
380
381         generic_freestruct_key(source);
382 }
383
384 static inline isc_result_t
385 additionaldata_key(ARGS_ADDLDATA) {
386
387         REQUIRE(rdata != NULL);
388         REQUIRE(rdata->type == dns_rdatatype_key);
389
390         UNUSED(rdata);
391         UNUSED(add);
392         UNUSED(arg);
393
394         return (ISC_R_SUCCESS);
395 }
396
397 static inline isc_result_t
398 digest_key(ARGS_DIGEST) {
399         isc_region_t r;
400
401         REQUIRE(rdata != NULL);
402         REQUIRE(rdata->type == dns_rdatatype_key);
403
404         dns_rdata_toregion(rdata, &r);
405
406         return ((digest)(arg, &r));
407 }
408
409 static inline isc_boolean_t
410 checkowner_key(ARGS_CHECKOWNER) {
411
412         REQUIRE(type == dns_rdatatype_key);
413
414         UNUSED(name);
415         UNUSED(type);
416         UNUSED(rdclass);
417         UNUSED(wildcard);
418
419         return (ISC_TRUE);
420 }
421
422 static inline isc_boolean_t
423 checknames_key(ARGS_CHECKNAMES) {
424
425         REQUIRE(rdata != NULL);
426         REQUIRE(rdata->type == dns_rdatatype_key);
427
428         UNUSED(rdata);
429         UNUSED(owner);
430         UNUSED(bad);
431
432         return (ISC_TRUE);
433 }
434
435 static inline int
436 casecompare_key(ARGS_COMPARE) {
437         return (compare_key(rdata1, rdata2));
438 }
439
440 #endif  /* RDATA_GENERIC_KEY_25_C */