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