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