2 * Copyright (C) 2004, 2005, 2007, 2009, 2011-2013, 2015 Internet Systems Consortium, Inc. ("ISC")
3 * Copyright (C) 1999-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_KEY_25_C
27 #define RDATA_GENERIC_KEY_25_C
31 #define RRTYPE_KEY_ATTRIBUTES (0)
33 static inline isc_result_t
34 generic_fromtext_key(ARGS_FROMTEXT) {
48 RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_string,
50 RETTOK(dns_keyflags_fromtext(&flags, &token.value.as_textregion));
51 RETERR(uint16_tobuffer(flags, target));
54 RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_string,
56 RETTOK(dns_secproto_fromtext(&proto, &token.value.as_textregion));
57 RETERR(mem_tobuffer(target, &proto, 1));
60 RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_string,
62 RETTOK(dns_secalg_fromtext(&alg, &token.value.as_textregion));
63 RETERR(mem_tobuffer(target, &alg, 1));
66 if ((flags & 0xc000) == 0xc000)
67 return (ISC_R_SUCCESS);
69 result = isc_base64_tobuffer(lexer, target, -1);
70 if (result != ISC_R_SUCCESS)
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);
77 return (ISC_R_SUCCESS);
80 static inline isc_result_t
81 generic_totext_key(ARGS_TOTEXT) {
83 char buf[sizeof("[key id = 64000]")];
85 unsigned char algorithm;
86 char algbuf[DNS_NAME_FORMATSIZE];
90 REQUIRE(rdata->length != 0);
92 dns_rdata_toregion(rdata, &sr);
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";
110 sprintf(buf, "%u", sr.base[0]);
111 isc_region_consume(&sr, 1);
112 RETERR(str_totext(buf, target));
113 RETERR(str_totext(" ", target));
116 algorithm = sr.base[0];
117 sprintf(buf, "%u", algorithm);
118 isc_region_consume(&sr, 1);
119 RETERR(str_totext(buf, target));
122 if ((flags & 0xc000) == 0xc000)
123 return (ISC_R_SUCCESS);
125 if ((tctx->flags & DNS_STYLEFLAG_RRCOMMENT) != 0 &&
126 algorithm == DNS_KEYALG_PRIVATEDNS) {
128 dns_name_init(&name, NULL);
129 dns_name_fromregion(&name, &sr);
130 dns_name_format(&name, algbuf, sizeof(algbuf));
132 dns_secalg_format((dns_secalg_t) algorithm, algbuf,
137 if ((tctx->flags & DNS_STYLEFLAG_MULTILINE) != 0)
138 RETERR(str_totext(" (", target));
139 RETERR(str_totext(tctx->linebreak, target));
141 if (tctx->width == 0) /* No splitting */
142 RETERR(isc_base64_totext(&sr, 60, "", 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) {
157 if (rdata->type == dns_rdatatype_dnskey ||
158 rdata->type == dns_rdatatype_cdnskey) {
159 RETERR(str_totext(" ; ", target));
160 RETERR(str_totext(keyinfo, target));
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));
169 return (ISC_R_SUCCESS);
172 static inline isc_result_t
173 generic_fromwire_key(ARGS_FROMWIRE) {
174 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 fromtext_key(ARGS_FROMTEXT) {
214 REQUIRE(type == dns_rdatatype_key);
216 return (generic_fromtext_key(rdclass, type, lexer, origin,
217 options, target, callbacks));
220 static inline isc_result_t
221 totext_key(ARGS_TOTEXT) {
223 REQUIRE(rdata != NULL);
224 REQUIRE(rdata->type == dns_rdatatype_key);
226 return (generic_totext_key(rdata, tctx, target));
229 static inline isc_result_t
230 fromwire_key(ARGS_FROMWIRE) {
232 REQUIRE(type == dns_rdatatype_key);
234 return (generic_fromwire_key(rdclass, type, source, dctx,
238 static inline isc_result_t
239 towire_key(ARGS_TOWIRE) {
242 REQUIRE(rdata != NULL);
243 REQUIRE(rdata->type == dns_rdatatype_key);
244 REQUIRE(rdata->length != 0);
248 dns_rdata_toregion(rdata, &sr);
249 return (mem_tobuffer(target, sr.base, sr.length));
253 compare_key(ARGS_COMPARE) {
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);
265 dns_rdata_toregion(rdata1, &r1);
266 dns_rdata_toregion(rdata2, &r2);
267 return (isc_region_compare(&r1, &r2));
270 static inline isc_result_t
271 generic_fromstruct_key(ARGS_FROMSTRUCT) {
272 dns_rdata_key_t *key = source;
274 REQUIRE(key != NULL);
275 REQUIRE(key->common.rdtype == type);
276 REQUIRE(key->common.rdclass == rdclass);
282 RETERR(uint16_tobuffer(key->flags, target));
285 RETERR(uint8_tobuffer(key->protocol, target));
288 RETERR(uint8_tobuffer(key->algorithm, target));
291 return (mem_tobuffer(target, key->data, key->datalen));
294 static inline isc_result_t
295 generic_tostruct_key(ARGS_TOSTRUCT) {
296 dns_rdata_key_t *key = target;
299 REQUIRE(rdata != NULL);
300 REQUIRE(rdata->length != 0);
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));
307 dns_rdata_toregion(rdata, &sr);
311 return (ISC_R_UNEXPECTEDEND);
312 key->flags = uint16_fromregion(&sr);
313 isc_region_consume(&sr, 2);
317 return (ISC_R_UNEXPECTEDEND);
318 key->protocol = uint8_fromregion(&sr);
319 isc_region_consume(&sr, 1);
323 return (ISC_R_UNEXPECTEDEND);
324 key->algorithm = uint8_fromregion(&sr);
325 isc_region_consume(&sr, 1);
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);
334 return (ISC_R_SUCCESS);
338 generic_freestruct_key(ARGS_FREESTRUCT) {
339 dns_rdata_key_t *key = (dns_rdata_key_t *) source;
341 REQUIRE(key != NULL);
343 if (key->mctx == NULL)
346 if (key->data != NULL)
347 isc_mem_free(key->mctx, key->data);
351 static inline isc_result_t
352 fromstruct_key(ARGS_FROMSTRUCT) {
354 REQUIRE(type == dns_rdatatype_key);
356 return (generic_fromstruct_key(rdclass, type, source, target));
359 static inline isc_result_t
360 tostruct_key(ARGS_TOSTRUCT) {
361 dns_rdata_key_t *key = target;
363 REQUIRE(key != NULL);
364 REQUIRE(rdata != NULL);
365 REQUIRE(rdata->type == dns_rdatatype_key);
367 key->common.rdclass = rdata->rdclass;
368 key->common.rdtype = rdata->type;
369 ISC_LINK_INIT(&key->common, link);
371 return (generic_tostruct_key(rdata, target, mctx));
375 freestruct_key(ARGS_FREESTRUCT) {
376 dns_rdata_key_t *key = (dns_rdata_key_t *) source;
378 REQUIRE(key != NULL);
379 REQUIRE(key->common.rdtype == dns_rdatatype_key);
381 generic_freestruct_key(source);
384 static inline isc_result_t
385 additionaldata_key(ARGS_ADDLDATA) {
387 REQUIRE(rdata != NULL);
388 REQUIRE(rdata->type == dns_rdatatype_key);
394 return (ISC_R_SUCCESS);
397 static inline isc_result_t
398 digest_key(ARGS_DIGEST) {
401 REQUIRE(rdata != NULL);
402 REQUIRE(rdata->type == dns_rdatatype_key);
404 dns_rdata_toregion(rdata, &r);
406 return ((digest)(arg, &r));
409 static inline isc_boolean_t
410 checkowner_key(ARGS_CHECKOWNER) {
412 REQUIRE(type == dns_rdatatype_key);
422 static inline isc_boolean_t
423 checknames_key(ARGS_CHECKNAMES) {
425 REQUIRE(rdata != NULL);
426 REQUIRE(rdata->type == dns_rdatatype_key);
436 casecompare_key(ARGS_COMPARE) {
437 return (compare_key(rdata1, rdata2));
440 #endif /* RDATA_GENERIC_KEY_25_C */