OpenDNSSEC-signer  2.0.3
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 "file.h"
34 #include "hsm.h"
35 #include "log.h"
36 #include "util.h"
37 #include "compat.h"
38 #include "signer/rrset.h"
39 #include "signer/zone.h"
40 
41 static const char* rrset_str = "rrset";
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 }
92 
93 
98 void
99 log_rrset(ldns_rdf* dname, ldns_rr_type type, const char* pre, int level)
100 {
101  char* str = NULL;
102  size_t i = 0;
103 
104  if (ods_log_get_level() < level) {
105  return;
106  }
107  str = ldns_rdf2str(dname);
108  if (!str) {
109  return;
110  }
111  str[(strlen(str))-1] = '\0';
112  /* replace tabs with white space */
113  for (i=0; i < strlen(str); i++) {
114  if (str[i] == '\t') {
115  str[i] = ' ';
116  }
117  }
118  if (level == LOG_EMERG) {
119  ods_fatal_exit("[%s] %s: <%s,%s>", rrset_str, pre?pre:"", str,
120  rrset_type2str(type));
121  } else if (level == LOG_ALERT) {
122  ods_log_alert("[%s] %s: <%s,%s>", rrset_str, pre?pre:"", str,
123  rrset_type2str(type));
124  } else if (level == LOG_CRIT) {
125  ods_log_crit("[%s] %s: <%s,%s>", rrset_str, pre?pre:"", str,
126  rrset_type2str(type));
127  } else if (level == LOG_ERR) {
128  ods_log_error("[%s] %s: <%s,%s>", rrset_str, pre?pre:"", str,
129  rrset_type2str(type));
130  } else if (level == LOG_WARNING) {
131  ods_log_warning("[%s] %s: <%s,%s>", rrset_str, pre?pre:"", str,
132  rrset_type2str(type));
133  } else if (level == LOG_NOTICE) {
134  ods_log_info("[%s] %s: <%s,%s>", rrset_str, pre?pre:"", str,
135  rrset_type2str(type));
136  } else if (level == LOG_INFO) {
137  ods_log_verbose("[%s] %s: <%s,%s>", rrset_str, pre?pre:"", str,
138  rrset_type2str(type));
139  } else if (level == LOG_DEBUG) {
140  ods_log_debug("[%s] %s: <%s,%s>", rrset_str, pre?pre:"", str,
141  rrset_type2str(type));
142  } else if (level == LOG_DEEEBUG) {
143  ods_log_deeebug("[%s] %s: <%s,%s>", rrset_str, pre?pre:"", str,
144  rrset_type2str(type));
145  } else {
146  ods_log_deeebug("[%s] %s: <%s,%s>", rrset_str, pre?pre:"", str,
147  rrset_type2str(type));
148  }
149  free((void*)str);
150 }
151 
152 
157 const char*
158 rrset_type2str(ldns_rr_type type)
159 {
160  if (type == LDNS_RR_TYPE_IXFR) {
161  return "IXFR";
162  } else if (type == LDNS_RR_TYPE_AXFR) {
163  return "AXFR";
164  } else if (type == LDNS_RR_TYPE_MAILB) {
165  return "MAILB";
166  } else if (type == LDNS_RR_TYPE_MAILA) {
167  return "MAILA";
168  } else if (type == LDNS_RR_TYPE_ANY) {
169  return "ANY";
170  } else {
171  const ldns_rr_descriptor* descriptor = ldns_rr_descript(type);
172  if (descriptor && descriptor->_name) {
173  return descriptor->_name;
174  }
175  }
176  return "TYPE???";
177 }
178 
179 static int
180 memberdestroy(void* dummy, void* member)
181 {
182  rrsig_type* sig = (rrsig_type*) member;
183  (void)dummy;
184  free((void*) sig->key_locator);
185  sig->key_locator = NULL;
186  /* The rrs may still be in use by IXFRs so cannot do ldns_rr_free(sig->rr); */
187  sig->owner = NULL;
188  sig->rr = NULL;
189  return 0;
190 }
191 
192 
197 rrset_type*
198 rrset_create(zone_type* zone, ldns_rr_type type)
199 {
200  rrset_type* rrset = NULL;
201  if (!type || !zone) {
202  return NULL;
203  }
204  CHECKALLOC(rrset = (rrset_type*) malloc(sizeof(rrset_type)));
205  if (!rrset) {
206  ods_log_error("[%s] unable to create RRset %u: allocator_alloc() "
207  "failed", rrset_str, (unsigned) type);
208  return NULL;
209  }
210  rrset->next = NULL;
211  rrset->rrs = NULL;
212  rrset->domain = NULL;
213  rrset->zone = zone;
214  rrset->rrtype = type;
215  rrset->rr_count = 0;
216  collection_create_array(&rrset->rrsigs, sizeof(rrsig_type), rrset->zone->rrstore);
217  rrset->needs_signing = 0;
218  return rrset;
219 }
220 
221 collection_class
223 {
224  collection_class klass;
225  collection_class_allocated(&klass, NULL, memberdestroy);
226  return klass;
227 }
228 
229 
234 rr_type*
235 rrset_lookup_rr(rrset_type* rrset, ldns_rr* rr)
236 {
237  ldns_status lstatus = LDNS_STATUS_OK;
238  int cmp = 0;
239  size_t i = 0;
240 
241  if (!rrset || !rr || rrset->rr_count <= 0) {
242  return NULL;
243  }
244  for (i=0; i < rrset->rr_count; i++) {
245  lstatus = util_dnssec_rrs_compare(rrset->rrs[i].rr, rr, &cmp);
246  if (lstatus != LDNS_STATUS_OK) {
247  ods_log_error("[%s] unable to lookup RR: compare failed (%s)",
248  rrset_str, ldns_get_errorstr_by_id(lstatus));
249  return NULL;
250  }
251  if (!cmp) { /* equal */
252  return &rrset->rrs[i];
253  }
254  }
255  return NULL;
256 }
257 
258 
263 size_t
265 {
266  size_t i = 0;
267  size_t count = 0;
268  if (!rrset) {
269  return 0;
270  }
271  for (i=0; i < rrset->rr_count; i++) {
272  if (rrset->rrs[i].is_added) {
273  count++;
274  }
275  }
276  return count;
277 }
278 
279 
284 rr_type*
285 rrset_add_rr(rrset_type* rrset, ldns_rr* rr)
286 {
287  rr_type* rrs_old = NULL;
288 
289  ods_log_assert(rrset);
290  ods_log_assert(rr);
291  ods_log_assert(rrset->rrtype == ldns_rr_get_type(rr));
292 
293  rrs_old = rrset->rrs;
294  CHECKALLOC(rrset->rrs = (rr_type*) malloc((rrset->rr_count + 1) * sizeof(rr_type)));
295  if (!rrset->rrs) {
296  ods_fatal_exit("[%s] fatal unable to add RR: allocator_alloc() failed",
297  rrset_str);
298  }
299  if (rrs_old) {
300  memcpy(rrset->rrs, rrs_old, (rrset->rr_count) * sizeof(rr_type));
301  }
302  free(rrs_old);
303  rrset->rr_count++;
304  rrset->rrs[rrset->rr_count - 1].owner = rrset->domain;
305  rrset->rrs[rrset->rr_count - 1].rr = rr;
306  rrset->rrs[rrset->rr_count - 1].exists = 0;
307  rrset->rrs[rrset->rr_count - 1].is_added = 1;
308  rrset->rrs[rrset->rr_count - 1].is_removed = 0;
309  rrset->needs_signing = 1;
310  log_rr(rr, "+RR", LOG_DEEEBUG);
311  return &rrset->rrs[rrset->rr_count -1];
312 }
313 
314 
319 void
320 rrset_del_rr(rrset_type* rrset, uint16_t rrnum)
321 {
322  rr_type* rrs_orig = NULL;
323 
324  ods_log_assert(rrset);
325  ods_log_assert(rrnum < rrset->rr_count);
326 
327  log_rr(rrset->rrs[rrnum].rr, "-RR", LOG_DEEEBUG);
328  rrset->rrs[rrnum].owner = NULL;
329  rrset->rrs[rrnum].rr = NULL;
330  while (rrnum < rrset->rr_count-1) {
331  rrset->rrs[rrnum] = rrset->rrs[rrnum+1];
332  rrnum++;
333  }
334  memset(&rrset->rrs[rrset->rr_count-1], 0, sizeof(rr_type));
335  rrs_orig = rrset->rrs;
336  CHECKALLOC(rrset->rrs = (rr_type*) malloc((rrset->rr_count - 1) * sizeof(rr_type)));
337  if(!rrset->rrs) {
338  ods_fatal_exit("[%s] fatal unable to delete RR: allocator_alloc() failed",
339  rrset_str);
340  }
341  memcpy(rrset->rrs, rrs_orig, (rrset->rr_count -1) * sizeof(rr_type));
342  free(rrs_orig);
343  rrset->rr_count--;
344  rrset->needs_signing = 1;
345 }
346 
351 void
352 rrset_diff(rrset_type* rrset, unsigned is_ixfr, unsigned more_coming)
353 {
354  zone_type* zone = NULL;
355  uint16_t i = 0;
356  uint8_t del_sigs = 0;
357  if (!rrset) {
358  return;
359  }
360  zone = (zone_type*) rrset->zone;
361  for (i=0; i < rrset->rr_count; i++) {
362  if (rrset->rrs[i].is_added) {
363  if (!rrset->rrs[i].exists) {
364  /* ixfr +RR */
365  lock_basic_lock(&zone->ixfr->ixfr_lock);
366  ixfr_add_rr(zone->ixfr, rrset->rrs[i].rr);
367  lock_basic_unlock(&zone->ixfr->ixfr_lock);
368  del_sigs = 1;
369  }
370  rrset->rrs[i].exists = 1;
371  if ((rrset->rrtype == LDNS_RR_TYPE_DNSKEY ||
372  rrset->rrtype == LDNS_RR_TYPE_NSEC3PARAMS) && more_coming) {
373  continue;
374  }
375  rrset->rrs[i].is_added = 0;
376  } else if (!is_ixfr || rrset->rrs[i].is_removed) {
377  if (rrset->rrs[i].exists) {
378  /* ixfr -RR */
379  lock_basic_lock(&zone->ixfr->ixfr_lock);
380  ixfr_del_rr(zone->ixfr, rrset->rrs[i].rr);
381  lock_basic_unlock(&zone->ixfr->ixfr_lock);
382  }
383  rrset->rrs[i].exists = 0;
384  rrset_del_rr(rrset, i);
385  del_sigs = 1;
386  i--;
387  }
388  }
389  if (del_sigs) {
390  rrset_drop_rrsigs(zone, rrset);
391  }
392 }
393 
398 void
400 {
401  rrsig_type* rrsig;
402  while((rrsig = collection_iterator(rrset->rrsigs))) {
403  /* ixfr -RRSIG */
404  lock_basic_lock(&zone->ixfr->ixfr_lock);
405  ixfr_del_rr(zone->ixfr, rrsig->rr);
406  lock_basic_unlock(&zone->ixfr->ixfr_lock);
407  collection_del_cursor(rrset->rrsigs);
408  }
409 }
410 
415 void
416 rrset_add_rrsig(rrset_type* rrset, ldns_rr* rr,
417  const char* locator, uint32_t flags)
418 {
419  rrsig_type rrsig;
420  ods_log_assert(rrset);
421  ods_log_assert(rr);
422  ods_log_assert(ldns_rr_get_type(rr) == LDNS_RR_TYPE_RRSIG);
423  rrsig.owner = rrset->domain;
424  rrsig.rr = rr;
425  rrsig.key_locator = locator;
426  rrsig.key_flags = flags;
427  collection_add(rrset->rrsigs, &rrsig);
428 }
429 
434 static uint32_t
435 rrset_recycle(rrset_type* rrset, time_t signtime, ldns_rr_type dstatus,
436  ldns_rr_type delegpt)
437 {
438  uint32_t refresh = 0;
439  uint32_t expiration = 0;
440  uint32_t inception = 0;
441  uint32_t reusedsigs = 0;
442  unsigned drop_sig = 0;
443  key_type* key = NULL;
444  zone_type* zone = NULL;
445  rrsig_type* rrsig;
446 
447  if (!rrset) {
448  return 0;
449  }
450  zone = (zone_type*) rrset->zone;
451  /* Calculate the Refresh Window = Signing time + Refresh */
452  if (zone->signconf && zone->signconf->sig_refresh_interval) {
453  refresh = (uint32_t) (signtime +
454  duration2time(zone->signconf->sig_refresh_interval));
455  }
456  /* Check every signature if it matches the recycling logic. */
457  while((rrsig = collection_iterator(rrset->rrsigs))) {
458  drop_sig = 0;
459  /* 0. Skip delegation, glue and occluded RRsets */
460  if (dstatus != LDNS_RR_TYPE_SOA || (delegpt != LDNS_RR_TYPE_SOA &&
461  rrset->rrtype != LDNS_RR_TYPE_DS)) {
462  drop_sig = 1;
463  goto recycle_drop_sig;
464  }
465  ods_log_assert(dstatus == LDNS_RR_TYPE_SOA ||
466  (delegpt == LDNS_RR_TYPE_SOA || rrset->rrtype == LDNS_RR_TYPE_DS));
467  /* 1. If the RRset has changed, drop all signatures */
468  /* 2. If Refresh is disabled, drop all signatures */
469  if (rrset->needs_signing || refresh <= (uint32_t) signtime) {
470  drop_sig = 1;
471  goto recycle_drop_sig;
472  }
473  /* 3. Expiration - Refresh has passed */
474  expiration = ldns_rdf2native_int32(
475  ldns_rr_rrsig_expiration(rrsig->rr));
476  if (expiration < refresh) {
477  drop_sig = 1;
478  goto recycle_drop_sig;
479  }
480  /* 4. Inception has not yet passed */
481  inception = ldns_rdf2native_int32(
482  ldns_rr_rrsig_inception(rrsig->rr));
483  if (inception > (uint32_t) signtime) {
484  drop_sig = 1;
485  goto recycle_drop_sig;
486  }
487  /* 5. Corresponding key is dead (key is locator+flags) */
489  rrsig->key_locator);
490  if (!key || key->flags != rrsig->key_flags) {
491  drop_sig = 1;
492  }
493 
494 recycle_drop_sig:
495  if (drop_sig) {
496  /* A rule mismatched, refresh signature */
497  /* ixfr -RRSIG */
498  lock_basic_lock(&zone->ixfr->ixfr_lock);
499  ixfr_del_rr(zone->ixfr, rrsig->rr);
500  lock_basic_unlock(&zone->ixfr->ixfr_lock);
501  collection_del_cursor(rrset->rrsigs);
502  } else {
503  /* All rules ok, recycle signature */
504  reusedsigs += 1;
505  }
506  }
507  return reusedsigs;
508 }
509 
510 
515 static int
516 rrset_sigalgo(rrset_type* rrset, uint8_t algorithm)
517 {
518  rrsig_type* rrsig;
519  int match = 0;
520  if (rrset) {
521  while((rrsig = collection_iterator(rrset->rrsigs))) {
522  if (algorithm == ldns_rdf2native_int8(ldns_rr_rrsig_algorithm(rrsig->rr))) {
523  match = 1;
524  }
525  }
526  }
527  return match;
528 }
529 
534 static int
535 rrset_siglocator(rrset_type* rrset, const char* locator)
536 {
537  rrsig_type* rrsig;
538  int match = 0;
539  if (rrset) {
540  while ((rrsig = collection_iterator(rrset->rrsigs))) {
541  if (!ods_strcmp(locator, rrsig->key_locator)) {
542  match = 1;
543  }
544  }
545  }
546  return match;
547 }
548 
549 
554 static ldns_rr_list*
555 rrset2rrlist(rrset_type* rrset)
556 {
557  ldns_rr_list* rr_list = NULL;
558  int ret = 0;
559  size_t i = 0;
560  rr_list = ldns_rr_list_new();
561  for (i=0; i < rrset->rr_count; i++) {
562  if (!rrset->rrs[i].exists) {
563  log_rr(rrset->rrs[i].rr, "RR does not exist", LOG_WARNING);
564  continue;
565  }
566  /* clone if you want to keep the original format in the signed zone */
567  ldns_rr2canonical(rrset->rrs[i].rr);
568  ret = (int) ldns_rr_list_push_rr(rr_list, rrset->rrs[i].rr);
569  if (!ret) {
570  ldns_rr_list_free(rr_list);
571  return NULL;
572  }
573  if (rrset->rrtype == LDNS_RR_TYPE_CNAME ||
574  rrset->rrtype == LDNS_RR_TYPE_DNAME) {
575  /* singleton types */
576  return rr_list;
577  }
578  }
579  ldns_rr_list_sort(rr_list);
580  return rr_list;
581 }
582 
583 
588 static void
589 rrset_sigvalid_period(signconf_type* sc, ldns_rr_type rrtype, time_t signtime,
590  time_t* inception, time_t* expiration)
591 {
592  time_t jitter = 0;
593  time_t offset = 0;
594  time_t validity = 0;
595  time_t random_jitter = 0;
596  if (!sc || !rrtype || !signtime) {
597  return;
598  }
599  jitter = duration2time(sc->sig_jitter);
600  if (jitter) {
601  random_jitter = ods_rand(jitter*2);
602  }
603  offset = duration2time(sc->sig_inception_offset);
604  switch (rrtype) {
605  case LDNS_RR_TYPE_NSEC:
606  case LDNS_RR_TYPE_NSEC3:
607  validity = duration2time(sc->sig_validity_denial);
608  break;
609  case LDNS_RR_TYPE_DNSKEY:
610  if (sc->sig_validity_keyset != NULL && duration2time(sc->sig_validity_keyset) > 0) {
611  validity = duration2time(sc->sig_validity_keyset);
612  } else {
613  validity = duration2time(sc->sig_validity_default);
614  }
615  break;
616  default:
617  validity = duration2time(sc->sig_validity_default);
618  }
619  *inception = signtime - offset;
620  *expiration = (signtime + validity + random_jitter) - jitter;
621 }
622 
623 
628 ods_status
629 rrset_sign(hsm_ctx_t* ctx, rrset_type* rrset, time_t signtime)
630 {
631  ods_status status;
632  zone_type* zone = NULL;
633  uint32_t newsigs = 0;
634  uint32_t reusedsigs = 0;
635  ldns_rr* rrsig = NULL;
636  ldns_rr_list* rr_list = NULL;
637  const char* locator = NULL;
638  time_t inception = 0;
639  time_t expiration = 0;
640  size_t i = 0;
641  domain_type* domain = NULL;
642  ldns_rr_type dstatus = LDNS_RR_TYPE_FIRST;
643  ldns_rr_type delegpt = LDNS_RR_TYPE_FIRST;
644 
645  ods_log_assert(ctx);
646  ods_log_assert(rrset);
647  zone = (zone_type*) rrset->zone;
648  ods_log_assert(zone);
649  ods_log_assert(zone->signconf);
650  /* Recycle signatures */
651  if (rrset->rrtype == LDNS_RR_TYPE_NSEC ||
652  rrset->rrtype == LDNS_RR_TYPE_NSEC3) {
653  dstatus = LDNS_RR_TYPE_SOA;
654  delegpt = LDNS_RR_TYPE_SOA;
655  } else {
656  domain = (domain_type*) rrset->domain;
657  dstatus = domain_is_occluded(domain);
658  delegpt = domain_is_delegpt(domain);
659  }
660  reusedsigs = rrset_recycle(rrset, signtime, dstatus, delegpt);
661  rrset->needs_signing = 0;
662 
663  ods_log_assert(rrset->rrs);
664  ods_log_assert(rrset->rrs[0].rr);
665 
666  /* Skip delegation, glue and occluded RRsets */
667  if (dstatus != LDNS_RR_TYPE_SOA) {
668  log_rrset(ldns_rr_owner(rrset->rrs[0].rr), rrset->rrtype,
669  "skip signing occluded RRset", LOG_DEEEBUG);
670  return ODS_STATUS_OK;
671  }
672  if (delegpt != LDNS_RR_TYPE_SOA && rrset->rrtype != LDNS_RR_TYPE_DS) {
673  log_rrset(ldns_rr_owner(rrset->rrs[0].rr), rrset->rrtype,
674  "skip signing delegation RRset", LOG_DEEEBUG);
675  return ODS_STATUS_OK;
676  }
677 
678  log_rrset(ldns_rr_owner(rrset->rrs[0].rr), rrset->rrtype,
679  "sign RRset", LOG_DEEEBUG);
680  ods_log_assert(dstatus == LDNS_RR_TYPE_SOA ||
681  (delegpt == LDNS_RR_TYPE_SOA || rrset->rrtype == LDNS_RR_TYPE_DS));
682  /* Transmogrify rrset */
683  rr_list = rrset2rrlist(rrset);
684  if (ldns_rr_list_rr_count(rr_list) <= 0) {
685  /* Empty RRset, no signatures needed */
686  ldns_rr_list_free(rr_list);
687  return ODS_STATUS_OK;
688  }
689  /* Calculate signature validity */
690  rrset_sigvalid_period(zone->signconf, rrset->rrtype, signtime,
691  &inception, &expiration);
692  /* Walk keys */
693  for (i=0; i < zone->signconf->keys->count; i++) {
694  /* If not ZSK don't sign other RRsets */
695  if (!zone->signconf->keys->keys[i].zsk &&
696  rrset->rrtype != LDNS_RR_TYPE_DNSKEY) {
697  continue;
698  }
699  /* If not KSK don't sign DNSKEY RRset */
700  if (!zone->signconf->keys->keys[i].ksk &&
701  rrset->rrtype == LDNS_RR_TYPE_DNSKEY) {
702  continue;
703  }
704  /* Additional rules for signatures */
705  if (rrset_siglocator(rrset, zone->signconf->keys->keys[i].locator)) {
706  continue;
707  }
708  if (rrset->rrtype != LDNS_RR_TYPE_DNSKEY &&
709  rrset_sigalgo(rrset, zone->signconf->keys->keys[i].algorithm)) {
710  continue;
711  }
712  /* If key has no locator, and should be pre-signed dnskey RR, skip */
713  if (zone->signconf->keys->keys[i].ksk && zone->signconf->keys->keys[i].locator == NULL) {
714  continue;
715  }
716 
717  /* Sign the RRset with this key */
718  ods_log_deeebug("[%s] signing RRset[%i] with key %s", rrset_str,
719  rrset->rrtype, zone->signconf->keys->keys[i].locator);
720  rrsig = lhsm_sign(ctx, rr_list, &zone->signconf->keys->keys[i],
721  zone->apex, inception, expiration);
722  if (!rrsig) {
723  ods_log_crit("[%s] unable to sign RRset[%i]: lhsm_sign() failed",
724  rrset_str, rrset->rrtype);
725  ldns_rr_list_free(rr_list);
726  return ODS_STATUS_HSM_ERR;
727  }
728  /* Add signature */
729  locator = strdup(zone->signconf->keys->keys[i].locator);
730  rrset_add_rrsig(rrset, rrsig, locator,
731  zone->signconf->keys->keys[i].flags);
732  newsigs++;
733  /* ixfr +RRSIG */
734  lock_basic_lock(&zone->ixfr->ixfr_lock);
735  ixfr_add_rr(zone->ixfr, rrsig);
736  lock_basic_unlock(&zone->ixfr->ixfr_lock);
737  }
738  if(rrset->rrtype == LDNS_RR_TYPE_DNSKEY && zone->signconf->dnskey_signature) {
739  for(i=0; zone->signconf->dnskey_signature[i]; i++) {
740  rrsig = NULL;
741  if ((status = rrset_getliteralrr(&rrsig, zone->signconf->dnskey_signature[i], duration2time(zone->signconf->dnskey_ttl), zone->apex)) != ODS_STATUS_OK) {
742  ods_log_error("[%s] unable to publish dnskeys for zone %s: "
743  "error decoding literal dnskey", rrset_str, zone->name);
744  return status;
745  }
746  /* Add signature */
747  rrset_add_rrsig(rrset, rrsig, NULL, 0);
748  newsigs++;
749  /* ixfr +RRSIG */
750  lock_basic_lock(&zone->ixfr->ixfr_lock);
751  ixfr_add_rr(zone->ixfr, rrsig);
752  lock_basic_unlock(&zone->ixfr->ixfr_lock);
753  }
754  }
755  /* RRset signing completed */
756  ldns_rr_list_free(rr_list);
757  lock_basic_lock(&zone->stats->stats_lock);
758  if (rrset->rrtype == LDNS_RR_TYPE_SOA) {
759  zone->stats->sig_soa_count += newsigs;
760  }
761  zone->stats->sig_count += newsigs;
762  zone->stats->sig_reuse += reusedsigs;
763  lock_basic_unlock(&zone->stats->stats_lock);
764  return ODS_STATUS_OK;
765 }
766 
767 ods_status
768 rrset_getliteralrr(ldns_rr** dnskey, const char *resourcerecord, uint32_t ttl, ldns_rdf* apex)
769 {
770  uint8_t dnskeystring[4096];
771  ldns_status ldnsstatus;
772  int len;
773  if ((len = b64_pton(resourcerecord, dnskeystring, sizeof (dnskeystring) - 2)) < 0) {
774  return ODS_STATUS_PARSE_ERR;
775  }
776  dnskeystring[len] = '\0';
777  if ((ldnsstatus = ldns_rr_new_frm_str(dnskey, (const char*) dnskeystring, ttl, apex, NULL)) != LDNS_STATUS_OK) {
778  return ODS_STATUS_PARSE_ERR;
779  }
780  return ODS_STATUS_OK;
781 }
782 
787 void
788 rrset_print(FILE* fd, rrset_type* rrset, int skip_rrsigs,
789  ods_status* status)
790 {
791  rrsig_type* rrsig;
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  } else {
802  for (i=0; i < rrset->rr_count; i++) {
803  if (rrset->rrs[i].exists) {
804  result = util_rr_print(fd, rrset->rrs[i].rr);
805  if (rrset->rrtype == LDNS_RR_TYPE_CNAME ||
806  rrset->rrtype == LDNS_RR_TYPE_DNAME) {
807  /* singleton types */
808  break;
809  }
810  if (result != ODS_STATUS_OK) {
811  zone_type* zone = (zone_type*) rrset->zone;
812  log_rrset(ldns_rr_owner(rrset->rrs[i].rr), rrset->rrtype,
813  "error printing RRset", LOG_CRIT);
814  zone->adoutbound->error = 1;
815  break;
816  }
817  }
818  }
819  if (! skip_rrsigs) {
820  result = ODS_STATUS_OK;
821  while((rrsig = collection_iterator(rrset->rrsigs))) {
822  if (result == ODS_STATUS_OK) {
823  result = util_rr_print(fd, rrsig->rr);
824  if (result != ODS_STATUS_OK) {
825  zone_type* zone = rrset->zone;
826  log_rrset(ldns_rr_owner(rrset->rrs[i].rr), rrset->rrtype,
827  "error printing RRset", LOG_CRIT);
828  zone->adoutbound->error = 1;
829  }
830  }
831  }
832  }
833  if (status) {
834  *status = result;
835  }
836  }
837 }
838 
839 
844 void
846 {
847  uint16_t i = 0;
848  if (!rrset) {
849  return;
850  }
851  rrset_cleanup(rrset->next);
852  rrset->next = NULL;
853  rrset->domain = NULL;
854  for (i=0; i < rrset->rr_count; i++) {
855  ldns_rr_free(rrset->rrs[i].rr);
856  rrset->rrs[i].owner = NULL;
857  }
858  collection_destroy(&rrset->rrsigs);
859  free(rrset->rrs);
860  free(rrset);
861 }
862 
867 void
868 rrset_backup2(FILE* fd, rrset_type* rrset)
869 {
870  rrsig_type* rrsig;
871  char* str = NULL;
872  if (!rrset || !fd) {
873  return;
874  }
875  while((rrsig = collection_iterator(rrset->rrsigs))) {
876  if ((str = ldns_rr2str(rrsig->rr))) {
877  fprintf(fd, "%.*s; {locator %s flags %u}\n", (int)strlen(str)-1, str,
878  rrsig->key_locator, rrsig->key_flags);
879  free(str);
880  }
881  }
882 }
rr_type * rrset_lookup_rr(rrset_type *rrset, ldns_rr *rr)
Definition: rrset.c:235
duration_type * sig_inception_offset
Definition: signconf.h:52
int zsk
Definition: keys.h:59
size_t rr_count
Definition: rrset.h:65
void rrset_cleanup(rrset_type *rrset)
Definition: rrset.c:845
key_type * keylist_lookup_by_locator(keylist_type *kl, const char *locator)
Definition: keys.c:73
void rrset_add_rrsig(rrset_type *rrset, ldns_rr *rr, const char *locator, uint32_t flags)
Definition: rrset.c:416
const char * rrset_type2str(ldns_rr_type type)
Definition: rrset.c:158
uint32_t key_flags
Definition: rrset.h:48
ods_status rrset_getliteralrr(ldns_rr **dnskey, const char *resourcerecord, uint32_t ttl, ldns_rdf *apex)
Definition: rrset.c:768
keylist_type * keys
Definition: signconf.h:64
duration_type * sig_validity_default
Definition: signconf.h:48
collection_t rrsigs
Definition: rrset.h:66
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:145
size_t rrset_count_rr_is_added(rrset_type *rrset)
Definition: rrset.c:264
void ixfr_add_rr(ixfr_type *ixfr, ldns_rr *rr)
Definition: ixfr.c:121
duration_type * sig_validity_denial
Definition: signconf.h:49
void ixfr_del_rr(ixfr_type *ixfr, ldns_rr *rr)
Definition: ixfr.c:151
unsigned error
Definition: adapter.h:63
collection_class rrset_store_initialize()
Definition: rrset.c:222
void rrset_drop_rrsigs(zone_type *zone, rrset_type *rrset)
Definition: rrset.c:399
rr_type * rrset_add_rr(rrset_type *rrset, ldns_rr *rr)
Definition: rrset.c:285
lock_basic_type stats_lock
Definition: stats.h:63
ldns_rr_type rrtype
Definition: rrset.h:63
rrset_type * next
Definition: rrset.h:60
adapter_type * adoutbound
Definition: zone.h:73
void log_rr(ldns_rr *rr, const char *pre, int level)
Definition: rrset.c:48
unsigned exists
Definition: rrset.h:54
duration_type * sig_refresh_interval
Definition: signconf.h:47
unsigned is_removed
Definition: rrset.h:56
duration_type * sig_validity_keyset
Definition: signconf.h:50
void log_rrset(ldns_rdf *dname, ldns_rr_type type, const char *pre, int level)
Definition: rrset.c:99
ixfr_type * ixfr
Definition: zone.h:78
const char * locator
Definition: keys.h:53
unsigned needs_signing
Definition: rrset.h:67
key_type * keys
Definition: keys.h:68
const char ** dnskey_signature
Definition: signconf.h:63
ldns_rr_type domain_is_delegpt(domain_type *domain)
Definition: domain.c:348
ldns_rr * rr
Definition: rrset.h:45
signconf_type * signconf
Definition: zone.h:75
ldns_rr_type domain_is_occluded(domain_type *domain)
Definition: domain.c:373
domain_type * owner
Definition: rrset.h:46
uint32_t sig_reuse
Definition: stats.h:58
const char * key_locator
Definition: rrset.h:47
domain_type * owner
Definition: rrset.h:53
void rrset_backup2(FILE *fd, rrset_type *rrset)
Definition: rrset.c:868
void rrset_del_rr(rrset_type *rrset, uint16_t rrnum)
Definition: rrset.c:320
domain_type * domain
Definition: rrset.h:62
ldns_rr * rr
Definition: rrset.h:52
lock_basic_type ixfr_lock
Definition: ixfr.h:64
collection_class rrstore
Definition: zone.h:89
size_t count
Definition: keys.h:69
duration_type * dnskey_ttl
Definition: signconf.h:62
const char * name
Definition: zone.h:67
uint32_t sig_soa_count
Definition: stats.h:57
int ksk
Definition: keys.h:58
uint8_t algorithm
Definition: keys.h:55
duration_type * sig_jitter
Definition: signconf.h:51
ods_status rrset_sign(hsm_ctx_t *ctx, rrset_type *rrset, time_t signtime)
Definition: rrset.c:629
uint32_t sig_count
Definition: stats.h:56
void rrset_diff(rrset_type *rrset, unsigned is_ixfr, unsigned more_coming)
Definition: rrset.c:352
rrset_type * rrset_create(zone_type *zone, ldns_rr_type type)
Definition: rrset.c:198
uint32_t flags
Definition: keys.h:56
unsigned is_added
Definition: rrset.h:55
ldns_rdf * apex
Definition: zone.h:59
void rrset_print(FILE *fd, rrset_type *rrset, int skip_rrsigs, ods_status *status)
Definition: rrset.c:788
stats_type * stats
Definition: zone.h:85
rr_type * rrs
Definition: rrset.h:64
zone_type * zone
Definition: rrset.h:61