OpenDNSSEC-signer  1.4.1
rrset.c
Go to the documentation of this file.
1 /*
2  * $Id: rrset.c 6870 2012-11-27 13:01:48Z 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  const ldns_rr_descriptor* descriptor;
165  descriptor = ldns_rr_descript(type);
166  if (descriptor && descriptor->_name) {
167  return descriptor->_name;
168  } else if (type == LDNS_RR_TYPE_AXFR) {
169  return "AXFR";
170  } else if (type == LDNS_RR_TYPE_IXFR) {
171  return "IXFR";
172  }
173  return "TYPE???";
174 }
175 
176 
181 rrset_type*
182 rrset_create(void* zoneptr, ldns_rr_type type)
183 {
184  zone_type* zone = (zone_type*) zoneptr;
185  rrset_type* rrset = NULL;
186  if (!type || !zoneptr) {
187  return NULL;
188  }
189  rrset = (rrset_type*) allocator_alloc(
190  zone->allocator, sizeof(rrset_type));
191  if (!rrset) {
192  ods_log_error("[%s] unable to create RRset %u: allocator_alloc() "
193  "failed", rrset_str, (unsigned) type);
194  return NULL;
195  }
196  rrset->next = NULL;
197  rrset->rrs = NULL;
198  rrset->rrsigs = NULL;
199  rrset->domain = NULL;
200  rrset->zone = zoneptr;
201  rrset->rrtype = type;
202  rrset->rr_count = 0;
203  rrset->rrsig_count = 0;
204  rrset->needs_signing = 0;
205  return rrset;
206 }
207 
208 
213 rr_type*
214 rrset_lookup_rr(rrset_type* rrset, ldns_rr* rr)
215 {
216  ldns_status lstatus = LDNS_STATUS_OK;
217  int cmp = 0;
218  size_t i = 0;
219 
220  if (!rrset || !rr || rrset->rr_count <= 0) {
221  return NULL;
222  }
223  for (i=0; i < rrset->rr_count; i++) {
224  lstatus = util_dnssec_rrs_compare(rrset->rrs[i].rr, rr, &cmp);
225  if (lstatus != LDNS_STATUS_OK) {
226  ods_log_error("[%s] unable to lookup RR: compare failed (%s)",
227  rrset_str, ldns_get_errorstr_by_id(lstatus));
228  return NULL;
229  }
230  if (!cmp) { /* equal */
231  return &rrset->rrs[i];
232  }
233  }
234  return NULL;
235 }
236 
237 
242 size_t
244 {
245  size_t i = 0;
246  size_t count = 0;
247  if (!rrset) {
248  return 0;
249  }
250  for (i=0; i < rrset->rr_count; i++) {
251  if (rrset->rrs[i].is_added) {
252  count++;
253  }
254  }
255  return count;
256 }
257 
258 
263 rr_type*
264 rrset_add_rr(rrset_type* rrset, ldns_rr* rr)
265 {
266  rr_type* rrs_old = NULL;
267  zone_type* zone = NULL;
268 
269  ods_log_assert(rrset);
270  ods_log_assert(rr);
271  ods_log_assert(rrset->rrtype == ldns_rr_get_type(rr));
272 
273  zone = (zone_type*) rrset->zone;
274  rrs_old = rrset->rrs;
275  rrset->rrs = (rr_type*) allocator_alloc(zone->allocator,
276  (rrset->rr_count + 1) * sizeof(rr_type));
277  if (!rrset->rrs) {
278  ods_fatal_exit("[%s] fatal unable to add RR: allocator_alloc() failed",
279  rrset_str);
280  }
281  if (rrs_old) {
282  memcpy(rrset->rrs, rrs_old, (rrset->rr_count) * sizeof(rr_type));
283  }
284  allocator_deallocate(zone->allocator, (void*) rrs_old);
285  rrset->rr_count++;
286  rrset->rrs[rrset->rr_count - 1].owner = rrset->domain;
287  rrset->rrs[rrset->rr_count - 1].rr = rr;
288  rrset->rrs[rrset->rr_count - 1].exists = 0;
289  rrset->rrs[rrset->rr_count - 1].is_added = 1;
290  rrset->rrs[rrset->rr_count - 1].is_removed = 0;
291  rrset->needs_signing = 1;
292  log_rr(rr, "+RR", LOG_DEEEBUG);
293  return &rrset->rrs[rrset->rr_count -1];
294 }
295 
296 
301 void
302 rrset_del_rr(rrset_type* rrset, uint16_t rrnum)
303 {
304  rr_type* rrs_orig = NULL;
305  zone_type* zone = NULL;
306 
307  ods_log_assert(rrset);
308  ods_log_assert(rrnum < rrset->rr_count);
309 
310  zone = (zone_type*) rrset->zone;
311  log_rr(rrset->rrs[rrnum].rr, "-RR", LOG_DEEEBUG);
312  rrset->rrs[rrnum].owner = NULL;
313  rrset->rrs[rrnum].rr = NULL;
314  while (rrnum < rrset->rr_count-1) {
315  rrset->rrs[rrnum] = rrset->rrs[rrnum+1];
316  rrnum++;
317  }
318  memset(&rrset->rrs[rrset->rr_count-1], 0, sizeof(rr_type));
319  rrs_orig = rrset->rrs;
320  rrset->rrs = (rr_type*) allocator_alloc(zone->allocator,
321  (rrset->rr_count - 1) * sizeof(rr_type));
322  if(!rrset->rrs) {
323  ods_fatal_exit("[%s] fatal unable to delete RR: allocator_alloc() failed",
324  rrset_str);
325  }
326  memcpy(rrset->rrs, rrs_orig, (rrset->rr_count -1) * sizeof(rr_type));
327  allocator_deallocate(zone->allocator, (void*) rrs_orig);
328  rrset->rr_count--;
329  rrset->needs_signing = 1;
330  return;
331 }
332 
333 
338 void
339 rrset_diff(rrset_type* rrset, unsigned is_ixfr, unsigned more_coming)
340 {
341  zone_type* zone = NULL;
342  uint16_t i = 0;
343  uint8_t del_sigs = 0;
344  if (!rrset) {
345  return;
346  }
347  zone = (zone_type*) rrset->zone;
348  for (i=0; i < rrset->rr_count; i++) {
349  if (rrset->rrs[i].is_added) {
350  if (!rrset->rrs[i].exists) {
351  /* ixfr +RR */
352  lock_basic_lock(&zone->ixfr->ixfr_lock);
353  ixfr_add_rr(zone->ixfr, rrset->rrs[i].rr);
355  del_sigs = 1;
356  }
357  rrset->rrs[i].exists = 1;
358  if ((rrset->rrtype == LDNS_RR_TYPE_DNSKEY ||
359  rrset->rrtype == LDNS_RR_TYPE_NSEC3PARAMS) && more_coming) {
360  continue;
361  }
362  rrset->rrs[i].is_added = 0;
363  } else if (!is_ixfr || rrset->rrs[i].is_removed) {
364  if (rrset->rrs[i].exists) {
365  /* ixfr -RR */
366  lock_basic_lock(&zone->ixfr->ixfr_lock);
367  ixfr_del_rr(zone->ixfr, rrset->rrs[i].rr);
369  }
370  rrset->rrs[i].exists = 0;
371  rrset_del_rr(rrset, i);
372  del_sigs = 1;
373  i--;
374  }
375  }
376  if (del_sigs) {
377  for (i=0; i < rrset->rrsig_count; i++) {
378  /* ixfr -RRSIG */
379  lock_basic_lock(&zone->ixfr->ixfr_lock);
380  ixfr_del_rr(zone->ixfr, rrset->rrsigs[i].rr);
382  rrset_del_rrsig(rrset, i);
383  i--;
384  }
385  }
386  return;
387 }
388 
389 
394 rrsig_type*
395 rrset_add_rrsig(rrset_type* rrset, ldns_rr* rr,
396  const char* locator, uint32_t flags)
397 {
398  rrsig_type* rrsigs_old = NULL;
399  zone_type* zone = NULL;
400  ods_log_assert(rrset);
401  ods_log_assert(rr);
402  ods_log_assert(ldns_rr_get_type(rr) == LDNS_RR_TYPE_RRSIG);
403  zone = (zone_type*) rrset->zone;
404  rrsigs_old = rrset->rrsigs;
405  rrset->rrsigs = (rrsig_type*) allocator_alloc(zone->allocator,
406  (rrset->rrsig_count + 1) * sizeof(rrsig_type));
407  if (!rrset->rrsigs) {
408  ods_fatal_exit("[%s] fatal unable to add RRSIG: allocator_alloc() failed",
409  rrset_str);
410  }
411  if (rrsigs_old) {
412  memcpy(rrset->rrsigs, rrsigs_old,
413  (rrset->rrsig_count) * sizeof(rrsig_type));
414  }
415  allocator_deallocate(zone->allocator, (void*) rrsigs_old);
416  rrset->rrsig_count++;
417  rrset->rrsigs[rrset->rrsig_count - 1].owner = rrset->domain;
418  rrset->rrsigs[rrset->rrsig_count - 1].rr = rr;
419  rrset->rrsigs[rrset->rrsig_count - 1].key_locator = locator;
420  rrset->rrsigs[rrset->rrsig_count - 1].key_flags = flags;
421  log_rr(rr, "+RRSIG", LOG_DEEEBUG);
422  return &rrset->rrsigs[rrset->rrsig_count -1];
423 }
424 
425 
430 void
431 rrset_del_rrsig(rrset_type* rrset, uint16_t rrnum)
432 {
433  rrsig_type* rrsigs_orig = NULL;
434  zone_type* zone = NULL;
435  ods_log_assert(rrset);
436  ods_log_assert(rrnum < rrset->rrsig_count);
437  zone = (zone_type*) rrset->zone;
438  log_rr(rrset->rrsigs[rrnum].rr, "-RRSIG", LOG_DEEEBUG);
439  rrset->rrsigs[rrnum].owner = NULL;
440  rrset->rrsigs[rrnum].rr = NULL;
441  while (rrnum < rrset->rrsig_count-1) {
442  rrset->rrsigs[rrnum] = rrset->rrsigs[rrnum+1];
443  rrnum++;
444  }
445  memset(&rrset->rrsigs[rrset->rrsig_count-1], 0, sizeof(rrsig_type));
446  rrsigs_orig = rrset->rrsigs;
447  rrset->rrsigs = (rrsig_type*) allocator_alloc(zone->allocator,
448  (rrset->rrsig_count - 1) * sizeof(rrsig_type));
449  if(!rrset->rrsigs) {
450  ods_fatal_exit("[%s] fatal unable to delete RRSIG: allocator_alloc() failed",
451  rrset_str);
452  }
453  memcpy(rrset->rrsigs, rrsigs_orig,
454  (rrset->rrsig_count -1) * sizeof(rrsig_type));
455  allocator_deallocate(zone->allocator, (void*) rrsigs_orig);
456  rrset->rrsig_count--;
457  return;
458 }
459 
460 
465 static uint32_t
466 rrset_recycle(rrset_type* rrset, time_t signtime, ldns_rr_type dstatus,
467  ldns_rr_type delegpt)
468 {
469  uint32_t refresh = 0;
470  uint32_t expiration = 0;
471  uint32_t inception = 0;
472  uint32_t reusedsigs = 0;
473  unsigned drop_sig = 0;
474  size_t i = 0;
475  key_type* key = NULL;
476  zone_type* zone = NULL;
477 
478  if (!rrset) {
479  return 0;
480  }
481  zone = (zone_type*) rrset->zone;
482  /* Calculate the Refresh Window = Signing time + Refresh */
483  if (zone->signconf && zone->signconf->sig_refresh_interval) {
484  refresh = (uint32_t) (signtime +
486  }
487  /* Check every signature if it matches the recycling logic. */
488  for (i=0; i < rrset->rrsig_count; i++) {
489  drop_sig = 0;
490  /* 0. Skip delegation, glue and occluded RRsets */
491  if (dstatus != LDNS_RR_TYPE_SOA || (delegpt != LDNS_RR_TYPE_SOA &&
492  rrset->rrtype != LDNS_RR_TYPE_DS)) {
493  drop_sig = 1;
494  goto recycle_drop_sig;
495  }
496  ods_log_assert(dstatus == LDNS_RR_TYPE_SOA ||
497  (delegpt == LDNS_RR_TYPE_SOA || rrset->rrtype == LDNS_RR_TYPE_DS));
498  /* 1. If the RRset has changed, drop all signatures */
499  /* 2. If Refresh is disabled, drop all signatures */
500  if (rrset->needs_signing || refresh <= (uint32_t) signtime) {
501  drop_sig = 1;
502  goto recycle_drop_sig;
503  }
504  /* 3. Expiration - Refresh has passed */
505  expiration = ldns_rdf2native_int32(
506  ldns_rr_rrsig_expiration(rrset->rrsigs[i].rr));
507  if (expiration < refresh) {
508  drop_sig = 1;
509  goto recycle_drop_sig;
510  }
511  /* 4. Inception has not yet passed */
512  inception = ldns_rdf2native_int32(
513  ldns_rr_rrsig_inception(rrset->rrsigs[i].rr));
514  if (inception > (uint32_t) signtime) {
515  drop_sig = 1;
516  goto recycle_drop_sig;
517  }
518  /* 5. Corresponding key is dead (key is locator+flags) */
520  rrset->rrsigs[i].key_locator);
521  if (!key || key->flags != rrset->rrsigs[i].key_flags) {
522  drop_sig = 1;
523  }
524 
525 recycle_drop_sig:
526  if (drop_sig) {
527  /* A rule mismatched, refresh signature */
528  /* ixfr -RRSIG */
529  lock_basic_lock(&zone->ixfr->ixfr_lock);
530  ixfr_del_rr(zone->ixfr, rrset->rrsigs[i].rr);
532  rrset_del_rrsig(rrset, i);
533  i--;
534  } else {
535  /* All rules ok, recycle signature */
536  reusedsigs += 1;
537  }
538  }
539  return reusedsigs;
540 }
541 
542 
547 static int
548 rrset_sigalgo(rrset_type* rrset, uint8_t algorithm)
549 {
550  size_t i = 0;
551  if (!rrset) {
552  return 0;
553  }
554  for (i=0; i < rrset->rrsig_count; i++) {
555  if (algorithm == ldns_rdf2native_int8(
556  ldns_rr_rrsig_algorithm(rrset->rrsigs[i].rr))) {
557  return 1;
558  }
559  }
560  return 0;
561 }
562 
563 
568 static int
569 rrset_siglocator(rrset_type* rrset, const char* locator)
570 {
571  size_t i = 0;
572  if (!rrset) {
573  return 0;
574  }
575  for (i=0; i < rrset->rrsig_count; i++) {
576  if (!ods_strcmp(locator, rrset->rrsigs[i].key_locator)) {
577  return 1;
578  }
579  }
580  return 0;
581 }
582 
583 
588 static ldns_rr_list*
589 rrset2rrlist(rrset_type* rrset)
590 {
591  ldns_rr_list* rr_list = NULL;
592  int ret = 0;
593  size_t i = 0;
594  rr_list = ldns_rr_list_new();
595  for (i=0; i < rrset->rr_count; i++) {
596  if (!rrset->rrs[i].exists) {
597  log_rr(rrset->rrs[i].rr, "RR does not exist", LOG_WARNING);
598  continue;
599  }
600  /* clone if you want to keep the original format in the signed zone */
601  ldns_rr2canonical(rrset->rrs[i].rr);
602  ret = (int) ldns_rr_list_push_rr(rr_list, rrset->rrs[i].rr);
603  if (!ret) {
604  ldns_rr_list_free(rr_list);
605  return NULL;
606  }
607  if (rrset->rrtype == LDNS_RR_TYPE_CNAME ||
608  rrset->rrtype == LDNS_RR_TYPE_DNAME) {
609  /* singleton types */
610  return rr_list;
611  }
612  }
613  ldns_rr_list_sort(rr_list);
614  return rr_list;
615 }
616 
617 
622 static void
623 rrset_sigvalid_period(signconf_type* sc, ldns_rr_type rrtype, time_t signtime,
624  time_t* inception, time_t* expiration)
625 {
626  time_t jitter = 0;
627  time_t offset = 0;
628  time_t validity = 0;
629  time_t random_jitter = 0;
630  if (!sc || !rrtype || !signtime) {
631  return;
632  }
633  jitter = duration2time(sc->sig_jitter);
634  if (jitter) {
635  random_jitter = ods_rand(jitter*2);
636  }
637  offset = duration2time(sc->sig_inception_offset);
638  if (rrtype == LDNS_RR_TYPE_NSEC || rrtype == LDNS_RR_TYPE_NSEC3) {
639  validity = duration2time(sc->sig_validity_denial);
640  } else {
641  validity = duration2time(sc->sig_validity_default);
642  }
643  *inception = signtime - offset;
644  *expiration = (signtime + validity + random_jitter) - jitter;
645  return;
646 }
647 
648 
654 rrset_sign(hsm_ctx_t* ctx, rrset_type* rrset, time_t signtime)
655 {
656  zone_type* zone = NULL;
657  uint32_t newsigs = 0;
658  uint32_t reusedsigs = 0;
659  ldns_rr* rrsig = NULL;
660  ldns_rr_list* rr_list = NULL;
661  rrsig_type* signature = NULL;
662  const char* locator = NULL;
663  time_t inception = 0;
664  time_t expiration = 0;
665  size_t i = 0;
666  domain_type* domain = NULL;
667  ldns_rr_type dstatus = LDNS_RR_TYPE_FIRST;
668  ldns_rr_type delegpt = LDNS_RR_TYPE_FIRST;
669 
670  ods_log_assert(ctx);
671  ods_log_assert(rrset);
672  zone = (zone_type*) rrset->zone;
673  ods_log_assert(zone);
674  ods_log_assert(zone->signconf);
675  /* Recycle signatures */
676  if (rrset->rrtype == LDNS_RR_TYPE_NSEC ||
677  rrset->rrtype == LDNS_RR_TYPE_NSEC3) {
678  dstatus = LDNS_RR_TYPE_SOA;
679  delegpt = LDNS_RR_TYPE_SOA;
680  } else {
681  domain = (domain_type*) rrset->domain;
682  dstatus = domain_is_occluded(domain);
683  delegpt = domain_is_delegpt(domain);
684  }
685  reusedsigs = rrset_recycle(rrset, signtime, dstatus, delegpt);
686  rrset->needs_signing = 0;
687 
688  ods_log_assert(rrset->rrs);
689  ods_log_assert(rrset->rrs[0].rr);
690 
691  /* Skip delegation, glue and occluded RRsets */
692  if (dstatus != LDNS_RR_TYPE_SOA) {
693  log_rrset(ldns_rr_owner(rrset->rrs[0].rr), rrset->rrtype,
694  "skip signing occluded RRset", LOG_DEEEBUG);
695  return ODS_STATUS_OK;
696  }
697  if (delegpt != LDNS_RR_TYPE_SOA && rrset->rrtype != LDNS_RR_TYPE_DS) {
698  log_rrset(ldns_rr_owner(rrset->rrs[0].rr), rrset->rrtype,
699  "skip signing delegation RRset", LOG_DEEEBUG);
700  return ODS_STATUS_OK;
701  }
702 
703  log_rrset(ldns_rr_owner(rrset->rrs[0].rr), rrset->rrtype,
704  "sign RRset", LOG_DEEEBUG);
705  ods_log_assert(dstatus == LDNS_RR_TYPE_SOA ||
706  (delegpt == LDNS_RR_TYPE_SOA || rrset->rrtype == LDNS_RR_TYPE_DS));
707  /* Transmogrify rrset */
708  rr_list = rrset2rrlist(rrset);
709  if (!rr_list) {
710  ods_log_error("[%s] unable to sign RRset[%i]: rrset2rrlist() failed",
711  rrset_str, rrset->rrtype);
712  return ODS_STATUS_MALLOC_ERR;
713  }
714  if (ldns_rr_list_rr_count(rr_list) <= 0) {
715  /* Empty RRset, no signatures needed */
716  ldns_rr_list_free(rr_list);
717  return ODS_STATUS_OK;
718  }
719  /* Calculate signature validity */
720  rrset_sigvalid_period(zone->signconf, rrset->rrtype, signtime,
721  &inception, &expiration);
722  /* Walk keys */
723  for (i=0; i < zone->signconf->keys->count; i++) {
724  /* If not ZSK don't sign other RRsets */
725  if (!zone->signconf->keys->keys[i].zsk &&
726  rrset->rrtype != LDNS_RR_TYPE_DNSKEY) {
727  continue;
728  }
729  /* If not KSK don't sign DNSKEY RRset */
730  if (!zone->signconf->keys->keys[i].ksk &&
731  rrset->rrtype == LDNS_RR_TYPE_DNSKEY) {
732  continue;
733  }
734  /* Additional rules for signatures */
735  if (rrset_siglocator(rrset, zone->signconf->keys->keys[i].locator)) {
736  continue;
737  }
738  if (rrset->rrtype != LDNS_RR_TYPE_DNSKEY &&
739  rrset_sigalgo(rrset, zone->signconf->keys->keys[i].algorithm)) {
740  continue;
741  }
742 
748  /* Sign the RRset with this key */
749  ods_log_deeebug("[%s] signing RRset[%i] with key %s", rrset_str,
750  rrset->rrtype, zone->signconf->keys->keys[i].locator);
751  rrsig = lhsm_sign(ctx, rr_list, &zone->signconf->keys->keys[i],
752  zone->apex, inception, expiration);
753  if (!rrsig) {
754  ods_log_crit("[%s] unable to sign RRset[%i]: lhsm_sign() failed",
755  rrset_str, rrset->rrtype);
756  ldns_rr_list_free(rr_list);
757  return ODS_STATUS_HSM_ERR;
758  }
759  /* Add signature */
760  locator = allocator_strdup(zone->allocator,
761  zone->signconf->keys->keys[i].locator);
762  signature = rrset_add_rrsig(rrset, rrsig, locator,
763  zone->signconf->keys->keys[i].flags);
764  newsigs++;
765  /* ixfr +RRSIG */
766  ods_log_assert(signature->rr);
767  lock_basic_lock(&zone->ixfr->ixfr_lock);
768  ixfr_add_rr(zone->ixfr, signature->rr);
770  }
771  /* RRset signing completed */
772  ldns_rr_list_free(rr_list);
774  if (rrset->rrtype == LDNS_RR_TYPE_SOA) {
775  zone->stats->sig_soa_count += newsigs;
776  }
777  zone->stats->sig_count += newsigs;
778  zone->stats->sig_reuse += reusedsigs;
780  return ODS_STATUS_OK;
781 }
782 
783 
788 void
789 rrset_print(FILE* fd, rrset_type* rrset, int skip_rrsigs,
790  ods_status* status)
791 {
792  uint16_t i = 0;
793  ods_status result = ODS_STATUS_OK;
794 
795  if (!rrset || !fd) {
796  ods_log_crit("[%s] unable to print RRset: rrset or fd missing",
797  rrset_str);
798  if (status) {
799  *status = ODS_STATUS_ASSERT_ERR;
800  }
801  return;
802  }
803  for (i=0; i < rrset->rr_count; i++) {
804  if (rrset->rrs[i].exists) {
805  result = util_rr_print(fd, rrset->rrs[i].rr);
806  if (rrset->rrtype == LDNS_RR_TYPE_CNAME ||
807  rrset->rrtype == LDNS_RR_TYPE_DNAME) {
808  /* singleton types */
809  break;
810  }
811  if (result != ODS_STATUS_OK) {
812  zone_type* zone = (zone_type*) rrset->zone;
813  log_rrset(ldns_rr_owner(rrset->rrs[i].rr), rrset->rrtype,
814  "error printing RRset", LOG_CRIT);
815  zone->adoutbound->error = 1;
816  break;
817  }
818  }
819  }
820  if (! (skip_rrsigs || !rrset->rrsig_count)) {
821  for (i=0; i < rrset->rrsig_count; i++) {
822  result = util_rr_print(fd, rrset->rrsigs[i].rr);
823  if (result != ODS_STATUS_OK) {
824  zone_type* zone = (zone_type*) rrset->zone;
825  log_rrset(ldns_rr_owner(rrset->rrs[i].rr), rrset->rrtype,
826  "error printing RRset", LOG_CRIT);
827  zone->adoutbound->error = 1;
828  break;
829  }
830  }
831  }
832  if (status) {
833  *status = result;
834  }
835  return;
836 }
837 
838 
843 void
845 {
846  uint16_t i = 0;
847  zone_type* zone = NULL;
848  if (!rrset) {
849  return;
850  }
851  rrset_cleanup(rrset->next);
852  rrset->next = NULL;
853  rrset->domain = NULL;
854  zone = (zone_type*) rrset->zone;
855  for (i=0; i < rrset->rr_count; i++) {
856  ldns_rr_free(rrset->rrs[i].rr);
857  rrset->rrs[i].owner = NULL;
858  }
859  for (i=0; i < rrset->rrsig_count; i++) {
861  (void*)rrset->rrsigs[i].key_locator);
862  ldns_rr_free(rrset->rrsigs[i].rr);
863  rrset->rrsigs[i].owner = NULL;
864  }
865  allocator_deallocate(zone->allocator, (void*) rrset->rrs);
866  allocator_deallocate(zone->allocator, (void*) rrset->rrsigs);
867  allocator_deallocate(zone->allocator, (void*) rrset);
868  return;
869 }
870 
871 
876 void
877 rrset_backup2(FILE* fd, rrset_type* rrset)
878 {
879  char* str = NULL;
880  uint16_t i = 0;
881  if (!rrset || !fd) {
882  return;
883  }
884  for (i=0; i < rrset->rrsig_count; i++) {
885  str = ldns_rr2str(rrset->rrsigs[i].rr);
886  if (!str) {
887  continue;
888  }
889  str[(strlen(str))-1] = '\0';
890  fprintf(fd, "%s; {locator %s flags %u}\n", str,
891  rrset->rrsigs[i].key_locator, rrset->rrsigs[i].key_flags);
892  free((void*)str);
893  }
894  return;
895 }