OpenDNSSEC-signer  1.4.3
rrset.c
Go to the documentation of this file.
1 /*
2  * $Id: rrset.c 7400 2013-11-14 13:52:11Z 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 "shared/file.h"
36 #include "shared/hsm.h"
37 #include "shared/log.h"
38 #include "shared/util.h"
39 #include "signer/rrset.h"
40 #include "signer/zone.h"
41 
42 static const char* rrset_str = "rrset";
43 
44 
49 void
50 log_rr(ldns_rr* rr, const char* pre, int level)
51 {
52  char* str = NULL;
53  size_t i = 0;
54 
55  if (ods_log_get_level() < level) {
56  return;
57  }
58  str = ldns_rr2str(rr);
59  if (!str) {
60  ods_log_error("[%s] %s: Error converting RR to string", rrset_str,
61  pre?pre:"");
62  return;
63  }
64  str[(strlen(str))-1] = '\0';
65  /* replace tabs with white space */
66  for (i=0; i < strlen(str); i++) {
67  if (str[i] == '\t') {
68  str[i] = ' ';
69  }
70  }
71  if (level == LOG_EMERG) {
72  ods_fatal_exit("[%s] %s: %s", rrset_str, pre?pre:"", str);
73  } else if (level == LOG_ALERT) {
74  ods_log_alert("[%s] %s: %s", rrset_str, pre?pre:"", str);
75  } else if (level == LOG_CRIT) {
76  ods_log_crit("[%s] %s: %s", rrset_str, pre?pre:"", str);
77  } else if (level == LOG_ERR) {
78  ods_log_error("[%s] %s: %s", rrset_str, pre?pre:"", str);
79  } else if (level == LOG_WARNING) {
80  ods_log_warning("[%s] %s: %s", rrset_str, pre?pre:"", str);
81  } else if (level == LOG_NOTICE) {
82  ods_log_info("[%s] %s: %s", rrset_str, pre?pre:"", str);
83  } else if (level == LOG_INFO) {
84  ods_log_verbose("[%s] %s: %s", rrset_str, pre?pre:"", str);
85  } else if (level == LOG_DEBUG) {
86  ods_log_debug("[%s] %s: %s", rrset_str, pre?pre:"", str);
87  } else if (level == LOG_DEEEBUG) {
88  ods_log_deeebug("[%s] %s: %s", rrset_str, pre?pre:"", str);
89  } else {
90  ods_log_deeebug("[%s] %s: %s", rrset_str, pre?pre:"", str);
91  }
92  free((void*)str);
93  return;
94 }
95 
96 
101 void
102 log_rrset(ldns_rdf* dname, ldns_rr_type type, const char* pre, int level)
103 {
104  char* str = NULL;
105  size_t i = 0;
106 
107  if (ods_log_get_level() < level) {
108  return;
109  }
110  str = ldns_rdf2str(dname);
111  if (!str) {
112  return;
113  }
114  str[(strlen(str))-1] = '\0';
115  /* replace tabs with white space */
116  for (i=0; i < strlen(str); i++) {
117  if (str[i] == '\t') {
118  str[i] = ' ';
119  }
120  }
121  if (level == LOG_EMERG) {
122  ods_fatal_exit("[%s] %s: <%s,%s>", rrset_str, pre?pre:"", str,
123  rrset_type2str(type));
124  } else if (level == LOG_ALERT) {
125  ods_log_alert("[%s] %s: <%s,%s>", rrset_str, pre?pre:"", str,
126  rrset_type2str(type));
127  } else if (level == LOG_CRIT) {
128  ods_log_crit("[%s] %s: <%s,%s>", rrset_str, pre?pre:"", str,
129  rrset_type2str(type));
130  } else if (level == LOG_ERR) {
131  ods_log_error("[%s] %s: <%s,%s>", rrset_str, pre?pre:"", str,
132  rrset_type2str(type));
133  } else if (level == LOG_WARNING) {
134  ods_log_warning("[%s] %s: <%s,%s>", rrset_str, pre?pre:"", str,
135  rrset_type2str(type));
136  } else if (level == LOG_NOTICE) {
137  ods_log_info("[%s] %s: <%s,%s>", rrset_str, pre?pre:"", str,
138  rrset_type2str(type));
139  } else if (level == LOG_INFO) {
140  ods_log_verbose("[%s] %s: <%s,%s>", rrset_str, pre?pre:"", str,
141  rrset_type2str(type));
142  } else if (level == LOG_DEBUG) {
143  ods_log_debug("[%s] %s: <%s,%s>", rrset_str, pre?pre:"", str,
144  rrset_type2str(type));
145  } else if (level == LOG_DEEEBUG) {
146  ods_log_deeebug("[%s] %s: <%s,%s>", rrset_str, pre?pre:"", str,
147  rrset_type2str(type));
148  } else {
149  ods_log_deeebug("[%s] %s: <%s,%s>", rrset_str, pre?pre:"", str,
150  rrset_type2str(type));
151  }
152  free((void*)str);
153  return;
154 }
155 
156 
161 const char*
162 rrset_type2str(ldns_rr_type type)
163 {
164  if (type == LDNS_RR_TYPE_IXFR) {
165  return "IXFR";
166  } else if (type == LDNS_RR_TYPE_AXFR) {
167  return "AXFR";
168  } else if (type == LDNS_RR_TYPE_MAILB) {
169  return "MAILB";
170  } else if (type == LDNS_RR_TYPE_MAILA) {
171  return "MAILA";
172  } else if (type == LDNS_RR_TYPE_ANY) {
173  return "ANY";
174  } else {
175  const ldns_rr_descriptor* descriptor = ldns_rr_descript(type);
176  if (descriptor && descriptor->_name) {
177  return descriptor->_name;
178  }
179  }
180  return "TYPE???";
181 }
182 
183 
188 rrset_type*
189 rrset_create(void* zoneptr, ldns_rr_type type)
190 {
191  zone_type* zone = (zone_type*) zoneptr;
192  rrset_type* rrset = NULL;
193  if (!type || !zoneptr) {
194  return NULL;
195  }
196  rrset = (rrset_type*) allocator_alloc(
197  zone->allocator, sizeof(rrset_type));
198  if (!rrset) {
199  ods_log_error("[%s] unable to create RRset %u: allocator_alloc() "
200  "failed", rrset_str, (unsigned) type);
201  return NULL;
202  }
203  rrset->next = NULL;
204  rrset->rrs = NULL;
205  rrset->rrsigs = NULL;
206  rrset->domain = NULL;
207  rrset->zone = zoneptr;
208  rrset->rrtype = type;
209  rrset->rr_count = 0;
210  rrset->rrsig_count = 0;
211  rrset->needs_signing = 0;
212  return rrset;
213 }
214 
215 
220 rr_type*
221 rrset_lookup_rr(rrset_type* rrset, ldns_rr* rr)
222 {
223  ldns_status lstatus = LDNS_STATUS_OK;
224  int cmp = 0;
225  size_t i = 0;
226 
227  if (!rrset || !rr || rrset->rr_count <= 0) {
228  return NULL;
229  }
230  for (i=0; i < rrset->rr_count; i++) {
231  lstatus = util_dnssec_rrs_compare(rrset->rrs[i].rr, rr, &cmp);
232  if (lstatus != LDNS_STATUS_OK) {
233  ods_log_error("[%s] unable to lookup RR: compare failed (%s)",
234  rrset_str, ldns_get_errorstr_by_id(lstatus));
235  return NULL;
236  }
237  if (!cmp) { /* equal */
238  return &rrset->rrs[i];
239  }
240  }
241  return NULL;
242 }
243 
244 
249 size_t
251 {
252  size_t i = 0;
253  size_t count = 0;
254  if (!rrset) {
255  return 0;
256  }
257  for (i=0; i < rrset->rr_count; i++) {
258  if (rrset->rrs[i].is_added) {
259  count++;
260  }
261  }
262  return count;
263 }
264 
265 
270 rr_type*
271 rrset_add_rr(rrset_type* rrset, ldns_rr* rr)
272 {
273  rr_type* rrs_old = NULL;
274  zone_type* zone = NULL;
275 
276  ods_log_assert(rrset);
277  ods_log_assert(rr);
278  ods_log_assert(rrset->rrtype == ldns_rr_get_type(rr));
279 
280  zone = (zone_type*) rrset->zone;
281  rrs_old = rrset->rrs;
282  rrset->rrs = (rr_type*) allocator_alloc(zone->allocator,
283  (rrset->rr_count + 1) * sizeof(rr_type));
284  if (!rrset->rrs) {
285  ods_fatal_exit("[%s] fatal unable to add RR: allocator_alloc() failed",
286  rrset_str);
287  }
288  if (rrs_old) {
289  memcpy(rrset->rrs, rrs_old, (rrset->rr_count) * sizeof(rr_type));
290  }
291  allocator_deallocate(zone->allocator, (void*) rrs_old);
292  rrset->rr_count++;
293  rrset->rrs[rrset->rr_count - 1].owner = rrset->domain;
294  rrset->rrs[rrset->rr_count - 1].rr = rr;
295  rrset->rrs[rrset->rr_count - 1].exists = 0;
296  rrset->rrs[rrset->rr_count - 1].is_added = 1;
297  rrset->rrs[rrset->rr_count - 1].is_removed = 0;
298  rrset->needs_signing = 1;
299  log_rr(rr, "+RR", LOG_DEEEBUG);
300  return &rrset->rrs[rrset->rr_count -1];
301 }
302 
303 
308 void
309 rrset_del_rr(rrset_type* rrset, uint16_t rrnum)
310 {
311  rr_type* rrs_orig = NULL;
312  zone_type* zone = NULL;
313 
314  ods_log_assert(rrset);
315  ods_log_assert(rrnum < rrset->rr_count);
316 
317  zone = (zone_type*) rrset->zone;
318  log_rr(rrset->rrs[rrnum].rr, "-RR", LOG_DEEEBUG);
319  rrset->rrs[rrnum].owner = NULL;
320  rrset->rrs[rrnum].rr = NULL;
321  while (rrnum < rrset->rr_count-1) {
322  rrset->rrs[rrnum] = rrset->rrs[rrnum+1];
323  rrnum++;
324  }
325  memset(&rrset->rrs[rrset->rr_count-1], 0, sizeof(rr_type));
326  rrs_orig = rrset->rrs;
327  rrset->rrs = (rr_type*) allocator_alloc(zone->allocator,
328  (rrset->rr_count - 1) * sizeof(rr_type));
329  if(!rrset->rrs) {
330  ods_fatal_exit("[%s] fatal unable to delete RR: allocator_alloc() failed",
331  rrset_str);
332  }
333  memcpy(rrset->rrs, rrs_orig, (rrset->rr_count -1) * sizeof(rr_type));
334  allocator_deallocate(zone->allocator, (void*) rrs_orig);
335  rrset->rr_count--;
336  rrset->needs_signing = 1;
337  return;
338 }
339 
340 
345 void
346 rrset_diff(rrset_type* rrset, unsigned is_ixfr, unsigned more_coming)
347 {
348  zone_type* zone = NULL;
349  uint16_t i = 0;
350  uint8_t del_sigs = 0;
351  if (!rrset) {
352  return;
353  }
354  zone = (zone_type*) rrset->zone;
355  for (i=0; i < rrset->rr_count; i++) {
356  if (rrset->rrs[i].is_added) {
357  if (!rrset->rrs[i].exists) {
358  /* ixfr +RR */
359  lock_basic_lock(&zone->ixfr->ixfr_lock);
360  ixfr_add_rr(zone->ixfr, rrset->rrs[i].rr);
362  del_sigs = 1;
363  }
364  rrset->rrs[i].exists = 1;
365  if ((rrset->rrtype == LDNS_RR_TYPE_DNSKEY ||
366  rrset->rrtype == LDNS_RR_TYPE_NSEC3PARAMS) && more_coming) {
367  continue;
368  }
369  rrset->rrs[i].is_added = 0;
370  } else if (!is_ixfr || rrset->rrs[i].is_removed) {
371  if (rrset->rrs[i].exists) {
372  /* ixfr -RR */
373  lock_basic_lock(&zone->ixfr->ixfr_lock);
374  ixfr_del_rr(zone->ixfr, rrset->rrs[i].rr);
376  }
377  rrset->rrs[i].exists = 0;
378  rrset_del_rr(rrset, i);
379  del_sigs = 1;
380  i--;
381  }
382  }
383  if (del_sigs) {
384  for (i=0; i < rrset->rrsig_count; i++) {
385  /* ixfr -RRSIG */
386  lock_basic_lock(&zone->ixfr->ixfr_lock);
387  ixfr_del_rr(zone->ixfr, rrset->rrsigs[i].rr);
389  rrset_del_rrsig(rrset, i);
390  i--;
391  }
392  }
393  return;
394 }
395 
396 
401 rrsig_type*
402 rrset_add_rrsig(rrset_type* rrset, ldns_rr* rr,
403  const char* locator, uint32_t flags)
404 {
405  rrsig_type* rrsigs_old = NULL;
406  zone_type* zone = NULL;
407  ods_log_assert(rrset);
408  ods_log_assert(rr);
409  ods_log_assert(ldns_rr_get_type(rr) == LDNS_RR_TYPE_RRSIG);
410  zone = (zone_type*) rrset->zone;
411  rrsigs_old = rrset->rrsigs;
412  rrset->rrsigs = (rrsig_type*) allocator_alloc(zone->allocator,
413  (rrset->rrsig_count + 1) * sizeof(rrsig_type));
414  if (!rrset->rrsigs) {
415  ods_fatal_exit("[%s] fatal unable to add RRSIG: allocator_alloc() failed",
416  rrset_str);
417  }
418  if (rrsigs_old) {
419  memcpy(rrset->rrsigs, rrsigs_old,
420  (rrset->rrsig_count) * sizeof(rrsig_type));
421  }
422  allocator_deallocate(zone->allocator, (void*) rrsigs_old);
423  rrset->rrsig_count++;
424  rrset->rrsigs[rrset->rrsig_count - 1].owner = rrset->domain;
425  rrset->rrsigs[rrset->rrsig_count - 1].rr = rr;
426  rrset->rrsigs[rrset->rrsig_count - 1].key_locator = locator;
427  rrset->rrsigs[rrset->rrsig_count - 1].key_flags = flags;
428  log_rr(rr, "+RRSIG", LOG_DEEEBUG);
429  return &rrset->rrsigs[rrset->rrsig_count -1];
430 }
431 
432 
437 void
438 rrset_del_rrsig(rrset_type* rrset, uint16_t rrnum)
439 {
440  rrsig_type* rrsigs_orig = NULL;
441  zone_type* zone = NULL;
442  ods_log_assert(rrset);
443  ods_log_assert(rrnum < rrset->rrsig_count);
444  zone = (zone_type*) rrset->zone;
445  log_rr(rrset->rrsigs[rrnum].rr, "-RRSIG", LOG_DEEEBUG);
446  rrset->rrsigs[rrnum].owner = NULL;
447  rrset->rrsigs[rrnum].rr = NULL;
449  (void*)rrset->rrsigs[rrnum].key_locator);
450  rrset->rrsigs[rrnum].key_locator = NULL;
451  while (rrnum < rrset->rrsig_count-1) {
452  rrset->rrsigs[rrnum] = rrset->rrsigs[rrnum+1];
453  rrnum++;
454  }
455  memset(&rrset->rrsigs[rrset->rrsig_count-1], 0, sizeof(rrsig_type));
456  rrsigs_orig = rrset->rrsigs;
457  rrset->rrsigs = (rrsig_type*) allocator_alloc(zone->allocator,
458  (rrset->rrsig_count - 1) * sizeof(rrsig_type));
459  if(!rrset->rrsigs) {
460  ods_fatal_exit("[%s] fatal unable to delete RRSIG: allocator_alloc() failed",
461  rrset_str);
462  }
463  memcpy(rrset->rrsigs, rrsigs_orig,
464  (rrset->rrsig_count -1) * sizeof(rrsig_type));
465  allocator_deallocate(zone->allocator, (void*) rrsigs_orig);
466  rrset->rrsig_count--;
467  return;
468 }
469 
470 
475 static uint32_t
476 rrset_recycle(rrset_type* rrset, time_t signtime, ldns_rr_type dstatus,
477  ldns_rr_type delegpt)
478 {
479  uint32_t refresh = 0;
480  uint32_t expiration = 0;
481  uint32_t inception = 0;
482  uint32_t reusedsigs = 0;
483  unsigned drop_sig = 0;
484  size_t i = 0;
485  key_type* key = NULL;
486  zone_type* zone = NULL;
487 
488  if (!rrset) {
489  return 0;
490  }
491  zone = (zone_type*) rrset->zone;
492  /* Calculate the Refresh Window = Signing time + Refresh */
493  if (zone->signconf && zone->signconf->sig_refresh_interval) {
494  refresh = (uint32_t) (signtime +
496  }
497  /* Check every signature if it matches the recycling logic. */
498  for (i=0; i < rrset->rrsig_count; i++) {
499  drop_sig = 0;
500  /* 0. Skip delegation, glue and occluded RRsets */
501  if (dstatus != LDNS_RR_TYPE_SOA || (delegpt != LDNS_RR_TYPE_SOA &&
502  rrset->rrtype != LDNS_RR_TYPE_DS)) {
503  drop_sig = 1;
504  goto recycle_drop_sig;
505  }
506  ods_log_assert(dstatus == LDNS_RR_TYPE_SOA ||
507  (delegpt == LDNS_RR_TYPE_SOA || rrset->rrtype == LDNS_RR_TYPE_DS));
508  /* 1. If the RRset has changed, drop all signatures */
509  /* 2. If Refresh is disabled, drop all signatures */
510  if (rrset->needs_signing || refresh <= (uint32_t) signtime) {
511  drop_sig = 1;
512  goto recycle_drop_sig;
513  }
514  /* 3. Expiration - Refresh has passed */
515  expiration = ldns_rdf2native_int32(
516  ldns_rr_rrsig_expiration(rrset->rrsigs[i].rr));
517  if (expiration < refresh) {
518  drop_sig = 1;
519  goto recycle_drop_sig;
520  }
521  /* 4. Inception has not yet passed */
522  inception = ldns_rdf2native_int32(
523  ldns_rr_rrsig_inception(rrset->rrsigs[i].rr));
524  if (inception > (uint32_t) signtime) {
525  drop_sig = 1;
526  goto recycle_drop_sig;
527  }
528  /* 5. Corresponding key is dead (key is locator+flags) */
530  rrset->rrsigs[i].key_locator);
531  if (!key || key->flags != rrset->rrsigs[i].key_flags) {
532  drop_sig = 1;
533  }
534 
535 recycle_drop_sig:
536  if (drop_sig) {
537  /* A rule mismatched, refresh signature */
538  /* ixfr -RRSIG */
539  lock_basic_lock(&zone->ixfr->ixfr_lock);
540  ixfr_del_rr(zone->ixfr, rrset->rrsigs[i].rr);
542  rrset_del_rrsig(rrset, i);
543  i--;
544  } else {
545  /* All rules ok, recycle signature */
546  reusedsigs += 1;
547  }
548  }
549  return reusedsigs;
550 }
551 
552 
557 static int
558 rrset_sigalgo(rrset_type* rrset, uint8_t algorithm)
559 {
560  size_t i = 0;
561  if (!rrset) {
562  return 0;
563  }
564  for (i=0; i < rrset->rrsig_count; i++) {
565  if (algorithm == ldns_rdf2native_int8(
566  ldns_rr_rrsig_algorithm(rrset->rrsigs[i].rr))) {
567  return 1;
568  }
569  }
570  return 0;
571 }
572 
573 
578 static int
579 rrset_siglocator(rrset_type* rrset, const char* locator)
580 {
581  size_t i = 0;
582  if (!rrset) {
583  return 0;
584  }
585  for (i=0; i < rrset->rrsig_count; i++) {
586  if (!ods_strcmp(locator, rrset->rrsigs[i].key_locator)) {
587  return 1;
588  }
589  }
590  return 0;
591 }
592 
593 
598 static ldns_rr_list*
599 rrset2rrlist(rrset_type* rrset)
600 {
601  ldns_rr_list* rr_list = NULL;
602  int ret = 0;
603  size_t i = 0;
604  rr_list = ldns_rr_list_new();
605  for (i=0; i < rrset->rr_count; i++) {
606  if (!rrset->rrs[i].exists) {
607  log_rr(rrset->rrs[i].rr, "RR does not exist", LOG_WARNING);
608  continue;
609  }
610  /* clone if you want to keep the original format in the signed zone */
611  ldns_rr2canonical(rrset->rrs[i].rr);
612  ret = (int) ldns_rr_list_push_rr(rr_list, rrset->rrs[i].rr);
613  if (!ret) {
614  ldns_rr_list_free(rr_list);
615  return NULL;
616  }
617  if (rrset->rrtype == LDNS_RR_TYPE_CNAME ||
618  rrset->rrtype == LDNS_RR_TYPE_DNAME) {
619  /* singleton types */
620  return rr_list;
621  }
622  }
623  ldns_rr_list_sort(rr_list);
624  return rr_list;
625 }
626 
627 
632 static void
633 rrset_sigvalid_period(signconf_type* sc, ldns_rr_type rrtype, time_t signtime,
634  time_t* inception, time_t* expiration)
635 {
636  time_t jitter = 0;
637  time_t offset = 0;
638  time_t validity = 0;
639  time_t random_jitter = 0;
640  if (!sc || !rrtype || !signtime) {
641  return;
642  }
643  jitter = duration2time(sc->sig_jitter);
644  if (jitter) {
645  random_jitter = ods_rand(jitter*2);
646  }
647  offset = duration2time(sc->sig_inception_offset);
648  if (rrtype == LDNS_RR_TYPE_NSEC || rrtype == LDNS_RR_TYPE_NSEC3) {
649  validity = duration2time(sc->sig_validity_denial);
650  } else {
651  validity = duration2time(sc->sig_validity_default);
652  }
653  *inception = signtime - offset;
654  *expiration = (signtime + validity + random_jitter) - jitter;
655  return;
656 }
657 
658 
664 rrset_sign(hsm_ctx_t* ctx, rrset_type* rrset, time_t signtime)
665 {
666  zone_type* zone = NULL;
667  uint32_t newsigs = 0;
668  uint32_t reusedsigs = 0;
669  ldns_rr* rrsig = NULL;
670  ldns_rr_list* rr_list = NULL;
671  rrsig_type* signature = NULL;
672  const char* locator = NULL;
673  time_t inception = 0;
674  time_t expiration = 0;
675  size_t i = 0;
676  domain_type* domain = NULL;
677  ldns_rr_type dstatus = LDNS_RR_TYPE_FIRST;
678  ldns_rr_type delegpt = LDNS_RR_TYPE_FIRST;
679 
680  ods_log_assert(ctx);
681  ods_log_assert(rrset);
682  zone = (zone_type*) rrset->zone;
683  ods_log_assert(zone);
684  ods_log_assert(zone->signconf);
685  /* Recycle signatures */
686  if (rrset->rrtype == LDNS_RR_TYPE_NSEC ||
687  rrset->rrtype == LDNS_RR_TYPE_NSEC3) {
688  dstatus = LDNS_RR_TYPE_SOA;
689  delegpt = LDNS_RR_TYPE_SOA;
690  } else {
691  domain = (domain_type*) rrset->domain;
692  dstatus = domain_is_occluded(domain);
693  delegpt = domain_is_delegpt(domain);
694  }
695  reusedsigs = rrset_recycle(rrset, signtime, dstatus, delegpt);
696  rrset->needs_signing = 0;
697 
698  ods_log_assert(rrset->rrs);
699  ods_log_assert(rrset->rrs[0].rr);
700 
701  /* Skip delegation, glue and occluded RRsets */
702  if (dstatus != LDNS_RR_TYPE_SOA) {
703  log_rrset(ldns_rr_owner(rrset->rrs[0].rr), rrset->rrtype,
704  "skip signing occluded RRset", LOG_DEEEBUG);
705  return ODS_STATUS_OK;
706  }
707  if (delegpt != LDNS_RR_TYPE_SOA && rrset->rrtype != LDNS_RR_TYPE_DS) {
708  log_rrset(ldns_rr_owner(rrset->rrs[0].rr), rrset->rrtype,
709  "skip signing delegation RRset", LOG_DEEEBUG);
710  return ODS_STATUS_OK;
711  }
712 
713  log_rrset(ldns_rr_owner(rrset->rrs[0].rr), rrset->rrtype,
714  "sign RRset", LOG_DEEEBUG);
715  ods_log_assert(dstatus == LDNS_RR_TYPE_SOA ||
716  (delegpt == LDNS_RR_TYPE_SOA || rrset->rrtype == LDNS_RR_TYPE_DS));
717  /* Transmogrify rrset */
718  rr_list = rrset2rrlist(rrset);
719  if (!rr_list) {
720  ods_log_error("[%s] unable to sign RRset[%i]: rrset2rrlist() failed",
721  rrset_str, rrset->rrtype);
722  return ODS_STATUS_MALLOC_ERR;
723  }
724  if (ldns_rr_list_rr_count(rr_list) <= 0) {
725  /* Empty RRset, no signatures needed */
726  ldns_rr_list_free(rr_list);
727  return ODS_STATUS_OK;
728  }
729  /* Calculate signature validity */
730  rrset_sigvalid_period(zone->signconf, rrset->rrtype, signtime,
731  &inception, &expiration);
732  /* Walk keys */
733  for (i=0; i < zone->signconf->keys->count; i++) {
734  /* If not ZSK don't sign other RRsets */
735  if (!zone->signconf->keys->keys[i].zsk &&
736  rrset->rrtype != LDNS_RR_TYPE_DNSKEY) {
737  continue;
738  }
739  /* If not KSK don't sign DNSKEY RRset */
740  if (!zone->signconf->keys->keys[i].ksk &&
741  rrset->rrtype == LDNS_RR_TYPE_DNSKEY) {
742  continue;
743  }
744  /* Additional rules for signatures */
745  if (rrset_siglocator(rrset, zone->signconf->keys->keys[i].locator)) {
746  continue;
747  }
748  if (rrset->rrtype != LDNS_RR_TYPE_DNSKEY &&
749  rrset_sigalgo(rrset, zone->signconf->keys->keys[i].algorithm)) {
750  continue;
751  }
752 
758  /* Sign the RRset with this key */
759  ods_log_deeebug("[%s] signing RRset[%i] with key %s", rrset_str,
760  rrset->rrtype, zone->signconf->keys->keys[i].locator);
761  rrsig = lhsm_sign(ctx, rr_list, &zone->signconf->keys->keys[i],
762  zone->apex, inception, expiration);
763  if (!rrsig) {
764  ods_log_crit("[%s] unable to sign RRset[%i]: lhsm_sign() failed",
765  rrset_str, rrset->rrtype);
766  ldns_rr_list_free(rr_list);
767  return ODS_STATUS_HSM_ERR;
768  }
769  /* Add signature */
770  locator = allocator_strdup(zone->allocator,
771  zone->signconf->keys->keys[i].locator);
772  signature = rrset_add_rrsig(rrset, rrsig, locator,
773  zone->signconf->keys->keys[i].flags);
774  newsigs++;
775  /* ixfr +RRSIG */
776  ods_log_assert(signature->rr);
777  lock_basic_lock(&zone->ixfr->ixfr_lock);
778  ixfr_add_rr(zone->ixfr, signature->rr);
780  }
781  /* RRset signing completed */
782  ldns_rr_list_free(rr_list);
784  if (rrset->rrtype == LDNS_RR_TYPE_SOA) {
785  zone->stats->sig_soa_count += newsigs;
786  }
787  zone->stats->sig_count += newsigs;
788  zone->stats->sig_reuse += reusedsigs;
790  return ODS_STATUS_OK;
791 }
792 
793 
798 void
799 rrset_print(FILE* fd, rrset_type* rrset, int skip_rrsigs,
800  ods_status* status)
801 {
802  uint16_t i = 0;
803  ods_status result = ODS_STATUS_OK;
804 
805  if (!rrset || !fd) {
806  ods_log_crit("[%s] unable to print RRset: rrset or fd missing",
807  rrset_str);
808  if (status) {
809  *status = ODS_STATUS_ASSERT_ERR;
810  }
811  return;
812  }
813  for (i=0; i < rrset->rr_count; i++) {
814  if (rrset->rrs[i].exists) {
815  result = util_rr_print(fd, rrset->rrs[i].rr);
816  if (rrset->rrtype == LDNS_RR_TYPE_CNAME ||
817  rrset->rrtype == LDNS_RR_TYPE_DNAME) {
818  /* singleton types */
819  break;
820  }
821  if (result != ODS_STATUS_OK) {
822  zone_type* zone = (zone_type*) rrset->zone;
823  log_rrset(ldns_rr_owner(rrset->rrs[i].rr), rrset->rrtype,
824  "error printing RRset", LOG_CRIT);
825  zone->adoutbound->error = 1;
826  break;
827  }
828  }
829  }
830  if (! (skip_rrsigs || !rrset->rrsig_count)) {
831  for (i=0; i < rrset->rrsig_count; i++) {
832  result = util_rr_print(fd, rrset->rrsigs[i].rr);
833  if (result != ODS_STATUS_OK) {
834  zone_type* zone = (zone_type*) rrset->zone;
835  log_rrset(ldns_rr_owner(rrset->rrs[i].rr), rrset->rrtype,
836  "error printing RRset", LOG_CRIT);
837  zone->adoutbound->error = 1;
838  break;
839  }
840  }
841  }
842  if (status) {
843  *status = result;
844  }
845  return;
846 }
847 
848 
853 void
855 {
856  uint16_t i = 0;
857  zone_type* zone = NULL;
858  if (!rrset) {
859  return;
860  }
861  rrset_cleanup(rrset->next);
862  rrset->next = NULL;
863  rrset->domain = NULL;
864  zone = (zone_type*) rrset->zone;
865  for (i=0; i < rrset->rr_count; i++) {
866  ldns_rr_free(rrset->rrs[i].rr);
867  rrset->rrs[i].owner = NULL;
868  }
869  for (i=0; i < rrset->rrsig_count; i++) {
871  (void*)rrset->rrsigs[i].key_locator);
872  ldns_rr_free(rrset->rrsigs[i].rr);
873  rrset->rrsigs[i].owner = NULL;
874  }
875  allocator_deallocate(zone->allocator, (void*) rrset->rrs);
876  allocator_deallocate(zone->allocator, (void*) rrset->rrsigs);
877  allocator_deallocate(zone->allocator, (void*) rrset);
878  return;
879 }
880 
881 
886 void
887 rrset_backup2(FILE* fd, rrset_type* rrset)
888 {
889  char* str = NULL;
890  uint16_t i = 0;
891  if (!rrset || !fd) {
892  return;
893  }
894  for (i=0; i < rrset->rrsig_count; i++) {
895  str = ldns_rr2str(rrset->rrsigs[i].rr);
896  if (!str) {
897  continue;
898  }
899  str[(strlen(str))-1] = '\0';
900  fprintf(fd, "%s; {locator %s flags %u}\n", str,
901  rrset->rrsigs[i].key_locator, rrset->rrsigs[i].key_flags);
902  free((void*)str);
903  }
904  return;
905 }
void ods_log_alert(const char *format,...)
Definition: log.c:368
rr_type * rrset_lookup_rr(rrset_type *rrset, ldns_rr *rr)
Definition: rrset.c:221
duration_type * sig_inception_offset
Definition: signconf.h:62
int zsk
Definition: keys.h:65
size_t rr_count
Definition: rrset.h:81
void rrset_cleanup(rrset_type *rrset)
Definition: rrset.c:854
key_type * keylist_lookup_by_locator(keylist_type *kl, const char *locator)
Definition: keys.c:76
const char * rrset_type2str(ldns_rr_type type)
Definition: rrset.c:162
void ods_log_debug(const char *format,...)
Definition: log.c:272
uint32_t key_flags
Definition: rrset.h:53
keylist_type * keys
Definition: signconf.h:73
void * allocator_alloc(allocator_type *allocator, size_t size)
Definition: allocator.c:68
duration_type * sig_validity_default
Definition: signconf.h:59
ldns_status util_dnssec_rrs_compare(ldns_rr *rr1, ldns_rr *rr2, int *cmp)
Definition: util.c:142
#define LOG_INFO
Definition: log.h:52
ldns_rr * lhsm_sign(hsm_ctx_t *ctx, ldns_rr_list *rrset, key_type *key_id, ldns_rdf *owner, time_t inception, time_t expiration)
Definition: hsm.c:219
size_t rrset_count_rr_is_added(rrset_type *rrset)
Definition: rrset.c:250
void ods_fatal_exit(const char *format,...)
Definition: log.c:384
void ixfr_add_rr(ixfr_type *ixfr, ldns_rr *rr)
Definition: ixfr.c:132
rrset_type * rrset_create(void *zoneptr, ldns_rr_type type)
Definition: rrset.c:189
duration_type * sig_validity_denial
Definition: signconf.h:60
void ixfr_del_rr(ixfr_type *ixfr, ldns_rr *rr)
Definition: ixfr.c:163
unsigned error
Definition: adapter.h:65
void ods_log_info(const char *format,...)
Definition: log.c:304
enum ods_enum_status ods_status
Definition: status.h:91
rr_type * rrset_add_rr(rrset_type *rrset, ldns_rr *rr)
Definition: rrset.c:271
#define LOG_EMERG
Definition: log.h:46
void ods_log_error(const char *format,...)
Definition: log.c:336
rrsig_type * rrset_add_rrsig(rrset_type *rrset, ldns_rr *rr, const char *locator, uint32_t flags)
Definition: rrset.c:402
lock_basic_type stats_lock
Definition: stats.h:69
#define LOG_NOTICE
Definition: log.h:51
int ods_strcmp(const char *s1, const char *s2)
Definition: file.c:317
ldns_rr_type rrtype
Definition: rrset.h:78
rrset_type * next
Definition: rrset.h:75
adapter_type * adoutbound
Definition: zone.h:84
ods_status util_rr_print(FILE *fd, const ldns_rr *rr)
Definition: util.c:380
void log_rr(ldns_rr *rr, const char *pre, int level)
Definition: rrset.c:50
void ods_log_crit(const char *format,...)
Definition: log.c:352
unsigned exists
Definition: rrset.h:64
#define LOG_ALERT
Definition: log.h:47
duration_type * sig_refresh_interval
Definition: signconf.h:58
#define lock_basic_lock(lock)
Definition: locks.h:93
unsigned is_removed
Definition: rrset.h:66
void log_rrset(ldns_rdf *dname, ldns_rr_type type, const char *pre, int level)
Definition: rrset.c:102
ixfr_type * ixfr
Definition: zone.h:89
const char * locator
Definition: keys.h:60
unsigned needs_signing
Definition: rrset.h:83
key_type * keys
Definition: keys.h:75
ldns_rr_type domain_is_delegpt(domain_type *domain)
Definition: domain.c:441
ldns_rr * rr
Definition: rrset.h:50
signconf_type * signconf
Definition: zone.h:86
ldns_rr_type domain_is_occluded(domain_type *domain)
Definition: domain.c:466
void * zone
Definition: rrset.h:76
char * allocator_strdup(allocator_type *allocator, const char *string)
Definition: allocator.c:123
void rrset_del_rrsig(rrset_type *rrset, uint16_t rrnum)
Definition: rrset.c:438
void * owner
Definition: rrset.h:51
#define LOG_CRIT
Definition: log.h:48
uint32_t sig_reuse
Definition: stats.h:64
struct rr_struct rr_type
Definition: rrset.h:60
const char * key_locator
Definition: rrset.h:52
void * owner
Definition: rrset.h:63
void rrset_backup2(FILE *fd, rrset_type *rrset)
Definition: rrset.c:887
allocator_type * allocator
Definition: zone.h:69
void rrset_del_rr(rrset_type *rrset, uint16_t rrnum)
Definition: rrset.c:309
#define LOG_ERR
Definition: log.h:49
int ods_log_get_level()
Definition: log.c:209
time_t duration2time(duration_type *duration)
Definition: duration.c:373
ldns_rr * rr
Definition: rrset.h:62
void ods_log_verbose(const char *format,...)
Definition: log.c:288
#define LOG_DEEEBUG
Definition: log.h:55
struct rrsig_struct rrsig_type
Definition: rrset.h:48
lock_basic_type ixfr_lock
Definition: ixfr.h:64
size_t count
Definition: keys.h:76
uint32_t sig_soa_count
Definition: stats.h:63
int ksk
Definition: keys.h:64
uint8_t algorithm
Definition: keys.h:61
duration_type * sig_jitter
Definition: signconf.h:61
void ods_log_deeebug(const char *format,...)
Definition: log.c:256
size_t rrsig_count
Definition: rrset.h:82
ods_status rrset_sign(hsm_ctx_t *ctx, rrset_type *rrset, time_t signtime)
Definition: rrset.c:664
void allocator_deallocate(allocator_type *allocator, void *data)
Definition: allocator.c:137
uint32_t sig_count
Definition: stats.h:62
#define LOG_DEBUG
Definition: log.h:53
void rrset_diff(rrset_type *rrset, unsigned is_ixfr, unsigned more_coming)
Definition: rrset.c:346
void * domain
Definition: rrset.h:77
rrsig_type * rrsigs
Definition: rrset.h:80
#define ods_log_assert(x)
Definition: log.h:156
time_t ods_rand(time_t mod)
Definition: duration.c:424
uint32_t flags
Definition: keys.h:62
unsigned is_added
Definition: rrset.h:65
#define lock_basic_unlock(lock)
Definition: locks.h:94
#define LOG_WARNING
Definition: log.h:50
void ods_log_warning(const char *format,...)
Definition: log.c:320
ldns_rdf * apex
Definition: zone.h:70
void rrset_print(FILE *fd, rrset_type *rrset, int skip_rrsigs, ods_status *status)
Definition: rrset.c:799
stats_type * stats
Definition: zone.h:96
rr_type * rrs
Definition: rrset.h:79