OpenDNSSEC-signer 1.2.1
|
00001 /* 00002 * $Id: rrset.c 4521 2011-03-01 14:56:15Z matthijs $ 00003 * 00004 * Copyright (c) 2009 NLNet Labs. All rights reserved. 00005 * 00006 * Redistribution and use in source and binary forms, with or without 00007 * modification, are permitted provided that the following conditions 00008 * are met: 00009 * 1. Redistributions of source code must retain the above copyright 00010 * notice, this list of conditions and the following disclaimer. 00011 * 2. Redistributions in binary form must reproduce the above copyright 00012 * notice, this list of conditions and the following disclaimer in the 00013 * documentation and/or other materials provided with the distribution. 00014 * 00015 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 00016 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 00017 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 00018 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY 00019 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 00020 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE 00021 * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 00022 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER 00023 * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 00024 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN 00025 * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 00026 * 00027 */ 00028 00034 #include "config.h" 00035 #include "signer/hsm.h" 00036 #include "signer/rrset.h" 00037 #include "util/duration.h" 00038 #include "util/log.h" 00039 #include "util/se_malloc.h" 00040 #include "util/util.h" 00041 00042 #include <ldns/ldns.h> /* ldns_rr_*(), ldns_dnssec_*() */ 00043 00044 00049 rrset_type* 00050 rrset_create(ldns_rr_type rrtype) 00051 { 00052 rrset_type* rrset = (rrset_type*) se_calloc(1, sizeof(rrset_type)); 00053 se_log_assert(rrtype); 00054 rrset->rr_type = rrtype; 00055 rrset->rr_count = 0; 00056 rrset->rrsig_count = 0; 00057 rrset->add_count = 0; 00058 rrset->del_count = 0; 00059 rrset->internal_serial = 0; 00060 rrset->initialized = 0; 00061 rrset->rrs = ldns_dnssec_rrs_new(); 00062 rrset->add = NULL; 00063 rrset->del = NULL; 00064 rrset->rrsigs = NULL; 00065 rrset->drop_signatures = 0; 00066 return rrset; 00067 } 00068 00069 00074 rrset_type* 00075 rrset_create_frm_rr(ldns_rr* rr) 00076 { 00077 rrset_type* rrset = (rrset_type*) se_calloc(1, sizeof(rrset_type)); 00078 se_log_assert(rr); 00079 rrset->rr_type = ldns_rr_get_type(rr); 00080 rrset->rr_count = 1; 00081 rrset->add_count = 0; 00082 rrset->del_count = 0; 00083 rrset->rrsig_count = 0; 00084 rrset->internal_serial = 0; 00085 rrset->initialized = 0; 00086 rrset->rrs = ldns_dnssec_rrs_new(); 00087 rrset->rrs->rr = rr; 00088 rrset->add = NULL; 00089 rrset->del = NULL; 00090 rrset->rrsigs = NULL; 00091 rrset->drop_signatures = 0; 00092 return rrset; 00093 } 00094 00099 int 00100 rrset_compare_rrs(ldns_dnssec_rrs* rrs1, ldns_dnssec_rrs* rrs2) 00101 { 00102 int cmp = 0; 00103 ldns_status status = LDNS_STATUS_OK; 00104 00105 if (!rrs1 || !rrs2) { 00106 return 1; 00107 } 00108 while (rrs1 && rrs2) { 00109 if (rrs1->rr && rrs2->rr) { 00110 status = util_dnssec_rrs_compare(rrs1->rr, rrs2->rr, &cmp); 00111 if (status != LDNS_STATUS_OK || cmp != 0) { 00112 return cmp; 00113 } 00114 /* check ttl */ 00115 if (ldns_rr_ttl(rrs1->rr) != ldns_rr_ttl(rrs2->rr)) { 00116 return ldns_rr_ttl(rrs1->rr) - ldns_rr_ttl(rrs2->rr); 00117 } 00118 00119 /* the same */ 00120 } else { 00121 return 1; 00122 } 00123 rrs1 = rrs1->next; 00124 rrs2 = rrs2->next; 00125 } 00126 00127 if (!rrs1 && !rrs2) { 00128 return 0; 00129 } 00130 return 1; 00131 } 00132 00133 00138 static int 00139 rrs_examine_ns_rdata(ldns_dnssec_rrs* rrs, ldns_rdf* nsdname) 00140 { 00141 ldns_dnssec_rrs* walk = NULL; 00142 00143 if (!rrs || !nsdname) { 00144 return 1; 00145 } 00146 walk = rrs; 00147 while (walk) { 00148 if (walk->rr && 00149 ldns_dname_compare(ldns_rr_rdf(walk->rr, 0), nsdname) == 0) { 00150 return 0; 00151 } 00152 walk = walk->next; 00153 } 00154 return 1; 00155 } 00156 00157 00162 int 00163 rrset_examine_ns_rdata(rrset_type* rrset, ldns_rdf* nsdname) 00164 { 00165 if (!rrset || !nsdname || rrset->rr_type != LDNS_RR_TYPE_NS) { 00166 return 1; 00167 } 00168 00169 if (rrs_examine_ns_rdata(rrset->add, nsdname) == 0) { 00170 return 0; 00171 } 00172 if (rrs_examine_ns_rdata(rrset->del, nsdname) == 0) { 00173 return 1; 00174 } 00175 if (rrs_examine_ns_rdata(rrset->rrs, nsdname) == 0) { 00176 return 0; 00177 } 00178 return 1; 00179 } 00180 00181 00186 void 00187 log_rr(ldns_rr* rr, const char* pre, int level) 00188 { 00189 char* str = NULL; 00190 00191 str = ldns_rr2str(rr); 00192 if (str) { 00193 str[(strlen(str))-1] = '\0'; 00194 } 00195 if (level == 1) { 00196 se_log_error("%s %s", pre?pre:"", str?str:"(null)"); 00197 } else if (level == 2) { 00198 se_log_warning("%s %s", pre?pre:"", str?str:"(null)"); 00199 } else if (level == 3) { 00200 se_log_info("%s %s", pre?pre:"", str?str:"(null)"); 00201 } else if (level == 4) { 00202 se_log_verbose("%s %s", pre?pre:"", str?str:"(null)"); 00203 } else if (level == 5) { 00204 se_log_debug("%s %s", pre?pre:"", str?str:"(null)"); 00205 } else { 00206 se_log_deeebug("%s %s", pre?pre:"", str?str:"(null)"); 00207 } 00208 se_free((void*)str); 00209 return; 00210 } 00211 00212 00217 static ldns_status 00218 rrset_add_pending_rr(rrset_type* rrset, ldns_rr* rr) 00219 { 00220 ldns_status status = LDNS_STATUS_OK; 00221 00222 if (!rrset->rrs) { 00223 rrset->rrs = ldns_dnssec_rrs_new(); 00224 } 00225 00226 if (!rrset->rrs->rr) { 00227 rrset->rrs->rr = rr; 00228 rrset->rr_count += 1; 00229 rrset->add_count -= 1; 00230 log_rr(rr, "+RR", 6); 00231 return LDNS_STATUS_OK; 00232 } else { 00233 status = util_dnssec_rrs_add_rr(rrset->rrs, rr); 00234 if (status != LDNS_STATUS_OK) { 00235 if (status == LDNS_STATUS_NO_DATA) { 00236 se_log_warning("error adding RR to RRset (%i): duplicate", 00237 rrset->rr_type); 00238 log_rr(rr, "+RR", 2); 00239 return LDNS_STATUS_OK; 00240 } else { 00241 se_log_error("error adding RR to RRset (%i): %s", 00242 rrset->rr_type, ldns_get_errorstr_by_id(status)); 00243 log_rr(rr, "+RR", 1); 00244 return status; 00245 } 00246 } 00247 log_rr(rr, "+RR", 6); 00248 rrset->rr_count += 1; 00249 rrset->add_count -= 1; 00250 return LDNS_STATUS_OK; 00251 } 00252 /* not reached */ 00253 return LDNS_STATUS_ERR; 00254 } 00255 00256 00261 static void 00262 rrset_del_pending_rr(rrset_type* rrset, ldns_rr* rr) 00263 { 00264 ldns_dnssec_rrs* rrs = NULL; 00265 ldns_dnssec_rrs* prev_rrs = NULL; 00266 00267 rrs = rrset->rrs; 00268 while (rrs) { 00269 if (util_soa_compare(rrs->rr, rr) == 0 || 00270 ldns_rr_compare(rrs->rr, rr) == 0) { 00271 /* this is it */ 00272 if (prev_rrs) { 00273 prev_rrs->next = rrs->next; 00274 } else { 00275 rrset->rrs = rrs->next; 00276 } 00277 ldns_rr_free(rrs->rr); 00278 se_free((void*)rrs); 00279 rrset->rr_count -= 1; 00280 rrset->del_count -= 1; 00281 log_rr(rr, "-RR", 6); 00282 return; 00283 } 00284 prev_rrs = rrs; 00285 rrs = rrs->next; 00286 } 00287 se_log_warning("error deleting RR from RRset (%i): does not exist", 00288 rrset->rr_type); 00289 log_rr(rr, "-RR", 2); 00290 return; 00291 } 00292 00293 00298 int 00299 rrset_recover_rr_from_backup(rrset_type* rrset, ldns_rr* rr) 00300 { 00301 return !(rrset_add_pending_rr(rrset, rr) == LDNS_STATUS_OK); 00302 } 00303 00304 00309 int 00310 rrset_recover_rrsig_from_backup(rrset_type* rrset, ldns_rr* rrsig, 00311 const char* locator, uint32_t flags) 00312 { 00313 int error = 0; 00314 00315 se_log_assert(rrset); 00316 se_log_assert(rrsig); 00317 00318 if (!rrset->rrsigs) { 00319 rrset->rrsigs = rrsigs_create(); 00320 } 00321 00322 error = rrsigs_add_sig(rrset->rrsigs, rrsig, locator, flags); 00323 if (!error) { 00324 rrset->rrsig_count += 1; 00325 } else { 00326 switch (error) { 00327 case 2: 00328 se_log_warning("error adding RRSIG to RRset (%i): duplicate", 00329 rrset->rr_type); 00330 log_rr(rrsig, "+RR", 2); 00331 break; 00332 case 1: 00333 se_log_error("error adding RRSIG to RRset (%i): compare failed", 00334 rrset->rr_type); 00335 log_rr(rrsig, "+RR", 2); 00336 break; 00337 default: 00338 se_log_error("error adding RRSIG to RRset (%i): unknown error", 00339 rrset->rr_type); 00340 log_rr(rrsig, "+RR", 2); 00341 break; 00342 } 00343 } 00344 return error; 00345 } 00346 00347 00352 int 00353 rrset_update(rrset_type* rrset, uint32_t serial) 00354 { 00355 ldns_dnssec_rrs* rrs = NULL; 00356 ldns_status status = LDNS_STATUS_OK; 00357 00358 se_log_assert(rrset); 00359 00360 if (!rrset->initialized || DNS_SERIAL_GT(serial, rrset->internal_serial)) { 00361 /* compare del and add */ 00362 if (rrset_compare_rrs(rrset->del, rrset->add) != 0) { 00363 rrset->drop_signatures = 1; 00364 } 00365 00366 /* delete RRs */ 00367 rrs = rrset->del; 00368 while (rrs) { 00369 if (rrs->rr) { 00370 rrset_del_pending_rr(rrset, rrs->rr); 00371 } 00372 rrs = rrs->next; 00373 } 00374 ldns_dnssec_rrs_deep_free(rrset->del); 00375 rrset->del = NULL; 00376 rrset->del_count = 0; 00377 00378 /* add RRs */ 00379 rrs = rrset->add; 00380 while (rrs) { 00381 if (rrs->rr) { 00382 status = rrset_add_pending_rr(rrset, rrs->rr); 00383 if (status != LDNS_STATUS_OK) { 00384 se_log_alert("update RRset[%i] to serial %u failed", 00385 rrset->rr_type, serial); 00386 return 1; 00387 } 00388 } 00389 rrs = rrs->next; 00390 } 00391 ldns_dnssec_rrs_free(rrset->add); 00392 rrset->add = NULL; 00393 rrset->add_count = 0; 00394 00395 /* update serial */ 00396 rrset->internal_serial = serial; 00397 rrset->initialized = 1; 00398 } 00399 return 0; 00400 } 00401 00406 void 00407 rrset_cancel_update(rrset_type* rrset) 00408 { 00409 if (rrset->add) { 00410 ldns_dnssec_rrs_deep_free(rrset->add); 00411 rrset->add = NULL; 00412 rrset->add_count = 0; 00413 } 00414 if (rrset->del) { 00415 ldns_dnssec_rrs_deep_free(rrset->del); 00416 rrset->del = NULL; 00417 rrset->del_count = 0; 00418 } 00419 return; 00420 } 00421 00426 int 00427 rrset_count_rr(rrset_type* rrset) 00428 { 00429 se_log_assert(rrset); 00430 return rrset->rr_count; 00431 } 00432 00433 00438 int 00439 rrset_count_add(rrset_type* rrset) 00440 { 00441 se_log_assert(rrset); 00442 return rrset->add_count; 00443 } 00444 00445 00450 int 00451 rrset_count_del(rrset_type* rrset) 00452 { 00453 se_log_assert(rrset); 00454 return rrset->del_count; 00455 } 00456 00457 00462 int 00463 rrset_count_RR(rrset_type* rrset) 00464 { 00465 se_log_assert(rrset); 00466 return ((rrset->rr_count + rrset->add_count) - rrset->del_count); 00467 } 00468 00469 00474 int 00475 rrset_add_rr(rrset_type* rrset, ldns_rr* rr) 00476 { 00477 ldns_status status = LDNS_STATUS_OK; 00478 00479 se_log_assert(rr); 00480 se_log_assert(rrset); 00481 se_log_assert(ldns_rr_get_type(rr) == rrset->rr_type); 00482 00483 if (!rrset->add) { 00484 rrset->add = ldns_dnssec_rrs_new(); 00485 } 00486 00487 if (!rrset->add->rr) { 00488 rrset->add->rr = rr; 00489 rrset->add_count = 1; 00490 log_rr(rr, "+rr", 6); 00491 } else { 00492 status = util_dnssec_rrs_add_rr(rrset->add, rr); 00493 if (status != LDNS_STATUS_OK) { 00494 if (status == LDNS_STATUS_NO_DATA) { 00495 se_log_warning("error adding RR to pending add RRset (%i): " 00496 "duplicate", rrset->rr_type); 00497 log_rr(rr, "+rr", 2); 00498 return 0; 00499 } else { 00500 se_log_error("error adding RR to pending add RRset (%i): %s", 00501 rrset->rr_type, ldns_get_errorstr_by_id(status)); 00502 log_rr(rr, "+rr", 1); 00503 ldns_dnssec_rrs_deep_free(rrset->add); 00504 rrset->add = NULL; 00505 rrset->add_count = 0; 00506 return 1; 00507 } 00508 } 00509 rrset->add_count += 1; 00510 log_rr(rr, "+rr", 6); 00511 } 00512 return 0; 00513 } 00514 00515 00520 int 00521 rrset_del_rr(rrset_type* rrset, ldns_rr* rr) 00522 { 00523 ldns_status status = LDNS_STATUS_OK; 00524 00525 se_log_assert(rr); 00526 se_log_assert(rrset); 00527 se_log_assert(ldns_rr_get_type(rr) == rrset->rr_type); 00528 00529 if (!rrset->del) { 00530 rrset->del = ldns_dnssec_rrs_new(); 00531 } 00532 00533 if (!rrset->del->rr) { 00534 rrset->del->rr = rr; 00535 rrset->del_count = 1; 00536 log_rr(rr, "-rr", 6); 00537 } else { 00538 status = util_dnssec_rrs_add_rr(rrset->del, rr); 00539 if (status != LDNS_STATUS_OK) { 00540 if (status == LDNS_STATUS_NO_DATA) { 00541 se_log_warning("error adding RR to pending del RRset (%i): " 00542 "duplicate", rrset->rr_type); 00543 log_rr(rr, "-rr", 2); 00544 return 0; 00545 } else { 00546 se_log_error("error adding RR to pending del RRset (%i): %s", 00547 rrset->rr_type, ldns_get_errorstr_by_id(status)); 00548 log_rr(rr, "-rr", 1); 00549 ldns_dnssec_rrs_deep_free(rrset->del); 00550 rrset->del = NULL; 00551 rrset->del_count = 0; 00552 return 1; 00553 } 00554 } 00555 rrset->del_count += 1; 00556 log_rr(rr, "-rr", 6); 00557 } 00558 return 0; 00559 } 00560 00561 00566 static int 00567 rrset_recycle_rrsigs(rrset_type* rrset, signconf_type* sc, time_t signtime, 00568 uint32_t* reusedsigs) 00569 { 00570 rrsigs_type* rrsigs = NULL; 00571 rrsigs_type* prev_rrsigs = NULL; 00572 rrsigs_type* next_rrsigs = NULL; 00573 uint32_t refresh = 0; 00574 uint32_t expiration = 0; 00575 uint32_t inception = 0; 00576 int drop_sig = 0; 00577 key_type* key = NULL; 00578 00579 if (sc && sc->sig_refresh_interval) { 00580 refresh = (uint32_t) (signtime + 00581 duration2time(sc->sig_refresh_interval)); 00582 } 00583 00584 /* 1. If the RRset has changed, drop all signatures */ 00585 /* 2. If Refresh is disabled, drop all signatures */ 00586 if (rrset->drop_signatures || !refresh) { 00587 se_log_debug("drop signatures for RRset[%i]", rrset->rr_type); 00588 if (rrset->rrsigs) { 00589 rrsigs_cleanup(rrset->rrsigs); 00590 rrset->rrsigs = NULL; 00591 } 00592 rrset->rrsig_count = 0; 00593 rrset->drop_signatures = 0; 00594 return 0; 00595 } 00596 00597 /* 3. Check every signature if it matches the recycling logic. */ 00598 rrsigs = rrset->rrsigs; 00599 while (rrsigs) { 00600 if (!rrsigs->rr) { 00601 se_log_warning("signature set has no RRSIG record: " 00602 "drop signatures for RRset[%i]", rrset->rr_type); 00603 rrsigs_cleanup(rrset->rrsigs); 00604 rrset->rrsigs = NULL; 00605 rrset->rrsig_count = 0; 00606 rrset->drop_signatures = 0; 00607 return 0; 00608 } 00609 00610 expiration = ldns_rdf2native_int32( 00611 ldns_rr_rrsig_expiration(rrsigs->rr)); 00612 inception = ldns_rdf2native_int32( 00613 ldns_rr_rrsig_inception(rrsigs->rr)); 00614 00615 if (expiration < refresh) { 00616 /* 3a. Expiration - Refresh has passed */ 00617 drop_sig = 1; 00618 se_log_deeebug("refresh signature for RRset[%i]: expiration minus " 00619 "refresh has passed: %u - %u < (signtime)", 00620 rrset->rr_type, expiration, refresh, (uint32_t) signtime); 00621 } else if (inception > (uint32_t) signtime) { 00622 /* 3b. Inception has not yet passed */ 00623 drop_sig = 1; 00624 se_log_deeebug("refresh signature for RRset[%i]: inception has " 00625 "not passed: %u < %u (signtime)", 00626 rrset->rr_type, inception, (uint32_t) signtime); 00627 } else { 00628 /* 3c. Corresponding key is dead */ 00629 key = keylist_lookup(sc->keys, rrsigs->key_locator); 00630 if (!key) { 00631 drop_sig = 1; 00632 se_log_deeebug("refresh signature for RRset[%i]: key %s %u " 00633 "is dead", 00634 rrset->rr_type, rrsigs->key_locator, rrsigs->key_flags); 00635 } else if (key->flags != rrsigs->key_flags) { 00636 drop_sig = 1; 00637 se_log_deeebug("refresh signature for RRset[%i]: key %s %u " 00638 "flags mismatch", 00639 rrset->rr_type, rrsigs->key_locator, rrsigs->key_flags); 00640 } 00641 } 00642 00643 next_rrsigs = rrsigs->next; 00644 if (drop_sig) { 00645 /* A rule mismatched, refresh signature */ 00646 if (prev_rrsigs) { 00647 prev_rrsigs->next = rrsigs->next; 00648 } else { 00649 rrset->rrsigs = rrsigs->next; 00650 } 00651 log_rr(rrsigs->rr, "-RRSIG", 6); 00652 rrset->rrsig_count -= 1; 00653 rrsigs->next = NULL; 00654 rrsigs_cleanup(rrsigs); 00655 } else { 00656 /* All rules ok, recycle signature */ 00657 se_log_deeebug("recycle signature for RRset[%i] (refresh=%u, " 00658 "signtime=%u, inception=%u, expiration=%u)", rrset->rr_type, 00659 refresh, (uint32_t) signtime, inception, expiration); 00660 log_rr(rrsigs->rr, "*RRSIG", 6); 00661 *reusedsigs += 1; 00662 prev_rrsigs = rrsigs; 00663 } 00664 rrsigs = next_rrsigs; 00665 } 00666 return 0; 00667 } 00668 00669 00674 static void 00675 rrset_sign_set_timers(signconf_type* sc, ldns_rr_type rrtype, time_t signtime, 00676 time_t* inception, time_t* expiration) 00677 { 00678 time_t jitter = 0; 00679 time_t offset = 0; 00680 time_t validity = 0; 00681 time_t random_jitter = 0; 00682 00683 se_log_assert(sc); 00684 se_log_assert(rrtype); 00685 se_log_assert(signtime); 00686 00687 jitter = duration2time(sc->sig_jitter); 00688 if (jitter) { 00689 random_jitter = se_rand(jitter*2); 00690 } 00691 offset = duration2time(sc->sig_inception_offset); 00692 if (rrtype == LDNS_RR_TYPE_NSEC || rrtype == LDNS_RR_TYPE_NSEC3) { 00693 validity = duration2time(sc->sig_validity_denial); 00694 } else { 00695 validity = duration2time(sc->sig_validity_default); 00696 } 00697 00701 if (((validity + offset + random_jitter) - jitter) < 00702 ((validity + offset) - jitter) ) { 00703 se_log_error("signature validity %u too low, should be at least %u", 00704 ((validity + offset + random_jitter) - jitter), 00705 ((validity + offset) - jitter)); 00706 } else if (((validity + offset + random_jitter) - jitter) > 00707 ((validity + offset) + jitter) ) { 00708 se_log_error("signature validity %u too high, should be at most %u", 00709 ((validity + offset + random_jitter) - jitter), 00710 ((validity + offset) + jitter)); 00711 } else { 00712 se_log_debug("signature validity %u in range [%u - %u]", 00713 ((validity + offset + random_jitter) - jitter), 00714 ((validity + offset) - jitter), 00715 ((validity + offset) + jitter)); 00716 } 00717 00718 *inception = signtime - offset; 00719 *expiration = (signtime + validity + random_jitter) - jitter; 00720 return; 00721 } 00722 00723 00728 static int 00729 rrset_signed_with_algorithm(rrset_type* rrset, uint8_t algorithm) 00730 { 00731 rrsigs_type* rrsigs = NULL; 00732 00733 if (!rrset || !algorithm) { 00734 return 0; 00735 } 00736 00737 rrsigs = rrset->rrsigs; 00738 while (rrsigs) { 00739 if (rrsigs->rr && algorithm == 00740 ldns_rdf2native_int8(ldns_rr_rrsig_algorithm(rrsigs->rr))) { 00741 return 1; 00742 } 00743 rrsigs = rrsigs->next; 00744 } 00745 00746 return 0; 00747 } 00748 00753 static ldns_rr_list* 00754 rrset2rrlist(rrset_type* rrset) 00755 { 00756 ldns_dnssec_rrs* rrs = NULL; 00757 ldns_rr_list* rr_list = NULL; 00758 int error = 0; 00759 00760 rr_list = ldns_rr_list_new(); 00761 rrs = rrset->rrs; 00762 while (rrs && rrs->rr) { 00763 error = (int) ldns_rr_list_push_rr(rr_list, rrs->rr); 00764 if (!error) { 00765 ldns_rr_list_free(rr_list); 00766 return NULL; 00767 } 00768 if (rrset->rr_type == LDNS_RR_TYPE_CNAME || 00769 rrset->rr_type == LDNS_RR_TYPE_DNAME) { 00770 /* singleton types */ 00771 return rr_list; 00772 } 00773 00774 rrs = rrs->next; 00775 } 00776 return rr_list; 00777 } 00778 00779 00784 int 00785 rrset_sign(hsm_ctx_t* ctx, rrset_type* rrset, ldns_rdf* owner, 00786 signconf_type* sc, time_t signtime, stats_type* stats) 00787 { 00788 int error = 0; 00789 uint32_t newsigs = 0; 00790 uint32_t reusedsigs = 0; 00791 ldns_rr* rrsig = NULL; 00792 ldns_rr_list* rr_list = NULL; 00793 rrsigs_type* new_rrsigs = NULL; 00794 rrsigs_type* walk_rrsigs = NULL; 00795 key_type* key = NULL; 00796 time_t inception = 0; 00797 time_t expiration = 0; 00798 00799 se_log_assert(rrset); 00800 se_log_assert(sc); 00801 se_log_assert(stats); 00802 00803 /* drop unrecyclable signatures */ 00804 error = rrset_recycle_rrsigs(rrset, sc, signtime, &reusedsigs); 00805 00806 /* convert the RRset */ 00807 rr_list = rrset2rrlist(rrset); 00808 if (!rr_list) { 00809 se_log_error("error signing RRset[%i], cannot convert to rr " 00810 "list", rrset->rr_type); 00811 return 1; 00812 } 00813 if (ldns_rr_list_rr_count(rr_list) <= 0) { 00814 /* empty RRset, no signatures needed */ 00815 ldns_rr_list_free(rr_list); 00816 return 0; 00817 } 00818 00819 /* prepare for signing */ 00820 new_rrsigs = rrsigs_create(); 00821 if (!rrset->rrsigs) { 00822 rrset->rrsigs = rrsigs_create(); 00823 } 00824 rrset_sign_set_timers(sc, rrset->rr_type, signtime, 00825 &inception, &expiration); 00826 00827 key = sc->keys->first_key; 00828 while (key) { 00829 /* ksk or zsk ? */ 00830 if (!key->zsk && rrset->rr_type != LDNS_RR_TYPE_DNSKEY) { 00831 se_log_deeebug("skipping key %s for signing RRset[%i]: no " 00832 "active ZSK", key->locator, rrset->rr_type); 00833 key = key->next; 00834 continue; 00835 } 00836 00837 if (!key->ksk && rrset->rr_type == LDNS_RR_TYPE_DNSKEY) { 00838 se_log_deeebug("skipping key %s for signing RRset[DNSKEY]: no " 00839 "active KSK", key->locator); 00840 key = key->next; 00841 continue; 00842 } 00843 00844 /* is there a signature with this algorithm already? */ 00845 if (rrset_signed_with_algorithm(rrset, key->algorithm)) { 00846 se_log_deeebug("skipping key %s for signing: RRset[%i] " 00847 "already has signature with same algorithm", key->locator); 00848 key = key->next; 00849 continue; 00850 } 00851 00857 /* sign the RRset with current key */ 00858 se_log_deeebug("signing RRset[%i] with key %s", 00859 rrset->rr_type, key->locator); 00860 rrsig = hsm_sign_rrset_with_key(ctx, owner, key, rr_list, 00861 inception, expiration); 00862 if (!rrsig) { 00863 se_log_error("error creating RRSIG for rrset[%i]", 00864 rrset->rr_type); 00865 ldns_rr_list_free(rr_list); 00866 rrsigs_cleanup(new_rrsigs); 00867 return 1; 00868 } 00869 /* add the signature to the set of new signatures */ 00870 se_log_deeebug("new signature created for RRset[%i]", 00871 rrset->rr_type); 00872 log_rr(rrsig, "+RRSIG", 6); 00873 error = rrsigs_add_sig(new_rrsigs, rrsig, key->locator, 00874 key->flags); 00875 if (error) { 00876 se_log_error("error adding RRSIG to list of signatures"); 00877 log_rr(rrsig, "+RRSIG", 1); 00878 ldns_rr_list_free(rr_list); 00879 rrsigs_cleanup(new_rrsigs); 00880 return 1; 00881 } 00882 00883 /* next key */ 00884 key = key->next; 00885 } 00886 00887 /* now add the signatures to the RRset */ 00888 walk_rrsigs = new_rrsigs; 00889 while (walk_rrsigs) { 00890 if (walk_rrsigs->rr) { 00891 se_log_deeebug("adding signature to RRset[%i]", 00892 rrset->rr_type); 00893 log_rr(rrsig, "+RRSIG", 6); 00894 error = rrsigs_add_sig(rrset->rrsigs, 00895 ldns_rr_clone(walk_rrsigs->rr), 00896 walk_rrsigs->key_locator, walk_rrsigs->key_flags); 00897 if (error) { 00898 se_log_error("error adding RRSIG to RRset[%i]", 00899 rrset->rr_type); 00900 log_rr(walk_rrsigs->rr, "+RRSIG", 1); 00901 ldns_rr_list_free(rr_list); 00902 rrsigs_cleanup(new_rrsigs); 00903 return 1; 00904 } 00905 rrset->rrsig_count += 1; 00906 log_rr(walk_rrsigs->rr, "+RRSIG", 6); 00907 newsigs++; 00908 } 00909 walk_rrsigs = walk_rrsigs->next; 00910 } 00911 00912 /* clean up */ 00913 rrsigs_cleanup(new_rrsigs); 00914 ldns_rr_list_free(rr_list); 00915 00916 if (rrset->rr_type == LDNS_RR_TYPE_SOA) { 00917 stats->sig_soa_count += newsigs; 00918 } 00919 stats->sig_count += newsigs; 00920 stats->sig_reuse += reusedsigs; 00921 return 0; 00922 } 00923 00924 00929 int 00930 rrset_del_rrs(rrset_type* rrset) 00931 { 00932 ldns_dnssec_rrs* rrs = NULL; 00933 ldns_rr* rr = NULL; 00934 00935 se_log_assert(rrset); 00936 if (!rrset->rrs) { 00937 return 0; 00938 } 00939 if (!rrset->del) { 00940 rrset->del = ldns_dnssec_rrs_new(); 00941 } 00942 rrs = rrset->rrs; 00943 while (rrs) { 00944 if (rrs->rr) { 00945 rr = ldns_rr_clone(rrs->rr); 00946 if (rrset_del_rr(rrset, rr) != 0) { 00947 return 1; 00948 } 00949 } 00950 rrs = rrs->next; 00951 } 00952 return 0; 00953 } 00954 00955 00960 void 00961 rrset_cleanup(rrset_type* rrset) 00962 { 00963 if (rrset) { 00964 if (rrset->rrs) { 00965 ldns_dnssec_rrs_deep_free(rrset->rrs); 00966 rrset->rrs = NULL; 00967 } 00968 if (rrset->add) { 00969 ldns_dnssec_rrs_deep_free(rrset->add); 00970 rrset->add = NULL; 00971 } 00972 if (rrset->del) { 00973 ldns_dnssec_rrs_deep_free(rrset->del); 00974 rrset->del = NULL; 00975 } 00976 if (rrset->rrsigs) { 00977 rrsigs_cleanup(rrset->rrsigs); 00978 rrset->rrsigs = NULL; 00979 } 00980 se_free((void*) rrset); 00981 } else { 00982 se_log_warning("cleanup empty rrset"); 00983 } 00984 return; 00985 } 00986 00987 00992 void 00993 rrset_print(FILE* fd, rrset_type* rrset, int skip_rrsigs) 00994 { 00995 se_log_assert(fd); 00996 se_log_assert(rrset); 00997 00998 if (rrset->rrs) { 00999 if (rrset->rr_type == LDNS_RR_TYPE_CNAME || 01000 rrset->rr_type == LDNS_RR_TYPE_DNAME) { 01001 /* singleton types */ 01002 if (rrset->rrs->rr) { 01003 ldns_rr_print(fd, rrset->rrs->rr); 01004 } 01005 } else { 01006 ldns_dnssec_rrs_print(fd, rrset->rrs); 01007 } 01008 } 01009 if (rrset->rrsigs && !skip_rrsigs) { 01010 rrsigs_print(fd, rrset->rrsigs, 0); 01011 } 01012 return; 01013 } 01014 01015 01020 void 01021 rrset_print_rrsig(FILE* fd, rrset_type* rrset) 01022 { 01023 se_log_assert(fd); 01024 se_log_assert(rrset); 01025 01026 if (rrset->rrsigs) { 01027 rrsigs_print(fd, rrset->rrsigs, 1); 01028 } 01029 return; 01030 }