OpenDNSSEC-signer  1.3.14
denial.c
Go to the documentation of this file.
1 /*
2  * $Id$
3  *
4  * Copyright (c) 2011 NLNet Labs. All rights reserved.
5  *
6  * Redistribution and use in source and binary forms, with or without
7  * modification, are permitted provided that the following conditions
8  * are met:
9  * 1. Redistributions of source code must retain the above copyright
10  * notice, this list of conditions and the following disclaimer.
11  * 2. Redistributions in binary form must reproduce the above copyright
12  * notice, this list of conditions and the following disclaimer in the
13  * documentation and/or other materials provided with the distribution.
14  *
15  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
16  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
17  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18  * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
19  * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
20  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
21  * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
22  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
23  * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
24  * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
25  * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26  *
27  */
28 
34 #include "config.h"
35 #include "shared/allocator.h"
36 #include "shared/log.h"
37 #include "signer/denial.h"
38 #include "signer/domain.h"
39 #include "signer/nsec3params.h"
40 
41 #include <ldns/ldns.h>
42 
43 #define SE_MAX_RRTYPE_COUNT 65536
44 
45 static const char* denial_str = "denial";
46 
47 
53 denial_create(ldns_rdf* owner)
54 {
55  allocator_type* allocator = NULL;
56  denial_type* denial = NULL;
57  char* str = NULL;
58 
59  if (!owner) {
60  ods_log_error("[%s] unable to create denial of existence data point: "
61  "no owner name", denial_str);
62  return NULL;
63  }
64  ods_log_assert(owner);
65 
66  allocator = allocator_create(malloc, free);
67  if (!allocator) {
68  str = ldns_rdf2str(owner);
69  ods_log_error("[%s] unable to create denial of existence data point: "
70  "%s: create allocator failed", denial_str, str?str:"(null)");
71  free((void*)str);
72  return NULL;
73  }
74  ods_log_assert(allocator);
75 
76  denial = (denial_type*) allocator_alloc(allocator, sizeof(denial_type));
77  if (!denial) {
78  str = ldns_rdf2str(denial->owner);
79  ods_log_error("[%s] unable to create denial of existence data point: "
80  "%s: allocator failed", denial_str, str?str:"(null)");
81  free((void*)str);
82  allocator_cleanup(allocator);
83  return NULL;
84  }
85  ods_log_assert(denial);
86 
87  denial->allocator = allocator;
88  denial->owner = ldns_rdf_clone(owner);
89  denial->bitmap_changed = 0;
90  denial->nxt_changed = 0;
91  denial->rrset = NULL;
92  denial->domain = NULL;
93  return denial;
94 }
95 
96 
101 static void
102 denial_create_bitmap(denial_type* denial, ldns_rr_type types[],
103  size_t* types_count)
104 {
105  ldns_rbnode_t* node = LDNS_RBTREE_NULL;
106  domain_type* domain = NULL;
107  rrset_type* rrset = NULL;
108 
109  ods_log_assert(denial->domain);
110 
111  domain = (domain_type*) denial->domain;
112  node = ldns_rbtree_first(domain->rrsets);
113 
114  while (node && node != LDNS_RBTREE_NULL) {
115  rrset = (rrset_type*) node->data;
116  types[*types_count] = rrset->rr_type;
117  *types_count = *types_count + 1;
118  node = ldns_rbtree_next(node);
119  }
120  return;
121 }
122 
123 
128 static ldns_rr*
129 denial_create_nsec(denial_type* denial, denial_type* nxt, uint32_t ttl,
130  ldns_rr_class klass)
131 {
132  ldns_rr* nsec_rr = NULL;
133  ldns_rdf* rdf = NULL;
134  ldns_rr_type types[SE_MAX_RRTYPE_COUNT];
135  size_t types_count = 0;
136 
137  ods_log_assert(denial);
138  ods_log_assert(denial->owner);
139  ods_log_assert(nxt);
140  ods_log_assert(nxt->owner);
141 
142  nsec_rr = ldns_rr_new();
143  if (!nsec_rr) {
144  ods_log_alert("[%s] unable to create NSEC RR: ldns error",
145  denial_str);
146  return NULL;
147  }
148  ods_log_assert(nsec_rr);
149 
150  ldns_rr_set_type(nsec_rr, LDNS_RR_TYPE_NSEC);
151  rdf = ldns_rdf_clone(denial->owner);
152  if (!rdf) {
153  ods_log_alert("[%s] unable to create NSEC RR: failed to clone owner",
154  denial_str);
155  ldns_rr_free(nsec_rr);
156  return NULL;
157  }
158  ldns_rr_set_owner(nsec_rr, rdf);
159 
160  rdf = ldns_rdf_clone(nxt->owner);
161  if (!rdf) {
162  ods_log_alert("[%s] unable to create NSEC RR: failed to clone nxt",
163  denial_str);
164  ldns_rr_free(nsec_rr);
165  return NULL;
166  }
167  ldns_rr_push_rdf(nsec_rr, rdf);
168 
169  /* create types bitmap */
170  denial_create_bitmap(denial, types, &types_count);
171  types[types_count] = LDNS_RR_TYPE_RRSIG;
172  types_count++;
173  types[types_count] = LDNS_RR_TYPE_NSEC;
174  types_count++;
175 
176  rdf = ldns_dnssec_create_nsec_bitmap(types,
177  types_count, LDNS_RR_TYPE_NSEC);
178  if (!rdf) {
179  ods_log_alert("[%s] unable to create NSEC RR: failed to create bitmap",
180  denial_str);
181  ldns_rr_free(nsec_rr);
182  return NULL;
183  }
184  ldns_rr_push_rdf(nsec_rr, rdf);
185  ldns_rr_set_ttl(nsec_rr, ttl);
186  ldns_rr_set_class(nsec_rr, klass);
187  return nsec_rr;
188 }
189 
190 
196 denial_nsecify(denial_type* denial, denial_type* nxt, uint32_t ttl,
197  ldns_rr_class klass)
198 {
199  ldns_rr* nsec_rr = NULL;
200  ods_status status = ODS_STATUS_OK;
201 
202  if (!denial) {
203  ods_log_error("[%s] unable to nsecify: no data point", denial_str);
204  return ODS_STATUS_ASSERT_ERR;
205  }
206  ods_log_assert(denial);
207 
208  if (!nxt) {
209  ods_log_error("[%s] unable to nsecify: no next", denial_str);
210  return ODS_STATUS_ASSERT_ERR;
211  }
212  ods_log_assert(nxt);
213 
214  if (denial->nxt_changed || denial->bitmap_changed) {
215  /* assert there is a NSEC RRset */
216  if (!denial->rrset) {
217  denial->rrset = rrset_create(LDNS_RR_TYPE_NSEC);
218  if (!denial->rrset) {
219  ods_log_alert("[%s] unable to nsecify: failed to "
220  "create NSEC RRset", denial_str);
221  return ODS_STATUS_ERR;
222  }
223  }
224  ods_log_assert(denial->rrset);
225  /* create new NSEC rr */
226  nsec_rr = denial_create_nsec(denial, nxt, ttl, klass);
227  if (!nsec_rr) {
228  ods_log_alert("[%s] unable to nsecify: failed to "
229  "create NSEC RR", denial_str);
230  return ODS_STATUS_ERR;
231  }
232  /* delete old NSEC RR(s)... */
233  status = rrset_wipe_out(denial->rrset);
234  if (status != ODS_STATUS_OK) {
235  ods_log_alert("[%s] unable to nsecify: failed to "
236  "wipe out NSEC RRset", denial_str);
237  ldns_rr_free(nsec_rr);
238  return status;
239  }
240  /* ...and add the new one */
241  if (!rrset_add_rr(denial->rrset, nsec_rr)) {
242  ods_log_alert("[%s] unable to nsecify: failed to "
243  "add NSEC to RRset", denial_str);
244  ldns_rr_free(nsec_rr);
245  return ODS_STATUS_ERR;
246  }
247  /* commit */
248  status = rrset_commit(denial->rrset);
249  if (status != ODS_STATUS_OK) {
250  ods_log_alert("[%s] unable to nsecify: failed to "
251  "commit the NSEC RRset", denial_str);
252  return status;
253  }
254 
255  /* ok */
256  denial->bitmap_changed = 0;
257  denial->nxt_changed = 0;
258  }
259  return ODS_STATUS_OK;
260 }
261 
262 
267 static ldns_rr*
268 denial_create_nsec3(denial_type* denial, denial_type* nxt, uint32_t ttl,
269  ldns_rr_class klass, nsec3params_type* nsec3params)
270 {
271  ldns_status status = LDNS_STATUS_OK;
272  ldns_rr* nsec_rr = NULL;
273  ldns_rdf* rdf = NULL;
274  ldns_rdf* next_owner_label = NULL;
275  ldns_rdf* next_owner_rdf = NULL;
276  char* next_owner_string = NULL;
277  domain_type* domain = NULL;
278  ldns_rr_type types[SE_MAX_RRTYPE_COUNT];
279  size_t types_count = 0;
280  int i = 0;
281 
282  ods_log_assert(denial);
283  ods_log_assert(denial->owner);
284  ods_log_assert(nxt);
285  ods_log_assert(nxt->owner);
286  ods_log_assert(nsec3params);
287 
288  nsec_rr = ldns_rr_new();
289  if (!nsec_rr) {
290  ods_log_alert("[%s] unable to create NSEC3 RR: ldns error",
291  denial_str);
292  return NULL;
293  }
294  ods_log_assert(nsec_rr);
295 
296  ldns_rr_set_type(nsec_rr, LDNS_RR_TYPE_NSEC3);
297  rdf = ldns_rdf_clone(denial->owner);
298  if (!rdf) {
299  ods_log_alert("[%s] unable to create NSEC3 RR: failed to clone owner",
300  denial_str);
301  ldns_rr_free(nsec_rr);
302  return NULL;
303  }
304  ldns_rr_set_owner(nsec_rr, rdf);
305 
306  /* set all to NULL first, then call nsec3_add_param_rdfs. */
307  for (i=0; i < SE_NSEC3_RDATA_NSEC3PARAMS; i++) {
308  ldns_rr_push_rdf(nsec_rr, NULL);
309  }
310  ldns_nsec3_add_param_rdfs(nsec_rr, nsec3params->algorithm,
311  nsec3params->flags, nsec3params->iterations,
312  nsec3params->salt_len, nsec3params->salt_data);
313  /* nxt owner label */
314  next_owner_label = ldns_dname_label(nxt->owner, 0);
315  if (!next_owner_label) {
316  ods_log_alert("[%s] unable to create NSEC3 RR: failed to get nxt "
317  "owner label", denial_str);
318  ldns_rr_free(nsec_rr);
319  return NULL;
320  }
321  next_owner_string = ldns_rdf2str(next_owner_label);
322  if (!next_owner_string) {
323  ods_log_alert("[%s] unable to create NSEC3 RR: failed to get nxt "
324  "owner string", denial_str);
325  ldns_rdf_deep_free(next_owner_label);
326  ldns_rr_free(nsec_rr);
327  return NULL;
328  }
329  if (next_owner_string[strlen(next_owner_string)-1] == '.') {
330  next_owner_string[strlen(next_owner_string)-1] = '\0';
331  }
332  status = ldns_str2rdf_b32_ext(&next_owner_rdf, next_owner_string);
333  free((void*)next_owner_string);
334  ldns_rdf_deep_free(next_owner_label);
335  if (status != LDNS_STATUS_OK) {
336  ods_log_alert("[%s] unable to create NSEC3 RR: failed to create nxt "
337  "owner rdf: %s", denial_str, ldns_get_errorstr_by_id(status));
338  ldns_rr_free(nsec_rr);
339  return NULL;
340  }
341  ldns_rr_push_rdf(nsec_rr, next_owner_rdf);
342 
343  /* create types bitmap */
344  denial_create_bitmap(denial, types, &types_count);
345  /* only add RRSIG type if we have authoritative data to sign */
346  domain = (domain_type*) denial->domain;
347  if (domain_count_rrset(domain) > 0 &&
348  (domain->dstatus == DOMAIN_STATUS_APEX ||
349  domain->dstatus == DOMAIN_STATUS_AUTH ||
350  domain->dstatus == DOMAIN_STATUS_DS)) {
351  types[types_count] = LDNS_RR_TYPE_RRSIG;
352  types_count++;
353  }
354  /* and don't add NSEC3 type... */
355  rdf = ldns_dnssec_create_nsec_bitmap(types,
356  types_count, LDNS_RR_TYPE_NSEC3);
357  if (!rdf) {
358  ods_log_alert("[%s] unable to create NSEC3 RR: failed to create "
359  "bitmap", denial_str);
360  ldns_rr_free(nsec_rr);
361  return NULL;
362  }
363  ldns_rr_push_rdf(nsec_rr, rdf);
364  ldns_rr_set_ttl(nsec_rr, ttl);
365  ldns_rr_set_class(nsec_rr, klass);
366  return nsec_rr;
367 }
368 
369 
375 denial_nsecify3(denial_type* denial, denial_type* nxt, uint32_t ttl,
376  ldns_rr_class klass, nsec3params_type* nsec3params)
377 {
378  ldns_rr* nsec_rr = NULL;
379  ods_status status = ODS_STATUS_OK;
380 
381  if (!denial) {
382  ods_log_error("[%s] unable to nsecify3: no data point", denial_str);
383  return ODS_STATUS_ASSERT_ERR;
384  }
385  ods_log_assert(denial);
386 
387  if (!nxt) {
388  ods_log_error("[%s] unable to nsecify3: no next", denial_str);
389  return ODS_STATUS_ASSERT_ERR;
390  }
391  ods_log_assert(nxt);
392 
393  if (denial->nxt_changed || denial->bitmap_changed) {
394  /* assert there is a NSEC RRset */
395  if (!denial->rrset) {
396  denial->rrset = rrset_create(LDNS_RR_TYPE_NSEC3);
397  if (!denial->rrset) {
398  ods_log_alert("[%s] unable to nsecify3: failed to "
399  "create NSEC3 RRset", denial_str);
400  return ODS_STATUS_ERR;
401  }
402  }
403  ods_log_assert(denial->rrset);
404  /* create new NSEC3 rr */
405  nsec_rr = denial_create_nsec3(denial, nxt, ttl, klass, nsec3params);
406  if (!nsec_rr) {
407  ods_log_alert("[%s] unable to nsecify3: failed to "
408  "create NSEC3 RR", denial_str);
409  return ODS_STATUS_ERR;
410  }
411  ods_log_assert(nsec_rr);
412  /* delete old NSEC RR(s) */
413  status = rrset_wipe_out(denial->rrset);
414  if (status != ODS_STATUS_OK) {
415  ods_log_alert("[%s] unable to nsecify3: failed to "
416  "wipe out NSEC3 RRset", denial_str);
417  return status;
418  }
419  /* add the new one */
420  if (!rrset_add_rr(denial->rrset, nsec_rr)) {
421  ods_log_alert("[%s] unable to nsecify3: failed to "
422  "add NSEC3 to RRset", denial_str);
423  return ODS_STATUS_ERR;
424  }
425  /* commit */
426  status = rrset_commit(denial->rrset);
427  if (status != ODS_STATUS_OK) {
428  ods_log_alert("[%s] unable to nsecify3: failed to "
429  "commit the NSEC3 RRset", denial_str);
430  return status;
431  }
432  /* ok */
433  denial->bitmap_changed = 0;
434  denial->nxt_changed = 0;
435  }
436  return ODS_STATUS_OK;
437 }
438 
439 
444 void
446 {
447  allocator_type* allocator;
448 
449  if (!denial) {
450  return;
451  }
452  allocator = denial->allocator;
453 
454  if (denial->owner) {
455  ldns_rdf_deep_free(denial->owner);
456  denial->owner = NULL;
457  }
458  if (denial->rrset) {
459  rrset_cleanup(denial->rrset);
460  denial->rrset = NULL;
461  }
462 
463  allocator_deallocate(allocator, (void*) denial);
464  allocator_cleanup(allocator);
465  return;
466 
467 }