1/* 2 * Copyright (C) 2004, 2005, 2007, 2009, 2012 Internet Systems Consortium, Inc. ("ISC") 3 * Copyright (C) 1999-2003 Internet Software Consortium. 4 * 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. 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$ */ 19 20/* 21 * Reviewed: Wed Mar 15 16:47:10 PST 2000 by halley. 22 */ 23 24/* RFC2535 */ 25 26#ifndef RDATA_GENERIC_KEY_25_C 27#define RDATA_GENERIC_KEY_25_C 28 29#include <dst/dst.h> 30 31#define RRTYPE_KEY_ATTRIBUTES (0) 32 33static inline isc_result_t 34fromtext_key(ARGS_FROMTEXT) { 35 isc_token_t token; 36 dns_secalg_t alg; 37 dns_secproto_t proto; 38 dns_keyflags_t flags; 39 40 REQUIRE(type == 25); 41 42 UNUSED(type); 43 UNUSED(rdclass); 44 UNUSED(origin); 45 UNUSED(options); 46 UNUSED(callbacks); 47 48 /* flags */ 49 RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_string, 50 ISC_FALSE)); 51 RETTOK(dns_keyflags_fromtext(&flags, &token.value.as_textregion)); 52 RETERR(uint16_tobuffer(flags, target)); 53 54 /* protocol */ 55 RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_string, 56 ISC_FALSE)); 57 RETTOK(dns_secproto_fromtext(&proto, &token.value.as_textregion)); 58 RETERR(mem_tobuffer(target, &proto, 1)); 59 60 /* algorithm */ 61 RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_string, 62 ISC_FALSE)); 63 RETTOK(dns_secalg_fromtext(&alg, &token.value.as_textregion)); 64 RETERR(mem_tobuffer(target, &alg, 1)); 65 66 /* No Key? */ 67 if ((flags & 0xc000) == 0xc000) 68 return (ISC_R_SUCCESS); 69 70 return (isc_base64_tobuffer(lexer, target, -1)); 71} 72 73static inline isc_result_t 74totext_key(ARGS_TOTEXT) { 75 isc_region_t sr; 76 char buf[sizeof("64000")]; 77 unsigned int flags; 78 unsigned char algorithm; 79 char namebuf[DNS_NAME_FORMATSIZE]; 80 81 REQUIRE(rdata->type == 25); 82 REQUIRE(rdata->length != 0); 83 84 dns_rdata_toregion(rdata, &sr); 85 86 /* flags */ 87 flags = uint16_fromregion(&sr); 88 isc_region_consume(&sr, 2); 89 sprintf(buf, "%u", flags); 90 RETERR(str_totext(buf, target)); 91 RETERR(str_totext(" ", target)); 92 93 /* protocol */ 94 sprintf(buf, "%u", sr.base[0]); 95 isc_region_consume(&sr, 1); 96 RETERR(str_totext(buf, target)); 97 RETERR(str_totext(" ", target)); 98 99 /* algorithm */ 100 algorithm = sr.base[0]; 101 sprintf(buf, "%u", algorithm); 102 isc_region_consume(&sr, 1); 103 RETERR(str_totext(buf, target)); 104 105 /* No Key? */ 106 if ((flags & 0xc000) == 0xc000) 107 return (ISC_R_SUCCESS); 108 109 if ((tctx->flags & DNS_STYLEFLAG_COMMENT) != 0 && 110 algorithm == DNS_KEYALG_PRIVATEDNS) { 111 dns_name_t name; 112 dns_name_init(&name, NULL); 113 dns_name_fromregion(&name, &sr); 114 dns_name_format(&name, namebuf, sizeof(namebuf)); 115 } else 116 namebuf[0] = 0; 117 118 /* key */ 119 if ((tctx->flags & DNS_STYLEFLAG_MULTILINE) != 0) 120 RETERR(str_totext(" (", target)); 121 RETERR(str_totext(tctx->linebreak, target)); 122 RETERR(isc_base64_totext(&sr, tctx->width - 2, 123 tctx->linebreak, target)); 124 125 if ((tctx->flags & DNS_STYLEFLAG_COMMENT) != 0) 126 RETERR(str_totext(tctx->linebreak, target)); 127 else if ((tctx->flags & DNS_STYLEFLAG_MULTILINE) != 0) 128 RETERR(str_totext(" ", target)); 129 130 if ((tctx->flags & DNS_STYLEFLAG_MULTILINE) != 0) 131 RETERR(str_totext(")", target)); 132 133 if ((tctx->flags & DNS_STYLEFLAG_COMMENT) != 0) { 134 isc_region_t tmpr; 135 136 RETERR(str_totext(" ; key id = ", target)); 137 dns_rdata_toregion(rdata, &tmpr); 138 sprintf(buf, "%u", dst_region_computeid(&tmpr, algorithm)); 139 RETERR(str_totext(buf, target)); 140 if (algorithm == DNS_KEYALG_PRIVATEDNS) { 141 RETERR(str_totext(tctx->linebreak, target)); 142 RETERR(str_totext("; alg = ", target)); 143 RETERR(str_totext(namebuf, target)); 144 } 145 } 146 return (ISC_R_SUCCESS); 147} 148 149static inline isc_result_t 150fromwire_key(ARGS_FROMWIRE) { 151 unsigned char algorithm; 152 isc_region_t sr; 153 154 REQUIRE(type == 25); 155 156 UNUSED(type); 157 UNUSED(rdclass); 158 UNUSED(dctx); 159 UNUSED(options); 160 161 isc_buffer_activeregion(source, &sr); 162 if (sr.length < 4) 163 return (ISC_R_UNEXPECTEDEND); 164 165 algorithm = sr.base[3]; 166 RETERR(mem_tobuffer(target, sr.base, 4)); 167 isc_region_consume(&sr, 4); 168 isc_buffer_forward(source, 4); 169 170 if (algorithm == DNS_KEYALG_PRIVATEDNS) { 171 dns_name_t name; 172 dns_decompress_setmethods(dctx, DNS_COMPRESS_NONE); 173 dns_name_init(&name, NULL); 174 RETERR(dns_name_fromwire(&name, source, dctx, options, target)); 175 } 176 isc_buffer_activeregion(source, &sr); 177 isc_buffer_forward(source, sr.length); 178 return (mem_tobuffer(target, sr.base, sr.length)); 179} 180 181static inline isc_result_t 182towire_key(ARGS_TOWIRE) { 183 isc_region_t sr; 184 185 REQUIRE(rdata->type == 25); 186 REQUIRE(rdata->length != 0); 187 188 UNUSED(cctx); 189 190 dns_rdata_toregion(rdata, &sr); 191 return (mem_tobuffer(target, sr.base, sr.length)); 192} 193 194static inline int 195compare_key(ARGS_COMPARE) { 196 isc_region_t r1; 197 isc_region_t r2; 198 199 REQUIRE(rdata1->type == rdata2->type); 200 REQUIRE(rdata1->rdclass == rdata2->rdclass); 201 REQUIRE(rdata1->type == 25); 202 REQUIRE(rdata1->length != 0); 203 REQUIRE(rdata2->length != 0); 204 205 dns_rdata_toregion(rdata1, &r1); 206 dns_rdata_toregion(rdata2, &r2); 207 return (isc_region_compare(&r1, &r2)); 208} 209 210static inline isc_result_t 211fromstruct_key(ARGS_FROMSTRUCT) { 212 dns_rdata_key_t *key = source; 213 214 REQUIRE(type == 25); 215 REQUIRE(source != NULL); 216 REQUIRE(key->common.rdtype == type); 217 REQUIRE(key->common.rdclass == rdclass); 218 219 UNUSED(type); 220 UNUSED(rdclass); 221 222 /* Flags */ 223 RETERR(uint16_tobuffer(key->flags, target)); 224 225 /* Protocol */ 226 RETERR(uint8_tobuffer(key->protocol, target)); 227 228 /* Algorithm */ 229 RETERR(uint8_tobuffer(key->algorithm, target)); 230 231 /* Data */ 232 return (mem_tobuffer(target, key->data, key->datalen)); 233} 234 235static inline isc_result_t 236tostruct_key(ARGS_TOSTRUCT) { 237 dns_rdata_key_t *key = target; 238 isc_region_t sr; 239 240 REQUIRE(rdata->type == 25); 241 REQUIRE(target != NULL); 242 REQUIRE(rdata->length != 0); 243 244 key->common.rdclass = rdata->rdclass; 245 key->common.rdtype = rdata->type; 246 ISC_LINK_INIT(&key->common, link); 247 248 dns_rdata_toregion(rdata, &sr); 249 250 /* Flags */ 251 if (sr.length < 2) 252 return (ISC_R_UNEXPECTEDEND); 253 key->flags = uint16_fromregion(&sr); 254 isc_region_consume(&sr, 2); 255 256 /* Protocol */ 257 if (sr.length < 1) 258 return (ISC_R_UNEXPECTEDEND); 259 key->protocol = uint8_fromregion(&sr); 260 isc_region_consume(&sr, 1); 261 262 /* Algorithm */ 263 if (sr.length < 1) 264 return (ISC_R_UNEXPECTEDEND); 265 key->algorithm = uint8_fromregion(&sr); 266 isc_region_consume(&sr, 1); 267 268 /* Data */ 269 key->datalen = sr.length; 270 key->data = mem_maybedup(mctx, sr.base, key->datalen); 271 if (key->data == NULL) 272 return (ISC_R_NOMEMORY); 273 274 key->mctx = mctx; 275 return (ISC_R_SUCCESS); 276} 277 278static inline void 279freestruct_key(ARGS_FREESTRUCT) { 280 dns_rdata_key_t *key = (dns_rdata_key_t *) source; 281 282 REQUIRE(source != NULL); 283 REQUIRE(key->common.rdtype == 25); 284 285 if (key->mctx == NULL) 286 return; 287 288 if (key->data != NULL) 289 isc_mem_free(key->mctx, key->data); 290 key->mctx = NULL; 291} 292 293static inline isc_result_t 294additionaldata_key(ARGS_ADDLDATA) { 295 REQUIRE(rdata->type == 25); 296 297 UNUSED(rdata); 298 UNUSED(add); 299 UNUSED(arg); 300 301 return (ISC_R_SUCCESS); 302} 303 304static inline isc_result_t 305digest_key(ARGS_DIGEST) { 306 isc_region_t r; 307 308 REQUIRE(rdata->type == 25); 309 310 dns_rdata_toregion(rdata, &r); 311 312 return ((digest)(arg, &r)); 313} 314 315static inline isc_boolean_t 316checkowner_key(ARGS_CHECKOWNER) { 317 318 REQUIRE(type == 25); 319 320 UNUSED(name); 321 UNUSED(type); 322 UNUSED(rdclass); 323 UNUSED(wildcard); 324 325 return (ISC_TRUE); 326} 327 328static inline isc_boolean_t 329checknames_key(ARGS_CHECKNAMES) { 330 331 REQUIRE(rdata->type == 25); 332 333 UNUSED(rdata); 334 UNUSED(owner); 335 UNUSED(bad); 336 337 return (ISC_TRUE); 338} 339 340static inline int 341casecompare_key(ARGS_COMPARE) { 342 return (compare_key(rdata1, rdata2)); 343} 344 345#endif /* RDATA_GENERIC_KEY_25_C */ 346