2 * Copyright (C) 2004, 2005, 2007, 2009, 2012, 2013 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 fromtext_key(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_key(ARGS_TOTEXT) {
85 char buf[sizeof("64000")];
87 unsigned char algorithm;
88 char namebuf[DNS_NAME_FORMATSIZE];
90 REQUIRE(rdata->type == 25);
91 REQUIRE(rdata->length != 0);
93 dns_rdata_toregion(rdata, &sr);
96 flags = uint16_fromregion(&sr);
97 isc_region_consume(&sr, 2);
98 sprintf(buf, "%u", flags);
99 RETERR(str_totext(buf, target));
100 RETERR(str_totext(" ", target));
103 sprintf(buf, "%u", sr.base[0]);
104 isc_region_consume(&sr, 1);
105 RETERR(str_totext(buf, target));
106 RETERR(str_totext(" ", target));
109 algorithm = sr.base[0];
110 sprintf(buf, "%u", algorithm);
111 isc_region_consume(&sr, 1);
112 RETERR(str_totext(buf, target));
115 if ((flags & 0xc000) == 0xc000)
116 return (ISC_R_SUCCESS);
118 if ((tctx->flags & DNS_STYLEFLAG_COMMENT) != 0 &&
119 algorithm == DNS_KEYALG_PRIVATEDNS) {
121 dns_name_init(&name, NULL);
122 dns_name_fromregion(&name, &sr);
123 dns_name_format(&name, namebuf, sizeof(namebuf));
128 if ((tctx->flags & DNS_STYLEFLAG_MULTILINE) != 0)
129 RETERR(str_totext(" (", target));
130 RETERR(str_totext(tctx->linebreak, target));
131 RETERR(isc_base64_totext(&sr, tctx->width - 2,
132 tctx->linebreak, target));
134 if ((tctx->flags & DNS_STYLEFLAG_COMMENT) != 0)
135 RETERR(str_totext(tctx->linebreak, target));
136 else if ((tctx->flags & DNS_STYLEFLAG_MULTILINE) != 0)
137 RETERR(str_totext(" ", target));
139 if ((tctx->flags & DNS_STYLEFLAG_MULTILINE) != 0)
140 RETERR(str_totext(")", target));
142 if ((tctx->flags & DNS_STYLEFLAG_COMMENT) != 0) {
145 RETERR(str_totext(" ; key id = ", target));
146 dns_rdata_toregion(rdata, &tmpr);
147 sprintf(buf, "%u", dst_region_computeid(&tmpr, algorithm));
148 RETERR(str_totext(buf, target));
149 if (algorithm == DNS_KEYALG_PRIVATEDNS) {
150 RETERR(str_totext(tctx->linebreak, target));
151 RETERR(str_totext("; alg = ", target));
152 RETERR(str_totext(namebuf, target));
155 return (ISC_R_SUCCESS);
158 static inline isc_result_t
159 fromwire_key(ARGS_FROMWIRE) {
160 unsigned char algorithm;
170 isc_buffer_activeregion(source, &sr);
172 return (ISC_R_UNEXPECTEDEND);
174 algorithm = sr.base[3];
175 RETERR(mem_tobuffer(target, sr.base, 4));
176 isc_region_consume(&sr, 4);
177 isc_buffer_forward(source, 4);
179 if (algorithm == DNS_KEYALG_PRIVATEDNS) {
181 dns_decompress_setmethods(dctx, DNS_COMPRESS_NONE);
182 dns_name_init(&name, NULL);
183 RETERR(dns_name_fromwire(&name, source, dctx, options, target));
187 * RSAMD5 computes key ID differently from other
188 * algorithms: we need to ensure there's enough data
189 * present for the computation
191 if (algorithm == DST_ALG_RSAMD5 && sr.length < 3)
192 return (ISC_R_UNEXPECTEDEND);
194 isc_buffer_activeregion(source, &sr);
195 isc_buffer_forward(source, sr.length);
196 return (mem_tobuffer(target, sr.base, sr.length));
199 static inline isc_result_t
200 towire_key(ARGS_TOWIRE) {
203 REQUIRE(rdata->type == 25);
204 REQUIRE(rdata->length != 0);
208 dns_rdata_toregion(rdata, &sr);
209 return (mem_tobuffer(target, sr.base, sr.length));
213 compare_key(ARGS_COMPARE) {
217 REQUIRE(rdata1->type == rdata2->type);
218 REQUIRE(rdata1->rdclass == rdata2->rdclass);
219 REQUIRE(rdata1->type == 25);
220 REQUIRE(rdata1->length != 0);
221 REQUIRE(rdata2->length != 0);
223 dns_rdata_toregion(rdata1, &r1);
224 dns_rdata_toregion(rdata2, &r2);
225 return (isc_region_compare(&r1, &r2));
228 static inline isc_result_t
229 fromstruct_key(ARGS_FROMSTRUCT) {
230 dns_rdata_key_t *key = source;
233 REQUIRE(source != NULL);
234 REQUIRE(key->common.rdtype == type);
235 REQUIRE(key->common.rdclass == rdclass);
241 RETERR(uint16_tobuffer(key->flags, target));
244 RETERR(uint8_tobuffer(key->protocol, target));
247 RETERR(uint8_tobuffer(key->algorithm, target));
250 return (mem_tobuffer(target, key->data, key->datalen));
253 static inline isc_result_t
254 tostruct_key(ARGS_TOSTRUCT) {
255 dns_rdata_key_t *key = target;
258 REQUIRE(rdata->type == 25);
259 REQUIRE(target != NULL);
260 REQUIRE(rdata->length != 0);
262 key->common.rdclass = rdata->rdclass;
263 key->common.rdtype = rdata->type;
264 ISC_LINK_INIT(&key->common, link);
266 dns_rdata_toregion(rdata, &sr);
270 return (ISC_R_UNEXPECTEDEND);
271 key->flags = uint16_fromregion(&sr);
272 isc_region_consume(&sr, 2);
276 return (ISC_R_UNEXPECTEDEND);
277 key->protocol = uint8_fromregion(&sr);
278 isc_region_consume(&sr, 1);
282 return (ISC_R_UNEXPECTEDEND);
283 key->algorithm = uint8_fromregion(&sr);
284 isc_region_consume(&sr, 1);
287 key->datalen = sr.length;
288 key->data = mem_maybedup(mctx, sr.base, key->datalen);
289 if (key->data == NULL)
290 return (ISC_R_NOMEMORY);
293 return (ISC_R_SUCCESS);
297 freestruct_key(ARGS_FREESTRUCT) {
298 dns_rdata_key_t *key = (dns_rdata_key_t *) source;
300 REQUIRE(source != NULL);
301 REQUIRE(key->common.rdtype == 25);
303 if (key->mctx == NULL)
306 if (key->data != NULL)
307 isc_mem_free(key->mctx, key->data);
311 static inline isc_result_t
312 additionaldata_key(ARGS_ADDLDATA) {
313 REQUIRE(rdata->type == 25);
319 return (ISC_R_SUCCESS);
322 static inline isc_result_t
323 digest_key(ARGS_DIGEST) {
326 REQUIRE(rdata->type == 25);
328 dns_rdata_toregion(rdata, &r);
330 return ((digest)(arg, &r));
333 static inline isc_boolean_t
334 checkowner_key(ARGS_CHECKOWNER) {
346 static inline isc_boolean_t
347 checknames_key(ARGS_CHECKNAMES) {
349 REQUIRE(rdata->type == 25);
359 casecompare_key(ARGS_COMPARE) {
360 return (compare_key(rdata1, rdata2));
363 #endif /* RDATA_GENERIC_KEY_25_C */