1/* 2 * Copyright (C) 2009, 2012 Internet Systems Consortium, Inc. ("ISC") 3 * 4 * Permission to use, copy, modify, and/or distribute this software for any 5 * purpose with or without fee is hereby granted, provided that the above 6 * copyright notice and this permission notice appear in all copies. 7 * 8 * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH 9 * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY 10 * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, 11 * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM 12 * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE 13 * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 14 * PERFORMANCE OF THIS SOFTWARE. 15 */ 16 17/* $Id$ */ 18 19#ifndef GENERIC_KEYDATA_65533_C 20#define GENERIC_KEYDATA_65533_C 1 21 22#include <dst/dst.h> 23 24#define RRTYPE_KEYDATA_ATTRIBUTES (DNS_RDATATYPEATTR_DNSSEC) 25 26static inline isc_result_t 27fromtext_keydata(ARGS_FROMTEXT) { 28 isc_token_t token; 29 dns_secalg_t alg; 30 dns_secproto_t proto; 31 dns_keyflags_t flags; 32 isc_uint32_t refresh, addhd, removehd; 33 34 REQUIRE(type == 65533); 35 36 UNUSED(type); 37 UNUSED(rdclass); 38 UNUSED(origin); 39 UNUSED(options); 40 UNUSED(callbacks); 41 42 /* refresh timer */ 43 RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_string, 44 ISC_FALSE)); 45 RETTOK(dns_time32_fromtext(DNS_AS_STR(token), &refresh)); 46 RETERR(uint32_tobuffer(refresh, target)); 47 48 /* add hold-down */ 49 RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_string, 50 ISC_FALSE)); 51 RETTOK(dns_time32_fromtext(DNS_AS_STR(token), &addhd)); 52 RETERR(uint32_tobuffer(addhd, target)); 53 54 /* remove hold-down */ 55 RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_string, 56 ISC_FALSE)); 57 RETTOK(dns_time32_fromtext(DNS_AS_STR(token), &removehd)); 58 RETERR(uint32_tobuffer(removehd, target)); 59 60 /* flags */ 61 RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_string, 62 ISC_FALSE)); 63 RETTOK(dns_keyflags_fromtext(&flags, &token.value.as_textregion)); 64 RETERR(uint16_tobuffer(flags, target)); 65 66 /* protocol */ 67 RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_string, 68 ISC_FALSE)); 69 RETTOK(dns_secproto_fromtext(&proto, &token.value.as_textregion)); 70 RETERR(mem_tobuffer(target, &proto, 1)); 71 72 /* algorithm */ 73 RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_string, 74 ISC_FALSE)); 75 RETTOK(dns_secalg_fromtext(&alg, &token.value.as_textregion)); 76 RETERR(mem_tobuffer(target, &alg, 1)); 77 78 /* No Key? */ 79 if ((flags & 0xc000) == 0xc000) 80 return (ISC_R_SUCCESS); 81 82 return (isc_base64_tobuffer(lexer, target, -1)); 83} 84 85static inline isc_result_t 86totext_keydata(ARGS_TOTEXT) { 87 isc_region_t sr; 88 char buf[sizeof("64000")]; 89 unsigned int flags; 90 unsigned char algorithm; 91 unsigned long when; 92 93 REQUIRE(rdata->type == 65533); 94 REQUIRE(rdata->length != 0); 95 96 dns_rdata_toregion(rdata, &sr); 97 98 /* refresh timer */ 99 when = uint32_fromregion(&sr); 100 isc_region_consume(&sr, 4); 101 RETERR(dns_time32_totext(when, target)); 102 RETERR(str_totext(" ", target)); 103 104 /* add hold-down */ 105 when = uint32_fromregion(&sr); 106 isc_region_consume(&sr, 4); 107 RETERR(dns_time32_totext(when, target)); 108 RETERR(str_totext(" ", target)); 109 110 /* remove hold-down */ 111 when = uint32_fromregion(&sr); 112 isc_region_consume(&sr, 4); 113 RETERR(dns_time32_totext(when, target)); 114 RETERR(str_totext(" ", target)); 115 116 /* flags */ 117 flags = uint16_fromregion(&sr); 118 isc_region_consume(&sr, 2); 119 sprintf(buf, "%u", flags); 120 RETERR(str_totext(buf, target)); 121 RETERR(str_totext(" ", target)); 122 123 /* protocol */ 124 sprintf(buf, "%u", sr.base[0]); 125 isc_region_consume(&sr, 1); 126 RETERR(str_totext(buf, target)); 127 RETERR(str_totext(" ", target)); 128 129 /* algorithm */ 130 algorithm = sr.base[0]; 131 sprintf(buf, "%u", algorithm); 132 isc_region_consume(&sr, 1); 133 RETERR(str_totext(buf, target)); 134 135 /* No Key? */ 136 if ((flags & 0xc000) == 0xc000) 137 return (ISC_R_SUCCESS); 138 139 /* key */ 140 if ((tctx->flags & DNS_STYLEFLAG_MULTILINE) != 0) 141 RETERR(str_totext(" (", target)); 142 RETERR(str_totext(tctx->linebreak, target)); 143 RETERR(isc_base64_totext(&sr, tctx->width - 2, 144 tctx->linebreak, target)); 145 146 if ((tctx->flags & DNS_STYLEFLAG_COMMENT) != 0) 147 RETERR(str_totext(tctx->linebreak, target)); 148 else if ((tctx->flags & DNS_STYLEFLAG_MULTILINE) != 0) 149 RETERR(str_totext(" ", target)); 150 151 if ((tctx->flags & DNS_STYLEFLAG_MULTILINE) != 0) 152 RETERR(str_totext(")", target)); 153 154 if ((tctx->flags & DNS_STYLEFLAG_COMMENT) != 0) { 155 isc_region_t tmpr; 156 157 RETERR(str_totext(" ; key id = ", target)); 158 dns_rdata_toregion(rdata, &tmpr); 159 /* Skip over refresh, addhd, and removehd */ 160 isc_region_consume(&tmpr, 12); 161 sprintf(buf, "%u", dst_region_computeid(&tmpr, algorithm)); 162 RETERR(str_totext(buf, target)); 163 } 164 return (ISC_R_SUCCESS); 165} 166 167static inline isc_result_t 168fromwire_keydata(ARGS_FROMWIRE) { 169 isc_region_t sr; 170 171 REQUIRE(type == 65533); 172 173 UNUSED(type); 174 UNUSED(rdclass); 175 UNUSED(dctx); 176 UNUSED(options); 177 178 isc_buffer_activeregion(source, &sr); 179 if (sr.length < 4) 180 return (ISC_R_UNEXPECTEDEND); 181 182 isc_buffer_forward(source, sr.length); 183 return (mem_tobuffer(target, sr.base, sr.length)); 184} 185 186static inline isc_result_t 187towire_keydata(ARGS_TOWIRE) { 188 isc_region_t sr; 189 190 REQUIRE(rdata->type == 65533); 191 REQUIRE(rdata->length != 0); 192 193 UNUSED(cctx); 194 195 dns_rdata_toregion(rdata, &sr); 196 return (mem_tobuffer(target, sr.base, sr.length)); 197} 198 199static inline int 200compare_keydata(ARGS_COMPARE) { 201 isc_region_t r1; 202 isc_region_t r2; 203 204 REQUIRE(rdata1->type == rdata2->type); 205 REQUIRE(rdata1->rdclass == rdata2->rdclass); 206 REQUIRE(rdata1->type == 65533); 207 REQUIRE(rdata1->length != 0); 208 REQUIRE(rdata2->length != 0); 209 210 dns_rdata_toregion(rdata1, &r1); 211 dns_rdata_toregion(rdata2, &r2); 212 return (isc_region_compare(&r1, &r2)); 213} 214 215static inline isc_result_t 216fromstruct_keydata(ARGS_FROMSTRUCT) { 217 dns_rdata_keydata_t *keydata = source; 218 219 REQUIRE(type == 65533); 220 REQUIRE(source != NULL); 221 REQUIRE(keydata->common.rdtype == type); 222 REQUIRE(keydata->common.rdclass == rdclass); 223 224 UNUSED(type); 225 UNUSED(rdclass); 226 227 /* Refresh timer */ 228 RETERR(uint32_tobuffer(keydata->refresh, target)); 229 230 /* Add hold-down */ 231 RETERR(uint32_tobuffer(keydata->addhd, target)); 232 233 /* Remove hold-down */ 234 RETERR(uint32_tobuffer(keydata->removehd, target)); 235 236 /* Flags */ 237 RETERR(uint16_tobuffer(keydata->flags, target)); 238 239 /* Protocol */ 240 RETERR(uint8_tobuffer(keydata->protocol, target)); 241 242 /* Algorithm */ 243 RETERR(uint8_tobuffer(keydata->algorithm, target)); 244 245 /* Data */ 246 return (mem_tobuffer(target, keydata->data, keydata->datalen)); 247} 248 249static inline isc_result_t 250tostruct_keydata(ARGS_TOSTRUCT) { 251 dns_rdata_keydata_t *keydata = target; 252 isc_region_t sr; 253 254 REQUIRE(rdata->type == 65533); 255 REQUIRE(target != NULL); 256 REQUIRE(rdata->length != 0); 257 258 keydata->common.rdclass = rdata->rdclass; 259 keydata->common.rdtype = rdata->type; 260 ISC_LINK_INIT(&keydata->common, link); 261 262 dns_rdata_toregion(rdata, &sr); 263 264 /* Refresh timer */ 265 if (sr.length < 4) 266 return (ISC_R_UNEXPECTEDEND); 267 keydata->refresh = uint32_fromregion(&sr); 268 isc_region_consume(&sr, 4); 269 270 /* Add hold-down */ 271 if (sr.length < 4) 272 return (ISC_R_UNEXPECTEDEND); 273 keydata->addhd = uint32_fromregion(&sr); 274 isc_region_consume(&sr, 4); 275 276 /* Remove hold-down */ 277 if (sr.length < 4) 278 return (ISC_R_UNEXPECTEDEND); 279 keydata->removehd = uint32_fromregion(&sr); 280 isc_region_consume(&sr, 4); 281 282 /* Flags */ 283 if (sr.length < 2) 284 return (ISC_R_UNEXPECTEDEND); 285 keydata->flags = uint16_fromregion(&sr); 286 isc_region_consume(&sr, 2); 287 288 /* Protocol */ 289 if (sr.length < 1) 290 return (ISC_R_UNEXPECTEDEND); 291 keydata->protocol = uint8_fromregion(&sr); 292 isc_region_consume(&sr, 1); 293 294 /* Algorithm */ 295 if (sr.length < 1) 296 return (ISC_R_UNEXPECTEDEND); 297 keydata->algorithm = uint8_fromregion(&sr); 298 isc_region_consume(&sr, 1); 299 300 /* Data */ 301 keydata->datalen = sr.length; 302 keydata->data = mem_maybedup(mctx, sr.base, keydata->datalen); 303 if (keydata->data == NULL) 304 return (ISC_R_NOMEMORY); 305 306 keydata->mctx = mctx; 307 return (ISC_R_SUCCESS); 308} 309 310static inline void 311freestruct_keydata(ARGS_FREESTRUCT) { 312 dns_rdata_keydata_t *keydata = (dns_rdata_keydata_t *) source; 313 314 REQUIRE(source != NULL); 315 REQUIRE(keydata->common.rdtype == 65533); 316 317 if (keydata->mctx == NULL) 318 return; 319 320 if (keydata->data != NULL) 321 isc_mem_free(keydata->mctx, keydata->data); 322 keydata->mctx = NULL; 323} 324 325static inline isc_result_t 326additionaldata_keydata(ARGS_ADDLDATA) { 327 REQUIRE(rdata->type == 65533); 328 329 UNUSED(rdata); 330 UNUSED(add); 331 UNUSED(arg); 332 333 return (ISC_R_SUCCESS); 334} 335 336static inline isc_result_t 337digest_keydata(ARGS_DIGEST) { 338 isc_region_t r; 339 340 REQUIRE(rdata->type == 65533); 341 342 dns_rdata_toregion(rdata, &r); 343 344 return ((digest)(arg, &r)); 345} 346 347static inline isc_boolean_t 348checkowner_keydata(ARGS_CHECKOWNER) { 349 350 REQUIRE(type == 65533); 351 352 UNUSED(name); 353 UNUSED(type); 354 UNUSED(rdclass); 355 UNUSED(wildcard); 356 357 return (ISC_TRUE); 358} 359 360static inline isc_boolean_t 361checknames_keydata(ARGS_CHECKNAMES) { 362 363 REQUIRE(rdata->type == 65533); 364 365 UNUSED(rdata); 366 UNUSED(owner); 367 UNUSED(bad); 368 369 return (ISC_TRUE); 370} 371 372static inline int 373casecompare_keydata(ARGS_COMPARE) { 374 return (compare_keydata(rdata1, rdata2)); 375} 376 377#endif /* GENERIC_KEYDATA_65533_C */ 378