1 /* 2 * special zone file structures and functions for better dnssec handling 3 */ 4 5 #include <ldns/config.h> 6 7 #include <ldns/ldns.h> 8 #include <ldns/internal.h> 9 10 ldns_dnssec_rrs * 11 ldns_dnssec_rrs_new(void) 12 { 13 ldns_dnssec_rrs *new_rrs; 14 new_rrs = LDNS_MALLOC(ldns_dnssec_rrs); 15 if(!new_rrs) return NULL; 16 new_rrs->rr = NULL; 17 new_rrs->next = NULL; 18 return new_rrs; 19 } 20 21 INLINE void 22 ldns_dnssec_rrs_free_internal(ldns_dnssec_rrs *rrs, int deep) 23 { 24 ldns_dnssec_rrs *next; 25 while (rrs) { 26 next = rrs->next; 27 if (deep) { 28 ldns_rr_free(rrs->rr); 29 } 30 LDNS_FREE(rrs); 31 rrs = next; 32 } 33 } 34 35 void 36 ldns_dnssec_rrs_free(ldns_dnssec_rrs *rrs) 37 { 38 ldns_dnssec_rrs_free_internal(rrs, 0); 39 } 40 41 void 42 ldns_dnssec_rrs_deep_free(ldns_dnssec_rrs *rrs) 43 { 44 ldns_dnssec_rrs_free_internal(rrs, 1); 45 } 46 47 ldns_status 48 ldns_dnssec_rrs_add_rr(ldns_dnssec_rrs *rrs, ldns_rr *rr) 49 { 50 int cmp; 51 ldns_dnssec_rrs *new_rrs; 52 if (!rrs || !rr) { 53 return LDNS_STATUS_ERR; 54 } 55 56 /* this could be done more efficiently; name and type should already 57 be equal */ 58 cmp = ldns_rr_compare(rrs->rr, rr); 59 if (cmp < 0) { 60 if (rrs->next) { 61 return ldns_dnssec_rrs_add_rr(rrs->next, rr); 62 } else { 63 new_rrs = ldns_dnssec_rrs_new(); 64 new_rrs->rr = rr; 65 rrs->next = new_rrs; 66 } 67 } else if (cmp > 0) { 68 /* put the current old rr in the new next, put the new 69 rr in the current container */ 70 new_rrs = ldns_dnssec_rrs_new(); 71 new_rrs->rr = rrs->rr; 72 new_rrs->next = rrs->next; 73 rrs->rr = rr; 74 rrs->next = new_rrs; 75 } 76 /* Silently ignore equal rr's */ 77 return LDNS_STATUS_OK; 78 } 79 80 void 81 ldns_dnssec_rrs_print_fmt(FILE *out, const ldns_output_format *fmt, 82 const ldns_dnssec_rrs *rrs) 83 { 84 if (!rrs) { 85 if ((fmt->flags & LDNS_COMMENT_LAYOUT)) 86 fprintf(out, "; <void>"); 87 } else { 88 if (rrs->rr) { 89 ldns_rr_print_fmt(out, fmt, rrs->rr); 90 } 91 if (rrs->next) { 92 ldns_dnssec_rrs_print_fmt(out, fmt, rrs->next); 93 } 94 } 95 } 96 97 void 98 ldns_dnssec_rrs_print(FILE *out, const ldns_dnssec_rrs *rrs) 99 { 100 ldns_dnssec_rrs_print_fmt(out, ldns_output_format_default, rrs); 101 } 102 103 104 ldns_dnssec_rrsets * 105 ldns_dnssec_rrsets_new(void) 106 { 107 ldns_dnssec_rrsets *new_rrsets; 108 new_rrsets = LDNS_MALLOC(ldns_dnssec_rrsets); 109 if(!new_rrsets) return NULL; 110 new_rrsets->rrs = NULL; 111 new_rrsets->type = 0; 112 new_rrsets->signatures = NULL; 113 new_rrsets->next = NULL; 114 return new_rrsets; 115 } 116 117 INLINE void 118 ldns_dnssec_rrsets_free_internal(ldns_dnssec_rrsets *rrsets, int deep) 119 { 120 if (rrsets) { 121 if (rrsets->rrs) { 122 ldns_dnssec_rrs_free_internal(rrsets->rrs, deep); 123 } 124 if (rrsets->next) { 125 ldns_dnssec_rrsets_free_internal(rrsets->next, deep); 126 } 127 if (rrsets->signatures) { 128 ldns_dnssec_rrs_free_internal(rrsets->signatures, deep); 129 } 130 LDNS_FREE(rrsets); 131 } 132 } 133 134 void 135 ldns_dnssec_rrsets_free(ldns_dnssec_rrsets *rrsets) 136 { 137 ldns_dnssec_rrsets_free_internal(rrsets, 0); 138 } 139 140 void 141 ldns_dnssec_rrsets_deep_free(ldns_dnssec_rrsets *rrsets) 142 { 143 ldns_dnssec_rrsets_free_internal(rrsets, 1); 144 } 145 146 ldns_rr_type 147 ldns_dnssec_rrsets_type(const ldns_dnssec_rrsets *rrsets) 148 { 149 if (rrsets) { 150 return rrsets->type; 151 } else { 152 return 0; 153 } 154 } 155 156 ldns_status 157 ldns_dnssec_rrsets_set_type(ldns_dnssec_rrsets *rrsets, 158 ldns_rr_type type) 159 { 160 if (rrsets) { 161 rrsets->type = type; 162 return LDNS_STATUS_OK; 163 } 164 return LDNS_STATUS_ERR; 165 } 166 167 static ldns_dnssec_rrsets * 168 ldns_dnssec_rrsets_new_frm_rr(ldns_rr *rr) 169 { 170 ldns_dnssec_rrsets *new_rrsets; 171 ldns_rr_type rr_type; 172 bool rrsig; 173 174 new_rrsets = ldns_dnssec_rrsets_new(); 175 rr_type = ldns_rr_get_type(rr); 176 if (rr_type == LDNS_RR_TYPE_RRSIG) { 177 rrsig = true; 178 rr_type = ldns_rdf2rr_type(ldns_rr_rrsig_typecovered(rr)); 179 } else { 180 rrsig = false; 181 } 182 if (!rrsig) { 183 new_rrsets->rrs = ldns_dnssec_rrs_new(); 184 new_rrsets->rrs->rr = rr; 185 } else { 186 new_rrsets->signatures = ldns_dnssec_rrs_new(); 187 new_rrsets->signatures->rr = rr; 188 } 189 new_rrsets->type = rr_type; 190 return new_rrsets; 191 } 192 193 ldns_status 194 ldns_dnssec_rrsets_add_rr(ldns_dnssec_rrsets *rrsets, ldns_rr *rr) 195 { 196 ldns_dnssec_rrsets *new_rrsets; 197 ldns_rr_type rr_type; 198 bool rrsig = false; 199 ldns_status result = LDNS_STATUS_OK; 200 201 if (!rrsets || !rr) { 202 return LDNS_STATUS_ERR; 203 } 204 205 rr_type = ldns_rr_get_type(rr); 206 207 if (rr_type == LDNS_RR_TYPE_RRSIG) { 208 rrsig = true; 209 rr_type = ldns_rdf2rr_type(ldns_rr_rrsig_typecovered(rr)); 210 } 211 212 if (!rrsets->rrs && rrsets->type == 0 && !rrsets->signatures) { 213 if (!rrsig) { 214 rrsets->rrs = ldns_dnssec_rrs_new(); 215 rrsets->rrs->rr = rr; 216 rrsets->type = rr_type; 217 } else { 218 rrsets->signatures = ldns_dnssec_rrs_new(); 219 rrsets->signatures->rr = rr; 220 rrsets->type = rr_type; 221 } 222 return LDNS_STATUS_OK; 223 } 224 225 if (rr_type > ldns_dnssec_rrsets_type(rrsets)) { 226 if (rrsets->next) { 227 result = ldns_dnssec_rrsets_add_rr(rrsets->next, rr); 228 } else { 229 new_rrsets = ldns_dnssec_rrsets_new_frm_rr(rr); 230 rrsets->next = new_rrsets; 231 } 232 } else if (rr_type < ldns_dnssec_rrsets_type(rrsets)) { 233 /* move the current one into the new next, 234 replace field of current with data from new rr */ 235 new_rrsets = ldns_dnssec_rrsets_new(); 236 new_rrsets->rrs = rrsets->rrs; 237 new_rrsets->type = rrsets->type; 238 new_rrsets->signatures = rrsets->signatures; 239 new_rrsets->next = rrsets->next; 240 if (!rrsig) { 241 rrsets->rrs = ldns_dnssec_rrs_new(); 242 rrsets->rrs->rr = rr; 243 rrsets->signatures = NULL; 244 } else { 245 rrsets->rrs = NULL; 246 rrsets->signatures = ldns_dnssec_rrs_new(); 247 rrsets->signatures->rr = rr; 248 } 249 rrsets->type = rr_type; 250 rrsets->next = new_rrsets; 251 } else { 252 /* equal, add to current rrsets */ 253 if (rrsig) { 254 if (rrsets->signatures) { 255 result = ldns_dnssec_rrs_add_rr(rrsets->signatures, rr); 256 } else { 257 rrsets->signatures = ldns_dnssec_rrs_new(); 258 rrsets->signatures->rr = rr; 259 } 260 } else { 261 if (rrsets->rrs) { 262 result = ldns_dnssec_rrs_add_rr(rrsets->rrs, rr); 263 } else { 264 rrsets->rrs = ldns_dnssec_rrs_new(); 265 rrsets->rrs->rr = rr; 266 } 267 } 268 } 269 270 return result; 271 } 272 273 static void 274 ldns_dnssec_rrsets_print_soa_fmt(FILE *out, const ldns_output_format *fmt, 275 const ldns_dnssec_rrsets *rrsets, 276 bool follow, 277 bool show_soa) 278 { 279 if (!rrsets) { 280 if ((fmt->flags & LDNS_COMMENT_LAYOUT)) 281 fprintf(out, "; <void>\n"); 282 } else { 283 if (rrsets->rrs && 284 (show_soa || 285 ldns_rr_get_type(rrsets->rrs->rr) != LDNS_RR_TYPE_SOA 286 ) 287 ) { 288 ldns_dnssec_rrs_print_fmt(out, fmt, rrsets->rrs); 289 if (rrsets->signatures) { 290 ldns_dnssec_rrs_print_fmt(out, fmt, 291 rrsets->signatures); 292 } 293 } 294 if (follow && rrsets->next) { 295 ldns_dnssec_rrsets_print_soa_fmt(out, fmt, 296 rrsets->next, follow, show_soa); 297 } 298 } 299 } 300 301 302 void 303 ldns_dnssec_rrsets_print_fmt(FILE *out, const ldns_output_format *fmt, 304 const ldns_dnssec_rrsets *rrsets, 305 bool follow) 306 { 307 ldns_dnssec_rrsets_print_soa_fmt(out, fmt, rrsets, follow, true); 308 } 309 310 void 311 ldns_dnssec_rrsets_print(FILE *out, const ldns_dnssec_rrsets *rrsets, bool follow) 312 { 313 ldns_dnssec_rrsets_print_fmt(out, ldns_output_format_default, 314 rrsets, follow); 315 } 316 317 ldns_dnssec_name * 318 ldns_dnssec_name_new(void) 319 { 320 ldns_dnssec_name *new_name; 321 322 new_name = LDNS_CALLOC(ldns_dnssec_name, 1); 323 if (!new_name) { 324 return NULL; 325 } 326 /* 327 * not needed anymore because CALLOC initializes everything to zero. 328 329 new_name->name = NULL; 330 new_name->rrsets = NULL; 331 new_name->name_alloced = false; 332 new_name->nsec = NULL; 333 new_name->nsec_signatures = NULL; 334 335 new_name->is_glue = false; 336 new_name->hashed_name = NULL; 337 338 */ 339 return new_name; 340 } 341 342 ldns_dnssec_name * 343 ldns_dnssec_name_new_frm_rr(ldns_rr *rr) 344 { 345 ldns_dnssec_name *new_name = ldns_dnssec_name_new(); 346 347 new_name->name = ldns_rr_owner(rr); 348 if(ldns_dnssec_name_add_rr(new_name, rr) != LDNS_STATUS_OK) { 349 ldns_dnssec_name_free(new_name); 350 return NULL; 351 } 352 353 return new_name; 354 } 355 356 INLINE void 357 ldns_dnssec_name_free_internal(ldns_dnssec_name *name, 358 int deep) 359 { 360 if (name) { 361 if (name->name_alloced) { 362 ldns_rdf_deep_free(name->name); 363 } 364 if (name->rrsets) { 365 ldns_dnssec_rrsets_free_internal(name->rrsets, deep); 366 } 367 if (name->nsec && deep) { 368 ldns_rr_free(name->nsec); 369 } 370 if (name->nsec_signatures) { 371 ldns_dnssec_rrs_free_internal(name->nsec_signatures, deep); 372 } 373 if (name->hashed_name) { 374 /* Hashed name is always allocated when signing, 375 * so always deep free 376 */ 377 ldns_rdf_deep_free(name->hashed_name); 378 } 379 LDNS_FREE(name); 380 } 381 } 382 383 void 384 ldns_dnssec_name_free(ldns_dnssec_name *name) 385 { 386 ldns_dnssec_name_free_internal(name, 0); 387 } 388 389 void 390 ldns_dnssec_name_deep_free(ldns_dnssec_name *name) 391 { 392 ldns_dnssec_name_free_internal(name, 1); 393 } 394 395 ldns_rdf * 396 ldns_dnssec_name_name(const ldns_dnssec_name *name) 397 { 398 if (name) { 399 return name->name; 400 } 401 return NULL; 402 } 403 404 bool 405 ldns_dnssec_name_is_glue(const ldns_dnssec_name *name) 406 { 407 if (name) { 408 return name->is_glue; 409 } 410 return false; 411 } 412 413 void 414 ldns_dnssec_name_set_name(ldns_dnssec_name *rrset, 415 ldns_rdf *dname) 416 { 417 if (rrset && dname) { 418 rrset->name = dname; 419 } 420 } 421 422 423 void 424 ldns_dnssec_name_set_nsec(ldns_dnssec_name *rrset, ldns_rr *nsec) 425 { 426 if (rrset && nsec) { 427 rrset->nsec = nsec; 428 } 429 } 430 431 int 432 ldns_dnssec_name_cmp(const void *a, const void *b) 433 { 434 ldns_dnssec_name *na = (ldns_dnssec_name *) a; 435 ldns_dnssec_name *nb = (ldns_dnssec_name *) b; 436 437 if (na && nb) { 438 return ldns_dname_compare(ldns_dnssec_name_name(na), 439 ldns_dnssec_name_name(nb)); 440 } else if (na) { 441 return 1; 442 } else if (nb) { 443 return -1; 444 } else { 445 return 0; 446 } 447 } 448 449 ldns_status 450 ldns_dnssec_name_add_rr(ldns_dnssec_name *name, 451 ldns_rr *rr) 452 { 453 ldns_status result = LDNS_STATUS_OK; 454 ldns_rr_type rr_type; 455 ldns_rr_type typecovered = 0; 456 457 /* special handling for NSEC3 and NSECX covering RRSIGS */ 458 459 if (!name || !rr) { 460 return LDNS_STATUS_ERR; 461 } 462 463 rr_type = ldns_rr_get_type(rr); 464 465 if (rr_type == LDNS_RR_TYPE_RRSIG) { 466 typecovered = ldns_rdf2rr_type(ldns_rr_rrsig_typecovered(rr)); 467 } 468 469 if (rr_type == LDNS_RR_TYPE_NSEC || 470 rr_type == LDNS_RR_TYPE_NSEC3) { 471 /* XX check if is already set (and error?) */ 472 name->nsec = rr; 473 } else if (typecovered == LDNS_RR_TYPE_NSEC || 474 typecovered == LDNS_RR_TYPE_NSEC3) { 475 if (name->nsec_signatures) { 476 result = ldns_dnssec_rrs_add_rr(name->nsec_signatures, rr); 477 } else { 478 name->nsec_signatures = ldns_dnssec_rrs_new(); 479 name->nsec_signatures->rr = rr; 480 } 481 } else { 482 /* it's a 'normal' RR, add it to the right rrset */ 483 if (name->rrsets) { 484 result = ldns_dnssec_rrsets_add_rr(name->rrsets, rr); 485 } else { 486 name->rrsets = ldns_dnssec_rrsets_new(); 487 result = ldns_dnssec_rrsets_add_rr(name->rrsets, rr); 488 } 489 } 490 return result; 491 } 492 493 ldns_dnssec_rrsets * 494 ldns_dnssec_name_find_rrset(const ldns_dnssec_name *name, 495 ldns_rr_type type) { 496 ldns_dnssec_rrsets *result; 497 498 result = name->rrsets; 499 while (result) { 500 if (result->type == type) { 501 return result; 502 } else { 503 result = result->next; 504 } 505 } 506 return NULL; 507 } 508 509 ldns_dnssec_rrsets * 510 ldns_dnssec_zone_find_rrset(const ldns_dnssec_zone *zone, 511 const ldns_rdf *dname, 512 ldns_rr_type type) 513 { 514 ldns_rbnode_t *node; 515 516 if (!zone || !dname || !zone->names) { 517 return NULL; 518 } 519 520 node = ldns_rbtree_search(zone->names, dname); 521 if (node) { 522 return ldns_dnssec_name_find_rrset((ldns_dnssec_name *)node->data, 523 type); 524 } else { 525 return NULL; 526 } 527 } 528 529 static void 530 ldns_dnssec_name_print_soa_fmt(FILE *out, const ldns_output_format *fmt, 531 const ldns_dnssec_name *name, 532 bool show_soa) 533 { 534 if (name) { 535 if(name->rrsets) { 536 ldns_dnssec_rrsets_print_soa_fmt(out, fmt, 537 name->rrsets, true, show_soa); 538 } else if ((fmt->flags & LDNS_COMMENT_LAYOUT)) { 539 fprintf(out, ";; Empty nonterminal: "); 540 ldns_rdf_print(out, name->name); 541 fprintf(out, "\n"); 542 } 543 if(name->nsec) { 544 ldns_rr_print_fmt(out, fmt, name->nsec); 545 } 546 if (name->nsec_signatures) { 547 ldns_dnssec_rrs_print_fmt(out, fmt, 548 name->nsec_signatures); 549 } 550 } else if ((fmt->flags & LDNS_COMMENT_LAYOUT)) { 551 fprintf(out, "; <void>\n"); 552 } 553 } 554 555 556 void 557 ldns_dnssec_name_print_fmt(FILE *out, const ldns_output_format *fmt, 558 const ldns_dnssec_name *name) 559 { 560 ldns_dnssec_name_print_soa_fmt(out, fmt, name, true); 561 } 562 563 void 564 ldns_dnssec_name_print(FILE *out, const ldns_dnssec_name *name) 565 { 566 ldns_dnssec_name_print_fmt(out, ldns_output_format_default, name); 567 } 568 569 570 ldns_dnssec_zone * 571 ldns_dnssec_zone_new(void) 572 { 573 ldns_dnssec_zone *zone = LDNS_MALLOC(ldns_dnssec_zone); 574 if(!zone) return NULL; 575 zone->soa = NULL; 576 zone->names = NULL; 577 zone->hashed_names = NULL; 578 zone->_nsec3params = NULL; 579 580 return zone; 581 } 582 583 static bool 584 rr_is_rrsig_covering(ldns_rr* rr, ldns_rr_type t) 585 { 586 return ldns_rr_get_type(rr) == LDNS_RR_TYPE_RRSIG 587 && ldns_rdf2rr_type(ldns_rr_rrsig_typecovered(rr)) == t; 588 } 589 590 /* When the zone is first read into an list and then inserted into an 591 * ldns_dnssec_zone (rbtree) the nodes of the rbtree are allocated close (next) 592 * to each other. Because ldns-verify-zone (the only program that uses this 593 * function) uses the rbtree mostly for sequential walking, this results 594 * in a speed increase (of 15% on linux) because we have less CPU-cache misses. 595 */ 596 #define FASTER_DNSSEC_ZONE_NEW_FRM_FP 1 /* Because of L2 cache efficiency */ 597 598 static ldns_status 599 ldns_dnssec_zone_add_empty_nonterminals_nsec3( 600 ldns_dnssec_zone *zone, ldns_rbtree_t *nsec3s); 601 602 static void 603 ldns_todo_nsec3_ents_node_free(ldns_rbnode_t *node, void *arg) { 604 (void) arg; 605 ldns_rdf_deep_free((ldns_rdf *)node->key); 606 LDNS_FREE(node); 607 } 608 609 ldns_status 610 ldns_dnssec_zone_new_frm_fp_l(ldns_dnssec_zone** z, FILE* fp, const ldns_rdf* origin, 611 uint32_t default_ttl, ldns_rr_class ATTR_UNUSED(c), int* line_nr) 612 { 613 ldns_rr* cur_rr; 614 size_t i; 615 616 ldns_rdf *my_origin = NULL; 617 ldns_rdf *my_prev = NULL; 618 619 ldns_dnssec_zone *newzone = ldns_dnssec_zone_new(); 620 /* NSEC3s may occur before the names they refer to. We must remember 621 them and add them to the name later on, after the name is read. 622 We track not yet matching NSEC3s*n the todo_nsec3s list */ 623 ldns_rr_list* todo_nsec3s = ldns_rr_list_new(); 624 /* when reading NSEC3s, there is a chance that we encounter nsecs 625 for empty nonterminals, whose nonterminals we cannot derive yet 626 because the needed information is to be read later. 627 628 nsec3_ents (where ent is e.n.t.; i.e. empty non terminal) will 629 hold the NSEC3s that still didn't have a matching name in the 630 zone tree, even after all names were read. They can only match 631 after the zone is equipped with all the empty non terminals. */ 632 ldns_rbtree_t todo_nsec3_ents; 633 ldns_rbnode_t *new_node; 634 ldns_rr_list* todo_nsec3_rrsigs = ldns_rr_list_new(); 635 636 ldns_status status; 637 638 #ifdef FASTER_DNSSEC_ZONE_NEW_FRM_FP 639 ldns_zone* zone = NULL; 640 #else 641 ldns_rr *prev_rr = NULL; 642 uint32_t my_ttl = default_ttl; 643 /* RFC 1035 Section 5.1, says 'Omitted class and TTL values are default 644 * to the last explicitly stated values.' 645 */ 646 bool ttl_from_TTL = false; 647 bool explicit_ttl = false; 648 #endif 649 650 ldns_rbtree_init(&todo_nsec3_ents, ldns_dname_compare_v); 651 652 #ifdef FASTER_DNSSEC_ZONE_NEW_FRM_FP 653 status = ldns_zone_new_frm_fp_l(&zone, fp, origin, default_ttl, c, line_nr); 654 if (status != LDNS_STATUS_OK) 655 goto error; 656 #endif 657 if (!newzone || !todo_nsec3s || !todo_nsec3_rrsigs ) { 658 status = LDNS_STATUS_MEM_ERR; 659 goto error; 660 } 661 if (origin) { 662 if (!(my_origin = ldns_rdf_clone(origin))) { 663 status = LDNS_STATUS_MEM_ERR; 664 goto error; 665 } 666 if (!(my_prev = ldns_rdf_clone(origin))) { 667 status = LDNS_STATUS_MEM_ERR; 668 goto error; 669 } 670 } 671 672 #ifdef FASTER_DNSSEC_ZONE_NEW_FRM_FP 673 if (ldns_zone_soa(zone)) { 674 status = ldns_dnssec_zone_add_rr(newzone, ldns_zone_soa(zone)); 675 if (status != LDNS_STATUS_OK) 676 goto error; 677 } 678 for (i = 0; i < ldns_rr_list_rr_count(ldns_zone_rrs(zone)); i++) { 679 cur_rr = ldns_rr_list_rr(ldns_zone_rrs(zone), i); 680 status = LDNS_STATUS_OK; 681 #else 682 while (!feof(fp)) { 683 /* If ttl came from $TTL line, then it should be the default. 684 * (RFC 2308 Section 4) 685 * Otherwise it "defaults to the last explicitly stated value" 686 * (RFC 1035 Section 5.1) 687 */ 688 if (ttl_from_TTL) 689 my_ttl = default_ttl; 690 status = ldns_rr_new_frm_fp_l(&cur_rr, fp, &my_ttl, &my_origin, 691 &my_prev, line_nr, &explicit_ttl); 692 #endif 693 switch (status) { 694 case LDNS_STATUS_OK: 695 #ifndef FASTER_DNSSEC_ZONE_NEW_FRM_FP 696 if (explicit_ttl) { 697 if (!ttl_from_TTL) { 698 /* No $TTL, so ttl "defaults to the 699 * last explicitly stated value" 700 * (RFC 1035 Section 5.1) 701 */ 702 my_ttl = ldns_rr_ttl(cur_rr); 703 } 704 /* When ttl is implicit, try to adhere to the rules as 705 * much as possible. (also for compatibility with bind) 706 * This was changed when fixing an issue with ZONEMD 707 * which hashes the TTL too. 708 */ 709 } else if (ldns_rr_get_type(cur_rr) == LDNS_RR_TYPE_SIG 710 || ldns_rr_get_type(cur_rr) == LDNS_RR_TYPE_RRSIG) { 711 if (ldns_rr_rd_count(cur_rr) >= 4 712 && ldns_rdf_get_type(ldns_rr_rdf(cur_rr, 3)) == LDNS_RDF_TYPE_INT32) 713 714 /* SIG without explicit ttl get ttl 715 * from the original_ttl field 716 * (RFC 2535 Section 7.2) 717 * 718 * Similarly for RRSIG, but stated less 719 * specifically in the spec. 720 * (RFC 4034 Section 3) 721 */ 722 ldns_rr_set_ttl(cur_rr, 723 ldns_rdf2native_int32( 724 ldns_rr_rdf(rr, 3))); 725 726 } else if (prev_rr 727 && ldns_rr_get_type(prev_rr) == ldns_rr_get_type(cur_rr) 728 && ldns_dname_compare( ldns_rr_owner(prev_rr) 729 , ldns_rr_owner(cur_rr)) == 0) 730 731 /* "TTLs of all RRs in an RRSet must be the same" 732 * (RFC 2881 Section 5.2) 733 */ 734 ldns_rr_set_ttl(cur_rr, ldns_rr_ttl(prev_rr)); 735 736 prev_rr = cur_rr; 737 #endif 738 status = ldns_dnssec_zone_add_rr(newzone, cur_rr); 739 if (status == 740 LDNS_STATUS_DNSSEC_NSEC3_ORIGINAL_NOT_FOUND) { 741 742 if (rr_is_rrsig_covering(cur_rr, 743 LDNS_RR_TYPE_NSEC3)){ 744 ldns_rr_list_push_rr(todo_nsec3_rrsigs, 745 cur_rr); 746 } else { 747 ldns_rr_list_push_rr(todo_nsec3s, 748 cur_rr); 749 } 750 status = LDNS_STATUS_OK; 751 752 } else if (status != LDNS_STATUS_OK) 753 goto error; 754 755 break; 756 757 case LDNS_STATUS_SYNTAX_TTL: /* the ttl was set*/ 758 #ifndef FASTER_DNSSEC_ZONE_NEW_FRM_FP 759 default_ttl = my_ttl; 760 ttl_from_TTL = true; 761 #endif 762 status = LDNS_STATUS_OK; 763 break; 764 765 766 case LDNS_STATUS_SYNTAX_EMPTY: /* empty line was seen */ 767 case LDNS_STATUS_SYNTAX_ORIGIN: /* the origin was set*/ 768 status = LDNS_STATUS_OK; 769 break; 770 771 case LDNS_STATUS_SYNTAX_INCLUDE:/* $include not implemented */ 772 status = LDNS_STATUS_SYNTAX_INCLUDE_ERR_NOTIMPL; 773 break; 774 775 default: 776 goto error; 777 } 778 } 779 780 for (i = 0; status == LDNS_STATUS_OK && 781 i < ldns_rr_list_rr_count(todo_nsec3s); i++) { 782 cur_rr = ldns_rr_list_rr(todo_nsec3s, i); 783 status = ldns_dnssec_zone_add_rr(newzone, cur_rr); 784 if (status == LDNS_STATUS_DNSSEC_NSEC3_ORIGINAL_NOT_FOUND) { 785 if (!(new_node = LDNS_MALLOC(ldns_rbnode_t))) { 786 status = LDNS_STATUS_MEM_ERR; 787 break; 788 } 789 new_node->key = ldns_dname_label(ldns_rr_owner(cur_rr), 0); 790 new_node->data = cur_rr; 791 if (!ldns_rbtree_insert(&todo_nsec3_ents, new_node)) { 792 LDNS_FREE(new_node); 793 status = LDNS_STATUS_MEM_ERR; 794 break; 795 } 796 status = LDNS_STATUS_OK; 797 } 798 } 799 if (todo_nsec3_ents.count > 0) 800 (void) ldns_dnssec_zone_add_empty_nonterminals_nsec3( 801 newzone, &todo_nsec3_ents); 802 for (i = 0; status == LDNS_STATUS_OK && 803 i < ldns_rr_list_rr_count(todo_nsec3_rrsigs); i++) { 804 cur_rr = ldns_rr_list_rr(todo_nsec3_rrsigs, i); 805 status = ldns_dnssec_zone_add_rr(newzone, cur_rr); 806 } 807 if (z) { 808 *z = newzone; 809 newzone = NULL; 810 } else { 811 ldns_dnssec_zone_free(newzone); 812 newzone = NULL; 813 } 814 815 error: 816 #ifdef FASTER_DNSSEC_ZONE_NEW_FRM_FP 817 if (zone) { 818 ldns_zone_free(zone); 819 } 820 #endif 821 ldns_rr_list_free(todo_nsec3_rrsigs); 822 ldns_traverse_postorder(&todo_nsec3_ents, 823 ldns_todo_nsec3_ents_node_free, NULL); 824 ldns_rr_list_free(todo_nsec3s); 825 826 if (my_origin) { 827 ldns_rdf_deep_free(my_origin); 828 } 829 if (my_prev) { 830 ldns_rdf_deep_free(my_prev); 831 } 832 if (newzone) { 833 ldns_dnssec_zone_free(newzone); 834 } 835 return status; 836 } 837 838 ldns_status 839 ldns_dnssec_zone_new_frm_fp(ldns_dnssec_zone** z, FILE* fp, const ldns_rdf* origin, 840 uint32_t ttl, ldns_rr_class ATTR_UNUSED(c)) 841 { 842 return ldns_dnssec_zone_new_frm_fp_l(z, fp, origin, ttl, c, NULL); 843 } 844 845 static void 846 ldns_dnssec_name_node_free(ldns_rbnode_t *node, void *arg) { 847 (void) arg; 848 ldns_dnssec_name_free((ldns_dnssec_name *)node->data); 849 LDNS_FREE(node); 850 } 851 852 static void 853 ldns_dnssec_name_node_deep_free(ldns_rbnode_t *node, void *arg) { 854 (void) arg; 855 ldns_dnssec_name_deep_free((ldns_dnssec_name *)node->data); 856 LDNS_FREE(node); 857 } 858 859 static void 860 ldns_hashed_names_node_free(ldns_rbnode_t *node, void *arg) { 861 (void) arg; 862 LDNS_FREE(node); 863 } 864 865 void 866 ldns_dnssec_zone_free(ldns_dnssec_zone *zone) 867 { 868 if (zone) { 869 if (zone->hashed_names) { 870 ldns_traverse_postorder(zone->hashed_names, 871 ldns_hashed_names_node_free, NULL); 872 LDNS_FREE(zone->hashed_names); 873 } 874 if (zone->names) { 875 /* destroy all name structures within the tree */ 876 ldns_traverse_postorder(zone->names, 877 ldns_dnssec_name_node_free, 878 NULL); 879 LDNS_FREE(zone->names); 880 } 881 LDNS_FREE(zone); 882 } 883 } 884 885 void 886 ldns_dnssec_zone_deep_free(ldns_dnssec_zone *zone) 887 { 888 if (zone) { 889 if (zone->hashed_names) { 890 ldns_traverse_postorder(zone->hashed_names, 891 ldns_hashed_names_node_free, NULL); 892 LDNS_FREE(zone->hashed_names); 893 } 894 if (zone->names) { 895 /* destroy all name structures within the tree */ 896 ldns_traverse_postorder(zone->names, 897 ldns_dnssec_name_node_deep_free, 898 NULL); 899 LDNS_FREE(zone->names); 900 } 901 LDNS_FREE(zone); 902 } 903 } 904 905 /* use for dname comparison in tree */ 906 int 907 ldns_dname_compare_v(const void *a, const void *b) { 908 return ldns_dname_compare((ldns_rdf *)a, (ldns_rdf *)b); 909 } 910 911 static void 912 ldns_dnssec_name_make_hashed_name(ldns_dnssec_zone *zone, 913 ldns_dnssec_name* name, ldns_rr* nsec3rr); 914 915 static void 916 ldns_dnssec_zone_hashed_names_from_nsec3( 917 ldns_dnssec_zone* zone, ldns_rr* nsec3rr) 918 { 919 ldns_rbnode_t* current_node; 920 ldns_dnssec_name* current_name; 921 922 assert(zone != NULL); 923 assert(nsec3rr != NULL); 924 925 if (zone->hashed_names) { 926 ldns_traverse_postorder(zone->hashed_names, 927 ldns_hashed_names_node_free, NULL); 928 LDNS_FREE(zone->hashed_names); 929 } 930 zone->_nsec3params = nsec3rr; 931 932 /* So this is a NSEC3 zone. 933 * Calculate hashes for all names already in the zone 934 */ 935 zone->hashed_names = ldns_rbtree_create(ldns_dname_compare_v); 936 if (zone->hashed_names == NULL) { 937 return; 938 } 939 for ( current_node = ldns_rbtree_first(zone->names) 940 ; current_node != LDNS_RBTREE_NULL 941 ; current_node = ldns_rbtree_next(current_node) 942 ) { 943 current_name = (ldns_dnssec_name *) current_node->data; 944 ldns_dnssec_name_make_hashed_name(zone, current_name, nsec3rr); 945 946 } 947 } 948 949 static void 950 ldns_dnssec_name_make_hashed_name(ldns_dnssec_zone *zone, 951 ldns_dnssec_name* name, ldns_rr* nsec3rr) 952 { 953 ldns_rbnode_t* new_node; 954 955 assert(name != NULL); 956 if (! zone->_nsec3params) { 957 if (! nsec3rr) { 958 return; 959 } 960 ldns_dnssec_zone_hashed_names_from_nsec3(zone, nsec3rr); 961 962 } else if (! nsec3rr) { 963 nsec3rr = zone->_nsec3params; 964 } 965 name->hashed_name = ldns_nsec3_hash_name_frm_nsec3(nsec3rr, name->name); 966 967 /* Also store in zone->hashed_names */ 968 if ((new_node = LDNS_MALLOC(ldns_rbnode_t))) { 969 970 new_node->key = name->hashed_name; 971 new_node->data = name; 972 973 if (ldns_rbtree_insert(zone->hashed_names, new_node) == NULL) { 974 975 LDNS_FREE(new_node); 976 } 977 } 978 } 979 980 981 static ldns_rbnode_t * 982 ldns_dnssec_zone_find_nsec3_original(ldns_dnssec_zone *zone, ldns_rr *rr) { 983 ldns_rdf *hashed_name; 984 ldns_rbnode_t *to_return; 985 986 if (ldns_rr_get_type(rr) == LDNS_RR_TYPE_NSEC3 && ! zone->_nsec3params){ 987 988 ldns_dnssec_zone_hashed_names_from_nsec3(zone, rr); 989 } 990 if (zone->hashed_names == NULL) { 991 return NULL; 992 } 993 hashed_name = ldns_dname_label(ldns_rr_owner(rr), 0); 994 if (hashed_name == NULL) { 995 return NULL; 996 } 997 to_return = ldns_rbtree_search(zone->hashed_names, hashed_name); 998 ldns_rdf_deep_free(hashed_name); 999 return to_return; 1000 } 1001 1002 ldns_status 1003 ldns_dnssec_zone_add_rr(ldns_dnssec_zone *zone, ldns_rr *rr) 1004 { 1005 ldns_status result = LDNS_STATUS_OK; 1006 ldns_dnssec_name *cur_name; 1007 ldns_rbnode_t *cur_node; 1008 ldns_rr_type type_covered = 0; 1009 1010 if (!zone || !rr) { 1011 return LDNS_STATUS_ERR; 1012 } 1013 1014 if (!zone->names) { 1015 zone->names = ldns_rbtree_create(ldns_dname_compare_v); 1016 if(!zone->names) return LDNS_STATUS_MEM_ERR; 1017 } 1018 1019 /* we need the original of the hashed name if this is 1020 an NSEC3, or an RRSIG that covers an NSEC3 */ 1021 if (ldns_rr_get_type(rr) == LDNS_RR_TYPE_RRSIG) { 1022 type_covered = ldns_rdf2rr_type(ldns_rr_rrsig_typecovered(rr)); 1023 } 1024 if (ldns_rr_get_type(rr) == LDNS_RR_TYPE_NSEC3 || 1025 type_covered == LDNS_RR_TYPE_NSEC3) { 1026 cur_node = ldns_dnssec_zone_find_nsec3_original(zone, rr); 1027 if (!cur_node) { 1028 return LDNS_STATUS_DNSSEC_NSEC3_ORIGINAL_NOT_FOUND; 1029 } 1030 } else { 1031 cur_node = ldns_rbtree_search(zone->names, ldns_rr_owner(rr)); 1032 } 1033 if (!cur_node) { 1034 /* add */ 1035 cur_name = ldns_dnssec_name_new_frm_rr(rr); 1036 if(!cur_name) return LDNS_STATUS_MEM_ERR; 1037 cur_node = LDNS_MALLOC(ldns_rbnode_t); 1038 if(!cur_node) { 1039 ldns_dnssec_name_free(cur_name); 1040 return LDNS_STATUS_MEM_ERR; 1041 } 1042 cur_node->key = ldns_rr_owner(rr); 1043 cur_node->data = cur_name; 1044 (void)ldns_rbtree_insert(zone->names, cur_node); 1045 ldns_dnssec_name_make_hashed_name(zone, cur_name, NULL); 1046 } else { 1047 cur_name = (ldns_dnssec_name *) cur_node->data; 1048 result = ldns_dnssec_name_add_rr(cur_name, rr); 1049 } 1050 if (ldns_rr_get_type(rr) == LDNS_RR_TYPE_SOA) { 1051 zone->soa = cur_name; 1052 } 1053 return result; 1054 } 1055 1056 void 1057 ldns_dnssec_zone_names_print_fmt(FILE *out, const ldns_output_format *fmt, 1058 const ldns_rbtree_t *tree, 1059 bool print_soa) 1060 { 1061 ldns_rbnode_t *node; 1062 ldns_dnssec_name *name; 1063 1064 node = ldns_rbtree_first(tree); 1065 while (node != LDNS_RBTREE_NULL) { 1066 name = (ldns_dnssec_name *) node->data; 1067 ldns_dnssec_name_print_soa_fmt(out, fmt, name, print_soa); 1068 if ((fmt->flags & LDNS_COMMENT_LAYOUT)) 1069 fprintf(out, ";\n"); 1070 node = ldns_rbtree_next(node); 1071 } 1072 } 1073 1074 void 1075 ldns_dnssec_zone_names_print(FILE *out, const ldns_rbtree_t *tree, bool print_soa) 1076 { 1077 ldns_dnssec_zone_names_print_fmt(out, ldns_output_format_default, 1078 tree, print_soa); 1079 } 1080 1081 void 1082 ldns_dnssec_zone_print_fmt(FILE *out, const ldns_output_format *fmt, 1083 const ldns_dnssec_zone *zone) 1084 { 1085 if (zone) { 1086 if (zone->soa) { 1087 if ((fmt->flags & LDNS_COMMENT_LAYOUT)) { 1088 fprintf(out, ";; Zone: "); 1089 ldns_rdf_print(out, ldns_dnssec_name_name( 1090 zone->soa)); 1091 fprintf(out, "\n;\n"); 1092 } 1093 ldns_dnssec_rrsets_print_fmt(out, fmt, 1094 ldns_dnssec_name_find_rrset( 1095 zone->soa, 1096 LDNS_RR_TYPE_SOA), 1097 false); 1098 if ((fmt->flags & LDNS_COMMENT_LAYOUT)) 1099 fprintf(out, ";\n"); 1100 } 1101 1102 if (zone->names) { 1103 ldns_dnssec_zone_names_print_fmt(out, fmt, 1104 zone->names, false); 1105 } 1106 } 1107 } 1108 1109 void 1110 ldns_dnssec_zone_print(FILE *out, const ldns_dnssec_zone *zone) 1111 { 1112 ldns_dnssec_zone_print_fmt(out, ldns_output_format_default, zone); 1113 } 1114 1115 static ldns_status 1116 ldns_dnssec_zone_add_empty_nonterminals_nsec3( 1117 ldns_dnssec_zone *zone, ldns_rbtree_t *nsec3s) 1118 { 1119 ldns_dnssec_name *new_name; 1120 ldns_rdf *cur_name; 1121 ldns_rdf *next_name; 1122 ldns_rbnode_t *cur_node, *next_node, *new_node; 1123 1124 /* for the detection */ 1125 uint16_t i, cur_label_count, next_label_count; 1126 uint16_t soa_label_count = 0; 1127 ldns_rdf *l1, *l2; 1128 int lpos; 1129 1130 if (!zone) { 1131 return LDNS_STATUS_ERR; 1132 } 1133 if (zone->soa && zone->soa->name) { 1134 soa_label_count = ldns_dname_label_count(zone->soa->name); 1135 } 1136 1137 cur_node = ldns_rbtree_first(zone->names); 1138 while (cur_node != LDNS_RBTREE_NULL) { 1139 next_node = ldns_rbtree_next(cur_node); 1140 1141 /* skip glue */ 1142 while (next_node != LDNS_RBTREE_NULL && 1143 next_node->data && 1144 ((ldns_dnssec_name *)next_node->data)->is_glue 1145 ) { 1146 next_node = ldns_rbtree_next(next_node); 1147 } 1148 1149 if (next_node == LDNS_RBTREE_NULL) { 1150 next_node = ldns_rbtree_first(zone->names); 1151 } 1152 if (! cur_node->data || ! next_node->data) { 1153 return LDNS_STATUS_ERR; 1154 } 1155 cur_name = ((ldns_dnssec_name *)cur_node->data)->name; 1156 next_name = ((ldns_dnssec_name *)next_node->data)->name; 1157 cur_label_count = ldns_dname_label_count(cur_name); 1158 next_label_count = ldns_dname_label_count(next_name); 1159 1160 /* Since the names are in canonical order, we can 1161 * recognize empty non-terminals by their labels; 1162 * every label after the first one on the next owner 1163 * name is a non-terminal if it either does not exist 1164 * in the current name or is different from the same 1165 * label in the current name (counting from the end) 1166 */ 1167 for (i = 1; i < next_label_count - soa_label_count; i++) { 1168 lpos = (int)cur_label_count - (int)next_label_count + (int)i; 1169 if (lpos >= 0) { 1170 l1 = ldns_dname_clone_from(cur_name, (uint8_t)lpos); 1171 } else { 1172 l1 = NULL; 1173 } 1174 l2 = ldns_dname_clone_from(next_name, i); 1175 1176 if (!l1 || ldns_dname_compare(l1, l2) != 0) { 1177 /* We have an empty nonterminal, add it to the 1178 * tree 1179 */ 1180 ldns_rbnode_t *node = NULL; 1181 ldns_rdf *ent_name; 1182 1183 if (!(ent_name = ldns_dname_clone_from( 1184 next_name, i))) { 1185 1186 ldns_rdf_deep_free(l1); 1187 ldns_rdf_deep_free(l2); 1188 return LDNS_STATUS_MEM_ERR; 1189 } 1190 1191 if (nsec3s && zone->_nsec3params) { 1192 ldns_rdf *ent_hashed_name; 1193 1194 if (!(ent_hashed_name = 1195 ldns_nsec3_hash_name_frm_nsec3( 1196 zone->_nsec3params, 1197 ent_name))) { 1198 ldns_rdf_deep_free(l1); 1199 ldns_rdf_deep_free(l2); 1200 ldns_rdf_deep_free(ent_name); 1201 return LDNS_STATUS_MEM_ERR; 1202 } 1203 node = ldns_rbtree_search(nsec3s, 1204 ent_hashed_name); 1205 ldns_rdf_deep_free(ent_hashed_name); 1206 if (!node) { 1207 ldns_rdf_deep_free(l1); 1208 ldns_rdf_deep_free(l2); 1209 ldns_rdf_deep_free(ent_name); 1210 continue; 1211 } 1212 } 1213 new_name = ldns_dnssec_name_new(); 1214 if (!new_name) { 1215 ldns_rdf_deep_free(l1); 1216 ldns_rdf_deep_free(l2); 1217 ldns_rdf_deep_free(ent_name); 1218 return LDNS_STATUS_MEM_ERR; 1219 } 1220 new_name->name = ent_name; 1221 new_name->name_alloced = true; 1222 new_node = LDNS_MALLOC(ldns_rbnode_t); 1223 if (!new_node) { 1224 ldns_rdf_deep_free(l1); 1225 ldns_rdf_deep_free(l2); 1226 ldns_dnssec_name_free(new_name); 1227 return LDNS_STATUS_MEM_ERR; 1228 } 1229 new_node->key = new_name->name; 1230 new_node->data = new_name; 1231 (void)ldns_rbtree_insert(zone->names, new_node); 1232 ldns_dnssec_name_make_hashed_name( 1233 zone, new_name, NULL); 1234 if (node) 1235 (void) ldns_dnssec_zone_add_rr(zone, 1236 (ldns_rr *)node->data); 1237 } 1238 ldns_rdf_deep_free(l1); 1239 ldns_rdf_deep_free(l2); 1240 } 1241 1242 /* we might have inserted a new node after 1243 * the current one so we can't just use next() 1244 */ 1245 if (next_node != ldns_rbtree_first(zone->names)) { 1246 cur_node = next_node; 1247 } else { 1248 cur_node = LDNS_RBTREE_NULL; 1249 } 1250 } 1251 return LDNS_STATUS_OK; 1252 } 1253 1254 ldns_status 1255 ldns_dnssec_zone_add_empty_nonterminals(ldns_dnssec_zone *zone) 1256 { 1257 return ldns_dnssec_zone_add_empty_nonterminals_nsec3(zone, NULL); 1258 } 1259 1260 bool 1261 ldns_dnssec_zone_is_nsec3_optout(const ldns_dnssec_zone* zone) 1262 { 1263 ldns_rr* nsec3; 1264 ldns_rbnode_t* node; 1265 1266 if (ldns_dnssec_name_find_rrset(zone->soa, LDNS_RR_TYPE_NSEC3PARAM)) { 1267 node = ldns_rbtree_first(zone->names); 1268 while (node != LDNS_RBTREE_NULL) { 1269 nsec3 = ((ldns_dnssec_name*)node->data)->nsec; 1270 if (nsec3 &&ldns_rr_get_type(nsec3) 1271 == LDNS_RR_TYPE_NSEC3 && 1272 ldns_nsec3_optout(nsec3)) { 1273 return true; 1274 } 1275 node = ldns_rbtree_next(node); 1276 } 1277 } 1278 return false; 1279 } 1280 1281 /* 1282 * Stuff for calculating and verifying zone digests 1283 */ 1284 typedef enum dnssec_zone_rr_iter_state { 1285 DNSSEC_ZONE_RR_ITER_LT_RRSIG 1286 , DNSSEC_ZONE_RR_ITER_RRSIGs_NO_NSEC 1287 , DNSSEC_ZONE_RR_ITER_REST 1288 , DNSSEC_ZONE_RR_ITER_RRSIGs_NSEC 1289 , DNSSEC_ZONE_RR_ITER_RRSIGs_NSEC_REST 1290 , DNSSEC_ZONE_RR_ITER_NSEC3 1291 , DNSSEC_ZONE_RR_ITER_FINI 1292 } dnssec_zone_rr_iter_state; 1293 1294 typedef struct dnssec_zone_rr_iter { 1295 ldns_dnssec_zone *zone; 1296 ldns_rbnode_t *node; 1297 ldns_dnssec_name *name; 1298 ldns_dnssec_rrsets *rrsets; 1299 ldns_dnssec_rrs *rrs; 1300 ldns_dnssec_rrsets *rrsets4rrsigs; 1301 ldns_rbnode_t *nsec3_node; 1302 ldns_dnssec_name *nsec3_name; 1303 dnssec_zone_rr_iter_state state; 1304 ldns_rdf *apex_name; 1305 uint8_t apex_labs; 1306 } dnssec_zone_rr_iter; 1307 1308 INLINE void 1309 dnssec_zone_rr_iter_set_state_for_next_name(dnssec_zone_rr_iter *i) 1310 { 1311 /* Make sure the i->name is "in zone" (i.e. below the apex) */ 1312 if (i->apex_name) { 1313 ldns_rdf *name = (ldns_rdf *)i->node->key; 1314 1315 while (i->name && name != i->apex_name /* not apex */ 1316 1317 && ( ldns_dname_label_count(name) != i->apex_labs 1318 || ldns_dname_compare(name, i->apex_name)) /* not apex */ 1319 1320 && !ldns_dname_is_subdomain(name, i->apex_name) /* no sub */) { 1321 1322 /* next name */ 1323 i->node = ldns_rbtree_next(i->node); 1324 if (i->node == LDNS_RBTREE_NULL) 1325 i->name = NULL; 1326 else { 1327 i->name = (ldns_dnssec_name *)i->node->data; 1328 name = (ldns_rdf *)i->node->key; 1329 } 1330 } 1331 } 1332 /* determine state */ 1333 if (!i->name) { 1334 if (!i->nsec3_name) 1335 i->state = DNSSEC_ZONE_RR_ITER_FINI; 1336 else { 1337 i->rrs = i->nsec3_name->nsec_signatures; 1338 i->state = DNSSEC_ZONE_RR_ITER_NSEC3; 1339 } 1340 } else if (!i->nsec3_name) { 1341 i->rrsets = i->name->rrsets; 1342 i->state = DNSSEC_ZONE_RR_ITER_LT_RRSIG; 1343 1344 } else if (ldns_dname_compare( ldns_rr_owner(i->nsec3_name->nsec) 1345 , (ldns_rdf *)i->node->key) < 0) { 1346 i->rrs = i->nsec3_name->nsec_signatures; 1347 i->state = DNSSEC_ZONE_RR_ITER_NSEC3; 1348 } else { 1349 i->rrsets = i->name->rrsets; 1350 i->state = DNSSEC_ZONE_RR_ITER_LT_RRSIG; 1351 } 1352 } 1353 1354 /** 1355 * Iterate over the RR's in the ldns_dnssec_zone in canonical order. 1356 * There are three possible paths through the RR's in a ldns_dnssec_name. 1357 * 1358 * 1. There is no NSEC: 1359 * 1360 * 1.1. All the RRs in the name->rrsets with type < RRSIG, 1361 * state: DNSSEC_ZONE_RR_ITER_LT_RRSIG 1362 * 1363 * 1.2. Then all the RRSIGs from name->rrsets (likely none) 1364 * state: DNSSEC_ZONE_RR_ITER_RRSIGs_NO_NSEC 1365 * 1366 * 1.3. Finally the remaining RRs in name->rrsets (type > RRSIG) 1367 * state: DNSSEC_ZONE_RR_ITER_REST 1368 * 1369 * 1370 * 2. There is a NSEC of type NSEC with this name: 1371 * 1372 * 2.1. All the RRs in the name->rrsets with type < RRSIG, 1373 * state: DNSSEC_ZONE_RR_ITER_LT_RRSIG 1374 * 1375 * 2.2. Then all the RRSIGs from name->rrsets with type < NSEC 1376 * state: DNSSEC_ZONE_RR_ITER_RRSIGs_NO_NSEC 1377 * 1378 * 2.3. Then the signatures of the NSEC RR, followed by 1379 * the signatures of the remaining name->rrsets (type > NSEC), 1380 * followed by the NSEC rr. 1381 * state: DNSSEC_ZONE_RR_ITER_RRSIGs_NO_NSEC 1382 * 1383 * 2.4. Finally the remaining RRs in name->rrsets (type > RRSIG) 1384 * state: DNSSEC_ZONE_RR_ITER_REST 1385 * 1386 * 1387 * 3. There is a NSEC of type NSEC3 for this name: 1388 * 1389 * 3.1. If the NSEC3 name is before the name for other RRsets in the zone, 1390 * Then all signatures of the NSEC3 RR, followed by the NSEC3 1391 * state: DNSSEC_ZONE_RR_ITER_NSEC3 1392 * 1393 * otherwise follow path for "no NSEC" for the name for other RRsets 1394 */ 1395 static ldns_rr * 1396 dnssec_zone_rr_iter_next(dnssec_zone_rr_iter *i) 1397 { 1398 ldns_rr *nsec3; 1399 1400 for (;;) { 1401 if (i->rrs) { 1402 ldns_rr *rr = i->rrs->rr; 1403 i->rrs = i->rrs->next; 1404 return rr; 1405 } 1406 switch (i->state) { 1407 case DNSSEC_ZONE_RR_ITER_LT_RRSIG: 1408 if (i->rrsets 1409 && i->rrsets->type < LDNS_RR_TYPE_RRSIG) { 1410 1411 i->rrs = i->rrsets->rrs; 1412 i->rrsets = i->rrsets->next; 1413 break; 1414 } 1415 i->rrsets4rrsigs = i->name->rrsets; 1416 if (i->name->nsec && ldns_rr_get_type(i->name->nsec) 1417 == LDNS_RR_TYPE_NSEC) { 1418 1419 i->state = DNSSEC_ZONE_RR_ITER_RRSIGs_NSEC; 1420 break; 1421 } 1422 i->state = DNSSEC_ZONE_RR_ITER_RRSIGs_NO_NSEC; 1423 /* fallthrough */ 1424 1425 case DNSSEC_ZONE_RR_ITER_RRSIGs_NO_NSEC: 1426 if (i->rrsets4rrsigs) { 1427 i->rrs = i->rrsets4rrsigs->signatures; 1428 i->rrsets4rrsigs = i->rrsets4rrsigs->next; 1429 break; 1430 } 1431 i->state = DNSSEC_ZONE_RR_ITER_REST; 1432 /* fallthrough */ 1433 1434 case DNSSEC_ZONE_RR_ITER_REST: 1435 if (i->rrsets) { 1436 i->rrs = i->rrsets->rrs; 1437 i->rrsets = i->rrsets->next; 1438 break; 1439 } 1440 /* next name */ 1441 i->node = ldns_rbtree_next(i->node); 1442 i->name = i->node == LDNS_RBTREE_NULL ? NULL 1443 : (ldns_dnssec_name *)i->node->data; 1444 1445 dnssec_zone_rr_iter_set_state_for_next_name(i); 1446 break; 1447 1448 case DNSSEC_ZONE_RR_ITER_RRSIGs_NSEC: 1449 if (i->rrsets4rrsigs 1450 && i->rrsets4rrsigs->type < LDNS_RR_TYPE_NSEC) { 1451 1452 i->rrs = i->rrsets4rrsigs->signatures; 1453 i->rrsets4rrsigs = i->rrsets4rrsigs->next; 1454 break; 1455 } 1456 i->state = DNSSEC_ZONE_RR_ITER_RRSIGs_NSEC_REST; 1457 i->rrs = i->name->nsec_signatures; 1458 break; 1459 1460 case DNSSEC_ZONE_RR_ITER_RRSIGs_NSEC_REST: 1461 if (i->rrsets4rrsigs) { 1462 i->rrs = i->rrsets4rrsigs->signatures; 1463 i->rrsets4rrsigs = i->rrsets4rrsigs->next; 1464 break; 1465 } 1466 i->state = DNSSEC_ZONE_RR_ITER_REST; 1467 return i->name->nsec; 1468 1469 case DNSSEC_ZONE_RR_ITER_NSEC3: 1470 nsec3 = i->nsec3_name->nsec; 1471 1472 /* next nsec3 */ 1473 do { 1474 i->nsec3_node 1475 = ldns_rbtree_next(i->nsec3_node); 1476 i->nsec3_name 1477 = i->nsec3_node == LDNS_RBTREE_NULL ? NULL 1478 : (ldns_dnssec_name*)i->nsec3_node->data; 1479 1480 /* names for glue can be in the hashed_names 1481 * tree, but will not have a NSEC3 1482 */ 1483 } while (i->nsec3_name && !i->nsec3_name->nsec); 1484 1485 dnssec_zone_rr_iter_set_state_for_next_name(i); 1486 return nsec3; 1487 1488 case DNSSEC_ZONE_RR_ITER_FINI: 1489 return NULL; 1490 } 1491 } 1492 } 1493 1494 static ldns_rr * 1495 dnssec_zone_rr_iter_first(dnssec_zone_rr_iter *i, ldns_dnssec_zone *zone) 1496 { 1497 if (!i || !zone) 1498 return NULL; 1499 1500 memset(i, 0, sizeof(*i)); 1501 i->zone = zone; 1502 if (zone->soa && zone->soa->name) { 1503 i->apex_name = zone->soa->name; 1504 i->apex_labs = ldns_dname_label_count(i->apex_name); 1505 } else 1506 i->apex_name = NULL; 1507 1508 1509 i->node = ldns_rbtree_first(zone->names); 1510 i->name = i->node == LDNS_RBTREE_NULL ? NULL 1511 : (ldns_dnssec_name *)i->node->data; 1512 1513 if (zone->hashed_names) { 1514 do { 1515 i->nsec3_node = ldns_rbtree_first(zone->hashed_names); 1516 i->nsec3_name = i->nsec3_node == LDNS_RBTREE_NULL ?NULL 1517 : (ldns_dnssec_name*)i->nsec3_node->data; 1518 } while (i->nsec3_name && !i->nsec3_name->nsec); 1519 } 1520 dnssec_zone_rr_iter_set_state_for_next_name(i); 1521 return dnssec_zone_rr_iter_next(i); 1522 } 1523 1524 enum enum_zonemd_scheme { 1525 ZONEMD_SCHEME_FIRST = 1, 1526 ZONEMD_SCHEME_SIMPLE = 1, 1527 ZONEMD_SCHEME_LAST = 1 1528 }; 1529 typedef enum enum_zonemd_scheme zonemd_scheme; 1530 1531 enum enum_zonemd_hash { 1532 ZONEMD_HASH_FIRST = 1, 1533 ZONEMD_HASH_SHA384 = 1, 1534 ZONEMD_HASH_SHA512 = 2, 1535 ZONEMD_HASH_LAST = 2 1536 }; 1537 typedef enum enum_zonemd_hash zonemd_hash; 1538 1539 struct struct_zone_digester { 1540 ldns_sha384_CTX sha384_CTX; 1541 ldns_sha512_CTX sha512_CTX; 1542 unsigned simple_sha384 : 1; 1543 unsigned simple_sha512 : 1; 1544 unsigned double_sha384 : 1; 1545 unsigned double_sha512 : 1; 1546 }; 1547 typedef struct struct_zone_digester zone_digester; 1548 1549 INLINE bool zone_digester_set(zone_digester *zd) 1550 { return zd && (zd->simple_sha384 || zd->simple_sha512); } 1551 1552 INLINE void zone_digester_init(zone_digester *zd) 1553 { memset(zd, 0, sizeof(*zd)); } 1554 1555 static ldns_status 1556 zone_digester_add(zone_digester *zd, zonemd_scheme scheme, zonemd_hash hash) 1557 { 1558 if (!zd) 1559 return LDNS_STATUS_NULL; 1560 1561 switch (scheme) { 1562 case ZONEMD_SCHEME_SIMPLE: 1563 switch (hash) { 1564 case ZONEMD_HASH_SHA384: 1565 if (zd->double_sha384) 1566 return LDNS_STATUS_ZONEMD_DOUBLE_OCCURRENCE; 1567 1568 else if (zd->simple_sha384) { 1569 zd->simple_sha384 = 0; 1570 zd->double_sha384 = 1; 1571 return LDNS_STATUS_ZONEMD_DOUBLE_OCCURRENCE; 1572 } 1573 ldns_sha384_init(&zd->sha384_CTX); 1574 zd->simple_sha384 = 1; 1575 break; 1576 1577 case ZONEMD_HASH_SHA512: 1578 if (zd->double_sha512) 1579 return LDNS_STATUS_ZONEMD_DOUBLE_OCCURRENCE; 1580 1581 else if (zd->simple_sha512) { 1582 zd->simple_sha512 = 0; 1583 zd->double_sha512 = 1; 1584 return LDNS_STATUS_ZONEMD_DOUBLE_OCCURRENCE; 1585 } 1586 ldns_sha512_init(&zd->sha512_CTX); 1587 zd->simple_sha512 = 1; 1588 break; 1589 default: 1590 return LDNS_STATUS_ZONEMD_UNKNOWN_HASH; 1591 } 1592 break; 1593 default: 1594 return LDNS_STATUS_ZONEMD_UNKNOWN_SCHEME; 1595 } 1596 return LDNS_STATUS_OK; 1597 } 1598 1599 static ldns_status 1600 zone_digester_update(zone_digester *zd, ldns_rr *rr) 1601 { 1602 uint8_t data[65536]; 1603 ldns_buffer buf; 1604 ldns_status st; 1605 1606 buf._data = data; 1607 buf._position = 0; 1608 buf._limit = sizeof(data); 1609 buf._capacity = sizeof(data); 1610 buf._fixed = 1; 1611 buf._status = LDNS_STATUS_OK; 1612 1613 if ((st = ldns_rr2buffer_wire_canonical(&buf, rr, LDNS_SECTION_ANSWER))) 1614 return st; 1615 1616 if (zd->simple_sha384) 1617 ldns_sha384_update(&zd->sha384_CTX, data, buf._position); 1618 1619 if (zd->simple_sha512) 1620 ldns_sha512_update(&zd->sha512_CTX, data, buf._position); 1621 1622 return LDNS_STATUS_OK; 1623 } 1624 1625 INLINE ldns_rr * 1626 new_zonemd(ldns_rr *soa, zonemd_hash hash) 1627 { 1628 ldns_rr *rr = NULL; 1629 uint8_t *data = NULL; 1630 ldns_rdf *rdf; 1631 size_t md_len = hash == ZONEMD_HASH_SHA384 1632 ? LDNS_SHA384_DIGEST_LENGTH 1633 : LDNS_SHA512_DIGEST_LENGTH; 1634 1635 if (!(rr = ldns_rr_new_frm_type(LDNS_RR_TYPE_ZONEMD))) 1636 return NULL; 1637 1638 if (!(rdf = ldns_rdf_clone(ldns_rr_owner(soa)))) 1639 goto error; 1640 1641 ldns_rr_set_owner(rr, rdf); 1642 ldns_rr_set_class(rr, ldns_rr_get_class(soa)); 1643 ldns_rr_set_ttl(rr, ldns_rr_ttl(soa)); 1644 1645 if (!(rdf = ldns_rdf_clone(ldns_rr_rdf(soa, 2)))) 1646 goto error; 1647 ldns_rr_set_rdf(rr, rdf, 0); 1648 1649 if (!(rdf = ldns_native2rdf_int8(LDNS_RDF_TYPE_INT8, 1))) 1650 goto error; 1651 ldns_rr_set_rdf(rr, rdf, 1); 1652 1653 if (!(rdf = ldns_native2rdf_int8(LDNS_RDF_TYPE_INT8, hash))) 1654 goto error; 1655 ldns_rr_set_rdf(rr, rdf, 2); 1656 1657 if (!(data = LDNS_XMALLOC(uint8_t, md_len))) 1658 goto error; 1659 1660 if (!(rdf = ldns_rdf_new(LDNS_RDF_TYPE_HEX, md_len, data))) 1661 goto error; 1662 ldns_rr_set_rdf(rr, rdf, 3); 1663 1664 return rr; 1665 error: 1666 if (data) 1667 LDNS_FREE(data); 1668 ldns_rr_free(rr); 1669 return NULL; 1670 } 1671 1672 static ldns_rr_list * 1673 zone_digester_export( 1674 zone_digester *zd, ldns_rr *soa, ldns_status *ret_st) 1675 { 1676 ldns_status st = LDNS_STATUS_OK; 1677 ldns_rr_list *rr_list = NULL; 1678 ldns_rr *sha384 = NULL; 1679 ldns_rr *sha512 = NULL; 1680 1681 if (!zd || !soa) 1682 st = LDNS_STATUS_NULL; 1683 1684 else if (ldns_rr_get_type(soa) != LDNS_RR_TYPE_SOA 1685 || ldns_rr_rd_count(soa) < 3) 1686 st = LDNS_STATUS_ZONEMD_INVALID_SOA; 1687 1688 else if (!(rr_list = ldns_rr_list_new())) 1689 st = LDNS_STATUS_MEM_ERR; 1690 1691 else if (zd->simple_sha384 1692 && !(sha384 = new_zonemd(soa, ZONEMD_HASH_SHA384))) 1693 st = LDNS_STATUS_MEM_ERR; 1694 1695 else if (zd->simple_sha512 1696 && !(sha512 = new_zonemd(soa, ZONEMD_HASH_SHA512))) 1697 st = LDNS_STATUS_MEM_ERR; 1698 1699 else if (zd->simple_sha384 1700 && !ldns_rr_list_push_rr(rr_list, sha384)) 1701 st = LDNS_STATUS_MEM_ERR; 1702 1703 else if (zd->simple_sha512 1704 && !ldns_rr_list_push_rr(rr_list, sha512)) { 1705 if (zd->simple_sha384) 1706 sha384 = NULL; /* deleted by ldns_rr_list_deep_free */ 1707 st = LDNS_STATUS_MEM_ERR; 1708 1709 } else { 1710 if (sha384) 1711 ldns_sha384_final( ldns_rdf_data(ldns_rr_rdf(sha384,3)) 1712 , &zd->sha384_CTX); 1713 if (sha512) 1714 ldns_sha512_final( ldns_rdf_data(ldns_rr_rdf(sha512,3)) 1715 , &zd->sha512_CTX); 1716 return rr_list; 1717 } 1718 if (ret_st) 1719 *ret_st = st; 1720 if (sha384) 1721 ldns_rr_free(sha384); 1722 if (sha512) 1723 ldns_rr_free(sha512); 1724 if (rr_list) 1725 ldns_rr_list_deep_free(rr_list); 1726 return NULL; 1727 } 1728 1729 static ldns_status 1730 ldns_digest_zone(ldns_dnssec_zone *zone, zone_digester *zd) 1731 { 1732 ldns_status st = LDNS_STATUS_OK; 1733 dnssec_zone_rr_iter rr_iter; 1734 ldns_rr *rr; 1735 ldns_rdf *apex_name; /* name of zone apex */ 1736 1737 if (!zone || !zd || !zone->soa || !zone->soa->name) 1738 return LDNS_STATUS_NULL; 1739 1740 apex_name = zone->soa->name; 1741 for ( rr = dnssec_zone_rr_iter_first(&rr_iter, zone) 1742 ; rr && !st 1743 ; rr = dnssec_zone_rr_iter_next(&rr_iter)) { 1744 /* Skip apex ZONEMD RRs */ 1745 if (ldns_rr_get_type(rr) == LDNS_RR_TYPE_ZONEMD 1746 && !ldns_dname_compare(ldns_rr_owner(rr), apex_name)) 1747 continue; 1748 /* Skip RRSIGs for apex ZONEMD RRs */ 1749 if (ldns_rr_get_type(rr) == LDNS_RR_TYPE_RRSIG 1750 && LDNS_RR_TYPE_ZONEMD == ldns_rdf2rr_type( 1751 ldns_rr_rrsig_typecovered(rr)) 1752 && !ldns_dname_compare(ldns_rr_owner(rr), apex_name)) 1753 continue; 1754 st = zone_digester_update(zd, rr); 1755 } 1756 return st; 1757 } 1758 1759 ldns_status 1760 ldns_dnssec_zone_verify_zonemd(ldns_dnssec_zone *zone) 1761 { 1762 ldns_dnssec_rrsets *zonemd, *soa; 1763 zone_digester zd; 1764 ldns_dnssec_rrs *rrs; 1765 ldns_rr *soa_rr; 1766 ldns_status st; 1767 uint8_t simple_sha384[LDNS_SHA384_DIGEST_LENGTH]; 1768 uint8_t simple_sha512[LDNS_SHA512_DIGEST_LENGTH]; 1769 size_t valid_zonemds; 1770 1771 if (!zone) 1772 return LDNS_STATUS_NULL; 1773 1774 zonemd = ldns_dnssec_zone_find_rrset( 1775 zone, zone->soa->name, LDNS_RR_TYPE_ZONEMD); 1776 if (!zonemd) { 1777 ldns_rbnode_t *nsec3_node; 1778 1779 /* we need proof of non-existence for ZONEMD at the apex */ 1780 if (zone->soa->nsec) { 1781 if (ldns_nsec_bitmap_covers_type(ldns_nsec_get_bitmap( 1782 zone->soa->nsec), 1783 LDNS_RR_TYPE_ZONEMD)) 1784 return LDNS_STATUS_NO_ZONEMD; 1785 1786 } else if (!zone->soa->hashed_name || !zone->hashed_names) 1787 return LDNS_STATUS_NO_ZONEMD; 1788 1789 else if (LDNS_RBTREE_NULL == 1790 (nsec3_node = ldns_rbtree_search( zone->hashed_names 1791 , zone->soa->hashed_name))) 1792 return LDNS_STATUS_NO_ZONEMD; 1793 else { 1794 ldns_dnssec_name *nsec3 1795 = (ldns_dnssec_name *)nsec3_node->data; 1796 if (ldns_nsec_bitmap_covers_type(ldns_nsec_get_bitmap( 1797 nsec3->nsec), 1798 LDNS_RR_TYPE_ZONEMD)) 1799 return LDNS_STATUS_NO_ZONEMD; 1800 } 1801 /* ZONEMD at apex does really not exist */ 1802 return LDNS_STATUS_OK; 1803 } 1804 soa = ldns_dnssec_zone_find_rrset( 1805 zone, zone->soa->name, LDNS_RR_TYPE_SOA); 1806 if (!soa || !soa->rrs || !soa->rrs->rr) 1807 return LDNS_STATUS_ZONEMD_INVALID_SOA; 1808 1809 soa_rr = soa->rrs->rr; 1810 if (ldns_rr_get_type(soa_rr) != LDNS_RR_TYPE_SOA 1811 || ldns_rr_rd_count(soa_rr) < 3) 1812 return LDNS_STATUS_ZONEMD_INVALID_SOA; 1813 1814 zone_digester_init(&zd); 1815 for (rrs = zonemd->rrs; rrs; rrs = rrs->next) { 1816 if (!rrs->rr 1817 || ldns_rr_get_type(rrs->rr) != LDNS_RR_TYPE_ZONEMD 1818 || ldns_rr_rd_count(rrs->rr) < 4) 1819 continue; 1820 1821 /* serial should match SOA's serial */ 1822 if (ldns_rdf2native_int32(ldns_rr_rdf(soa_rr, 2)) 1823 != ldns_rdf2native_int32(ldns_rr_rdf(rrs->rr, 0))) 1824 continue; 1825 1826 /* Add (scheme, hash) to digester */ 1827 zone_digester_add(&zd, 1828 ldns_rdf2native_int8(ldns_rr_rdf(rrs->rr, 1)), 1829 ldns_rdf2native_int8(ldns_rr_rdf(rrs->rr, 2))); 1830 } 1831 if (!zone_digester_set(&zd)) 1832 return LDNS_STATUS_NO_VALID_ZONEMD; 1833 1834 if ((st = ldns_digest_zone(zone, &zd))) 1835 return st; 1836 1837 if (zd.simple_sha384) 1838 ldns_sha384_final(simple_sha384, &zd.sha384_CTX); 1839 if (zd.simple_sha512) 1840 ldns_sha512_final(simple_sha512, &zd.sha512_CTX); 1841 1842 valid_zonemds = 0; 1843 for (rrs = zonemd->rrs; rrs; rrs = rrs->next) { 1844 if (!rrs->rr 1845 || ldns_rr_get_type(rrs->rr) != LDNS_RR_TYPE_ZONEMD 1846 || ldns_rr_rd_count(rrs->rr) < 4) 1847 continue; 1848 1849 /* serial should match SOA's serial */ 1850 if (ldns_rdf2native_int32(ldns_rr_rdf(soa_rr, 2)) 1851 != ldns_rdf2native_int32(ldns_rr_rdf(rrs->rr, 0))) 1852 continue; 1853 1854 if (ZONEMD_SCHEME_SIMPLE != 1855 ldns_rdf2native_int8(ldns_rr_rdf(rrs->rr, 1))) 1856 continue; 1857 1858 if (ZONEMD_HASH_SHA384 1859 == ldns_rdf2native_int8(ldns_rr_rdf(rrs->rr,2)) 1860 && LDNS_SHA384_DIGEST_LENGTH 1861 == ldns_rdf_size(ldns_rr_rdf(rrs->rr, 3)) 1862 && memcmp( simple_sha384 1863 , ldns_rdf_data(ldns_rr_rdf(rrs->rr, 3)) 1864 , LDNS_SHA384_DIGEST_LENGTH) == 0) 1865 1866 valid_zonemds += 1; 1867 1868 if (ZONEMD_HASH_SHA512 1869 == ldns_rdf2native_int8(ldns_rr_rdf(rrs->rr,2)) 1870 && LDNS_SHA512_DIGEST_LENGTH 1871 == ldns_rdf_size(ldns_rr_rdf(rrs->rr, 3)) 1872 && memcmp( simple_sha512 1873 , ldns_rdf_data(ldns_rr_rdf(rrs->rr, 3)) 1874 , LDNS_SHA512_DIGEST_LENGTH) == 0) 1875 1876 valid_zonemds += 1; 1877 } 1878 return valid_zonemds ? LDNS_STATUS_OK : LDNS_STATUS_NO_VALID_ZONEMD; 1879 } 1880 1881 #ifdef HAVE_SSL 1882 static ldns_status 1883 rr_list2dnssec_rrs(ldns_rr_list *rr_list, ldns_dnssec_rrs **rrs, 1884 ldns_rr_list *new_rrs) 1885 { 1886 ldns_rr *rr = NULL; 1887 1888 if (!rr_list || !rrs) 1889 return LDNS_STATUS_NULL; 1890 1891 if (ldns_rr_list_rr_count(rr_list) == 0) 1892 return LDNS_STATUS_OK; 1893 1894 if (!*rrs) { 1895 if (!(*rrs = ldns_dnssec_rrs_new())) 1896 return LDNS_STATUS_MEM_ERR; 1897 (*rrs)->rr = ldns_rr_list_pop_rr(rr_list); 1898 if (new_rrs) 1899 ldns_rr_list_push_rr(new_rrs, (*rrs)->rr); 1900 } 1901 while ((rr = ldns_rr_list_pop_rr(rr_list))) { 1902 ldns_status st; 1903 1904 if ((st = ldns_dnssec_rrs_add_rr(*rrs, rr))) { 1905 ldns_rr_list_push_rr(rr_list, rr); 1906 return st; 1907 } else if (new_rrs) 1908 ldns_rr_list_push_rr(new_rrs, rr); 1909 } 1910 return LDNS_STATUS_OK; 1911 } 1912 1913 1914 ldns_status 1915 dnssec_zone_equip_zonemd(ldns_dnssec_zone *zone, 1916 ldns_rr_list *new_rrs, ldns_key_list *key_list, int signflags) 1917 { 1918 ldns_status st = LDNS_STATUS_OK; 1919 zone_digester zd; 1920 ldns_rr_list *zonemd_rr_list = NULL; 1921 ldns_rr_list *zonemd_rrsigs = NULL; 1922 ldns_dnssec_rrsets *soa_rrset; 1923 ldns_rr *soa_rr = NULL; 1924 ldns_dnssec_rrsets **rrset_ref; 1925 ldns_dnssec_rrsets *zonemd_rrset; 1926 1927 zone_digester_init(&zd); 1928 if (signflags & LDNS_SIGN_WITH_ZONEMD_SIMPLE_SHA384) 1929 zone_digester_add(&zd, ZONEMD_SCHEME_SIMPLE 1930 , ZONEMD_HASH_SHA384); 1931 1932 if (signflags & LDNS_SIGN_WITH_ZONEMD_SIMPLE_SHA512) 1933 zone_digester_add(&zd, ZONEMD_SCHEME_SIMPLE 1934 , ZONEMD_HASH_SHA512); 1935 1936 if ((st = ldns_digest_zone(zone, &zd))) 1937 return st; 1938 1939 soa_rrset = ldns_dnssec_zone_find_rrset( 1940 zone, zone->soa->name, LDNS_RR_TYPE_SOA); 1941 if (!soa_rrset || !soa_rrset->rrs || !soa_rrset->rrs->rr) 1942 return LDNS_STATUS_ZONEMD_INVALID_SOA; 1943 soa_rr = soa_rrset->rrs->rr; 1944 1945 if (!(zonemd_rr_list = zone_digester_export(&zd, soa_rr, &st))) 1946 return st; 1947 1948 /* - replace or add ZONEMD rrset */ 1949 rrset_ref = &zone->soa->rrsets; /* scan rrsets at apex */ 1950 while (*rrset_ref && (*rrset_ref)->type < LDNS_RR_TYPE_ZONEMD) 1951 rrset_ref = &(*rrset_ref)->next; 1952 if (*rrset_ref && (*rrset_ref)->type == LDNS_RR_TYPE_ZONEMD) { 1953 /* reuse zonemd rrset */ 1954 zonemd_rrset = *rrset_ref; 1955 ldns_dnssec_rrs_free(zonemd_rrset->rrs); 1956 zonemd_rrset->rrs = NULL; 1957 ldns_dnssec_rrs_free(zonemd_rrset->signatures); 1958 zonemd_rrset->signatures = NULL; 1959 } else { 1960 /* insert zonemd rrset */ 1961 zonemd_rrset = ldns_dnssec_rrsets_new(); 1962 if (!zonemd_rrset) { 1963 ldns_rr_list_deep_free(zonemd_rr_list); 1964 return LDNS_STATUS_MEM_ERR; 1965 } 1966 zonemd_rrset->type = LDNS_RR_TYPE_ZONEMD; 1967 zonemd_rrset->next = *rrset_ref; 1968 *rrset_ref = zonemd_rrset; 1969 } 1970 if ((zonemd_rrsigs = ldns_sign_public(zonemd_rr_list, key_list))) 1971 st = rr_list2dnssec_rrs( zonemd_rrsigs 1972 , &zonemd_rrset->signatures, new_rrs); 1973 if (!st) 1974 st = rr_list2dnssec_rrs( zonemd_rr_list 1975 , &zonemd_rrset->rrs, new_rrs); 1976 ldns_rr_list_deep_free(zonemd_rr_list); 1977 ldns_rr_list_deep_free(zonemd_rrsigs); 1978 return st; 1979 } 1980 1981 #endif /* HAVE_SSL */ 1982 1983