1/* 2 * Copyright (C) 2004, 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: 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 RETERR(isc_base64_totext(&dr, tctx->width - 2, 205 tctx->linebreak, target)); 206 if ((tctx->flags & DNS_STYLEFLAG_MULTILINE) != 0) 207 RETERR(str_totext(" ) ", target)); 208 else 209 RETERR(str_totext(" ", target)); 210 isc_region_consume(&sr, n); 211 212 /* 213 * Other Size. 214 */ 215 n = uint16_fromregion(&sr); 216 isc_region_consume(&sr, 2); 217 sprintf(buf, "%lu", n); 218 RETERR(str_totext(buf, target)); 219 220 /* 221 * Other Data. 222 */ 223 REQUIRE(n <= sr.length); 224 if (n != 0U) { 225 dr = sr; 226 dr.length = n; 227 if ((tctx->flags & DNS_STYLEFLAG_MULTILINE) != 0) 228 RETERR(str_totext(" (", target)); 229 RETERR(str_totext(tctx->linebreak, target)); 230 RETERR(isc_base64_totext(&dr, tctx->width - 2, 231 tctx->linebreak, target)); 232 if ((tctx->flags & DNS_STYLEFLAG_MULTILINE) != 0) 233 RETERR(str_totext(" )", target)); 234 } 235 return (ISC_R_SUCCESS); 236} 237 238static inline isc_result_t 239fromwire_tkey(ARGS_FROMWIRE) { 240 isc_region_t sr; 241 unsigned long n; 242 dns_name_t name; 243 244 REQUIRE(type == 249); 245 246 UNUSED(type); 247 UNUSED(rdclass); 248 249 dns_decompress_setmethods(dctx, DNS_COMPRESS_NONE); 250 251 /* 252 * Algorithm. 253 */ 254 dns_name_init(&name, NULL); 255 RETERR(dns_name_fromwire(&name, source, dctx, options, target)); 256 257 /* 258 * Inception: 4 259 * Expiration: 4 260 * Mode: 2 261 * Error: 2 262 */ 263 isc_buffer_activeregion(source, &sr); 264 if (sr.length < 12) 265 return (ISC_R_UNEXPECTEDEND); 266 RETERR(mem_tobuffer(target, sr.base, 12)); 267 isc_region_consume(&sr, 12); 268 isc_buffer_forward(source, 12); 269 270 /* 271 * Key Length + Key Data. 272 */ 273 if (sr.length < 2) 274 return (ISC_R_UNEXPECTEDEND); 275 n = uint16_fromregion(&sr); 276 if (sr.length < n + 2) 277 return (ISC_R_UNEXPECTEDEND); 278 RETERR(mem_tobuffer(target, sr.base, n + 2)); 279 isc_region_consume(&sr, n + 2); 280 isc_buffer_forward(source, n + 2); 281 282 /* 283 * Other Length + Other Data. 284 */ 285 if (sr.length < 2) 286 return (ISC_R_UNEXPECTEDEND); 287 n = uint16_fromregion(&sr); 288 if (sr.length < n + 2) 289 return (ISC_R_UNEXPECTEDEND); 290 isc_buffer_forward(source, n + 2); 291 return (mem_tobuffer(target, sr.base, n + 2)); 292} 293 294static inline isc_result_t 295towire_tkey(ARGS_TOWIRE) { 296 isc_region_t sr; 297 dns_name_t name; 298 dns_offsets_t offsets; 299 300 REQUIRE(rdata->type == 249); 301 REQUIRE(rdata->length != 0); 302 303 dns_compress_setmethods(cctx, DNS_COMPRESS_NONE); 304 /* 305 * Algorithm. 306 */ 307 dns_rdata_toregion(rdata, &sr); 308 dns_name_init(&name, offsets); 309 dns_name_fromregion(&name, &sr); 310 RETERR(dns_name_towire(&name, cctx, target)); 311 isc_region_consume(&sr, name_length(&name)); 312 313 return (mem_tobuffer(target, sr.base, sr.length)); 314} 315 316static inline int 317compare_tkey(ARGS_COMPARE) { 318 isc_region_t r1; 319 isc_region_t r2; 320 dns_name_t name1; 321 dns_name_t name2; 322 int order; 323 324 REQUIRE(rdata1->type == rdata2->type); 325 REQUIRE(rdata1->rdclass == rdata2->rdclass); 326 REQUIRE(rdata1->type == 249); 327 REQUIRE(rdata1->length != 0); 328 REQUIRE(rdata2->length != 0); 329 330 /* 331 * Algorithm. 332 */ 333 dns_rdata_toregion(rdata1, &r1); 334 dns_rdata_toregion(rdata2, &r2); 335 dns_name_init(&name1, NULL); 336 dns_name_init(&name2, NULL); 337 dns_name_fromregion(&name1, &r1); 338 dns_name_fromregion(&name2, &r2); 339 if ((order = dns_name_rdatacompare(&name1, &name2)) != 0) 340 return (order); 341 isc_region_consume(&r1, name_length(&name1)); 342 isc_region_consume(&r2, name_length(&name2)); 343 return (isc_region_compare(&r1, &r2)); 344} 345 346static inline isc_result_t 347fromstruct_tkey(ARGS_FROMSTRUCT) { 348 dns_rdata_tkey_t *tkey = source; 349 350 REQUIRE(type == 249); 351 REQUIRE(source != NULL); 352 REQUIRE(tkey->common.rdtype == type); 353 REQUIRE(tkey->common.rdclass == rdclass); 354 355 UNUSED(type); 356 UNUSED(rdclass); 357 358 /* 359 * Algorithm Name. 360 */ 361 RETERR(name_tobuffer(&tkey->algorithm, target)); 362 363 /* 364 * Inception: 32 bits. 365 */ 366 RETERR(uint32_tobuffer(tkey->inception, target)); 367 368 /* 369 * Expire: 32 bits. 370 */ 371 RETERR(uint32_tobuffer(tkey->expire, target)); 372 373 /* 374 * Mode: 16 bits. 375 */ 376 RETERR(uint16_tobuffer(tkey->mode, target)); 377 378 /* 379 * Error: 16 bits. 380 */ 381 RETERR(uint16_tobuffer(tkey->error, target)); 382 383 /* 384 * Key size: 16 bits. 385 */ 386 RETERR(uint16_tobuffer(tkey->keylen, target)); 387 388 /* 389 * Key. 390 */ 391 RETERR(mem_tobuffer(target, tkey->key, tkey->keylen)); 392 393 /* 394 * Other size: 16 bits. 395 */ 396 RETERR(uint16_tobuffer(tkey->otherlen, target)); 397 398 /* 399 * Other data. 400 */ 401 return (mem_tobuffer(target, tkey->other, tkey->otherlen)); 402} 403 404static inline isc_result_t 405tostruct_tkey(ARGS_TOSTRUCT) { 406 dns_rdata_tkey_t *tkey = target; 407 dns_name_t alg; 408 isc_region_t sr; 409 410 REQUIRE(rdata->type == 249); 411 REQUIRE(target != NULL); 412 REQUIRE(rdata->length != 0); 413 414 tkey->common.rdclass = rdata->rdclass; 415 tkey->common.rdtype = rdata->type; 416 ISC_LINK_INIT(&tkey->common, link); 417 418 dns_rdata_toregion(rdata, &sr); 419 420 /* 421 * Algorithm Name. 422 */ 423 dns_name_init(&alg, NULL); 424 dns_name_fromregion(&alg, &sr); 425 dns_name_init(&tkey->algorithm, NULL); 426 RETERR(name_duporclone(&alg, mctx, &tkey->algorithm)); 427 isc_region_consume(&sr, name_length(&tkey->algorithm)); 428 429 /* 430 * Inception. 431 */ 432 tkey->inception = uint32_fromregion(&sr); 433 isc_region_consume(&sr, 4); 434 435 /* 436 * Expire. 437 */ 438 tkey->expire = uint32_fromregion(&sr); 439 isc_region_consume(&sr, 4); 440 441 /* 442 * Mode. 443 */ 444 tkey->mode = uint16_fromregion(&sr); 445 isc_region_consume(&sr, 2); 446 447 /* 448 * Error. 449 */ 450 tkey->error = uint16_fromregion(&sr); 451 isc_region_consume(&sr, 2); 452 453 /* 454 * Key size. 455 */ 456 tkey->keylen = uint16_fromregion(&sr); 457 isc_region_consume(&sr, 2); 458 459 /* 460 * Key. 461 */ 462 tkey->key = mem_maybedup(mctx, sr.base, tkey->keylen); 463 if (tkey->key == NULL) 464 goto cleanup; 465 isc_region_consume(&sr, tkey->keylen); 466 467 /* 468 * Other size. 469 */ 470 tkey->otherlen = uint16_fromregion(&sr); 471 isc_region_consume(&sr, 2); 472 473 /* 474 * Other. 475 */ 476 tkey->other = mem_maybedup(mctx, sr.base, tkey->otherlen); 477 if (tkey->other == NULL) 478 goto cleanup; 479 480 tkey->mctx = mctx; 481 return (ISC_R_SUCCESS); 482 483 cleanup: 484 if (mctx != NULL) 485 dns_name_free(&tkey->algorithm, mctx); 486 if (mctx != NULL && tkey->key != NULL) 487 isc_mem_free(mctx, tkey->key); 488 return (ISC_R_NOMEMORY); 489} 490 491static inline void 492freestruct_tkey(ARGS_FREESTRUCT) { 493 dns_rdata_tkey_t *tkey = (dns_rdata_tkey_t *) source; 494 495 REQUIRE(source != NULL); 496 497 if (tkey->mctx == NULL) 498 return; 499 500 dns_name_free(&tkey->algorithm, tkey->mctx); 501 if (tkey->key != NULL) 502 isc_mem_free(tkey->mctx, tkey->key); 503 if (tkey->other != NULL) 504 isc_mem_free(tkey->mctx, tkey->other); 505 tkey->mctx = NULL; 506} 507 508static inline isc_result_t 509additionaldata_tkey(ARGS_ADDLDATA) { 510 UNUSED(rdata); 511 UNUSED(add); 512 UNUSED(arg); 513 514 REQUIRE(rdata->type == 249); 515 516 return (ISC_R_SUCCESS); 517} 518 519static inline isc_result_t 520digest_tkey(ARGS_DIGEST) { 521 UNUSED(rdata); 522 UNUSED(digest); 523 UNUSED(arg); 524 525 REQUIRE(rdata->type == 249); 526 527 return (ISC_R_NOTIMPLEMENTED); 528} 529 530static inline isc_boolean_t 531checkowner_tkey(ARGS_CHECKOWNER) { 532 533 REQUIRE(type == 249); 534 535 UNUSED(name); 536 UNUSED(type); 537 UNUSED(rdclass); 538 UNUSED(wildcard); 539 540 return (ISC_TRUE); 541} 542 543static inline isc_boolean_t 544checknames_tkey(ARGS_CHECKNAMES) { 545 546 REQUIRE(rdata->type == 249); 547 548 UNUSED(rdata); 549 UNUSED(owner); 550 UNUSED(bad); 551 552 return (ISC_TRUE); 553} 554 555static inline isc_result_t 556casecompare_tkey(ARGS_COMPARE) { 557 return (compare_tkey(rdata1, rdata2)); 558} 559#endif /* RDATA_GENERIC_TKEY_249_C */ 560