OpenDNSSEC-signer  2.1.7
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  ldns_rr_free(sig->rr);
188  sig->owner = NULL;
189  sig->rr = NULL;
190  return 0;
191 }
192 
193 
198 rrset_type*
199 rrset_create(zone_type* zone, ldns_rr_type type)
200 {
201  rrset_type* rrset = NULL;
202  if (!type || !zone) {
203  return NULL;
204  }
205  CHECKALLOC(rrset = (rrset_type*) malloc(sizeof(rrset_type)));
206  if (!rrset) {
207  ods_log_error("[%s] unable to create RRset %u: allocator_alloc() "
208  "failed", rrset_str, (unsigned) type);
209  return NULL;
210  }
211  rrset->next = NULL;
212  rrset->rrs = NULL;
213  rrset->domain = NULL;
214  rrset->zone = zone;
215  rrset->rrtype = type;
216  rrset->rr_count = 0;
217  collection_create_array(&rrset->rrsigs, sizeof(rrsig_type), rrset->zone->rrstore);
218  rrset->needs_signing = 0;
219  return rrset;
220 }
221 
222 collection_class
224 {
225  collection_class klass;
226  collection_class_allocated(&klass, NULL, memberdestroy);
227  return klass;
228 }
229 
230 
235 rr_type*
236 rrset_lookup_rr(rrset_type* rrset, ldns_rr* rr)
237 {
238  ldns_status lstatus = LDNS_STATUS_OK;
239  int cmp = 0;
240  size_t i = 0;
241 
242  if (!rrset || !rr || rrset->rr_count <= 0) {
243  return NULL;
244  }
245  for (i=0; i < rrset->rr_count; i++) {
246  lstatus = util_dnssec_rrs_compare(rrset->rrs[i].rr, rr, &cmp);
247  if (lstatus != LDNS_STATUS_OK) {
248  ods_log_error("[%s] unable to lookup RR: compare failed (%s)",
249  rrset_str, ldns_get_errorstr_by_id(lstatus));
250  return NULL;
251  }
252  if (!cmp) { /* equal */
253  return &rrset->rrs[i];
254  }
255  }
256  return NULL;
257 }
258 
262 uint32_t
263 rrset_lookup_ttl(rrset_type* rrset, uint32_t default_ttl)
264 {
265  for (int i = 0; i < rrset->rr_count; i++) {
266  if (!rrset->rrs[i].is_added) continue;
267  return ldns_rr_ttl(rrset->rrs[i].rr);
268  }
269  return default_ttl;
270 }
271 
272 
277 size_t
279 {
280  size_t i = 0;
281  size_t count = 0;
282  if (!rrset) {
283  return 0;
284  }
285  for (i=0; i < rrset->rr_count; i++) {
286  if (rrset->rrs[i].is_added) {
287  count++;
288  }
289  }
290  return count;
291 }
292 
293 
298 rr_type*
299 rrset_add_rr(rrset_type* rrset, ldns_rr* rr)
300 {
301  rr_type* rrs_old = NULL;
302 
303  ods_log_assert(rrset);
304  ods_log_assert(rr);
305  ods_log_assert(rrset->rrtype == ldns_rr_get_type(rr));
306 
307  rrs_old = rrset->rrs;
308  CHECKALLOC(rrset->rrs = (rr_type*) malloc((rrset->rr_count + 1) * sizeof(rr_type)));
309  if (!rrset->rrs) {
310  ods_fatal_exit("[%s] fatal unable to add RR: allocator_alloc() failed",
311  rrset_str);
312  }
313  if (rrs_old) {
314  memcpy(rrset->rrs, rrs_old, (rrset->rr_count) * sizeof(rr_type));
315  }
316  free(rrs_old);
317  rrset->rr_count++;
318  rrset->rrs[rrset->rr_count - 1].owner = rrset->domain;
319  rrset->rrs[rrset->rr_count - 1].rr = rr;
320  rrset->rrs[rrset->rr_count - 1].exists = 0;
321  rrset->rrs[rrset->rr_count - 1].is_added = 1;
322  rrset->rrs[rrset->rr_count - 1].is_removed = 0;
323  rrset->needs_signing = 1;
324  log_rr(rr, "+RR", LOG_DEEEBUG);
325  return &rrset->rrs[rrset->rr_count -1];
326 }
327 
328 
333 void
334 rrset_del_rr(rrset_type* rrset, uint16_t rrnum)
335 {
336  rr_type* rrs_orig = NULL;
337 
338  ods_log_assert(rrset);
339  ods_log_assert(rrnum < rrset->rr_count);
340 
341  log_rr(rrset->rrs[rrnum].rr, "-RR", LOG_DEEEBUG);
342  rrset->rrs[rrnum].owner = NULL; /* who owns owner? */
343  ldns_rr_free(rrset->rrs[rrnum].rr);
344  while (rrnum < rrset->rr_count-1) {
345  rrset->rrs[rrnum] = rrset->rrs[rrnum+1];
346  rrnum++;
347  }
348  memset(&rrset->rrs[rrset->rr_count-1], 0, sizeof(rr_type));
349  rrs_orig = rrset->rrs;
350  CHECKALLOC(rrset->rrs = (rr_type*) malloc((rrset->rr_count - 1) * sizeof(rr_type)));
351  if(!rrset->rrs) {
352  ods_fatal_exit("[%s] fatal unable to delete RR: allocator_alloc() failed",
353  rrset_str);
354  }
355  memcpy(rrset->rrs, rrs_orig, (rrset->rr_count -1) * sizeof(rr_type));
356  free(rrs_orig);
357  rrset->rr_count--;
358  rrset->needs_signing = 1;
359 }
360 
365 void
366 rrset_diff(rrset_type* rrset, unsigned is_ixfr, unsigned more_coming)
367 {
368  zone_type* zone = NULL;
369  uint16_t i = 0;
370  uint8_t del_sigs = 0;
371  if (!rrset) {
372  return;
373  }
374  zone = (zone_type*) rrset->zone;
375  /* CAUTION: both iterator and condition (implicit) are changed
376  * within the loop. */
377  for (i=0; i < rrset->rr_count; i++) {
378  if (rrset->rrs[i].is_added) {
379  if (!rrset->rrs[i].exists) {
380  /* ixfr +RR */
381  if (zone->db->is_initialized) {
382  pthread_mutex_lock(&zone->ixfr->ixfr_lock);
383  ixfr_add_rr(zone->ixfr, rrset->rrs[i].rr);
384  pthread_mutex_unlock(&zone->ixfr->ixfr_lock);
385  }
386  del_sigs = 1;
387  }
388  rrset->rrs[i].exists = 1;
389  if ((rrset->rrtype == LDNS_RR_TYPE_DNSKEY) && more_coming) {
390  continue;
391  }
392  rrset->rrs[i].is_added = 0;
393  } else if (!is_ixfr || rrset->rrs[i].is_removed) {
394  if (rrset->rrs[i].exists && zone->db->is_initialized) {
395  /* ixfr -RR */
396  pthread_mutex_lock(&zone->ixfr->ixfr_lock);
397  ixfr_del_rr(zone->ixfr, rrset->rrs[i].rr);
398  pthread_mutex_unlock(&zone->ixfr->ixfr_lock);
399  }
400  rrset->rrs[i].exists = 0;
401  rrset_del_rr(rrset, i);
402  del_sigs = 1;
403  i--;
404  }
405  }
406  if (del_sigs) {
407  rrset_drop_rrsigs(zone, rrset);
408  }
409 }
410 
415 void
417 {
418  rrsig_type* rrsig;
419  while((rrsig = collection_iterator(rrset->rrsigs))) {
420  /* ixfr -RRSIG */
421  if (zone->db->is_initialized) {
422  pthread_mutex_lock(&zone->ixfr->ixfr_lock);
423  ixfr_del_rr(zone->ixfr, rrsig->rr);
424  pthread_mutex_unlock(&zone->ixfr->ixfr_lock);
425  }
426  collection_del_cursor(rrset->rrsigs);
427  }
428 }
429 
434 void
435 rrset_add_rrsig(rrset_type* rrset, ldns_rr* rr,
436  const char* locator, uint32_t flags)
437 {
438  rrsig_type rrsig;
439  ods_log_assert(rrset);
440  ods_log_assert(rr);
441  ods_log_assert(ldns_rr_get_type(rr) == LDNS_RR_TYPE_RRSIG);
442  rrsig.owner = rrset->domain;
443  rrsig.rr = rr;
444  rrsig.key_locator = locator;
445  rrsig.key_flags = flags;
446  collection_add(rrset->rrsigs, &rrsig);
447 }
448 
453 static ldns_rr_list*
454 rrset2rrlist(rrset_type* rrset)
455 {
456  ldns_rr_list* rr_list = NULL;
457  int ret = 0;
458  size_t i = 0;
459  rr_list = ldns_rr_list_new();
460  for (i=0; i < rrset->rr_count; i++) {
461  if (!rrset->rrs[i].exists) {
462  log_rr(rrset->rrs[i].rr, "RR does not exist", LOG_WARNING);
463  continue;
464  }
465  ret = (int) ldns_rr_list_push_rr(rr_list, rrset->rrs[i].rr);
466  if (!ret) {
467  ldns_rr_list_free(rr_list);
468  return NULL;
469  }
470  if (rrset->rrtype == LDNS_RR_TYPE_CNAME ||
471  rrset->rrtype == LDNS_RR_TYPE_DNAME) {
472  /* singleton types */
473  return rr_list;
474  }
475  }
476  ldns_rr_list_sort(rr_list);
477  return rr_list;
478 }
479 
480 
485 static void
486 rrset_sigvalid_period(signconf_type* sc, ldns_rr_type rrtype, time_t signtime,
487  time_t* inception, time_t* expiration)
488 {
489  time_t jitter = 0;
490  time_t offset = 0;
491  time_t validity = 0;
492  time_t random_jitter = 0;
493  if (!sc || !rrtype || !signtime) {
494  return;
495  }
496  jitter = duration2time(sc->sig_jitter);
497  if (jitter) {
498  random_jitter = ods_rand(jitter*2);
499  }
500  offset = duration2time(sc->sig_inception_offset);
501  switch (rrtype) {
502  case LDNS_RR_TYPE_NSEC:
503  case LDNS_RR_TYPE_NSEC3:
504  validity = duration2time(sc->sig_validity_denial);
505  break;
506  case LDNS_RR_TYPE_DNSKEY:
507  if (sc->sig_validity_keyset != NULL && duration2time(sc->sig_validity_keyset) > 0) {
508  validity = duration2time(sc->sig_validity_keyset);
509  } else {
510  validity = duration2time(sc->sig_validity_default);
511  }
512  break;
513  default:
514  validity = duration2time(sc->sig_validity_default);
515  }
516  *inception = signtime - offset;
517  *expiration = (signtime + validity + random_jitter) - jitter;
518 }
519 
520 
524 };
525 
526 static int
527 rrsigkeyismatching(rrsig_type* rrsig, key_type* key)
528 {
529  if(rrsig->key_flags == key->flags && !strcmp(rrsig->key_locator,key->locator)) {
530  return 1;
531  } else {
532  return 0;
533  }
534 }
535 
536 static void
537 rrsigkeymatching(signconf_type* signconf, int nrrsigs, rrsig_type** rrsigs, struct rrsigkeymatching** rrsigkeymatchingptr, int* nrrsigkeymatchingptr)
538 {
539  int nmatches = 0;
540  struct rrsigkeymatching* matches = malloc(sizeof(struct rrsigkeymatching) * (signconf->keys->count + nrrsigs));
541  for(int i=0; i<nrrsigs; i++) {
542  matches[nmatches].signature = rrsigs[i];
543  matches[nmatches].key = NULL;
544  ++nmatches;
545  }
546  for(int keyidx=0; keyidx<signconf->keys->count; keyidx++) {
547  int matchidx;
548  for(matchidx=0; matchidx<nmatches; matchidx++) {
549  if(matches[matchidx].signature && rrsigkeyismatching(matches[matchidx].signature, &signconf->keys->keys[keyidx])) {
550  matches[matchidx].key = &signconf->keys->keys[keyidx];
551  break;
552  }
553  }
554  if(matchidx==nmatches) {
555  matches[nmatches].signature = NULL;
556  matches[nmatches].key = &signconf->keys->keys[keyidx];
557  ++nmatches;
558  }
559  }
560  *rrsigkeymatchingptr = matches;
561  *nrrsigkeymatchingptr = nmatches;
562 }
563 
564 
569 ods_status
570 rrset_sign(hsm_ctx_t* ctx, rrset_type* rrset, time_t signtime)
571 {
572  ods_status status;
573  zone_type* zone = NULL;
574  uint32_t newsigs = 0;
575  uint32_t reusedsigs = 0;
576  ldns_rr* rrsig = NULL;
578  ldns_rr_list* rr_list = NULL;
579  ldns_rr_list* rr_list_clone = NULL;
580  const char* locator = NULL;
581  time_t inception = 0;
582  time_t expiration = 0;
583  size_t i = 0, j;
584  domain_type* domain = NULL;
585  ldns_rr_type dstatus = LDNS_RR_TYPE_FIRST;
586  ldns_rr_type delegpt = LDNS_RR_TYPE_FIRST;
587  uint8_t algorithm = 0;
588 
589  ods_log_assert(ctx);
590  ods_log_assert(rrset);
591  zone = (zone_type*) rrset->zone;
592  ods_log_assert(zone);
593  ods_log_assert(zone->signconf);
594  /* Recycle signatures */
595  if (rrset->rrtype == LDNS_RR_TYPE_NSEC ||
596  rrset->rrtype == LDNS_RR_TYPE_NSEC3) {
597  dstatus = LDNS_RR_TYPE_SOA;
598  delegpt = LDNS_RR_TYPE_SOA;
599  } else {
600  domain = (domain_type*) rrset->domain;
601  dstatus = domain_is_occluded(domain);
602  delegpt = domain_is_delegpt(domain);
603  }
604 
605  int nrrsigs;
606  for(nrrsigs=0; (signature = collection_iterator(rrset->rrsigs)); nrrsigs++)
607  ;
608  rrsig_type** rrsigs = malloc(sizeof(rrsig_type*) * nrrsigs);
609  for(i=0; (signature = collection_iterator(rrset->rrsigs)); i++) {
610  assert(signature);
611  rrsigs[i] = signature;
612  }
613  struct rrsigkeymatching* matchedsignatures = NULL;
614  int nmatchedsignatures;
615  rrsigkeymatching(zone->signconf, nrrsigs, rrsigs, &matchedsignatures, &nmatchedsignatures);
616 
617  rrset->needs_signing = 0;
618 
619  ods_log_assert(rrset->rrs);
620  ods_log_assert(rrset->rrs[0].rr);
621 
622  /* Skip delegation, glue and occluded RRsets */
623  if (dstatus != LDNS_RR_TYPE_SOA) {
624  log_rrset(ldns_rr_owner(rrset->rrs[0].rr), rrset->rrtype,
625  "skip signing occluded RRset", LOG_DEEEBUG);
626  free(rrsigs);
627  free(matchedsignatures);
628  return ODS_STATUS_OK;
629  }
630  if (delegpt != LDNS_RR_TYPE_SOA && rrset->rrtype != LDNS_RR_TYPE_DS) {
631  log_rrset(ldns_rr_owner(rrset->rrs[0].rr), rrset->rrtype,
632  "skip signing delegation RRset", LOG_DEEEBUG);
633  free(rrsigs);
634  free(matchedsignatures);
635  return ODS_STATUS_OK;
636  }
637 
638  log_rrset(ldns_rr_owner(rrset->rrs[0].rr), rrset->rrtype,
639  "sign RRset", LOG_DEEEBUG);
640  ods_log_assert(dstatus == LDNS_RR_TYPE_SOA ||
641  (delegpt == LDNS_RR_TYPE_SOA || rrset->rrtype == LDNS_RR_TYPE_DS));
642  /* Transmogrify rrset */
643  rr_list = rrset2rrlist(rrset);
644  if (ldns_rr_list_rr_count(rr_list) <= 0) {
645  /* Empty RRset, no signatures needed */
646  ldns_rr_list_free(rr_list);
647  free(rrsigs);
648  free(matchedsignatures);
649  return ODS_STATUS_OK;
650  }
651  /* Use rr_list_clone for signing, keep the original rr_list untouched for case preservation */
652  rr_list_clone = ldns_rr_list_clone(rr_list);
653 
654  /* Further in the code the ORIG_TTL field for the signature will be set
655  * to the TTL of the first RR in the list. We must make sure all RR's
656  * have the same TTL when signing. We do not need to publish these TTLs.
657  * We find the smallest TTL as other software seems to do this.
658  **/
659  uint32_t min_ttl = ldns_rr_ttl(ldns_rr_list_rr(rr_list_clone, 0));
660  for (i = 1; i < ldns_rr_list_rr_count(rr_list_clone); i++) {
661  uint32_t rr_ttl = ldns_rr_ttl(ldns_rr_list_rr(rr_list_clone, i));
662  if (rr_ttl < min_ttl) min_ttl = rr_ttl;
663  }
664  for (i = 0; i < ldns_rr_list_rr_count(rr_list_clone); i++) {
665  ldns_rr_set_ttl(ldns_rr_list_rr(rr_list_clone, i), min_ttl);
666  }
667 
668  assert(zone->signconf);
669  /* Calculate signature validity */
670  rrset_sigvalid_period(zone->signconf, rrset->rrtype, signtime,
671  &inception, &expiration);
672  uint32_t refresh = 0;
673  if (zone->signconf && zone->signconf->sig_refresh_interval) {
674  refresh = (uint32_t) (signtime + duration2time(zone->signconf->sig_refresh_interval));
675  }
676 
677  /* for each signature-key pair, determine whether the signature is valid and/or the key
678  * should produce a signature.
679  */
680  for (int i = 0; i < nmatchedsignatures; i++) {
681  if (matchedsignatures[i].signature) {
682  assert(matchedsignatures[i].signature->rr);
683  expiration = ldns_rdf2native_int32(ldns_rr_rrsig_expiration(matchedsignatures[i].signature->rr));
684  inception = ldns_rdf2native_int32(ldns_rr_rrsig_inception(matchedsignatures[i].signature->rr));
685  }
686  if (matchedsignatures[i].key && matchedsignatures[i].key->ksk && !matchedsignatures[i].key->zsk && rrset->rrtype != LDNS_RR_TYPE_DNSKEY) {
687  /* If KSK (not CSK) don't sign non-DNSKEY RRsets */
688  matchedsignatures[i].key = NULL;
689  matchedsignatures[i].signature = NULL;
690  } else if (matchedsignatures[i].key && !matchedsignatures[i].key->ksk && !matchedsignatures[i].key->zsk && rrset->rrtype != LDNS_RR_TYPE_DNSKEY && !matchedsignatures[i].signature) {
691  /* Drop keys that aren't ZSK or KSK and still have signatures */
692  matchedsignatures[i].key = NULL;
693  } else if (matchedsignatures[i].key && !matchedsignatures[i].key->ksk && !matchedsignatures[i].key->zsk && rrset->rrtype != LDNS_RR_TYPE_DNSKEY && !matchedsignatures[i].key->publish) {
694  matchedsignatures[i].key = NULL;
695  matchedsignatures[i].signature = NULL;
696  } else if (matchedsignatures[i].key && !matchedsignatures[i].key->ksk && !matchedsignatures[i].key->zsk && rrset->rrtype == LDNS_RR_TYPE_DNSKEY) {
697  matchedsignatures[i].key = NULL;
698  matchedsignatures[i].signature = NULL;
699  } else if (matchedsignatures[i].key && !matchedsignatures[i].key->ksk && matchedsignatures[i].key->zsk && rrset->rrtype == LDNS_RR_TYPE_DNSKEY) {
700  /* If ZSK (not CSK) don't sign DNSKEY RRset */
701  matchedsignatures[i].key = NULL;
702  matchedsignatures[i].signature = NULL;
703  } else if (matchedsignatures[i].key && matchedsignatures[i].key->ksk && matchedsignatures[i].key->locator == NULL) {
704  /* If key has no locator, and should be pre-signed dnskey RR, skip */
705  matchedsignatures[i].key = NULL;
706  } else if (refresh <= (uint32_t) signtime) {
707  /* If Refresh is disabled, drop all signatures */
708  matchedsignatures[i].signature = NULL;
709  } else if (matchedsignatures[i].signature && expiration < refresh && !matchedsignatures[i].key->ksk && !matchedsignatures[i].key->zsk) {
710  /* Signature has expired but key not used for signing anymore */
711  matchedsignatures[i].signature = NULL;
712  matchedsignatures[i].key = NULL;
713  } else if (matchedsignatures[i].signature && expiration < refresh) {
714  /* Expiration - Refresh has passed */
715  matchedsignatures[i].signature = NULL;
716  } else if (matchedsignatures[i].signature && inception > (uint32_t) signtime) {
717  /* Inception has not yet passed */
718  matchedsignatures[i].signature = NULL;
719  } else if (matchedsignatures[i].signature && !matchedsignatures[i].key) {
720  /* Orphaned signatures */
721  matchedsignatures[i].signature = NULL;
722  } else if (dstatus != LDNS_RR_TYPE_SOA || (delegpt != LDNS_RR_TYPE_SOA && rrset->rrtype != LDNS_RR_TYPE_DS)) {
723  /* Skip delegation, glue and occluded RRsets */
724  matchedsignatures[i].key = NULL;
725  matchedsignatures[i].signature = NULL;
726  } else {
727  ods_log_assert(dstatus == LDNS_RR_TYPE_SOA || (delegpt == LDNS_RR_TYPE_SOA || rrset->rrtype == LDNS_RR_TYPE_DS));
728  }
729  }
730  /* At this time, each signature, key pair is valid, if there is a signature and a key, it is valid, if there is
731  * no key, there should be no signature, if there is no key, there should be no signature. However for DNS
732  * optimization, there needs to be no signature, if there is a signature for another key with the same algorithm
733  * that is still valid.
734  */
735  for (int i = 0; i < nmatchedsignatures; i++) {
736  if (!matchedsignatures[i].signature && matchedsignatures[i].key) {
737  /* We now know this key doesn't sign the set, we will only
738  * sign when there isn't already an active key for that algorithm
739  */
740  int j;
741  for (j = 0; j < nmatchedsignatures; j++) {
742  if (j != i) {
743  if (matchedsignatures[j].key && matchedsignatures[j].key->publish && matchedsignatures[j].signature && matchedsignatures[j].key->algorithm == matchedsignatures[i].key->algorithm) {
744  break;
745  }
746  }
747  }
748  if (j < nmatchedsignatures) {
749  matchedsignatures[i].key = NULL;
750  matchedsignatures[i].signature = NULL;
751  }
752  }
753  }
754 
755  /* For each of the existing signatures, if they are no longer present in the output, delete them
756  * The rrsigs array is guaranteed to line up with the mathcedsignatures array
757  */
758  if (zone->db->is_initialized) {
759  pthread_mutex_lock(&zone->ixfr->ixfr_lock);
760  for(i=0; i<nrrsigs; i++) {
761  if(matchedsignatures[i].signature == NULL) {
762  if (rrsigs[i] != NULL) {
763  ixfr_del_rr(zone->ixfr, rrsigs[i]->rr);
764  }
765  }
766  }
767  pthread_mutex_unlock(&zone->ixfr->ixfr_lock);
768  }
769  for(i=0; i<nrrsigs; i++) {
770  if(matchedsignatures[i].signature == NULL) {
771  if (rrsigs[i] != NULL) {
772  while((signature = collection_iterator(rrset->rrsigs))) {
773  if(signature == rrsigs[i]) {
774  collection_del_cursor(rrset->rrsigs);
775  }
776  }
777  }
778  } else
779  ++reusedsigs;
780  }
781  /* only at this time we have no need for the list anymore (just the list) */
782  free(rrsigs);
783 
784  /* Calculate signature validity for new signatures */
785  rrset_sigvalid_period(zone->signconf, rrset->rrtype, signtime, &inception, &expiration);
786  /* for each missing signature (no signature, but with key in the tuplie list) produce a signature */
787  for (int i = 0; i < nmatchedsignatures; i++) {
788  if (!matchedsignatures[i].signature && matchedsignatures[i].key) {
789  /* Sign the RRset with this key */
790  ods_log_deeebug("[%s] signing RRset[%i] with key %s", rrset_str,
791  rrset->rrtype, zone->signconf->keys->keys[i].locator);
792  rrsig = lhsm_sign(ctx, rr_list_clone, matchedsignatures[i].key,
793  zone->apex, inception, expiration);
794  if (!rrsig) {
795  ods_log_crit("[%s] unable to sign RRset[%i]: lhsm_sign() failed",
796  rrset_str, rrset->rrtype);
797  free(matchedsignatures);
798  ldns_rr_list_free(rr_list);
799  ldns_rr_list_free(rr_list_clone);
800  return ODS_STATUS_HSM_ERR;
801  }
802  /* Add signature */
803  locator = strdup(matchedsignatures[i].key->locator);
804  rrset_add_rrsig(rrset, rrsig, locator, matchedsignatures[i].key->flags);
805  newsigs++;
806  /* ixfr +RRSIG */
807  if (zone->db->is_initialized) {
808  pthread_mutex_lock(&zone->ixfr->ixfr_lock);
809  ixfr_add_rr(zone->ixfr, rrsig);
810  pthread_mutex_unlock(&zone->ixfr->ixfr_lock);
811  }
812  }
813  }
814  /* Add signatures for DNSKEY if have been configured to be added explicitjy */
815  if(rrset->rrtype == LDNS_RR_TYPE_DNSKEY && zone->signconf->dnskey_signature) {
816  for(i=0; zone->signconf->dnskey_signature[i]; i++) {
817  rrsig = NULL;
818  if ((status = rrset_getliteralrr(&rrsig, zone->signconf->dnskey_signature[i], duration2time(zone->signconf->dnskey_ttl), zone->apex)) != ODS_STATUS_OK) {
819  ods_log_error("[%s] unable to publish dnskeys for zone %s: "
820  "error decoding literal dnskey", rrset_str, zone->name);
821  ldns_rr_list_deep_free(rr_list_clone);
822  return status;
823  }
824  /* Add signature */
825  rrset_add_rrsig(rrset, rrsig, NULL, 0);
826  newsigs++;
827  /* ixfr +RRSIG */
828  if (zone->db->is_initialized) {
829  pthread_mutex_lock(&zone->ixfr->ixfr_lock);
830  ixfr_add_rr(zone->ixfr, rrsig);
831  pthread_mutex_unlock(&zone->ixfr->ixfr_lock);
832  }
833  }
834  }
835 
836  /* RRset signing completed */
837  free(matchedsignatures);
838  ldns_rr_list_free(rr_list);
839  ldns_rr_list_deep_free(rr_list_clone);
840  pthread_mutex_lock(&zone->stats->stats_lock);
841  if (rrset->rrtype == LDNS_RR_TYPE_SOA) {
842  zone->stats->sig_soa_count += newsigs;
843  }
844  zone->stats->sig_count += newsigs;
845  zone->stats->sig_reuse += reusedsigs;
846  pthread_mutex_unlock(&zone->stats->stats_lock);
847  return ODS_STATUS_OK;
848 }
849 
850 ods_status
851 rrset_getliteralrr(ldns_rr** dnskey, const char *resourcerecord, uint32_t ttl, ldns_rdf* apex)
852 {
853  uint8_t dnskeystring[4096];
854  ldns_status ldnsstatus;
855  int len;
856  if ((len = b64_pton(resourcerecord, dnskeystring, sizeof (dnskeystring) - 2)) < 0) {
857  return ODS_STATUS_PARSE_ERR;
858  }
859  dnskeystring[len] = '\0';
860  if ((ldnsstatus = ldns_rr_new_frm_str(dnskey, (const char*) dnskeystring, ttl, apex, NULL)) != LDNS_STATUS_OK) {
861  return ODS_STATUS_PARSE_ERR;
862  }
863  return ODS_STATUS_OK;
864 }
865 
870 void
871 rrset_print(FILE* fd, rrset_type* rrset, int skip_rrsigs,
872  ods_status* status)
873 {
874  rrsig_type* rrsig;
875  uint16_t i = 0;
876  ods_status result = ODS_STATUS_OK;
877 
878  if (!rrset || !fd) {
879  ods_log_crit("[%s] unable to print RRset: rrset or fd missing",
880  rrset_str);
881  if (status) {
882  *status = ODS_STATUS_ASSERT_ERR;
883  }
884  } else {
885  for (i=0; i < rrset->rr_count; i++) {
886  if (rrset->rrs[i].exists) {
887  result = util_rr_print(fd, rrset->rrs[i].rr);
888  if (rrset->rrtype == LDNS_RR_TYPE_CNAME ||
889  rrset->rrtype == LDNS_RR_TYPE_DNAME) {
890  /* singleton types */
891  break;
892  }
893  if (result != ODS_STATUS_OK) {
894  zone_type* zone = (zone_type*) rrset->zone;
895  log_rrset(ldns_rr_owner(rrset->rrs[i].rr), rrset->rrtype,
896  "error printing RRset", LOG_CRIT);
897  zone->adoutbound->error = 1;
898  break;
899  }
900  }
901  }
902  if (! skip_rrsigs) {
903  result = ODS_STATUS_OK;
904  while((rrsig = collection_iterator(rrset->rrsigs))) {
905  if (result == ODS_STATUS_OK) {
906  result = util_rr_print(fd, rrsig->rr);
907  if (result != ODS_STATUS_OK) {
908  zone_type* zone = rrset->zone;
909  log_rrset(ldns_rr_owner(rrset->rrs[i].rr), rrset->rrtype,
910  "error printing RRset", LOG_CRIT);
911  zone->adoutbound->error = 1;
912  }
913  }
914  }
915  }
916  if (status) {
917  *status = result;
918  }
919  }
920 }
921 
922 
927 void
929 {
930  uint16_t i = 0;
931  if (!rrset) {
932  return;
933  }
934  rrset_cleanup(rrset->next);
935  rrset->next = NULL;
936  rrset->domain = NULL;
937  for (i=0; i < rrset->rr_count; i++) {
938  ldns_rr_free(rrset->rrs[i].rr);
939  rrset->rrs[i].owner = NULL;
940  }
941  collection_destroy(&rrset->rrsigs);
942  free(rrset->rrs);
943  free(rrset);
944 }
945 
950 void
951 rrset_backup2(FILE* fd, rrset_type* rrset)
952 {
953  rrsig_type* rrsig;
954  char* str = NULL;
955  if (!rrset || !fd) {
956  return;
957  }
958  while((rrsig = collection_iterator(rrset->rrsigs))) {
959  if ((str = ldns_rr2str(rrsig->rr))) {
960  fprintf(fd, "%.*s; {locator %s flags %u}\n", (int)strlen(str)-1, str,
961  rrsig->key_locator, rrsig->key_flags);
962  free(str);
963  }
964  }
965 }
key_struct::flags
uint32_t flags
Definition: keys.h:56
rrset_create
rrset_type * rrset_create(zone_type *zone, ldns_rr_type type)
Definition: rrset.c:199
signconf_struct::sig_inception_offset
duration_type * sig_inception_offset
Definition: signconf.h:52
rrset_getliteralrr
ods_status rrset_getliteralrr(ldns_rr **dnskey, const char *resourcerecord, uint32_t ttl, ldns_rdf *apex)
Definition: rrset.c:851
signconf_struct::keys
keylist_type * keys
Definition: signconf.h:64
signconf_struct::sig_validity_default
duration_type * sig_validity_default
Definition: signconf.h:48
log_rrset
void log_rrset(ldns_rdf *dname, ldns_rr_type type, const char *pre, int level)
Definition: rrset.c:99
rrsigkeymatching::key
key_type * key
Definition: rrset.c:523
rrsigkeymatching::signature
rrsig_type * signature
Definition: rrset.c:522
rrset_struct::zone
zone_type * zone
Definition: rrset.h:61
domain_is_delegpt
ldns_rr_type domain_is_delegpt(domain_type *domain)
Definition: domain.c:344
zone_struct
Definition: zone.h:60
rrset_sign
ods_status rrset_sign(hsm_ctx_t *ctx, rrset_type *rrset, time_t signtime)
Definition: rrset.c:570
rrset_add_rr
rr_type * rrset_add_rr(rrset_type *rrset, ldns_rr *rr)
Definition: rrset.c:299
rrset_struct::rrtype
ldns_rr_type rrtype
Definition: rrset.h:63
rrset_struct
Definition: rrset.h:59
key_struct::algorithm
uint8_t algorithm
Definition: keys.h:55
signconf_struct::sig_validity_denial
duration_type * sig_validity_denial
Definition: signconf.h:49
zone.h
rrset_struct::rrs
rr_type * rrs
Definition: rrset.h:64
zone_struct::apex
ldns_rdf * apex
Definition: zone.h:61
zone_struct::name
const char * name
Definition: zone.h:69
rrsig_struct
Definition: rrset.h:44
rr_struct::is_removed
unsigned is_removed
Definition: rrset.h:56
zone_struct::rrstore
collection_class rrstore
Definition: zone.h:89
rrset_print
void rrset_print(FILE *fd, rrset_type *rrset, int skip_rrsigs, ods_status *status)
Definition: rrset.c:871
rrset_struct::needs_signing
unsigned needs_signing
Definition: rrset.h:67
keylist_struct::count
size_t count
Definition: keys.h:69
rrset_lookup_rr
rr_type * rrset_lookup_rr(rrset_type *rrset, ldns_rr *rr)
Definition: rrset.c:236
rrsig_struct::rr
ldns_rr * rr
Definition: rrset.h:45
rrset_lookup_ttl
uint32_t rrset_lookup_ttl(rrset_type *rrset, uint32_t default_ttl)
Definition: rrset.c:263
signconf_struct::sig_validity_keyset
duration_type * sig_validity_keyset
Definition: signconf.h:50
rrsig_struct::key_locator
const char * key_locator
Definition: rrset.h:47
key_struct::ksk
int ksk
Definition: keys.h:58
rr_struct::owner
domain_type * owner
Definition: rrset.h:53
rrset_type2str
const char * rrset_type2str(ldns_rr_type type)
Definition: rrset.c:158
rrset.h
zone_struct::signconf
signconf_type * signconf
Definition: zone.h:77
key_struct
Definition: keys.h:50
rrset_struct::next
rrset_type * next
Definition: rrset.h:60
signconf_struct::sig_refresh_interval
duration_type * sig_refresh_interval
Definition: signconf.h:47
key_struct::publish
int publish
Definition: keys.h:57
rrset_backup2
void rrset_backup2(FILE *fd, rrset_type *rrset)
Definition: rrset.c:951
stats_struct::sig_soa_count
uint32_t sig_soa_count
Definition: stats.h:57
rr_struct::rr
ldns_rr * rr
Definition: rrset.h:52
rrset_struct::domain
domain_type * domain
Definition: rrset.h:62
rrset_struct::rrsigs
collection_t rrsigs
Definition: rrset.h:66
key_struct::locator
const char * locator
Definition: keys.h:53
signconf_struct::dnskey_signature
const char ** dnskey_signature
Definition: signconf.h:63
rr_struct::exists
unsigned exists
Definition: rrset.h:54
domain_struct
Definition: domain.h:52
namedb_struct::is_initialized
unsigned is_initialized
Definition: namedb.h:57
zone_struct::db
namedb_type * db
Definition: zone.h:79
zone_struct::stats
stats_type * stats
Definition: zone.h:85
rrset_cleanup
void rrset_cleanup(rrset_type *rrset)
Definition: rrset.c:928
signconf_struct
Definition: signconf.h:41
rr_struct
Definition: rrset.h:51
stats_struct::sig_reuse
uint32_t sig_reuse
Definition: stats.h:58
signconf_struct::dnskey_ttl
duration_type * dnskey_ttl
Definition: signconf.h:62
log_rr
void log_rr(ldns_rr *rr, const char *pre, int level)
Definition: rrset.c:48
rrset_drop_rrsigs
void rrset_drop_rrsigs(zone_type *zone, rrset_type *rrset)
Definition: rrset.c:416
rrsigkeymatching
Definition: rrset.c:521
stats_struct::sig_count
uint32_t sig_count
Definition: stats.h:56
rrset_del_rr
void rrset_del_rr(rrset_type *rrset, uint16_t rrnum)
Definition: rrset.c:334
rrset_count_rr_is_added
size_t rrset_count_rr_is_added(rrset_type *rrset)
Definition: rrset.c:278
rr_struct::is_added
unsigned is_added
Definition: rrset.h:55
rrset_struct::rr_count
size_t rr_count
Definition: rrset.h:65
rrset_add_rrsig
void rrset_add_rrsig(rrset_type *rrset, ldns_rr *rr, const char *locator, uint32_t flags)
Definition: rrset.c:435
stats_struct::stats_lock
pthread_mutex_t stats_lock
Definition: stats.h:63
hsm.h
ixfr_del_rr
void ixfr_del_rr(ixfr_type *ixfr, ldns_rr *rr)
Definition: ixfr.c:132
signconf_struct::sig_jitter
duration_type * sig_jitter
Definition: signconf.h:51
zone_struct::ixfr
ixfr_type * ixfr
Definition: zone.h:80
zone_struct::adoutbound
adapter_type * adoutbound
Definition: zone.h:75
keylist_struct::keys
key_type * keys
Definition: keys.h:68
ixfr_add_rr
void ixfr_add_rr(ixfr_type *ixfr, ldns_rr *rr)
Definition: ixfr.c:107
rrsig_struct::owner
domain_type * owner
Definition: rrset.h:46
rrsig_struct::key_flags
uint32_t key_flags
Definition: rrset.h:48
domain_is_occluded
ldns_rr_type domain_is_occluded(domain_type *domain)
Definition: domain.c:369
adapter_struct::error
unsigned error
Definition: adapter.h:63
key_struct::zsk
int zsk
Definition: keys.h:59
rrset_store_initialize
collection_class rrset_store_initialize()
Definition: rrset.c:223
ixfr_struct::ixfr_lock
pthread_mutex_t ixfr_lock
Definition: ixfr.h:64
rrset_diff
void rrset_diff(rrset_type *rrset, unsigned is_ixfr, unsigned more_coming)
Definition: rrset.c:366
lhsm_sign
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:138