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