Merge from vendor branch GROFF:
[dragonfly.git] / contrib / bind-9.2.4rc7 / lib / dns / rdata / generic / tkey_249.c
1 /*
2  * Copyright (C) 2004  Internet Systems Consortium, Inc. ("ISC")
3  * Copyright (C) 1999-2001, 2003  Internet Software Consortium.
4  *
5  * Permission to use, copy, modify, and 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: tkey_249.c,v 1.48.2.3 2004/03/09 06:11:34 marka Exp $ */
19
20 /*
21  * Reviewed: Thu Mar 16 17:35:30 PST 2000 by halley.
22  */
23
24 /* draft-ietf-dnsext-tkey-01.txt */
25
26 #ifndef RDATA_GENERIC_TKEY_249_C
27 #define RDATA_GENERIC_TKEY_249_C
28
29 #define RRTYPE_TKEY_ATTRIBUTES (DNS_RDATATYPEATTR_META)
30
31 static inline isc_result_t
32 fromtext_tkey(ARGS_FROMTEXT) {
33         isc_token_t token;
34         dns_rcode_t rcode;
35         dns_name_t name;
36         isc_buffer_t buffer;
37         long i;
38         char *e;
39
40         REQUIRE(type == 249);
41
42         UNUSED(type);
43         UNUSED(rdclass);
44         UNUSED(callbacks);
45
46         /*
47          * Algorithm.
48          */
49         RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_string,
50                                       ISC_FALSE));
51         dns_name_init(&name, NULL);
52         buffer_fromregion(&buffer, &token.value.as_region);
53         origin = (origin != NULL) ? origin : dns_rootname;
54         RETTOK(dns_name_fromtext(&name, &buffer, origin, downcase, target));
55
56
57         /*
58          * Inception.
59          */
60         RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_number,
61                                       ISC_FALSE));
62         RETERR(uint32_tobuffer(token.value.as_ulong, target));
63
64         /*
65          * Expiration.
66          */
67         RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_number,
68                                       ISC_FALSE));
69         RETERR(uint32_tobuffer(token.value.as_ulong, target));
70
71         /*
72          * Mode.
73          */
74         RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_number,
75                                       ISC_FALSE));
76         if (token.value.as_ulong > 0xffffU)
77                 RETTOK(ISC_R_RANGE);
78         RETERR(uint16_tobuffer(token.value.as_ulong, target));
79
80         /*
81          * Error.
82          */
83         RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_string,
84                                       ISC_FALSE));
85         if (dns_tsigrcode_fromtext(&rcode, &token.value.as_textregion)
86                                 != ISC_R_SUCCESS)
87         {
88                 i = strtol(token.value.as_pointer, &e, 10);
89                 if (*e != 0)
90                         RETTOK(DNS_R_UNKNOWN);
91                 if (i < 0 || i > 0xffff)
92                         RETTOK(ISC_R_RANGE);
93                 rcode = (dns_rcode_t)i;
94         }
95         RETERR(uint16_tobuffer(rcode, target));
96
97         /*
98          * Key Size.
99          */
100         RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_number,
101                                       ISC_FALSE));
102         if (token.value.as_ulong > 0xffffU)
103                 RETTOK(ISC_R_RANGE);
104         RETERR(uint16_tobuffer(token.value.as_ulong, target));
105
106         /*
107          * Key Data.
108          */
109         RETERR(isc_base64_tobuffer(lexer, target, (int)token.value.as_ulong));
110
111         /*
112          * Other Size.
113          */
114         RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_number,
115                                       ISC_FALSE));
116         if (token.value.as_ulong > 0xffffU)
117                 RETTOK(ISC_R_RANGE);
118         RETERR(uint16_tobuffer(token.value.as_ulong, target));
119
120         /*
121          * Other Data.
122          */
123         return (isc_base64_tobuffer(lexer, target, (int)token.value.as_ulong));
124 }
125
126 static inline isc_result_t
127 totext_tkey(ARGS_TOTEXT) {
128         isc_region_t sr, dr;
129         char buf[sizeof "4294967295 "];
130         unsigned long n;
131         dns_name_t name;
132         dns_name_t prefix;
133         isc_boolean_t sub;
134
135         REQUIRE(rdata->type == 249);
136         REQUIRE(rdata->length != 0);
137
138         dns_rdata_toregion(rdata, &sr);
139
140         /*
141          * Algorithm.
142          */
143         dns_name_init(&name, NULL);
144         dns_name_init(&prefix, NULL);
145         dns_name_fromregion(&name, &sr);
146         sub = name_prefix(&name, tctx->origin, &prefix);
147         RETERR(dns_name_totext(&prefix, sub, target));
148         RETERR(str_totext(" ", target));
149         isc_region_consume(&sr, name_length(&name));
150
151         /*
152          * Inception.
153          */
154         n = uint32_fromregion(&sr);
155         isc_region_consume(&sr, 4);
156         sprintf(buf, "%lu ", n);
157         RETERR(str_totext(buf, target));
158
159         /*
160          * Expiration.
161          */
162         n = uint32_fromregion(&sr);
163         isc_region_consume(&sr, 4);
164         sprintf(buf, "%lu ", n);
165         RETERR(str_totext(buf, target));
166
167         /*
168          * Mode.
169          */
170         n = uint16_fromregion(&sr);
171         isc_region_consume(&sr, 2);
172         sprintf(buf, "%lu ", n);
173         RETERR(str_totext(buf, target));
174
175         /*
176          * Error.
177          */
178         n = uint16_fromregion(&sr);
179         isc_region_consume(&sr, 2);
180         if (dns_tsigrcode_totext((dns_rcode_t)n, target) == ISC_R_SUCCESS)
181                 RETERR(str_totext(" ", target));
182         else {
183                 sprintf(buf, "%lu ", n);
184                 RETERR(str_totext(buf, target));
185         }
186
187         /*
188          * Key Size.
189          */
190         n = uint16_fromregion(&sr);
191         isc_region_consume(&sr, 2);
192         sprintf(buf, "%lu", n);
193         RETERR(str_totext(buf, target));
194
195         /*
196          * Key Data.
197          */
198         REQUIRE(n <= sr.length);
199         dr = sr;
200         dr.length = n;
201         if ((tctx->flags & DNS_STYLEFLAG_MULTILINE) != 0)
202                 RETERR(str_totext(" (", target));
203         RETERR(str_totext(tctx->linebreak, target));
204         RETERR(isc_base64_totext(&dr, tctx->width - 2,
205                                  tctx->linebreak, target));
206         if ((tctx->flags & DNS_STYLEFLAG_MULTILINE) != 0)
207                 RETERR(str_totext(" ) ", target));
208         else
209                 RETERR(str_totext(" ", target));
210         isc_region_consume(&sr, n);
211
212         /*
213          * Other Size.
214          */
215         n = uint16_fromregion(&sr);
216         isc_region_consume(&sr, 2);
217         sprintf(buf, "%lu", n);
218         RETERR(str_totext(buf, target));
219
220         /*
221          * Other Data.
222          */
223         REQUIRE(n <= sr.length);
224         if (n != 0U) {
225             dr = sr;
226             dr.length = n;
227             if ((tctx->flags & DNS_STYLEFLAG_MULTILINE) != 0)
228                     RETERR(str_totext(" (", target));
229             RETERR(str_totext(tctx->linebreak, target));
230             RETERR(isc_base64_totext(&dr, tctx->width - 2,
231                                      tctx->linebreak, target));
232             if ((tctx->flags & DNS_STYLEFLAG_MULTILINE) != 0)
233                     RETERR(str_totext(" )", target));
234         }
235         return (ISC_R_SUCCESS);
236 }
237
238 static inline isc_result_t
239 fromwire_tkey(ARGS_FROMWIRE) {
240         isc_region_t sr;
241         unsigned long n;
242         dns_name_t name;
243
244         REQUIRE(type == 249);
245
246         UNUSED(type);
247         UNUSED(rdclass);
248
249         dns_decompress_setmethods(dctx, DNS_COMPRESS_NONE);
250
251         /*
252          * Algorithm.
253          */
254         dns_name_init(&name, NULL);
255         RETERR(dns_name_fromwire(&name, source, dctx, downcase, target));
256
257         /*
258          * Inception: 4
259          * Expiration: 4
260          * Mode: 2
261          * Error: 2
262          */
263         isc_buffer_activeregion(source, &sr);
264         if (sr.length < 12)
265                 return (ISC_R_UNEXPECTEDEND);
266         RETERR(mem_tobuffer(target, sr.base, 12));
267         isc_region_consume(&sr, 12);
268         isc_buffer_forward(source, 12);
269
270         /*
271          * Key Length + Key Data.
272          */
273         if (sr.length < 2)
274                 return (ISC_R_UNEXPECTEDEND);
275         n = uint16_fromregion(&sr);
276         if (sr.length < n + 2)
277                 return (ISC_R_UNEXPECTEDEND);
278         RETERR(mem_tobuffer(target, sr.base, n + 2));
279         isc_region_consume(&sr, n + 2);
280         isc_buffer_forward(source, n + 2);
281
282         /*
283          * Other Length + Other Data.
284          */
285         if (sr.length < 2)
286                 return (ISC_R_UNEXPECTEDEND);
287         n = uint16_fromregion(&sr);
288         if (sr.length < n + 2)
289                 return (ISC_R_UNEXPECTEDEND);
290         isc_buffer_forward(source, n + 2);
291         return (mem_tobuffer(target, sr.base, n + 2));
292 }
293
294 static inline isc_result_t
295 towire_tkey(ARGS_TOWIRE) {
296         isc_region_t sr;
297         dns_name_t name;
298         dns_offsets_t offsets;
299
300         REQUIRE(rdata->type == 249);
301         REQUIRE(rdata->length != 0);
302
303         dns_compress_setmethods(cctx, DNS_COMPRESS_NONE);
304         /*
305          * Algorithm.
306          */
307         dns_rdata_toregion(rdata, &sr);
308         dns_name_init(&name, offsets);
309         dns_name_fromregion(&name, &sr);
310         RETERR(dns_name_towire(&name, cctx, target));
311         isc_region_consume(&sr, name_length(&name));
312
313         return (mem_tobuffer(target, sr.base, sr.length));
314 }
315
316 static inline int
317 compare_tkey(ARGS_COMPARE) {
318         isc_region_t r1;
319         isc_region_t r2;
320         dns_name_t name1;
321         dns_name_t name2;
322         int order;
323
324         REQUIRE(rdata1->type == rdata2->type);
325         REQUIRE(rdata1->rdclass == rdata2->rdclass);
326         REQUIRE(rdata1->type == 249);
327         REQUIRE(rdata1->length != 0);
328         REQUIRE(rdata2->length != 0);
329
330         /*
331          * Algorithm.
332          */
333         dns_rdata_toregion(rdata1, &r1);
334         dns_rdata_toregion(rdata2, &r2);
335         dns_name_init(&name1, NULL);
336         dns_name_init(&name2, NULL);
337         dns_name_fromregion(&name1, &r1);
338         dns_name_fromregion(&name2, &r2);
339         if ((order = dns_name_rdatacompare(&name1, &name2)) != 0)
340                 return (order);
341         isc_region_consume(&r1, name_length(&name1));
342         isc_region_consume(&r2, name_length(&name2));
343         return (compare_region(&r1, &r2));
344 }
345
346 static inline isc_result_t
347 fromstruct_tkey(ARGS_FROMSTRUCT) {
348         dns_rdata_tkey_t *tkey = source;
349
350         REQUIRE(type == 249);
351         REQUIRE(source != NULL);
352         REQUIRE(tkey->common.rdtype == type);
353         REQUIRE(tkey->common.rdclass == rdclass);
354
355         UNUSED(type);
356         UNUSED(rdclass);
357
358         /*
359          * Algorithm Name.
360          */
361         RETERR(name_tobuffer(&tkey->algorithm, target));
362
363         /*
364          * Inception: 32 bits.
365          */
366         RETERR(uint32_tobuffer(tkey->inception, target));
367
368         /*
369          * Expire: 32 bits.
370          */
371         RETERR(uint32_tobuffer(tkey->expire, target));
372
373         /*
374          * Mode: 16 bits.
375          */
376         RETERR(uint16_tobuffer(tkey->mode, target));
377
378         /*
379          * Error: 16 bits.
380          */
381         RETERR(uint16_tobuffer(tkey->error, target));
382
383         /*
384          * Key size: 16 bits.
385          */
386         RETERR(uint16_tobuffer(tkey->keylen, target));
387
388         /*
389          * Key.
390          */
391         RETERR(mem_tobuffer(target, tkey->key, tkey->keylen));
392
393         /*
394          * Other size: 16 bits.
395          */
396         RETERR(uint16_tobuffer(tkey->otherlen, target));
397
398         /*
399          * Other data.
400          */
401         return (mem_tobuffer(target, tkey->other, tkey->otherlen));
402 }
403
404 static inline isc_result_t
405 tostruct_tkey(ARGS_TOSTRUCT) {
406         dns_rdata_tkey_t *tkey = target;
407         dns_name_t alg;
408         isc_region_t sr;
409
410         REQUIRE(rdata->type == 249);
411         REQUIRE(target != NULL);
412         REQUIRE(rdata->length != 0);
413
414         tkey->common.rdclass = rdata->rdclass;
415         tkey->common.rdtype = rdata->type;
416         ISC_LINK_INIT(&tkey->common, link);
417
418         dns_rdata_toregion(rdata, &sr);
419
420         /*
421          * Algorithm Name.
422          */
423         dns_name_init(&alg, NULL);
424         dns_name_fromregion(&alg, &sr);
425         dns_name_init(&tkey->algorithm, NULL);
426         RETERR(name_duporclone(&alg, mctx, &tkey->algorithm));
427         isc_region_consume(&sr, name_length(&tkey->algorithm));
428
429         /*
430          * Inception.
431          */
432         tkey->inception = uint32_fromregion(&sr);
433         isc_region_consume(&sr, 4);
434
435         /*
436          * Expire.
437          */
438         tkey->expire = uint32_fromregion(&sr);
439         isc_region_consume(&sr, 4);
440
441         /*
442          * Mode.
443          */
444         tkey->mode = uint16_fromregion(&sr);
445         isc_region_consume(&sr, 2);
446
447         /*
448          * Error.
449          */
450         tkey->error = uint16_fromregion(&sr);
451         isc_region_consume(&sr, 2);
452
453         /*
454          * Key size.
455          */
456         tkey->keylen = uint16_fromregion(&sr);
457         isc_region_consume(&sr, 2);
458
459         /*
460          * Key.
461          */
462         tkey->key = mem_maybedup(mctx, sr.base, tkey->keylen);
463         if (tkey->key == NULL)
464                 goto cleanup;
465         isc_region_consume(&sr, tkey->keylen);
466
467         /*
468          * Other size.
469          */
470         tkey->otherlen = uint16_fromregion(&sr);
471         isc_region_consume(&sr, 2);
472
473         /*
474          * Other.
475          */
476         tkey->other = mem_maybedup(mctx, sr.base, tkey->otherlen);
477         if (tkey->other == NULL)
478                 goto cleanup;
479
480         tkey->mctx = mctx;
481         return (ISC_R_SUCCESS);
482
483  cleanup:
484         if (mctx != NULL)
485                 dns_name_free(&tkey->algorithm, mctx);
486         if (mctx != NULL && tkey->key != NULL)
487                 isc_mem_free(mctx, tkey->key);
488         return (ISC_R_NOMEMORY);
489 }
490
491 static inline void
492 freestruct_tkey(ARGS_FREESTRUCT) {
493         dns_rdata_tkey_t *tkey = (dns_rdata_tkey_t *) source;
494
495         REQUIRE(source != NULL);
496
497         if (tkey->mctx == NULL)
498                 return;
499
500         dns_name_free(&tkey->algorithm, tkey->mctx);
501         if (tkey->key != NULL)
502                 isc_mem_free(tkey->mctx, tkey->key);
503         if (tkey->other != NULL)
504                 isc_mem_free(tkey->mctx, tkey->other);
505         tkey->mctx = NULL;
506 }
507
508 static inline isc_result_t
509 additionaldata_tkey(ARGS_ADDLDATA) {
510         UNUSED(rdata);
511         UNUSED(add);
512         UNUSED(arg);
513
514         REQUIRE(rdata->type == 249);
515
516         return (ISC_R_SUCCESS);
517 }
518
519 static inline isc_result_t
520 digest_tkey(ARGS_DIGEST) {
521         UNUSED(rdata);
522         UNUSED(digest);
523         UNUSED(arg);
524
525         REQUIRE(rdata->type == 249);
526
527         return (ISC_R_NOTIMPLEMENTED);
528 }
529
530 #endif  /* RDATA_GENERIC_TKEY_249_C */