2 * Copyright (C) 2004, 2005, 2007, 2009, 2011-2013 Internet Systems Consortium, Inc. ("ISC")
3 * Copyright (C) 2003 Internet Software Consortium.
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.
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.
21 * Reviewed: Wed Mar 15 16:47:10 PST 2000 by halley.
26 #ifndef RDATA_GENERIC_DNSKEY_48_C
27 #define RDATA_GENERIC_DNSKEY_48_C
31 #define RRTYPE_DNSKEY_ATTRIBUTES (DNS_RDATATYPEATTR_DNSSEC)
33 static inline isc_result_t
34 fromtext_dnskey(ARGS_FROMTEXT) {
50 RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_string,
52 RETTOK(dns_keyflags_fromtext(&flags, &token.value.as_textregion));
53 RETERR(uint16_tobuffer(flags, target));
56 RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_string,
58 RETTOK(dns_secproto_fromtext(&proto, &token.value.as_textregion));
59 RETERR(mem_tobuffer(target, &proto, 1));
62 RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_string,
64 RETTOK(dns_secalg_fromtext(&alg, &token.value.as_textregion));
65 RETERR(mem_tobuffer(target, &alg, 1));
68 if ((flags & 0xc000) == 0xc000)
69 return (ISC_R_SUCCESS);
71 result = isc_base64_tobuffer(lexer, target, -1);
72 if (result != ISC_R_SUCCESS)
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);
79 return (ISC_R_SUCCESS);
82 static inline isc_result_t
83 totext_dnskey(ARGS_TOTEXT) {
85 char buf[sizeof("64000")];
87 unsigned char algorithm;
88 char algbuf[DNS_NAME_FORMATSIZE];
91 REQUIRE(rdata->type == 48);
92 REQUIRE(rdata->length != 0);
94 dns_rdata_toregion(rdata, &sr);
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";
111 sprintf(buf, "%u", sr.base[0]);
112 isc_region_consume(&sr, 1);
113 RETERR(str_totext(buf, target));
114 RETERR(str_totext(" ", target));
117 algorithm = sr.base[0];
118 sprintf(buf, "%u", algorithm);
119 isc_region_consume(&sr, 1);
120 RETERR(str_totext(buf, target));
123 if ((flags & 0xc000) == 0xc000)
124 return (ISC_R_SUCCESS);
126 if ((tctx->flags & DNS_STYLEFLAG_RRCOMMENT) != 0 &&
127 algorithm == DNS_KEYALG_PRIVATEDNS) {
129 dns_name_init(&name, NULL);
130 dns_name_fromregion(&name, &sr);
131 dns_name_format(&name, algbuf, sizeof(algbuf));
133 dns_secalg_format((dns_secalg_t) algorithm, algbuf,
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));
144 RETERR(isc_base64_totext(&sr, tctx->width - 2,
145 tctx->linebreak, target));
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));
152 if ((tctx->flags & DNS_STYLEFLAG_MULTILINE) != 0)
153 RETERR(str_totext(")", target));
155 if ((tctx->flags & DNS_STYLEFLAG_RRCOMMENT) != 0) {
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));
167 return (ISC_R_SUCCESS);
170 static inline isc_result_t
171 fromwire_dnskey(ARGS_FROMWIRE) {
172 unsigned char algorithm;
182 isc_buffer_activeregion(source, &sr);
184 return (ISC_R_UNEXPECTEDEND);
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);
191 if (algorithm == DNS_KEYALG_PRIVATEDNS) {
193 dns_decompress_setmethods(dctx, DNS_COMPRESS_NONE);
194 dns_name_init(&name, NULL);
195 RETERR(dns_name_fromwire(&name, source, dctx, options, target));
199 * RSAMD5 computes key ID differently from other
200 * algorithms: we need to ensure there's enough data
201 * present for the computation
203 if (algorithm == DST_ALG_RSAMD5 && sr.length < 3)
204 return (ISC_R_UNEXPECTEDEND);
206 isc_buffer_activeregion(source, &sr);
207 isc_buffer_forward(source, sr.length);
208 return (mem_tobuffer(target, sr.base, sr.length));
211 static inline isc_result_t
212 towire_dnskey(ARGS_TOWIRE) {
215 REQUIRE(rdata->type == 48);
216 REQUIRE(rdata->length != 0);
220 dns_rdata_toregion(rdata, &sr);
221 return (mem_tobuffer(target, sr.base, sr.length));
225 compare_dnskey(ARGS_COMPARE) {
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);
235 dns_rdata_toregion(rdata1, &r1);
236 dns_rdata_toregion(rdata2, &r2);
237 return (isc_region_compare(&r1, &r2));
240 static inline isc_result_t
241 fromstruct_dnskey(ARGS_FROMSTRUCT) {
242 dns_rdata_dnskey_t *dnskey = source;
245 REQUIRE(source != NULL);
246 REQUIRE(dnskey->common.rdtype == type);
247 REQUIRE(dnskey->common.rdclass == rdclass);
253 RETERR(uint16_tobuffer(dnskey->flags, target));
256 RETERR(uint8_tobuffer(dnskey->protocol, target));
259 RETERR(uint8_tobuffer(dnskey->algorithm, target));
262 return (mem_tobuffer(target, dnskey->data, dnskey->datalen));
265 static inline isc_result_t
266 tostruct_dnskey(ARGS_TOSTRUCT) {
267 dns_rdata_dnskey_t *dnskey = target;
270 REQUIRE(rdata->type == 48);
271 REQUIRE(target != NULL);
272 REQUIRE(rdata->length != 0);
274 dnskey->common.rdclass = rdata->rdclass;
275 dnskey->common.rdtype = rdata->type;
276 ISC_LINK_INIT(&dnskey->common, link);
278 dns_rdata_toregion(rdata, &sr);
282 return (ISC_R_UNEXPECTEDEND);
283 dnskey->flags = uint16_fromregion(&sr);
284 isc_region_consume(&sr, 2);
288 return (ISC_R_UNEXPECTEDEND);
289 dnskey->protocol = uint8_fromregion(&sr);
290 isc_region_consume(&sr, 1);
294 return (ISC_R_UNEXPECTEDEND);
295 dnskey->algorithm = uint8_fromregion(&sr);
296 isc_region_consume(&sr, 1);
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);
305 return (ISC_R_SUCCESS);
309 freestruct_dnskey(ARGS_FREESTRUCT) {
310 dns_rdata_dnskey_t *dnskey = (dns_rdata_dnskey_t *) source;
312 REQUIRE(source != NULL);
313 REQUIRE(dnskey->common.rdtype == 48);
315 if (dnskey->mctx == NULL)
318 if (dnskey->data != NULL)
319 isc_mem_free(dnskey->mctx, dnskey->data);
323 static inline isc_result_t
324 additionaldata_dnskey(ARGS_ADDLDATA) {
325 REQUIRE(rdata->type == 48);
331 return (ISC_R_SUCCESS);
334 static inline isc_result_t
335 digest_dnskey(ARGS_DIGEST) {
338 REQUIRE(rdata->type == 48);
340 dns_rdata_toregion(rdata, &r);
342 return ((digest)(arg, &r));
345 static inline isc_boolean_t
346 checkowner_dnskey(ARGS_CHECKOWNER) {
358 static inline isc_boolean_t
359 checknames_dnskey(ARGS_CHECKNAMES) {
361 REQUIRE(rdata->type == 48);
371 casecompare_dnskey(ARGS_COMPARE) {
374 * Treat ALG 253 (private DNS) subtype name case sensistively.
376 return (compare_dnskey(rdata1, rdata2));
379 #endif /* RDATA_GENERIC_DNSKEY_48_C */