OpenDNSSEC-signer  1.3.15
rrset.c
Go to the documentation of this file.
1 /*
2  * $Id: rrset.c 7298 2013-09-11 11:26:35Z matthijs $
3  *
4  * Copyright (c) 2009 NLNet Labs. All rights reserved.
5  *
6  * Redistribution and use in source and binary forms, with or without
7  * modification, are permitted provided that the following conditions
8  * are met:
9  * 1. Redistributions of source code must retain the above copyright
10  * notice, this list of conditions and the following disclaimer.
11  * 2. Redistributions in binary form must reproduce the above copyright
12  * notice, this list of conditions and the following disclaimer in the
13  * documentation and/or other materials provided with the distribution.
14  *
15  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
16  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
17  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18  * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
19  * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
20  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
21  * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
22  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
23  * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
24  * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
25  * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26  *
27  */
28 
34 #include "config.h"
35 #include "daemon/worker.h"
36 #include "scheduler/fifoq.h"
37 #include "shared/allocator.h"
38 #include "shared/duration.h"
39 #include "shared/file.h"
40 #include "shared/hsm.h"
41 #include "shared/log.h"
42 #include "shared/status.h"
43 #include "shared/util.h"
44 #include "signer/rrset.h"
45 
46 #include <ldns/ldns.h>
47 #include <stdlib.h>
48 #include <unistd.h>
49 
50 static const char* rrset_str = "rrset";
51 
52 
57 void
58 log_rr(ldns_rr* rr, const char* pre, int level)
59 {
60  char* str = NULL;
61  size_t i = 0;
62 
63  if (ods_log_get_level() < level + 2) return;
64 
65  str = ldns_rr2str(rr);
66  if (str) {
67  str[(strlen(str))-1] = '\0';
68  /* replace tabs with white space */
69  for (i=0; i < strlen(str); i++) {
70  if (str[i] == '\t') {
71  str[i] = ' ';
72  }
73  }
74 
75  if (level == 1) { /* LOG_ERR */
76  ods_log_error("%s %s", pre?pre:"", str);
77  } else if (level == 2) { /* LOG_WARNING */
78  ods_log_warning("%s %s", pre?pre:"", str);
79  } else if (level == 3) { /* LOG_NOTICE */
80  ods_log_info("%s %s", pre?pre:"", str);
81  } else if (level == 4) { /* LOG_INFO */
82  ods_log_verbose("%s %s", pre?pre:"", str);
83  } else if (level == 5) { /* LOG_DEBUG */
84  ods_log_debug("%s %s", pre?pre:"", str);
85  } else if (level == 6) { /* more debugging */
86  ods_log_deeebug("%s %s", pre?pre:"", str);
87  } else { /* hardcore debugging */
88  ods_log_deeebug("%s %s", pre?pre:"", str);
89  }
90  free((void*)str);
91  }
92  return;
93 }
94 
95 
100 rrset_type*
101 rrset_create(ldns_rr_type rrtype)
102 {
103  allocator_type* allocator = NULL;
104  rrset_type* rrset = NULL;
105 
106  if (!rrtype) {
107  ods_log_error("[%s] unable to create RRset: no RRtype", rrset_str);
108  return NULL;
109  }
110  ods_log_assert(rrtype);
111 
112  allocator = allocator_create(malloc, free);
113  if (!allocator) {
114  ods_log_error("[%s] unable to create RRset %u: create allocator "
115  "failed", rrset_str, (unsigned) rrtype);
116  return NULL;
117  }
118  ods_log_assert(allocator);
119 
120  rrset = (rrset_type*) allocator_alloc(allocator, sizeof(rrset_type));
121  if (!rrset) {
122  ods_log_error("[%s] unable to create RRset %u: allocator failed",
123  rrset_str, (unsigned) rrtype);
124  allocator_cleanup(allocator);
125  return NULL;
126  }
127  ods_log_assert(rrset);
128 
129  rrset->allocator = allocator;
130  rrset->rr_type = rrtype;
131  rrset->rr_count = 0;
132  rrset->add_count = 0;
133  rrset->del_count = 0;
134  rrset->rrsig_count = 0;
135  rrset->needs_signing = 0;
136  rrset->rrs = ldns_dnssec_rrs_new();
137  rrset->add = NULL;
138  rrset->del = NULL;
139  rrset->rrsigs = NULL;
140  return rrset;
141 }
142 
143 
149 rrset_recover(rrset_type* rrset, ldns_rr* rrsig, const char* locator,
150  uint32_t flags)
151 {
152  ods_status status = ODS_STATUS_OK;
153 
154  if (!rrset || !rrsig || !locator || !flags) {
155  ods_log_error("[%s] unable to recover RRSIG: missing parameters",
156  rrset_str);
157  return ODS_STATUS_ASSERT_ERR;
158  }
159 
160  if (!rrset->rrsigs) {
161  rrset->rrsigs = rrsigs_create();
162  }
163 
164  status = rrsigs_add_sig(rrset->rrsigs, rrsig, locator, flags);
165  if (status != ODS_STATUS_OK) {
166  ods_log_error("[%s] unable to recover RRSIG: failed to add", rrset_str);
167  log_rr(rrsig, "+RRSIG", 1);
168  } else {
169  rrset->rrsig_count += 1;
175  rrset->needs_signing = 0;
176  }
177  return status;
178 }
179 
180 
185 static int
186 rrs_examine_ns_rdata(ldns_dnssec_rrs* rrs, ldns_rdf* nsdname)
187 {
188  ldns_dnssec_rrs* walk = NULL;
189  if (!rrs || !nsdname) {
190  return 0;
191  }
192  walk = rrs;
193  while (walk) {
194  if (walk->rr &&
195  ldns_dname_compare(ldns_rr_rdf(walk->rr, 0), nsdname) == 0) {
196  return 1;
197  }
198  walk = walk->next;
199  }
200  return 0;
201 }
202 
203 
208 int
209 rrset_examine_ns_rdata(rrset_type* rrset, ldns_rdf* nsdname)
210 {
211  if (!rrset || !nsdname || rrset->rr_type != LDNS_RR_TYPE_NS) {
212  return 0;
213  }
214  if (rrs_examine_ns_rdata(rrset->add, nsdname)) {
215  return 1;
216  }
217  if (rrs_examine_ns_rdata(rrset->del, nsdname)) {
218  return 0;
219  }
220  return rrs_examine_ns_rdata(rrset->rrs, nsdname);
221 }
222 
223 
228 size_t
230 {
231  ods_log_assert(rrset);
232  return ((rrset->rr_count + rrset->add_count) - rrset->del_count);
233 }
234 
235 
240 size_t
241 rrset_count_rr(rrset_type* rrset, int which)
242 {
243  if (!rrset) {
244  return 0;
245  }
246  switch (which) {
247  case COUNT_ADD:
248  return rrset->add_count;
249  case COUNT_DEL:
250  return rrset->del_count;
251  case COUNT_RR:
252  default:
253  return rrset->rr_count;
254  }
255  /* not reached */
256  return rrset->rr_count;
257 }
258 
259 
264 ldns_rr*
265 rrset_add_rr(rrset_type* rrset, ldns_rr* rr)
266 {
267  ldns_status status = LDNS_STATUS_OK;
268 
269  if (!rr) {
270  ods_log_error("[%s] unable to add RR: no RR", rrset_str);
271  return NULL;
272  }
273  ods_log_assert(rr);
274 
275  if (!rrset) {
276  ods_log_error("[%s] unable to add RR: no storage", rrset_str);
277  return NULL;
278  }
279  ods_log_assert(rrset);
280 
281  if (rrset->rr_type != ldns_rr_get_type(rr)) {
282  ods_log_error("[%s] unable to add RR: RRtype mismatch", rrset_str);
283  return NULL;
284  }
285 
286  if (!rrset->add) {
287  rrset->add = ldns_dnssec_rrs_new();
288  }
289 
290  if (!rrset->add->rr) {
291  rrset->add->rr = rr;
292  rrset->add_count = 1;
293  log_rr(rr, "+rr", 7);
294  } else {
295  status = util_dnssec_rrs_add_rr(rrset->add, rr);
296  if (status != LDNS_STATUS_OK) {
297  if (status == LDNS_STATUS_NO_DATA) {
298  ods_log_warning("[%s] unable to add RR to RRset (%i): "
299  "duplicate", rrset_str, rrset->rr_type);
300  log_rr(rr, "+rr", 2);
301  /* filter out duplicates */
302  return rr;
303  } else {
304  ods_log_error("[%s] unable to add RR to RRset (%i): %s",
305  rrset_str, rrset->rr_type,
306  ldns_get_errorstr_by_id(status));
307  log_rr(rr, "+rr", 1);
308  ldns_dnssec_rrs_deep_free(rrset->add);
309  rrset->add = NULL;
310  rrset->add_count = 0;
311  return NULL;
312  }
313  }
314  rrset->add_count += 1;
315  log_rr(rr, "+rr", 7);
316  }
317  return rr;
318 }
319 
320 
325 ldns_rr*
326 rrset_del_rr(rrset_type* rrset, ldns_rr* rr, int dupallowed)
327 {
328  ldns_status status = LDNS_STATUS_OK;
329 
330  if (!rr) {
331  ods_log_error("[%s] unable to delete RR: no RR", rrset_str);
332  return NULL;
333  }
334  ods_log_assert(rr);
335 
336  if (!rrset) {
337  ods_log_error("[%s] unable to delete RR: no storage", rrset_str);
338  return NULL;
339  }
340  ods_log_assert(rrset);
341 
342  if (rrset->rr_type != ldns_rr_get_type(rr)) {
343  ods_log_error("[%s] unable to delete RR: RRtype mismatch", rrset_str);
344  return NULL;
345  }
346 
347  if (!rrset->del) {
348  rrset->del = ldns_dnssec_rrs_new();
349  }
350 
351  if (!rrset->del->rr) {
352  rrset->del->rr = rr;
353  rrset->del_count = 1;
354  log_rr(rr, "-rr", 7);
355  } else {
356  status = util_dnssec_rrs_add_rr(rrset->del, rr);
357  if (status != LDNS_STATUS_OK) {
358  if (status == LDNS_STATUS_NO_DATA) {
359  if (dupallowed) {
360  return rr;
361  }
362  ods_log_warning("[%s] unable to delete RR from RRset (%i): "
363  "duplicate", rrset_str, rrset->rr_type);
364  log_rr(rr, "-rr", 2);
365  /* filter out duplicates */
366  return rr;
367  } else {
368  ods_log_error("[%s] unable to delete RR from RRset (%i): %s",
369  rrset_str, rrset->rr_type,
370  ldns_get_errorstr_by_id(status));
371  log_rr(rr, "-rr", 1);
372  ldns_dnssec_rrs_deep_free(rrset->del);
373  rrset->del = NULL;
374  rrset->del_count = 0;
375  return NULL;
376  }
377  }
378  rrset->del_count += 1;
379  log_rr(rr, "-rr", 7);
380  }
381  return rr;
382 }
383 
384 
391 {
392  ldns_dnssec_rrs* rrs = NULL;
393  ldns_rr* del_rr = NULL;
394  int error = 0;
395 
396  if (rrset) {
397  rrs = rrset->rrs;
398  }
399 
400  while (rrs) {
401  if (rrs->rr) {
402  del_rr = ldns_rr_clone(rrs->rr);
403  if (rrset_del_rr(rrset, del_rr,
404  (ldns_rr_get_type(del_rr) == LDNS_RR_TYPE_DNSKEY)) == NULL) {
405  ods_log_error("[%s] unable to wipe RR from RRset (%i)",
406  rrset_str, rrset->rr_type);
407  ldns_rr_free(del_rr);
408  error = 1;
409  }
410  del_rr = NULL;
411  }
412  rrs = rrs->next;
413  }
414 
415  if (error) {
416  return ODS_STATUS_ERR;
417  }
418  return ODS_STATUS_OK;
419 }
420 
421 
428 {
429  ods_status status = ODS_STATUS_OK;
430  ldns_status lstatus = LDNS_STATUS_OK;
431  ldns_dnssec_rrs* current = NULL;
432  ldns_dnssec_rrs* pending = NULL;
433  ldns_dnssec_rrs* prev = NULL;
434  ldns_rr* rr = NULL;
435  int cmp = 0;
436 
437  if (!rrset) {
438  return status;
439  }
440 
441  current = rrset->rrs;
442  pending = rrset->add;
443 
444  if (!current || !current->rr) {
445  current = NULL;
446  }
447  if (!pending || !pending->rr) {
448  pending = NULL;
449  }
450 
451  while (current && pending) {
452  lstatus = util_dnssec_rrs_compare(current->rr, pending->rr, &cmp);
453  if (lstatus != LDNS_STATUS_OK) {
454  ods_log_error("[%s] diff failed: compare failed (%s)",
455  rrset_str, ldns_get_errorstr_by_id(lstatus));
456  return ODS_STATUS_ERR;
457  }
458 
459  if (cmp > 0) {
460  prev = pending;
461  pending = pending->next;
462  } else if (cmp < 0) {
463  /* pend current RR to be removed */
464  if (rrset->rr_type != LDNS_RR_TYPE_DNSKEY ||
465  !keylist_lookup_by_dnskey(kl, current->rr)) {
466 
467  rr = ldns_rr_clone(current->rr);
468  rr = rrset_del_rr(rrset, rr,
469  (ldns_rr_get_type(rr) == LDNS_RR_TYPE_DNSKEY));
470  if (!rr) {
471  ods_log_error("[%s] diff failed: failed to delete RR",
472  rrset_str);
473  return ODS_STATUS_ERR;
474  }
475  }
476 
477  current = current->next;
478  } else { /* equal RRs */
479  /* TTL is not compared in util_dnssec_rrs_compare() so we copy it */
480  if (ldns_rr_ttl(current->rr) != ldns_rr_ttl(pending->rr)) {
481  ldns_rr_set_ttl(current->rr, ldns_rr_ttl(pending->rr));
482  rrset->needs_signing = 1;
483  }
484  /* remove pending RR */
485  if (!prev) {
486  rrset->add = pending->next;
487  } else {
488  prev->next = pending->next;
489  }
490  pending->next = NULL;
491  rrset->add_count -= 1;
492 
493  ldns_dnssec_rrs_deep_free(pending);
494  pending = NULL;
495 
496  current = current->next;
497  if (!prev) {
498  pending = rrset->add;
499  } else {
500  pending = prev->next;
501  }
502  }
503  }
504 
505  if (pending) {
506  ods_log_assert(!current);
507  /* all newly added RRs */
508  }
509 
510  if (current) {
511  ods_log_assert(!pending);
512  while (current) {
513  /* pend current RR to be removed */
514  if (rrset->rr_type != LDNS_RR_TYPE_DNSKEY ||
515  !keylist_lookup_by_dnskey(kl, current->rr)) {
516 
517  rr = ldns_rr_clone(current->rr);
518  rr = rrset_del_rr(rrset, rr,
519  (ldns_rr_get_type(rr) == LDNS_RR_TYPE_DNSKEY));
520  if (!rr) {
521  ods_log_error("[%s] diff failed: failed to delete RR",
522  rrset_str);
523  return ODS_STATUS_ERR;
524  }
525  }
526  current = current->next;
527  }
528  }
529  return ODS_STATUS_OK;
530 }
531 
532 
537 static ods_status
538 rrset_commit_del(rrset_type* rrset, ldns_rr* rr)
539 {
540  ldns_status status = LDNS_STATUS_OK;
541  ldns_dnssec_rrs* rrs = NULL;
542  ldns_dnssec_rrs* prev_rrs = NULL;
543  int cmp = 0;
544 
545  if (!rr) {
546  ods_log_error("[%s] unable to commit del RR: no RR", rrset_str);
547  return ODS_STATUS_ASSERT_ERR;
548  }
549  ods_log_assert(rr);
550  if (!rrset) {
551  ods_log_error("[%s] unable to commit del RR: no storage", rrset_str);
552  return ODS_STATUS_ASSERT_ERR;
553  }
554  ods_log_assert(rrset);
555 
556  rrs = rrset->rrs;
557  while (rrs) {
558  status = util_dnssec_rrs_compare(rrs->rr, rr, &cmp);
559  if (status != LDNS_STATUS_OK) {
560  ods_log_error("[%s] unable to commit del RR: compare failed",
561  rrset_str);
562  return ODS_STATUS_ERR;
563  }
564 
565  if (cmp == 0) {
566  /* this is it */
567  if (prev_rrs) {
568  prev_rrs->next = rrs->next;
569  } else {
570  rrset->rrs = rrs->next;
571  }
572  rrs->next = NULL;
573  ldns_dnssec_rrs_deep_free(rrs);
574  rrs = NULL;
575 
576  rrset->rr_count -= 1;
577  rrset->del_count -= 1;
578  log_rr(rr, "-RR", 6);
579  return ODS_STATUS_OK;
580  }
581 
582  /* keep looking */
583  prev_rrs = rrs;
584  rrs = rrs->next;
585  }
586 
587  ods_log_warning("[%s] unable to commit del RR: no such RR", rrset_str);
588  log_rr(rr, "-RR", 2);
589  return ODS_STATUS_UNCHANGED;
590 }
591 
592 
597 static ods_status
598 rrset_commit_add(rrset_type* rrset, ldns_rr* rr)
599 {
600  ldns_status status = LDNS_STATUS_OK;
601 
602  if (!rr) {
603  ods_log_error("[%s] unable to commit add RR: no RR", rrset_str);
604  return ODS_STATUS_ASSERT_ERR;
605  }
606  ods_log_assert(rr);
607  if (!rrset) {
608  ods_log_error("[%s] unable to commit add RR: no storage", rrset_str);
609  return ODS_STATUS_ASSERT_ERR;
610  }
611  ods_log_assert(rrset);
612 
613  if (!rrset->rrs) {
614  rrset->rrs = ldns_dnssec_rrs_new();
615  }
616 
617  if (!rrset->rrs->rr) {
618  rrset->rrs->rr = rr;
619  rrset->rr_count += 1;
620  rrset->add_count -= 1;
621  log_rr(rr, "+RR", 6);
622  return ODS_STATUS_OK;
623  } else {
624  status = util_dnssec_rrs_add_rr(rrset->rrs, rr);
625  if (status != LDNS_STATUS_OK) {
626  if (status == LDNS_STATUS_NO_DATA) {
627  ods_log_warning("[%s] unable to commit add RR: duplicate",
628  rrset_str);
629  log_rr(rr, "+RR", 2);
630  return ODS_STATUS_UNCHANGED;
631  } else {
632  ods_log_error("[%s] unable to commit add RR: %s",
633  rrset_str, ldns_get_errorstr_by_id(status));
634  log_rr(rr, "+RR", 1);
635  return ODS_STATUS_ERR;
636  }
637  }
638  log_rr(rr, "+RR", 6);
639  rrset->rr_count += 1;
640  rrset->add_count -= 1;
641  return ODS_STATUS_OK;
642  }
643  /* not reached */
644  return ODS_STATUS_ERR;
645 }
646 
647 
654 {
655  ldns_dnssec_rrs* rrs = NULL;
656  ods_status status = ODS_STATUS_OK;
657 
658  if (!rrset) {
659  return ODS_STATUS_ASSERT_ERR;
660  }
661  ods_log_assert(rrset);
662 
663  if (rrset->del_count || rrset->add_count) {
664  rrset->needs_signing = 1;
665  }
666 
667  /* delete RRs */
668  rrs = rrset->del;
669  while (rrs) {
670  status = rrset_commit_del(rrset, rrs->rr);
671  if (status != ODS_STATUS_OK) {
672  ods_log_alert("[%s] commit RRset (%i) failed: %s", rrset_str,
673  rrset->rr_type, ods_status2str(status));
674  return status;
675  }
676  rrs = rrs->next;
677  }
678  ldns_dnssec_rrs_deep_free(rrset->del);
679  rrset->del = NULL;
680  rrset->del_count = 0;
681 
682  /* add RRs */
683  rrs = rrset->add;
684  while (rrs) {
685  status = rrset_commit_add(rrset, rrs->rr);
686  if (status != ODS_STATUS_OK) {
687  ods_log_alert("[%s] commit RRset (%i) failed: %s", rrset_str,
688  rrset->rr_type, ods_status2str(status));
689  return status;
690  }
691  rrs = rrs->next;
692  }
693  ldns_dnssec_rrs_free(rrset->add);
694  rrset->add = NULL;
695  rrset->add_count = 0;
696 
697  /* update serial */
698 
699  return ODS_STATUS_OK;
700 }
701 
702 
707 void
709 {
710  if (!rrset) {
711  return;
712  }
713 
714  if (rrset->add) {
715  ldns_dnssec_rrs_deep_free(rrset->add);
716  rrset->add = NULL;
717  rrset->add_count = 0;
718  }
719  if (rrset->del) {
720  ldns_dnssec_rrs_deep_free(rrset->del);
721  rrset->del = NULL;
722  rrset->del_count = 0;
723  }
724  return;
725 }
726 
727 
732 static uint32_t
733 rrset_recycle(rrset_type* rrset, signconf_type* sc, time_t signtime)
734 {
735  rrsigs_type* rrsigs = NULL;
736  rrsigs_type* prev_rrsigs = NULL;
737  rrsigs_type* next_rrsigs = NULL;
738  uint32_t refresh = 0;
739  uint32_t expiration = 0;
740  uint32_t inception = 0;
741  uint32_t reusedsigs = 0;
742  int drop_sig = 0;
743  key_type* key = NULL;
744 
745  /* Calculate the Refresh Window = Signing time + Refresh */
746  if (sc && sc->sig_refresh_interval) {
747  refresh = (uint32_t) (signtime +
749  }
750 
751  /* 1. If the RRset has changed, drop all signatures */
752  /* 2. If Refresh is disabled, drop all signatures */
753  if (rrset->needs_signing || refresh <= (uint32_t) signtime) {
754  ods_log_deeebug("[%s] drop signatures for RRset[%i]", rrset_str,
755  rrset->rr_type);
756  if (rrset->rrsigs) {
757  rrsigs_cleanup(rrset->rrsigs);
758  rrset->rrsigs = NULL;
759  }
760  rrset->rrsig_count = 0;
761  rrset->needs_signing = 0;
762  return 0;
763  }
764 
765  /* 3. Check every signature if it matches the recycling logic. */
766  rrsigs = rrset->rrsigs;
767  while (rrsigs) {
768  if (!rrsigs->rr) {
769  ods_log_debug("[%s] signature set has no RRSIG record: "
770  "drop signatures for RRset[%i]", rrset_str, rrset->rr_type);
771  rrsigs_cleanup(rrset->rrsigs);
772  rrset->rrsigs = NULL;
773  rrset->rrsig_count = 0;
774  rrset->needs_signing = 0;
775  return 0;
776  }
777 
778  expiration = ldns_rdf2native_int32(
779  ldns_rr_rrsig_expiration(rrsigs->rr));
780  inception = ldns_rdf2native_int32(
781  ldns_rr_rrsig_inception(rrsigs->rr));
782 
783  if (expiration < refresh) {
784  /* 3a. Expiration - Refresh has passed */
785  drop_sig = 1;
786  ods_log_deeebug("[%s] refresh signature for RRset[%i]: "
787  "expiration minus refresh has passed: %u - %u < (signtime)",
788  rrset_str, rrset->rr_type, expiration, refresh,
789  (uint32_t) signtime);
790  } else if (inception > (uint32_t) signtime) {
791  /* 3b. Inception has not yet passed */
792  drop_sig = 1;
793  ods_log_deeebug("[%s] refresh signature for RRset[%i]: "
794  "inception has not passed: %u < %u (signtime)", rrset_str,
795  rrset->rr_type, inception, (uint32_t) signtime);
796  } else {
797  /* 3c. Corresponding key is dead (key is locator+flags) */
798  key = keylist_lookup(sc->keys, rrsigs->key_locator);
799  if (!key) {
800  drop_sig = 1;
801  ods_log_deeebug("[%s] refresh signature for RRset[%i]: "
802  "key %s %u is dead", rrset_str,
803  rrset->rr_type, rrsigs->key_locator, rrsigs->key_flags);
804  } else if (key->flags != rrsigs->key_flags) {
805  drop_sig = 1;
806  ods_log_deeebug("[%s] refresh signature for RRset[%i]: "
807  "key %s %u flags mismatch", rrset_str,
808  rrset->rr_type, rrsigs->key_locator, rrsigs->key_flags);
809  }
810  }
811 
812  next_rrsigs = rrsigs->next;
813  if (drop_sig) {
814  /* A rule mismatched, refresh signature */
815  if (prev_rrsigs) {
816  prev_rrsigs->next = rrsigs->next;
817  } else {
818  rrset->rrsigs = rrsigs->next;
819  }
820  log_rr(rrsigs->rr, "-RRSIG", 6);
821  rrset->rrsig_count -= 1;
822  rrsigs->next = NULL;
823  rrsigs_cleanup(rrsigs);
824  } else {
825  /* All rules ok, recycle signature */
826  ods_log_deeebug("[%s] recycle signature for RRset[%i] "
827  "(refresh=%u, signtime=%u, inception=%u, expiration=%u)",
828  rrset_str, rrset->rr_type, refresh, (uint32_t) signtime,
829  inception, expiration);
830  log_rr(rrsigs->rr, "*RRSIG", 7);
831  reusedsigs += 1;
832  prev_rrsigs = rrsigs;
833  }
834  drop_sig = 0;
835  rrsigs = next_rrsigs;
836  }
837  return reusedsigs;
838 }
839 
840 
845 static int
846 rrset_signed_with_algorithm(rrset_type* rrset, uint8_t algorithm)
847 {
848  rrsigs_type* rrsigs = NULL;
849 
850  if (!rrset || !algorithm) {
851  return 0;
852  }
853 
854  rrsigs = rrset->rrsigs;
855  while (rrsigs) {
856  if (rrsigs->rr && algorithm ==
857  ldns_rdf2native_int8(ldns_rr_rrsig_algorithm(rrsigs->rr))) {
858  return 1;
859  }
860  rrsigs = rrsigs->next;
861  }
862 
863  return 0;
864 }
865 
866 
871 static ldns_rr_list*
872 rrset2rrlist(rrset_type* rrset)
873 {
874  ldns_dnssec_rrs* rrs = NULL;
875  ldns_rr_list* rr_list = NULL;
876  int error = 0;
877 
878  rr_list = ldns_rr_list_new();
879  rrs = rrset->rrs;
880  while (rrs && rrs->rr) {
881  error = (int) ldns_rr_list_push_rr(rr_list, rrs->rr);
882  if (!error) {
883  ldns_rr_list_free(rr_list);
884  return NULL;
885  }
886  if (rrset->rr_type == LDNS_RR_TYPE_CNAME ||
887  rrset->rr_type == LDNS_RR_TYPE_DNAME) {
888  /* singleton types */
889  return rr_list;
890  }
891  rrs = rrs->next;
892  }
893  return rr_list;
894 }
895 
896 
901 static void
902 rrset_sigvalid_period(signconf_type* sc, ldns_rr_type rrtype, time_t signtime,
903  time_t* inception, time_t* expiration)
904 {
905  time_t jitter = 0;
906  time_t offset = 0;
907  time_t validity = 0;
908  time_t random_jitter = 0;
909 
910  if (!sc || !rrtype || !signtime) {
911  return;
912  }
913 
914  jitter = duration2time(sc->sig_jitter);
915  if (jitter) {
916  random_jitter = ods_rand(jitter*2);
917  }
918  offset = duration2time(sc->sig_inception_offset);
919  if (rrtype == LDNS_RR_TYPE_NSEC || rrtype == LDNS_RR_TYPE_NSEC3) {
920  validity = duration2time(sc->sig_validity_denial);
921  } else {
922  validity = duration2time(sc->sig_validity_default);
923  }
924 
928  if (((validity + offset + random_jitter) - jitter) <
929  ((validity + offset) - jitter) ) {
930  ods_log_error("[%s] signature validity %u too low, should be at "
931  "least %u", rrset_str,
932  ((validity + offset + random_jitter) - jitter),
933  ((validity + offset) - jitter));
934  } else if (((validity + offset + random_jitter) - jitter) >
935  ((validity + offset) + jitter) ) {
936  ods_log_error("[%s] signature validity %u too high, should be at "
937  "most %u", rrset_str,
938  ((validity + offset + random_jitter) - jitter),
939  ((validity + offset) + jitter));
940  } else {
941  ods_log_deeebug("[%s] signature validity %u in range [%u - %u]",
942  rrset_str, ((validity + offset + random_jitter) - jitter),
943  ((validity + offset) - jitter),
944  ((validity + offset) + jitter));
945  }
946  *inception = signtime - offset;
947  *expiration = (signtime + validity + random_jitter) - jitter;
948  return;
949 }
950 
951 
957 rrset_sign(hsm_ctx_t* ctx, rrset_type* rrset, ldns_rdf* owner,
958  signconf_type* sc, time_t signtime, stats_type* stats)
959 {
960  ods_status status = ODS_STATUS_OK;
961  uint32_t newsigs = 0;
962  uint32_t reusedsigs = 0;
963  ldns_rr* rrsig = NULL;
964  ldns_rr_list* rr_list = NULL;
965  rrsigs_type* new_rrsigs = NULL;
966  rrsigs_type* walk_rrsigs = NULL;
967  key_type* key = NULL;
968  time_t inception = 0;
969  time_t expiration = 0;
970 
971  if (!rrset) {
972  ods_log_error("[%s] unable to sign RRset: no RRset", rrset_str);
973  return ODS_STATUS_ASSERT_ERR;
974  }
975  ods_log_assert(rrset);
976 
977  if (!owner) {
978  ods_log_error("[%s] unable to sign RRset: no owner", rrset_str);
979  return ODS_STATUS_ASSERT_ERR;
980  }
981  ods_log_assert(owner);
982 
983  if (!sc) {
984  ods_log_error("[%s] unable to sign RRset: no signconf", rrset_str);
985  return ODS_STATUS_ASSERT_ERR;
986  }
987  ods_log_assert(sc);
988 
989  /* recycle signatures */
990  reusedsigs = rrset_recycle(rrset, sc, signtime);
991 
992  /* transmogrify the RRset */
993  rr_list = rrset2rrlist(rrset);
994  if (!rr_list) {
995  ods_log_error("[%s] unable to sign RRset[%i]: to RRlist failed",
996  rrset_str, rrset->rr_type);
997  return ODS_STATUS_ERR;
998  }
999  if (ldns_rr_list_rr_count(rr_list) <= 0) {
1000  /* empty RRset, no signatures needed */
1001  ldns_rr_list_free(rr_list);
1002  return ODS_STATUS_OK;
1003  }
1004 
1005  /* prepare for signing */
1006  new_rrsigs = rrsigs_create();
1007  if (!rrset->rrsigs) {
1008  rrset->rrsigs = rrsigs_create();
1009  }
1010  rrset_sigvalid_period(sc, rrset->rr_type, signtime,
1011  &inception, &expiration);
1012 
1013  key = sc->keys->first_key;
1014  while (key) {
1015  /* ksk or zsk ? */
1016  if (!key->zsk && rrset->rr_type != LDNS_RR_TYPE_DNSKEY) {
1017  ods_log_deeebug("[%s] skipping key %s for signing RRset[%i]: no "
1018  "active ZSK", rrset_str, key->locator, rrset->rr_type);
1019  key = key->next;
1020  continue;
1021  }
1022  if (!key->ksk && rrset->rr_type == LDNS_RR_TYPE_DNSKEY) {
1023  ods_log_deeebug("[%s] skipping key %s for signing RRset[%i]: no "
1024  "active KSK", rrset_str, key->locator, rrset->rr_type);
1025  key = key->next;
1026  continue;
1027  }
1028 
1029  /* is there a signature with this algorithm already? */
1030  if (rrset_signed_with_algorithm(rrset, key->algorithm)) {
1031  ods_log_deeebug("[%s] skipping key %s for signing: RRset[%i] "
1032  "already has signature with same algorithm", rrset_str,
1033  key->locator, rrset->rr_type);
1034  key = key->next;
1035  continue;
1036  }
1037 
1043  /* sign the RRset with current key */
1044  ods_log_deeebug("[%s] signing RRset[%i] with key %s", rrset_str,
1045  rrset->rr_type, key->locator);
1046  rrsig = lhsm_sign(ctx, rr_list, key, owner, inception, expiration);
1047  if (!rrsig) {
1048  ods_log_error("[%s] unable to sign RRset[%i]: error creating "
1049  "RRSIG RR", rrset_str, rrset->rr_type);
1050  ldns_rr_list_free(rr_list);
1051  rrsigs_cleanup(new_rrsigs);
1052  return ODS_STATUS_ERR;
1053  }
1054  /* add the signature to the set of new signatures */
1055  ods_log_deeebug("[%s] new signature created for RRset[%i]", rrset_str,
1056  rrset->rr_type);
1057  log_rr(rrsig, "+rrsig", 7);
1058  status = rrsigs_add_sig(new_rrsigs, rrsig, key->locator, key->flags);
1059  if (status == ODS_STATUS_UNCHANGED) {
1060  ods_log_warning("[%s] unable to add duplicate RRSIG: skipping",
1061  rrset_str);
1062  log_rr(rrsig, "~RRSIG", 2);
1063  status = ODS_STATUS_OK;
1064  ldns_rr_free(rrsig);
1065  rrsig = NULL;
1066  } else if (status != ODS_STATUS_OK) {
1067  ods_log_error("[%s] unable to sign RRset[%i]: error adding RRSIG",
1068  rrset_str, rrset->rr_type);
1069  log_rr(rrsig, "+RRSIG", 1);
1070  ldns_rr_list_free(rr_list);
1071  rrsigs_cleanup(new_rrsigs);
1072  return status;
1073  }
1074  /* next key */
1075  key = key->next;
1076  }
1077 
1078  /* signing completed, add the signatures to the right RRset */
1079  walk_rrsigs = new_rrsigs;
1080  while (walk_rrsigs) {
1081  if (walk_rrsigs->rr) {
1082  ods_log_deeebug("[%s] adding signature to RRset[%i]", rrset_str,
1083  rrset->rr_type);
1084  status = rrsigs_add_sig(rrset->rrsigs,
1085  ldns_rr_clone(walk_rrsigs->rr),
1086  walk_rrsigs->key_locator, walk_rrsigs->key_flags);
1087  if (status == ODS_STATUS_UNCHANGED) {
1088  ods_log_warning("[%s] unable to add duplicate RRSIG to "
1089  "RRset[%i]: skipping", rrset_str, rrset->rr_type);
1090  log_rr(walk_rrsigs->rr, "~RRSIG", 2);
1091  status = ODS_STATUS_OK;
1092  } else if (status != ODS_STATUS_OK) {
1093  ods_log_error("[%s] unable to sign RRset[%i]: error adding "
1094  "RRSIG to RRset[%i]", rrset_str, rrset->rr_type,
1095  rrset->rr_type);
1096  log_rr(walk_rrsigs->rr, "+RRSIG", 1);
1097  ldns_rr_list_free(rr_list);
1098  rrsigs_cleanup(new_rrsigs);
1099  return status;
1100  }
1101  rrset->rrsig_count += 1;
1102  newsigs++;
1103  log_rr(walk_rrsigs->rr, "+RRSIG", 6);
1104  }
1105  walk_rrsigs = walk_rrsigs->next;
1106  }
1107 
1108  /* clean up */
1109  rrsigs_cleanup(new_rrsigs);
1110  ldns_rr_list_free(rr_list);
1111 
1112  lock_basic_lock(&stats->stats_lock);
1114  if (rrset->rr_type == LDNS_RR_TYPE_SOA) {
1115  stats->sig_soa_count += newsigs;
1116  }
1117  stats->sig_count += newsigs;
1118  stats->sig_reuse += reusedsigs;
1119  stats->stats_locked = 0;
1120  lock_basic_unlock(&stats->stats_lock);
1121  return ODS_STATUS_OK;
1122 }
1123 
1124 
1129 ods_status
1131 {
1133  int tries = 0;
1134 
1135  if (!rrset) {
1136  ods_log_error("[%s] unable to queue RRset: no RRset", rrset_str);
1137  return ODS_STATUS_ASSERT_ERR;
1138  }
1139  ods_log_assert(rrset);
1140  if (!worker) {
1141  ods_log_error("[%s] unable to queue RRset: no worker", rrset_str);
1142  return ODS_STATUS_ASSERT_ERR;
1143  }
1144  ods_log_assert(worker);
1145  if (!q) {
1146  ods_log_error("[%s] unable to queue RRset: no queue", rrset_str);
1147  return ODS_STATUS_ASSERT_ERR;
1148  }
1149  ods_log_assert(q);
1150 
1151  lock_basic_lock(&q->q_lock);
1152  q->q_locked = LOCKED_Q_WORKER(worker->thread_num);
1153  status = fifoq_push(q, (void*) rrset, worker, &tries);
1154  while (status == ODS_STATUS_UNCHANGED) {
1155  tries++;
1156  if (worker->need_to_exit) {
1157  q->q_locked = 0;
1159  return ODS_STATUS_UNCHANGED;
1160  }
1167  q->q_locked = LOCKED_SLEEP_WORKER(worker->thread_num);
1168  lock_basic_sleep(&q->q_nonfull, &q->q_lock, 5);
1169  q->q_locked = LOCKED_Q_WORKER(worker->thread_num);
1170  status = fifoq_push(q, (void*) rrset, worker, &tries);
1171  }
1172  q->q_locked = 0;
1174  ods_log_assert(status == ODS_STATUS_OK);
1175  lock_basic_lock(&worker->worker_lock);
1176  worker->worker_locked = LOCKED_WORKER_RRSET(worker->thread_num);
1177  worker->jobs_appointed += 1;
1178  worker->worker_locked = 0;
1179  lock_basic_unlock(&worker->worker_lock);
1180  return status;
1181 }
1182 
1183 
1188 void
1190 {
1191  allocator_type* allocator;
1192 
1193  if (!rrset) {
1194  return;
1195  }
1196  allocator = rrset->allocator;
1197 
1198  if (rrset->rrs) {
1199  ldns_dnssec_rrs_deep_free(rrset->rrs);
1200  rrset->rrs = NULL;
1201  }
1202  if (rrset->add) {
1203  ldns_dnssec_rrs_deep_free(rrset->add);
1204  rrset->add = NULL;
1205  }
1206  if (rrset->del) {
1207  ldns_dnssec_rrs_deep_free(rrset->del);
1208  rrset->del = NULL;
1209  }
1210  if (rrset->rrsigs) {
1211  rrsigs_cleanup(rrset->rrsigs);
1212  rrset->rrsigs = NULL;
1213  }
1214 
1215  allocator_deallocate(allocator, (void*) rrset);
1216  allocator_cleanup(allocator);
1217  return;
1218 }
1219 
1220 
1225 void
1226 rrset_print(FILE* fd, rrset_type* rrset, int skip_rrsigs)
1227 {
1228  if (!rrset || !fd) {
1229  return;
1230  }
1231  ods_log_assert(fd);
1232  ods_log_assert(rrset);
1233 
1234  if (rrset->rrs) {
1235  if (rrset->rr_type == LDNS_RR_TYPE_CNAME ||
1236  rrset->rr_type == LDNS_RR_TYPE_DNAME) {
1237  /* singleton types */
1238  if (rrset->rrs->rr) {
1239  ldns_rr_print(fd, rrset->rrs->rr);
1240  }
1241  } else {
1242  ldns_dnssec_rrs_print(fd, rrset->rrs);
1243  }
1244  }
1245  if (rrset->rrsigs && !skip_rrsigs) {
1246  rrsigs_print(fd, rrset->rrsigs, 0);
1247  }
1248  return;
1249 }
1250 
1251 
1256 void
1257 rrset_backup(FILE* fd, rrset_type* rrset)
1258 {
1259  if (!rrset || !fd) {
1260  return;
1261  }
1262  if (rrset->rrsigs) {
1263  rrsigs_print(fd, rrset->rrsigs, 1);
1264  }
1265  return;
1266 }