1 /*
2  * Copyright (c) 2011 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 
27 /**
28  * Denial of Existence.
29  *
30  */
31 
32 #include "config.h"
33 #include "log.h"
34 #include "signer/denial.h"
35 #include "signer/domain.h"
36 #include "signer/zone.h"
37 
38 #define SE_MAX_RRTYPE_COUNT 65536
39 
40 static const char* denial_str = "denial";
41 
42 
43 /**
44  * Create new Denial of Existence data point.
45  *
46  */
47 denial_type*
denial_create(zone_type * zone,ldns_rdf * dname)48 denial_create(zone_type* zone, ldns_rdf* dname)
49 {
50     denial_type* denial = NULL;
51     if (!dname || !zone) {
52         return NULL;
53     }
54     CHECKALLOC(denial = (denial_type*) malloc(sizeof(denial_type)));
55     if (!denial) {
56         ods_log_error("[%s] unable to create denial: allocator_alloc() "
57             "failed", denial_str);
58         return NULL;
59     }
60     denial->dname = dname;
61     denial->zone = zone;
62     denial->domain = NULL; /* no back reference yet */
63     denial->node = NULL; /* not in db yet */
64     denial->rrset = NULL;
65     denial->bitmap_changed = 0;
66     denial->nxt_changed = 0;
67     return denial;
68 }
69 
70 
71 /**
72  * Create NSEC(3) Type Bitmaps Field.
73  *
74  */
75 static void
denial_create_bitmap(denial_type * denial,ldns_rr_type types[],size_t * types_count)76 denial_create_bitmap(denial_type* denial, ldns_rr_type types[],
77     size_t* types_count)
78 {
79     domain_type* domain = NULL;
80     rrset_type* rrset = NULL;
81 
82     ods_log_assert(denial);
83     ods_log_assert(denial->domain);
84 
85     domain = denial->domain;
86     rrset = domain->rrsets;
87     while (rrset) {
88         ldns_rr_type dstatus = domain_is_occluded(domain);
89         if (dstatus == LDNS_RR_TYPE_SOA) {
90             /* Authoritative or delegation */
91             dstatus = domain_is_delegpt(domain);
92             if (dstatus == LDNS_RR_TYPE_SOA ||
93                 rrset->rrtype == LDNS_RR_TYPE_NS ||
94                 rrset->rrtype == LDNS_RR_TYPE_DS) {
95 
96                 types[*types_count] = rrset->rrtype;
97                 *types_count = *types_count + 1;
98             }
99         }
100         rrset = rrset->next;
101     }
102 }
103 
104 
105 /**
106  * Create NSEC3 Next Hashed Owner Name Field.
107  *
108  */
109 static ldns_rdf*
denial_create_nsec3_nxt(ldns_rdf * nxt)110 denial_create_nsec3_nxt(ldns_rdf* nxt)
111 {
112     ldns_status status = LDNS_STATUS_OK;
113     ldns_rdf* next_owner_label = NULL;
114     ldns_rdf* next_owner_rdf = NULL;
115     char* next_owner_string = NULL;
116 
117     ods_log_assert(nxt);
118     next_owner_label = ldns_dname_label(nxt, 0);
119     if (!next_owner_label) {
120         ods_log_alert("[%s] unable to create NSEC3 Next: "
121             "ldns_dname_label() failed", denial_str);
122         return NULL;
123     }
124     next_owner_string = ldns_rdf2str(next_owner_label);
125     if (!next_owner_string) {
126         ods_log_alert("[%s] unable to create NSEC3 Next: "
127             "ldns_rdf2str() failed", denial_str);
128         ldns_rdf_deep_free(next_owner_label);
129         return NULL;
130     }
131     if (next_owner_string[strlen(next_owner_string)-1] == '.') {
132         next_owner_string[strlen(next_owner_string)-1] = '\0';
133     }
134     status = ldns_str2rdf_b32_ext(&next_owner_rdf, next_owner_string);
135     if (status != LDNS_STATUS_OK) {
136         ods_log_alert("[%s] unable to create NSEC3 Next: "
137             "ldns_str2rdf_b32_ext() failed", denial_str);
138     }
139     free((void*)next_owner_string);
140     ldns_rdf_deep_free(next_owner_label);
141     return next_owner_rdf;
142 }
143 
144 
145 /**
146  * Create NSEC(3) RR.
147  *
148  */
149 static ldns_rr*
denial_create_nsec(denial_type * denial,denial_type * nxt,uint32_t ttl,ldns_rr_class klass,nsec3params_type * n3p)150 denial_create_nsec(denial_type* denial, denial_type* nxt, uint32_t ttl,
151     ldns_rr_class klass, nsec3params_type* n3p)
152 {
153     ldns_rr* nsec_rr = NULL;
154     ldns_rr_type rrtype = LDNS_RR_TYPE_NSEC;
155     ldns_rr_type dstatus = LDNS_RR_TYPE_FIRST;
156     ldns_rdf* rdf = NULL;
157     domain_type* domain = NULL;
158     ldns_rr_type types[SE_MAX_RRTYPE_COUNT];
159     size_t types_count = 0;
160     int i = 0;
161     ods_log_assert(denial);
162     ods_log_assert(denial->dname);
163     ods_log_assert(nxt);
164     ods_log_assert(nxt->dname);
165     nsec_rr = ldns_rr_new();
166     if (!nsec_rr) {
167         ods_log_alert("[%s] unable to create NSEC(3) RR: "
168             "ldns_rr_new() failed", denial_str);
169         return NULL;
170     }
171     /* RRtype */
172     if (n3p) {
173         rrtype = LDNS_RR_TYPE_NSEC3;
174     }
175     ldns_rr_set_type(nsec_rr, rrtype);
176     /* owner */
177     rdf = ldns_rdf_clone(denial->dname);
178     if (!rdf) {
179         ods_log_alert("[%s] unable to create NSEC(3) RR: "
180             "ldns_rdf_clone(owner) failed", denial_str);
181         ldns_rr_free(nsec_rr);
182         return NULL;
183     }
184     ldns_rr_set_owner(nsec_rr, rdf);
185     /* NSEC3 parameters */
186     if (n3p) {
187         /* set all to NULL first, then call nsec3_add_param_rdfs. */
188         for (i=0; i < SE_NSEC3_RDATA_NSEC3PARAMS; i++) {
189             ldns_rr_push_rdf(nsec_rr, NULL);
190         }
191         ldns_nsec3_add_param_rdfs(nsec_rr, n3p->algorithm, n3p->flags,
192             n3p->iterations, n3p->salt_len, n3p->salt_data);
193     }
194     /* NXT */
195     if (n3p) {
196         rdf = denial_create_nsec3_nxt(nxt->dname);
197     } else {
198         rdf = ldns_rdf_clone(nxt->dname);
199     }
200     if (!rdf) {
201         ods_log_alert("[%s] unable to create NSEC(3) RR: "
202             "create next field failed", denial_str);
203         ldns_rr_free(nsec_rr);
204         return NULL;
205     }
206     ldns_rr_push_rdf(nsec_rr, rdf);
207     /* Type Bit Maps */
208     denial_create_bitmap(denial, types, &types_count);
209     if (n3p) {
210         domain = (domain_type*) denial->domain;
211         dstatus = domain_is_occluded(domain);
212         if (dstatus == LDNS_RR_TYPE_SOA) {
213             dstatus = domain_is_delegpt(domain);
214             if (dstatus != LDNS_RR_TYPE_NS && domain->rrsets) {
215                  /* Authoritative domain, not empty: add RRSIGs */
216                  types[types_count] = LDNS_RR_TYPE_RRSIG;
217                  types_count++;
218             }
219         }
220         /* and don't add NSEC3 type... */
221     } else {
222         types[types_count] = LDNS_RR_TYPE_RRSIG;
223         types_count++;
224         types[types_count] = LDNS_RR_TYPE_NSEC;
225         types_count++;
226     }
227     rdf = ldns_dnssec_create_nsec_bitmap(types, types_count, rrtype);
228     if (!rdf) {
229         ods_log_alert("[%s] unable to create NSEC(3) RR: "
230             "ldns_dnssec_create_nsec_bitmap() failed", denial_str);
231         ldns_rr_free(nsec_rr);
232         return NULL;
233     }
234     ldns_rr_push_rdf(nsec_rr, rdf);
235     ldns_rr_set_ttl(nsec_rr, ttl);
236     ldns_rr_set_class(nsec_rr, klass);
237     return nsec_rr;
238 }
239 
240 
241 /**
242  * Apply differences at denial.
243  *
244  */
245 void
denial_diff(denial_type * denial)246 denial_diff(denial_type* denial)
247 {
248     if (denial && denial->rrset) {
249         rrset_diff(denial->rrset, 0, 0);
250     }
251 }
252 
253 
254 /**
255  * Add NSEC(3) to the Denial of Existence data point.
256  *
257  */
258 void
denial_add_rr(denial_type * denial,ldns_rr * rr)259 denial_add_rr(denial_type* denial, ldns_rr* rr)
260 {
261     rr_type* record = NULL;
262     zone_type* zone = NULL;
263     ods_log_assert(denial);
264     ods_log_assert(rr);
265     zone = (zone_type*) denial->zone;
266     ods_log_assert(zone);
267     ods_log_assert(zone->signconf);
268     if (!denial->rrset) {
269         if (zone->signconf->nsec3params) {
270             denial->rrset = rrset_create(denial->zone, LDNS_RR_TYPE_NSEC3);
271         } else {
272             denial->rrset = rrset_create(denial->zone, LDNS_RR_TYPE_NSEC);
273         }
274         if (!denial->rrset) {
275             ods_fatal_exit("[%s] unable to nsecify: rrset_create() failed",
276                 denial_str);
277         }
278     }
279     ods_log_assert(denial->rrset);
280     record = rrset_add_rr(denial->rrset, rr);
281     ods_log_assert(record);
282     ods_log_assert(record->rr);
283     record->owner = (void*) denial;
284     denial_diff(denial);
285     denial->bitmap_changed = 0;
286     denial->nxt_changed = 0;
287 }
288 
289 
290 /**
291  * Nsecify Denial of Existence data point.
292  *
293  */
294 void
denial_nsecify(denial_type * denial,denial_type * nxt,uint32_t * num_added)295 denial_nsecify(denial_type* denial, denial_type* nxt, uint32_t* num_added)
296 {
297     ldns_rr* nsec_rr = NULL;
298     zone_type* zone = NULL;
299     uint32_t ttl = 0;
300     ods_log_assert(denial);
301     ods_log_assert(nxt);
302     zone = (zone_type*) denial->zone;
303     ods_log_assert(zone);
304     ods_log_assert(zone->signconf);
305     if (denial->nxt_changed || denial->bitmap_changed) {
306         ttl = zone->default_ttl;
307         /* SOA MINIMUM */
308         if (zone->signconf->soa_min) {
309             ttl = (uint32_t) duration2time(zone->signconf->soa_min);
310         }
311         /* create new NSEC(3) rr */
312         nsec_rr = denial_create_nsec(denial, nxt, ttl, zone->klass,
313             zone->signconf->nsec3params);
314         if (!nsec_rr) {
315             ods_fatal_exit("[%s] unable to nsecify: denial_create_nsec() "
316                 "failed", denial_str);
317         }
318         denial_add_rr(denial, nsec_rr);
319         if (num_added) {
320             (*num_added)++;
321         }
322     }
323 }
324 
325 
326 /**
327  * Print Denial of Existence data point.
328  *
329  */
330 void
denial_print(FILE * fd,denial_type * denial,ods_status * status)331 denial_print(FILE* fd, denial_type* denial, ods_status* status)
332 {
333     if (!denial || !fd) {
334         if (status) {
335             ods_log_crit("[%s] unable to print denial: denial of fd missing",
336                 denial_str);
337             *status = ODS_STATUS_ASSERT_ERR;
338         }
339     } else if (denial->rrset) {
340         rrset_print(fd, denial->rrset, 0, status);
341     }
342 }
343 
344 
345 /**
346  * Cleanup Denial of Existence data point.
347  *
348  */
349 void
denial_cleanup(denial_type * denial)350 denial_cleanup(denial_type* denial)
351 {
352     if (!denial) {
353         return;
354     }
355     ldns_rdf_deep_free(denial->dname);
356     rrset_cleanup(denial->rrset);
357     free(denial);
358 }
359