1249259Sdim/*	$NetBSD: keydata_65533.c,v 1.3.4.1 2012/06/05 21:15:11 bouyer Exp $	*/
2249259Sdim
3249259Sdim/*
4249259Sdim * Copyright (C) 2009, 2011, 2012  Internet Systems Consortium, Inc. ("ISC")
5249259Sdim *
6249259Sdim * Permission to use, copy, modify, and/or distribute this software for any
7249259Sdim * purpose with or without fee is hereby granted, provided that the above
8249259Sdim * copyright notice and this permission notice appear in all copies.
9249259Sdim *
10249259Sdim * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
11249259Sdim * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
12249259Sdim * AND FITNESS.  IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
13249259Sdim * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
14249259Sdim * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
15249259Sdim * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
16249259Sdim * PERFORMANCE OF THIS SOFTWARE.
17249259Sdim */
18249259Sdim
19249259Sdim/* Id */
20249259Sdim
21249259Sdim#ifndef GENERIC_KEYDATA_65533_C
22249259Sdim#define GENERIC_KEYDATA_65533_C 1
23249259Sdim
24249259Sdim#include <dst/dst.h>
25249259Sdim
26249259Sdim#define RRTYPE_KEYDATA_ATTRIBUTES (DNS_RDATATYPEATTR_DNSSEC)
27249259Sdim
28249259Sdimstatic inline isc_result_t
29249259Sdimfromtext_keydata(ARGS_FROMTEXT) {
30249259Sdim	isc_token_t token;
31249259Sdim	dns_secalg_t alg;
32249259Sdim	dns_secproto_t proto;
33249259Sdim	dns_keyflags_t flags;
34249259Sdim	isc_uint32_t refresh, addhd, removehd;
35249259Sdim
36249259Sdim	REQUIRE(type == 65533);
37249259Sdim
38249259Sdim	UNUSED(type);
39249259Sdim	UNUSED(rdclass);
40249259Sdim	UNUSED(origin);
41249259Sdim	UNUSED(options);
42249259Sdim	UNUSED(callbacks);
43249259Sdim
44249259Sdim	/* refresh timer */
45249259Sdim	RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_string,
46249259Sdim				      ISC_FALSE));
47249259Sdim	RETTOK(dns_time32_fromtext(DNS_AS_STR(token), &refresh));
48249259Sdim	RETERR(uint32_tobuffer(refresh, target));
49249259Sdim
50249259Sdim	/* add hold-down */
51249259Sdim	RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_string,
52249259Sdim				      ISC_FALSE));
53249259Sdim	RETTOK(dns_time32_fromtext(DNS_AS_STR(token), &addhd));
54249259Sdim	RETERR(uint32_tobuffer(addhd, target));
55249259Sdim
56249259Sdim	/* remove hold-down */
57249259Sdim	RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_string,
58249259Sdim				      ISC_FALSE));
59249259Sdim	RETTOK(dns_time32_fromtext(DNS_AS_STR(token), &removehd));
60249259Sdim	RETERR(uint32_tobuffer(removehd, target));
61249259Sdim
62249259Sdim	/* flags */
63249259Sdim	RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_string,
64249259Sdim				      ISC_FALSE));
65249259Sdim	RETTOK(dns_keyflags_fromtext(&flags, &token.value.as_textregion));
66249259Sdim	RETERR(uint16_tobuffer(flags, target));
67249259Sdim
68249259Sdim	/* protocol */
69249259Sdim	RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_string,
70249259Sdim				      ISC_FALSE));
71249259Sdim	RETTOK(dns_secproto_fromtext(&proto, &token.value.as_textregion));
72249259Sdim	RETERR(mem_tobuffer(target, &proto, 1));
73249259Sdim
74249259Sdim	/* algorithm */
75249259Sdim	RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_string,
76249259Sdim				      ISC_FALSE));
77249259Sdim	RETTOK(dns_secalg_fromtext(&alg, &token.value.as_textregion));
78249259Sdim	RETERR(mem_tobuffer(target, &alg, 1));
79249259Sdim
80249259Sdim	/* No Key? */
81249259Sdim	if ((flags & 0xc000) == 0xc000)
82249259Sdim		return (ISC_R_SUCCESS);
83249259Sdim
84249259Sdim	return (isc_base64_tobuffer(lexer, target, -1));
85249259Sdim}
86249259Sdim
87249259Sdimstatic inline isc_result_t
88249259Sdimtotext_keydata(ARGS_TOTEXT) {
89249259Sdim	isc_region_t sr;
90249259Sdim	char buf[sizeof("64000")];
91249259Sdim	unsigned int flags;
92249259Sdim	unsigned char algorithm;
93249259Sdim	unsigned long when;
94249259Sdim	char algbuf[DNS_NAME_FORMATSIZE];
95249259Sdim	const char *keyinfo;
96249259Sdim
97249259Sdim	REQUIRE(rdata->type == 65533);
98249259Sdim	REQUIRE(rdata->length != 0);
99249259Sdim
100249259Sdim	dns_rdata_toregion(rdata, &sr);
101249259Sdim
102249259Sdim	/* refresh timer */
103249259Sdim	when = uint32_fromregion(&sr);
104249259Sdim	isc_region_consume(&sr, 4);
105249259Sdim	RETERR(dns_time32_totext(when, target));
106249259Sdim	RETERR(str_totext(" ", target));
107249259Sdim
108249259Sdim	/* add hold-down */
109249259Sdim	when = uint32_fromregion(&sr);
110249259Sdim	isc_region_consume(&sr, 4);
111249259Sdim	RETERR(dns_time32_totext(when, target));
112249259Sdim	RETERR(str_totext(" ", target));
113249259Sdim
114249259Sdim	/* remove hold-down */
115249259Sdim	when = uint32_fromregion(&sr);
116249259Sdim	isc_region_consume(&sr, 4);
117249259Sdim	RETERR(dns_time32_totext(when, target));
118249259Sdim	RETERR(str_totext(" ", target));
119249259Sdim
120249259Sdim	/* flags */
121249259Sdim	flags = uint16_fromregion(&sr);
122249259Sdim	isc_region_consume(&sr, 2);
123249259Sdim	sprintf(buf, "%u", flags);
124249259Sdim	RETERR(str_totext(buf, target));
125249259Sdim	RETERR(str_totext(" ", target));
126249259Sdim	if ((flags & DNS_KEYFLAG_KSK) != 0) {
127249259Sdim		if (flags & DNS_KEYFLAG_REVOKE)
128249259Sdim			keyinfo = "revoked KSK";
129249259Sdim		else
130249259Sdim			keyinfo = "KSK";
131249259Sdim	} else
132249259Sdim		keyinfo = "ZSK";
133249259Sdim
134249259Sdim	/* protocol */
135249259Sdim	sprintf(buf, "%u", sr.base[0]);
136249259Sdim	isc_region_consume(&sr, 1);
137249259Sdim	RETERR(str_totext(buf, target));
138249259Sdim	RETERR(str_totext(" ", target));
139249259Sdim
140249259Sdim	/* algorithm */
141249259Sdim	algorithm = sr.base[0];
142249259Sdim	sprintf(buf, "%u", algorithm);
143249259Sdim	isc_region_consume(&sr, 1);
144249259Sdim	RETERR(str_totext(buf, target));
145249259Sdim
146249259Sdim	/* No Key? */
147249259Sdim	if ((flags & 0xc000) == 0xc000)
148249259Sdim		return (ISC_R_SUCCESS);
149249259Sdim
150249259Sdim	/* key */
151249259Sdim	if ((tctx->flags & DNS_STYLEFLAG_MULTILINE) != 0)
152249259Sdim		RETERR(str_totext(" (", target));
153249259Sdim	RETERR(str_totext(tctx->linebreak, target));
154249259Sdim	if (tctx->width == 0)   /* No splitting */
155249259Sdim		RETERR(isc_base64_totext(&sr, 60, "", target));
156249259Sdim	else
157249259Sdim		RETERR(isc_base64_totext(&sr, tctx->width - 2,
158249259Sdim					 tctx->linebreak, target));
159249259Sdim
160249259Sdim	if ((tctx->flags & DNS_STYLEFLAG_RRCOMMENT) != 0)
161249259Sdim		RETERR(str_totext(tctx->linebreak, target));
162249259Sdim	else if ((tctx->flags & DNS_STYLEFLAG_MULTILINE) != 0)
163249259Sdim		RETERR(str_totext(" ", target));
164249259Sdim
165249259Sdim	if ((tctx->flags & DNS_STYLEFLAG_MULTILINE) != 0)
166249259Sdim		RETERR(str_totext(")", target));
167249259Sdim
168249259Sdim	if ((tctx->flags & DNS_STYLEFLAG_RRCOMMENT) != 0) {
169249259Sdim		isc_region_t tmpr;
170249259Sdim
171249259Sdim		RETERR(str_totext(" ; ", target));
172249259Sdim		RETERR(str_totext(keyinfo, target));
173249259Sdim		dns_secalg_format((dns_secalg_t) algorithm, algbuf,
174249259Sdim				  sizeof(algbuf));
175249259Sdim		RETERR(str_totext("; alg = ", target));
176249259Sdim		RETERR(str_totext(algbuf, target));
177249259Sdim		RETERR(str_totext("; key id = ", target));
178249259Sdim		dns_rdata_toregion(rdata, &tmpr);
179249259Sdim		/* Skip over refresh, addhd, and removehd */
180249259Sdim		isc_region_consume(&tmpr, 12);
181249259Sdim		sprintf(buf, "%u", dst_region_computeid(&tmpr, algorithm));
182249259Sdim		RETERR(str_totext(buf, target));
183249259Sdim	}
184249259Sdim	return (ISC_R_SUCCESS);
185249259Sdim}
186249259Sdim
187249259Sdimstatic inline isc_result_t
188249259Sdimfromwire_keydata(ARGS_FROMWIRE) {
189249259Sdim	isc_region_t sr;
190249259Sdim
191249259Sdim	REQUIRE(type == 65533);
192249259Sdim
193249259Sdim	UNUSED(type);
194249259Sdim	UNUSED(rdclass);
195249259Sdim	UNUSED(dctx);
196249259Sdim	UNUSED(options);
197249259Sdim
198249259Sdim	isc_buffer_activeregion(source, &sr);
199249259Sdim	if (sr.length < 16)
200249259Sdim		return (ISC_R_UNEXPECTEDEND);
201249259Sdim
202249259Sdim	isc_buffer_forward(source, sr.length);
203249259Sdim	return (mem_tobuffer(target, sr.base, sr.length));
204249259Sdim}
205249259Sdim
206249259Sdimstatic inline isc_result_t
207249259Sdimtowire_keydata(ARGS_TOWIRE) {
208249259Sdim	isc_region_t sr;
209249259Sdim
210249259Sdim	REQUIRE(rdata->type == 65533);
211249259Sdim	REQUIRE(rdata->length != 0);
212249259Sdim
213249259Sdim	UNUSED(cctx);
214249259Sdim
215249259Sdim	dns_rdata_toregion(rdata, &sr);
216249259Sdim	return (mem_tobuffer(target, sr.base, sr.length));
217249259Sdim}
218249259Sdim
219249259Sdimstatic inline int
220249259Sdimcompare_keydata(ARGS_COMPARE) {
221249259Sdim	isc_region_t r1;
222249259Sdim	isc_region_t r2;
223249259Sdim
224249259Sdim	REQUIRE(rdata1->type == rdata2->type);
225249259Sdim	REQUIRE(rdata1->rdclass == rdata2->rdclass);
226249259Sdim	REQUIRE(rdata1->type == 65533);
227249259Sdim	REQUIRE(rdata1->length != 0);
228249259Sdim	REQUIRE(rdata2->length != 0);
229249259Sdim
230249259Sdim	dns_rdata_toregion(rdata1, &r1);
231249259Sdim	dns_rdata_toregion(rdata2, &r2);
232249259Sdim	return (isc_region_compare(&r1, &r2));
233249259Sdim}
234249259Sdim
235249259Sdimstatic inline isc_result_t
236249259Sdimfromstruct_keydata(ARGS_FROMSTRUCT) {
237249259Sdim	dns_rdata_keydata_t *keydata = source;
238249259Sdim
239249259Sdim	REQUIRE(type == 65533);
240249259Sdim	REQUIRE(source != NULL);
241249259Sdim	REQUIRE(keydata->common.rdtype == type);
242249259Sdim	REQUIRE(keydata->common.rdclass == rdclass);
243249259Sdim
244249259Sdim	UNUSED(type);
245249259Sdim	UNUSED(rdclass);
246249259Sdim
247249259Sdim	/* Refresh timer */
248249259Sdim	RETERR(uint32_tobuffer(keydata->refresh, target));
249249259Sdim
250249259Sdim	/* Add hold-down */
251249259Sdim	RETERR(uint32_tobuffer(keydata->addhd, target));
252249259Sdim
253249259Sdim	/* Remove hold-down */
254249259Sdim	RETERR(uint32_tobuffer(keydata->removehd, target));
255249259Sdim
256249259Sdim	/* Flags */
257249259Sdim	RETERR(uint16_tobuffer(keydata->flags, target));
258249259Sdim
259249259Sdim	/* Protocol */
260249259Sdim	RETERR(uint8_tobuffer(keydata->protocol, target));
261249259Sdim
262249259Sdim	/* Algorithm */
263249259Sdim	RETERR(uint8_tobuffer(keydata->algorithm, target));
264249259Sdim
265249259Sdim	/* Data */
266249259Sdim	return (mem_tobuffer(target, keydata->data, keydata->datalen));
267249259Sdim}
268249259Sdim
269249259Sdimstatic inline isc_result_t
270249259Sdimtostruct_keydata(ARGS_TOSTRUCT) {
271249259Sdim	dns_rdata_keydata_t *keydata = target;
272249259Sdim	isc_region_t sr;
273249259Sdim
274249259Sdim	REQUIRE(rdata->type == 65533);
275249259Sdim	REQUIRE(target != NULL);
276249259Sdim	REQUIRE(rdata->length != 0);
277249259Sdim
278249259Sdim	keydata->common.rdclass = rdata->rdclass;
279249259Sdim	keydata->common.rdtype = rdata->type;
280249259Sdim	ISC_LINK_INIT(&keydata->common, link);
281249259Sdim
282249259Sdim	dns_rdata_toregion(rdata, &sr);
283249259Sdim
284249259Sdim	/* Refresh timer */
285249259Sdim	if (sr.length < 4)
286249259Sdim		return (ISC_R_UNEXPECTEDEND);
287249259Sdim	keydata->refresh = uint32_fromregion(&sr);
288249259Sdim	isc_region_consume(&sr, 4);
289249259Sdim
290249259Sdim	/* Add hold-down */
291249259Sdim	if (sr.length < 4)
292249259Sdim		return (ISC_R_UNEXPECTEDEND);
293249259Sdim	keydata->addhd = uint32_fromregion(&sr);
294249259Sdim	isc_region_consume(&sr, 4);
295249259Sdim
296249259Sdim	/* Remove hold-down */
297249259Sdim	if (sr.length < 4)
298249259Sdim		return (ISC_R_UNEXPECTEDEND);
299249259Sdim	keydata->removehd = uint32_fromregion(&sr);
300249259Sdim	isc_region_consume(&sr, 4);
301249259Sdim
302249259Sdim	/* Flags */
303249259Sdim	if (sr.length < 2)
304249259Sdim		return (ISC_R_UNEXPECTEDEND);
305249259Sdim	keydata->flags = uint16_fromregion(&sr);
306249259Sdim	isc_region_consume(&sr, 2);
307249259Sdim
308249259Sdim	/* Protocol */
309249259Sdim	if (sr.length < 1)
310249259Sdim		return (ISC_R_UNEXPECTEDEND);
311249259Sdim	keydata->protocol = uint8_fromregion(&sr);
312249259Sdim	isc_region_consume(&sr, 1);
313249259Sdim
314249259Sdim	/* Algorithm */
315249259Sdim	if (sr.length < 1)
316249259Sdim		return (ISC_R_UNEXPECTEDEND);
317249259Sdim	keydata->algorithm = uint8_fromregion(&sr);
318249259Sdim	isc_region_consume(&sr, 1);
319249259Sdim
320249259Sdim	/* Data */
321249259Sdim	keydata->datalen = sr.length;
322249259Sdim	keydata->data = mem_maybedup(mctx, sr.base, keydata->datalen);
323249259Sdim	if (keydata->data == NULL)
324249259Sdim		return (ISC_R_NOMEMORY);
325249259Sdim
326249259Sdim	keydata->mctx = mctx;
327249259Sdim	return (ISC_R_SUCCESS);
328249259Sdim}
329249259Sdim
330249259Sdimstatic inline void
331249259Sdimfreestruct_keydata(ARGS_FREESTRUCT) {
332249259Sdim	dns_rdata_keydata_t *keydata = (dns_rdata_keydata_t *) source;
333249259Sdim
334249259Sdim	REQUIRE(source != NULL);
335249259Sdim	REQUIRE(keydata->common.rdtype == 65533);
336249259Sdim
337251662Sdim	if (keydata->mctx == NULL)
338251662Sdim		return;
339251662Sdim
340251662Sdim	if (keydata->data != NULL)
341251662Sdim		isc_mem_free(keydata->mctx, keydata->data);
342251662Sdim	keydata->mctx = NULL;
343251662Sdim}
344251662Sdim
345251662Sdimstatic inline isc_result_t
346251662Sdimadditionaldata_keydata(ARGS_ADDLDATA) {
347251662Sdim	REQUIRE(rdata->type == 65533);
348251662Sdim
349251662Sdim	UNUSED(rdata);
350251662Sdim	UNUSED(add);
351251662Sdim	UNUSED(arg);
352251662Sdim
353251662Sdim	return (ISC_R_SUCCESS);
354251662Sdim}
355251662Sdim
356251662Sdimstatic inline isc_result_t
357251662Sdimdigest_keydata(ARGS_DIGEST) {
358251662Sdim	isc_region_t r;
359251662Sdim
360251662Sdim	REQUIRE(rdata->type == 65533);
361251662Sdim
362251662Sdim	dns_rdata_toregion(rdata, &r);
363251662Sdim
364251662Sdim	return ((digest)(arg, &r));
365251662Sdim}
366251662Sdim
367251662Sdimstatic inline isc_boolean_t
368251662Sdimcheckowner_keydata(ARGS_CHECKOWNER) {
369251662Sdim
370251662Sdim	REQUIRE(type == 65533);
371249259Sdim
372249259Sdim	UNUSED(name);
373249259Sdim	UNUSED(type);
374251662Sdim	UNUSED(rdclass);
375249259Sdim	UNUSED(wildcard);
376249259Sdim
377249259Sdim	return (ISC_TRUE);
378249259Sdim}
379249259Sdim
380249259Sdimstatic inline isc_boolean_t
381249259Sdimchecknames_keydata(ARGS_CHECKNAMES) {
382249259Sdim
383249259Sdim	REQUIRE(rdata->type == 65533);
384249259Sdim
385249259Sdim	UNUSED(rdata);
386249259Sdim	UNUSED(owner);
387249259Sdim	UNUSED(bad);
388249259Sdim
389249259Sdim	return (ISC_TRUE);
390249259Sdim}
391249259Sdim
392249259Sdimstatic inline int
393249259Sdimcasecompare_keydata(ARGS_COMPARE) {
394249259Sdim	return (compare_keydata(rdata1, rdata2));
395249259Sdim}
396249259Sdim
397249259Sdim#endif /* GENERIC_KEYDATA_65533_C */
398249259Sdim