1/* 2 * Copyright (C) 2004, 2007, 2009, 2011, 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: Thu Mar 16 17:35:30 PST 2000 by halley. 22 */ 23 24/* draft-ietf-dnsext-tkey-01.txt */ 25 26#ifndef RDATA_GENERIC_TKEY_249_C 27#define RDATA_GENERIC_TKEY_249_C 28 29#define RRTYPE_TKEY_ATTRIBUTES (DNS_RDATATYPEATTR_META) 30 31static inline isc_result_t 32fromtext_tkey(ARGS_FROMTEXT) { 33 isc_token_t token; 34 dns_rcode_t rcode; 35 dns_name_t name; 36 isc_buffer_t buffer; 37 long i; 38 char *e; 39 40 REQUIRE(type == 249); 41 42 UNUSED(type); 43 UNUSED(rdclass); 44 UNUSED(callbacks); 45 46 /* 47 * Algorithm. 48 */ 49 RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_string, 50 ISC_FALSE)); 51 dns_name_init(&name, NULL); 52 buffer_fromregion(&buffer, &token.value.as_region); 53 origin = (origin != NULL) ? origin : dns_rootname; 54 RETTOK(dns_name_fromtext(&name, &buffer, origin, options, target)); 55 56 57 /* 58 * Inception. 59 */ 60 RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_number, 61 ISC_FALSE)); 62 RETERR(uint32_tobuffer(token.value.as_ulong, target)); 63 64 /* 65 * Expiration. 66 */ 67 RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_number, 68 ISC_FALSE)); 69 RETERR(uint32_tobuffer(token.value.as_ulong, target)); 70 71 /* 72 * Mode. 73 */ 74 RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_number, 75 ISC_FALSE)); 76 if (token.value.as_ulong > 0xffffU) 77 RETTOK(ISC_R_RANGE); 78 RETERR(uint16_tobuffer(token.value.as_ulong, target)); 79 80 /* 81 * Error. 82 */ 83 RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_string, 84 ISC_FALSE)); 85 if (dns_tsigrcode_fromtext(&rcode, &token.value.as_textregion) 86 != ISC_R_SUCCESS) 87 { 88 i = strtol(DNS_AS_STR(token), &e, 10); 89 if (*e != 0) 90 RETTOK(DNS_R_UNKNOWN); 91 if (i < 0 || i > 0xffff) 92 RETTOK(ISC_R_RANGE); 93 rcode = (dns_rcode_t)i; 94 } 95 RETERR(uint16_tobuffer(rcode, target)); 96 97 /* 98 * Key Size. 99 */ 100 RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_number, 101 ISC_FALSE)); 102 if (token.value.as_ulong > 0xffffU) 103 RETTOK(ISC_R_RANGE); 104 RETERR(uint16_tobuffer(token.value.as_ulong, target)); 105 106 /* 107 * Key Data. 108 */ 109 RETERR(isc_base64_tobuffer(lexer, target, (int)token.value.as_ulong)); 110 111 /* 112 * Other Size. 113 */ 114 RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_number, 115 ISC_FALSE)); 116 if (token.value.as_ulong > 0xffffU) 117 RETTOK(ISC_R_RANGE); 118 RETERR(uint16_tobuffer(token.value.as_ulong, target)); 119 120 /* 121 * Other Data. 122 */ 123 return (isc_base64_tobuffer(lexer, target, (int)token.value.as_ulong)); 124} 125 126static inline isc_result_t 127totext_tkey(ARGS_TOTEXT) { 128 isc_region_t sr, dr; 129 char buf[sizeof("4294967295 ")]; 130 unsigned long n; 131 dns_name_t name; 132 dns_name_t prefix; 133 isc_boolean_t sub; 134 135 REQUIRE(rdata->type == 249); 136 REQUIRE(rdata->length != 0); 137 138 dns_rdata_toregion(rdata, &sr); 139 140 /* 141 * Algorithm. 142 */ 143 dns_name_init(&name, NULL); 144 dns_name_init(&prefix, NULL); 145 dns_name_fromregion(&name, &sr); 146 sub = name_prefix(&name, tctx->origin, &prefix); 147 RETERR(dns_name_totext(&prefix, sub, target)); 148 RETERR(str_totext(" ", target)); 149 isc_region_consume(&sr, name_length(&name)); 150 151 /* 152 * Inception. 153 */ 154 n = uint32_fromregion(&sr); 155 isc_region_consume(&sr, 4); 156 sprintf(buf, "%lu ", n); 157 RETERR(str_totext(buf, target)); 158 159 /* 160 * Expiration. 161 */ 162 n = uint32_fromregion(&sr); 163 isc_region_consume(&sr, 4); 164 sprintf(buf, "%lu ", n); 165 RETERR(str_totext(buf, target)); 166 167 /* 168 * Mode. 169 */ 170 n = uint16_fromregion(&sr); 171 isc_region_consume(&sr, 2); 172 sprintf(buf, "%lu ", n); 173 RETERR(str_totext(buf, target)); 174 175 /* 176 * Error. 177 */ 178 n = uint16_fromregion(&sr); 179 isc_region_consume(&sr, 2); 180 if (dns_tsigrcode_totext((dns_rcode_t)n, target) == ISC_R_SUCCESS) 181 RETERR(str_totext(" ", target)); 182 else { 183 sprintf(buf, "%lu ", n); 184 RETERR(str_totext(buf, target)); 185 } 186 187 /* 188 * Key Size. 189 */ 190 n = uint16_fromregion(&sr); 191 isc_region_consume(&sr, 2); 192 sprintf(buf, "%lu", n); 193 RETERR(str_totext(buf, target)); 194 195 /* 196 * Key Data. 197 */ 198 REQUIRE(n <= sr.length); 199 dr = sr; 200 dr.length = n; 201 if ((tctx->flags & DNS_STYLEFLAG_MULTILINE) != 0) 202 RETERR(str_totext(" (", target)); 203 RETERR(str_totext(tctx->linebreak, target)); 204 if (tctx->width == 0) /* No splitting */ 205 RETERR(isc_base64_totext(&dr, 60, "", target)); 206 else 207 RETERR(isc_base64_totext(&dr, tctx->width - 2, 208 tctx->linebreak, target)); 209 if ((tctx->flags & DNS_STYLEFLAG_MULTILINE) != 0) 210 RETERR(str_totext(" ) ", target)); 211 else 212 RETERR(str_totext(" ", target)); 213 isc_region_consume(&sr, n); 214 215 /* 216 * Other Size. 217 */ 218 n = uint16_fromregion(&sr); 219 isc_region_consume(&sr, 2); 220 sprintf(buf, "%lu", n); 221 RETERR(str_totext(buf, target)); 222 223 /* 224 * Other Data. 225 */ 226 REQUIRE(n <= sr.length); 227 if (n != 0U) { 228 dr = sr; 229 dr.length = n; 230 if ((tctx->flags & DNS_STYLEFLAG_MULTILINE) != 0) 231 RETERR(str_totext(" (", target)); 232 RETERR(str_totext(tctx->linebreak, target)); 233 if (tctx->width == 0) /* No splitting */ 234 RETERR(isc_base64_totext(&dr, 60, "", target)); 235 else 236 RETERR(isc_base64_totext(&dr, tctx->width - 2, 237 tctx->linebreak, target)); 238 if ((tctx->flags & DNS_STYLEFLAG_MULTILINE) != 0) 239 RETERR(str_totext(" )", target)); 240 } 241 return (ISC_R_SUCCESS); 242} 243 244static inline isc_result_t 245fromwire_tkey(ARGS_FROMWIRE) { 246 isc_region_t sr; 247 unsigned long n; 248 dns_name_t name; 249 250 REQUIRE(type == 249); 251 252 UNUSED(type); 253 UNUSED(rdclass); 254 255 dns_decompress_setmethods(dctx, DNS_COMPRESS_NONE); 256 257 /* 258 * Algorithm. 259 */ 260 dns_name_init(&name, NULL); 261 RETERR(dns_name_fromwire(&name, source, dctx, options, target)); 262 263 /* 264 * Inception: 4 265 * Expiration: 4 266 * Mode: 2 267 * Error: 2 268 */ 269 isc_buffer_activeregion(source, &sr); 270 if (sr.length < 12) 271 return (ISC_R_UNEXPECTEDEND); 272 RETERR(mem_tobuffer(target, sr.base, 12)); 273 isc_region_consume(&sr, 12); 274 isc_buffer_forward(source, 12); 275 276 /* 277 * Key Length + Key Data. 278 */ 279 if (sr.length < 2) 280 return (ISC_R_UNEXPECTEDEND); 281 n = uint16_fromregion(&sr); 282 if (sr.length < n + 2) 283 return (ISC_R_UNEXPECTEDEND); 284 RETERR(mem_tobuffer(target, sr.base, n + 2)); 285 isc_region_consume(&sr, n + 2); 286 isc_buffer_forward(source, n + 2); 287 288 /* 289 * Other Length + Other Data. 290 */ 291 if (sr.length < 2) 292 return (ISC_R_UNEXPECTEDEND); 293 n = uint16_fromregion(&sr); 294 if (sr.length < n + 2) 295 return (ISC_R_UNEXPECTEDEND); 296 isc_buffer_forward(source, n + 2); 297 return (mem_tobuffer(target, sr.base, n + 2)); 298} 299 300static inline isc_result_t 301towire_tkey(ARGS_TOWIRE) { 302 isc_region_t sr; 303 dns_name_t name; 304 dns_offsets_t offsets; 305 306 REQUIRE(rdata->type == 249); 307 REQUIRE(rdata->length != 0); 308 309 dns_compress_setmethods(cctx, DNS_COMPRESS_NONE); 310 /* 311 * Algorithm. 312 */ 313 dns_rdata_toregion(rdata, &sr); 314 dns_name_init(&name, offsets); 315 dns_name_fromregion(&name, &sr); 316 RETERR(dns_name_towire(&name, cctx, target)); 317 isc_region_consume(&sr, name_length(&name)); 318 319 return (mem_tobuffer(target, sr.base, sr.length)); 320} 321 322static inline int 323compare_tkey(ARGS_COMPARE) { 324 isc_region_t r1; 325 isc_region_t r2; 326 dns_name_t name1; 327 dns_name_t name2; 328 int order; 329 330 REQUIRE(rdata1->type == rdata2->type); 331 REQUIRE(rdata1->rdclass == rdata2->rdclass); 332 REQUIRE(rdata1->type == 249); 333 REQUIRE(rdata1->length != 0); 334 REQUIRE(rdata2->length != 0); 335 336 /* 337 * Algorithm. 338 */ 339 dns_rdata_toregion(rdata1, &r1); 340 dns_rdata_toregion(rdata2, &r2); 341 dns_name_init(&name1, NULL); 342 dns_name_init(&name2, NULL); 343 dns_name_fromregion(&name1, &r1); 344 dns_name_fromregion(&name2, &r2); 345 if ((order = dns_name_rdatacompare(&name1, &name2)) != 0) 346 return (order); 347 isc_region_consume(&r1, name_length(&name1)); 348 isc_region_consume(&r2, name_length(&name2)); 349 return (isc_region_compare(&r1, &r2)); 350} 351 352static inline isc_result_t 353fromstruct_tkey(ARGS_FROMSTRUCT) { 354 dns_rdata_tkey_t *tkey = source; 355 356 REQUIRE(type == 249); 357 REQUIRE(source != NULL); 358 REQUIRE(tkey->common.rdtype == type); 359 REQUIRE(tkey->common.rdclass == rdclass); 360 361 UNUSED(type); 362 UNUSED(rdclass); 363 364 /* 365 * Algorithm Name. 366 */ 367 RETERR(name_tobuffer(&tkey->algorithm, target)); 368 369 /* 370 * Inception: 32 bits. 371 */ 372 RETERR(uint32_tobuffer(tkey->inception, target)); 373 374 /* 375 * Expire: 32 bits. 376 */ 377 RETERR(uint32_tobuffer(tkey->expire, target)); 378 379 /* 380 * Mode: 16 bits. 381 */ 382 RETERR(uint16_tobuffer(tkey->mode, target)); 383 384 /* 385 * Error: 16 bits. 386 */ 387 RETERR(uint16_tobuffer(tkey->error, target)); 388 389 /* 390 * Key size: 16 bits. 391 */ 392 RETERR(uint16_tobuffer(tkey->keylen, target)); 393 394 /* 395 * Key. 396 */ 397 RETERR(mem_tobuffer(target, tkey->key, tkey->keylen)); 398 399 /* 400 * Other size: 16 bits. 401 */ 402 RETERR(uint16_tobuffer(tkey->otherlen, target)); 403 404 /* 405 * Other data. 406 */ 407 return (mem_tobuffer(target, tkey->other, tkey->otherlen)); 408} 409 410static inline isc_result_t 411tostruct_tkey(ARGS_TOSTRUCT) { 412 dns_rdata_tkey_t *tkey = target; 413 dns_name_t alg; 414 isc_region_t sr; 415 416 REQUIRE(rdata->type == 249); 417 REQUIRE(target != NULL); 418 REQUIRE(rdata->length != 0); 419 420 tkey->common.rdclass = rdata->rdclass; 421 tkey->common.rdtype = rdata->type; 422 ISC_LINK_INIT(&tkey->common, link); 423 424 dns_rdata_toregion(rdata, &sr); 425 426 /* 427 * Algorithm Name. 428 */ 429 dns_name_init(&alg, NULL); 430 dns_name_fromregion(&alg, &sr); 431 dns_name_init(&tkey->algorithm, NULL); 432 RETERR(name_duporclone(&alg, mctx, &tkey->algorithm)); 433 isc_region_consume(&sr, name_length(&tkey->algorithm)); 434 435 /* 436 * Inception. 437 */ 438 tkey->inception = uint32_fromregion(&sr); 439 isc_region_consume(&sr, 4); 440 441 /* 442 * Expire. 443 */ 444 tkey->expire = uint32_fromregion(&sr); 445 isc_region_consume(&sr, 4); 446 447 /* 448 * Mode. 449 */ 450 tkey->mode = uint16_fromregion(&sr); 451 isc_region_consume(&sr, 2); 452 453 /* 454 * Error. 455 */ 456 tkey->error = uint16_fromregion(&sr); 457 isc_region_consume(&sr, 2); 458 459 /* 460 * Key size. 461 */ 462 tkey->keylen = uint16_fromregion(&sr); 463 isc_region_consume(&sr, 2); 464 465 /* 466 * Key. 467 */ 468 tkey->key = mem_maybedup(mctx, sr.base, tkey->keylen); 469 if (tkey->key == NULL) 470 goto cleanup; 471 isc_region_consume(&sr, tkey->keylen); 472 473 /* 474 * Other size. 475 */ 476 tkey->otherlen = uint16_fromregion(&sr); 477 isc_region_consume(&sr, 2); 478 479 /* 480 * Other. 481 */ 482 tkey->other = mem_maybedup(mctx, sr.base, tkey->otherlen); 483 if (tkey->other == NULL) 484 goto cleanup; 485 486 tkey->mctx = mctx; 487 return (ISC_R_SUCCESS); 488 489 cleanup: 490 if (mctx != NULL) 491 dns_name_free(&tkey->algorithm, mctx); 492 if (mctx != NULL && tkey->key != NULL) 493 isc_mem_free(mctx, tkey->key); 494 return (ISC_R_NOMEMORY); 495} 496 497static inline void 498freestruct_tkey(ARGS_FREESTRUCT) { 499 dns_rdata_tkey_t *tkey = (dns_rdata_tkey_t *) source; 500 501 REQUIRE(source != NULL); 502 503 if (tkey->mctx == NULL) 504 return; 505 506 dns_name_free(&tkey->algorithm, tkey->mctx); 507 if (tkey->key != NULL) 508 isc_mem_free(tkey->mctx, tkey->key); 509 if (tkey->other != NULL) 510 isc_mem_free(tkey->mctx, tkey->other); 511 tkey->mctx = NULL; 512} 513 514static inline isc_result_t 515additionaldata_tkey(ARGS_ADDLDATA) { 516 UNUSED(rdata); 517 UNUSED(add); 518 UNUSED(arg); 519 520 REQUIRE(rdata->type == 249); 521 522 return (ISC_R_SUCCESS); 523} 524 525static inline isc_result_t 526digest_tkey(ARGS_DIGEST) { 527 UNUSED(rdata); 528 UNUSED(digest); 529 UNUSED(arg); 530 531 REQUIRE(rdata->type == 249); 532 533 return (ISC_R_NOTIMPLEMENTED); 534} 535 536static inline isc_boolean_t 537checkowner_tkey(ARGS_CHECKOWNER) { 538 539 REQUIRE(type == 249); 540 541 UNUSED(name); 542 UNUSED(type); 543 UNUSED(rdclass); 544 UNUSED(wildcard); 545 546 return (ISC_TRUE); 547} 548 549static inline isc_boolean_t 550checknames_tkey(ARGS_CHECKNAMES) { 551 552 REQUIRE(rdata->type == 249); 553 554 UNUSED(rdata); 555 UNUSED(owner); 556 UNUSED(bad); 557 558 return (ISC_TRUE); 559} 560 561static inline isc_result_t 562casecompare_tkey(ARGS_COMPARE) { 563 return (compare_tkey(rdata1, rdata2)); 564} 565#endif /* RDATA_GENERIC_TKEY_249_C */ 566