]> CyberLeo.Net >> Repos - FreeBSD/stable/9.git/blob - contrib/bind9/lib/dns/nsec3.c
Update BIND to 9.9.8
[FreeBSD/stable/9.git] / contrib / bind9 / lib / dns / nsec3.c
1 /*
2  * Copyright (C) 2006, 2008-2015  Internet Systems Consortium, Inc. ("ISC")
3  *
4  * Permission to use, copy, modify, and/or distribute this software for any
5  * purpose with or without fee is hereby granted, provided that the above
6  * copyright notice and this permission notice appear in all copies.
7  *
8  * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
9  * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
10  * AND FITNESS.  IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
11  * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
12  * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
13  * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
14  * PERFORMANCE OF THIS SOFTWARE.
15  */
16
17 /* $Id$ */
18
19 #include <config.h>
20
21 #include <isc/base32.h>
22 #include <isc/buffer.h>
23 #include <isc/hex.h>
24 #include <isc/iterated_hash.h>
25 #include <isc/log.h>
26 #include <isc/string.h>
27 #include <isc/util.h>
28 #include <isc/safe.h>
29
30 #include <dst/dst.h>
31
32 #include <dns/db.h>
33 #include <dns/zone.h>
34 #include <dns/compress.h>
35 #include <dns/dbiterator.h>
36 #include <dns/diff.h>
37 #include <dns/fixedname.h>
38 #include <dns/nsec.h>
39 #include <dns/nsec3.h>
40 #include <dns/rdata.h>
41 #include <dns/rdatalist.h>
42 #include <dns/rdataset.h>
43 #include <dns/rdatasetiter.h>
44 #include <dns/rdatastruct.h>
45 #include <dns/result.h>
46
47 #define CHECK(x) do { \
48         result = (x); \
49         if (result != ISC_R_SUCCESS) \
50                 goto failure; \
51         } while (0)
52
53 #define OPTOUT(x) (((x) & DNS_NSEC3FLAG_OPTOUT) != 0)
54 #define CREATE(x) (((x) & DNS_NSEC3FLAG_CREATE) != 0)
55 #define INITIAL(x) (((x) & DNS_NSEC3FLAG_INITIAL) != 0)
56 #define REMOVE(x) (((x) & DNS_NSEC3FLAG_REMOVE) != 0)
57
58 isc_result_t
59 dns_nsec3_buildrdata(dns_db_t *db, dns_dbversion_t *version,
60                      dns_dbnode_t *node, unsigned int hashalg,
61                      unsigned int flags, unsigned int iterations,
62                      const unsigned char *salt, size_t salt_length,
63                      const unsigned char *nexthash, size_t hash_length,
64                      unsigned char *buffer, dns_rdata_t *rdata)
65 {
66         isc_result_t result;
67         dns_rdataset_t rdataset;
68         isc_region_t r;
69         unsigned int i;
70         isc_boolean_t found;
71         isc_boolean_t found_ns;
72         isc_boolean_t need_rrsig;
73
74         unsigned char *nsec_bits, *bm;
75         unsigned int max_type;
76         dns_rdatasetiter_t *rdsiter;
77         unsigned char *p;
78
79         REQUIRE(salt_length < 256U);
80         REQUIRE(hash_length < 256U);
81         REQUIRE(flags <= 0xffU);
82         REQUIRE(hashalg <= 0xffU);
83         REQUIRE(iterations <= 0xffffU);
84
85         switch (hashalg) {
86         case dns_hash_sha1:
87                 REQUIRE(hash_length == ISC_SHA1_DIGESTLENGTH);
88                 break;
89         }
90
91         memset(buffer, 0, DNS_NSEC3_BUFFERSIZE);
92
93         p = buffer;
94
95         *p++ = hashalg;
96         *p++ = flags;
97
98         *p++ = iterations >> 8;
99         *p++ = iterations;
100
101         *p++ = (unsigned char)salt_length;
102         memmove(p, salt, salt_length);
103         p += salt_length;
104
105         *p++ = (unsigned char)hash_length;
106         memmove(p, nexthash, hash_length);
107         p += hash_length;
108
109         r.length = (unsigned int)(p - buffer);
110         r.base = buffer;
111
112         /*
113          * Use the end of the space for a raw bitmap leaving enough
114          * space for the window identifiers and length octets.
115          */
116         bm = r.base + r.length + 512;
117         nsec_bits = r.base + r.length;
118         max_type = 0;
119         if (node == NULL)
120                 goto collapse_bitmap;
121         dns_rdataset_init(&rdataset);
122         rdsiter = NULL;
123         result = dns_db_allrdatasets(db, node, version, 0, &rdsiter);
124         if (result != ISC_R_SUCCESS)
125                 return (result);
126         found = found_ns = need_rrsig = ISC_FALSE;
127         for (result = dns_rdatasetiter_first(rdsiter);
128              result == ISC_R_SUCCESS;
129              result = dns_rdatasetiter_next(rdsiter))
130         {
131                 dns_rdatasetiter_current(rdsiter, &rdataset);
132                 if (rdataset.type != dns_rdatatype_nsec &&
133                     rdataset.type != dns_rdatatype_nsec3 &&
134                     rdataset.type != dns_rdatatype_rrsig) {
135                         if (rdataset.type > max_type)
136                                 max_type = rdataset.type;
137                         dns_nsec_setbit(bm, rdataset.type, 1);
138                         /*
139                          * Work out if we need to set the RRSIG bit for
140                          * this node.  We set the RRSIG bit if either of
141                          * the following conditions are met:
142                          * 1) We have a SOA or DS then we need to set
143                          *    the RRSIG bit as both always will be signed.
144                          * 2) We set the RRSIG bit if we don't have
145                          *    a NS record but do have other data.
146                          */
147                         if (rdataset.type == dns_rdatatype_soa ||
148                             rdataset.type == dns_rdatatype_ds)
149                                 need_rrsig = ISC_TRUE;
150                         else if (rdataset.type == dns_rdatatype_ns)
151                                 found_ns = ISC_TRUE;
152                         else
153                                 found = ISC_TRUE;
154                 }
155                 dns_rdataset_disassociate(&rdataset);
156         }
157         if ((found && !found_ns) || need_rrsig) {
158                 if (dns_rdatatype_rrsig > max_type)
159                         max_type = dns_rdatatype_rrsig;
160                 dns_nsec_setbit(bm, dns_rdatatype_rrsig, 1);
161         }
162
163         /*
164          * At zone cuts, deny the existence of glue in the parent zone.
165          */
166         if (dns_nsec_isset(bm, dns_rdatatype_ns) &&
167             ! dns_nsec_isset(bm, dns_rdatatype_soa)) {
168                 for (i = 0; i <= max_type; i++) {
169                         if (dns_nsec_isset(bm, i) &&
170                             ! dns_rdatatype_iszonecutauth((dns_rdatatype_t)i))
171                                 dns_nsec_setbit(bm, i, 0);
172                 }
173         }
174
175         dns_rdatasetiter_destroy(&rdsiter);
176         if (result != ISC_R_NOMORE)
177                 return (result);
178
179  collapse_bitmap:
180         nsec_bits += dns_nsec_compressbitmap(nsec_bits, bm, max_type);
181         r.length = (unsigned int)(nsec_bits - r.base);
182         INSIST(r.length <= DNS_NSEC3_BUFFERSIZE);
183         dns_rdata_fromregion(rdata, dns_db_class(db), dns_rdatatype_nsec3, &r);
184
185         return (ISC_R_SUCCESS);
186 }
187
188 isc_boolean_t
189 dns_nsec3_typepresent(dns_rdata_t *rdata, dns_rdatatype_t type) {
190         dns_rdata_nsec3_t nsec3;
191         isc_result_t result;
192         isc_boolean_t present;
193         unsigned int i, len, window;
194
195         REQUIRE(rdata != NULL);
196         REQUIRE(rdata->type == dns_rdatatype_nsec3);
197
198         /* This should never fail */
199         result = dns_rdata_tostruct(rdata, &nsec3, NULL);
200         INSIST(result == ISC_R_SUCCESS);
201
202         present = ISC_FALSE;
203         for (i = 0; i < nsec3.len; i += len) {
204                 INSIST(i + 2 <= nsec3.len);
205                 window = nsec3.typebits[i];
206                 len = nsec3.typebits[i + 1];
207                 INSIST(len > 0 && len <= 32);
208                 i += 2;
209                 INSIST(i + len <= nsec3.len);
210                 if (window * 256 > type)
211                         break;
212                 if ((window + 1) * 256 <= type)
213                         continue;
214                 if (type < (window * 256) + len * 8)
215                         present = ISC_TF(dns_nsec_isset(&nsec3.typebits[i],
216                                                         type % 256));
217                 break;
218         }
219         dns_rdata_freestruct(&nsec3);
220         return (present);
221 }
222
223 isc_result_t
224 dns_nsec3_hashname(dns_fixedname_t *result,
225                    unsigned char rethash[NSEC3_MAX_HASH_LENGTH],
226                    size_t *hash_length, dns_name_t *name, dns_name_t *origin,
227                    dns_hash_t hashalg, unsigned int iterations,
228                    const unsigned char *salt, size_t saltlength)
229 {
230         unsigned char hash[NSEC3_MAX_HASH_LENGTH];
231         unsigned char nametext[DNS_NAME_FORMATSIZE];
232         dns_fixedname_t fixed;
233         dns_name_t *downcased;
234         isc_buffer_t namebuffer;
235         isc_region_t region;
236         size_t len;
237
238         if (rethash == NULL)
239                 rethash = hash;
240
241         memset(rethash, 0, NSEC3_MAX_HASH_LENGTH);
242
243         dns_fixedname_init(&fixed);
244         downcased = dns_fixedname_name(&fixed);
245         dns_name_downcase(name, downcased, NULL);
246
247         /* hash the node name */
248         len = isc_iterated_hash(rethash, hashalg, iterations,
249                                 salt, (int)saltlength,
250                                 downcased->ndata, downcased->length);
251         if (len == 0U)
252                 return (DNS_R_BADALG);
253
254         if (hash_length != NULL)
255                 *hash_length = len;
256
257         /* convert the hash to base32hex non-padded */
258         region.base = rethash;
259         region.length = (unsigned int)len;
260         isc_buffer_init(&namebuffer, nametext, sizeof nametext);
261         isc_base32hexnp_totext(&region, 1, "", &namebuffer);
262
263         /* convert the hex to a domain name */
264         dns_fixedname_init(result);
265         return (dns_name_fromtext(dns_fixedname_name(result), &namebuffer,
266                                   origin, 0, NULL));
267 }
268
269 unsigned int
270 dns_nsec3_hashlength(dns_hash_t hash) {
271
272         switch (hash) {
273         case dns_hash_sha1:
274                 return(ISC_SHA1_DIGESTLENGTH);
275         }
276         return (0);
277 }
278
279 isc_boolean_t
280 dns_nsec3_supportedhash(dns_hash_t hash) {
281         switch (hash) {
282         case dns_hash_sha1:
283                 return (ISC_TRUE);
284         }
285         return (ISC_FALSE);
286 }
287
288 /*%
289  * Update a single RR in version 'ver' of 'db' and log the
290  * update in 'diff'.
291  *
292  * Ensures:
293  * \li  '*tuple' == NULL.  Either the tuple is freed, or its
294  *      ownership has been transferred to the diff.
295  */
296 static isc_result_t
297 do_one_tuple(dns_difftuple_t **tuple, dns_db_t *db, dns_dbversion_t *ver,
298              dns_diff_t *diff)
299 {
300         dns_diff_t temp_diff;
301         isc_result_t result;
302
303         /*
304          * Create a singleton diff.
305          */
306         dns_diff_init(diff->mctx, &temp_diff);
307         ISC_LIST_APPEND(temp_diff.tuples, *tuple, link);
308
309         /*
310          * Apply it to the database.
311          */
312         result = dns_diff_apply(&temp_diff, db, ver);
313         ISC_LIST_UNLINK(temp_diff.tuples, *tuple, link);
314         if (result != ISC_R_SUCCESS) {
315                 dns_difftuple_free(tuple);
316                 return (result);
317         }
318
319         /*
320          * Merge it into the current pending journal entry.
321          */
322         dns_diff_appendminimal(diff, tuple);
323
324         /*
325          * Do not clear temp_diff.
326          */
327         return (ISC_R_SUCCESS);
328 }
329
330 /*%
331  * Set '*exists' to true iff the given name exists, to false otherwise.
332  */
333 static isc_result_t
334 name_exists(dns_db_t *db, dns_dbversion_t *version, dns_name_t *name,
335             isc_boolean_t *exists)
336 {
337         isc_result_t result;
338         dns_dbnode_t *node = NULL;
339         dns_rdatasetiter_t *iter = NULL;
340
341         result = dns_db_findnode(db, name, ISC_FALSE, &node);
342         if (result == ISC_R_NOTFOUND) {
343                 *exists = ISC_FALSE;
344                 return (ISC_R_SUCCESS);
345         }
346         if (result != ISC_R_SUCCESS)
347                 return (result);
348
349         result = dns_db_allrdatasets(db, node, version,
350                                      (isc_stdtime_t) 0, &iter);
351         if (result != ISC_R_SUCCESS)
352                 goto cleanup_node;
353
354         result = dns_rdatasetiter_first(iter);
355         if (result == ISC_R_SUCCESS) {
356                 *exists = ISC_TRUE;
357         } else if (result == ISC_R_NOMORE) {
358                 *exists = ISC_FALSE;
359                 result = ISC_R_SUCCESS;
360         } else
361                 *exists = ISC_FALSE;
362         dns_rdatasetiter_destroy(&iter);
363
364  cleanup_node:
365         dns_db_detachnode(db, &node);
366         return (result);
367 }
368
369 static isc_boolean_t
370 match_nsec3param(const dns_rdata_nsec3_t *nsec3,
371                  const dns_rdata_nsec3param_t *nsec3param)
372 {
373         if (nsec3->hash == nsec3param->hash &&
374             nsec3->iterations == nsec3param->iterations &&
375             nsec3->salt_length == nsec3param->salt_length &&
376             !memcmp(nsec3->salt, nsec3param->salt, nsec3->salt_length))
377                 return (ISC_TRUE);
378         return (ISC_FALSE);
379 }
380
381 /*%
382  * Delete NSEC3 records at "name" which match "param", recording the
383  * change in "diff".
384  */
385 static isc_result_t
386 delete(dns_db_t *db, dns_dbversion_t *version, dns_name_t *name,
387        const dns_rdata_nsec3param_t *nsec3param, dns_diff_t *diff)
388 {
389         dns_dbnode_t *node = NULL ;
390         dns_difftuple_t *tuple = NULL;
391         dns_rdata_nsec3_t nsec3;
392         dns_rdataset_t rdataset;
393         isc_result_t result;
394
395         result = dns_db_findnsec3node(db, name, ISC_FALSE, &node);
396         if (result == ISC_R_NOTFOUND)
397                 return (ISC_R_SUCCESS);
398         if (result != ISC_R_SUCCESS)
399                 return (result);
400
401         dns_rdataset_init(&rdataset);
402         result = dns_db_findrdataset(db, node, version, dns_rdatatype_nsec3, 0,
403                                      (isc_stdtime_t) 0, &rdataset, NULL);
404
405         if (result == ISC_R_NOTFOUND) {
406                 result = ISC_R_SUCCESS;
407                 goto cleanup_node;
408         }
409         if (result != ISC_R_SUCCESS)
410                 goto cleanup_node;
411
412         for (result = dns_rdataset_first(&rdataset);
413              result == ISC_R_SUCCESS;
414              result = dns_rdataset_next(&rdataset))
415         {
416                 dns_rdata_t rdata = DNS_RDATA_INIT;
417                 dns_rdataset_current(&rdataset, &rdata);
418                 CHECK(dns_rdata_tostruct(&rdata, &nsec3, NULL));
419
420                 if (!match_nsec3param(&nsec3, nsec3param))
421                         continue;
422
423                 result = dns_difftuple_create(diff->mctx, DNS_DIFFOP_DEL, name,
424                                               rdataset.ttl, &rdata, &tuple);
425                 if (result != ISC_R_SUCCESS)
426                         goto failure;
427                 result = do_one_tuple(&tuple, db, version, diff);
428                 if (result != ISC_R_SUCCESS)
429                         goto failure;
430         }
431         if (result != ISC_R_NOMORE)
432                 goto failure;
433         result = ISC_R_SUCCESS;
434
435  failure:
436         dns_rdataset_disassociate(&rdataset);
437  cleanup_node:
438         dns_db_detachnode(db, &node);
439
440         return (result);
441 }
442
443 static isc_boolean_t
444 better_param(dns_rdataset_t *nsec3paramset, dns_rdata_t *param) {
445         dns_rdataset_t rdataset;
446         isc_result_t result;
447
448         if (REMOVE(param->data[1]))
449                 return (ISC_TRUE);
450
451         dns_rdataset_init(&rdataset);
452         dns_rdataset_clone(nsec3paramset, &rdataset);
453         for (result = dns_rdataset_first(&rdataset);
454              result == ISC_R_SUCCESS;
455              result = dns_rdataset_next(&rdataset)) {
456                 dns_rdata_t rdata =  DNS_RDATA_INIT;
457                 unsigned char buf[DNS_NSEC3PARAM_BUFFERSIZE];
458
459                 if (rdataset.type != dns_rdatatype_nsec3param) {
460                         dns_rdata_t tmprdata =  DNS_RDATA_INIT;
461                         dns_rdataset_current(&rdataset, &tmprdata);
462                         if (!dns_nsec3param_fromprivate(&tmprdata, &rdata,
463                                                         buf, sizeof(buf)))
464                                 continue;
465                 } else
466                         dns_rdataset_current(&rdataset, &rdata);
467
468                 if (rdata.length != param->length)
469                         continue;
470                 if (rdata.data[0] != param->data[0] ||
471                     REMOVE(rdata.data[1]) ||
472                     rdata.data[2] != param->data[2] ||
473                     rdata.data[3] != param->data[3] ||
474                     rdata.data[4] != param->data[4] ||
475                     memcmp(&rdata.data[5], &param->data[5], param->data[4]))
476                         continue;
477                 if (CREATE(rdata.data[1]) && !CREATE(param->data[1])) {
478                         dns_rdataset_disassociate(&rdataset);
479                         return (ISC_TRUE);
480                 }
481         }
482         dns_rdataset_disassociate(&rdataset);
483         return (ISC_FALSE);
484 }
485
486 static isc_result_t
487 find_nsec3(dns_rdata_nsec3_t *nsec3, dns_rdataset_t *rdataset,
488            const dns_rdata_nsec3param_t *nsec3param)
489 {
490         isc_result_t result;
491         for (result = dns_rdataset_first(rdataset);
492              result == ISC_R_SUCCESS;
493              result = dns_rdataset_next(rdataset)) {
494                 dns_rdata_t rdata = DNS_RDATA_INIT;
495
496                 dns_rdataset_current(rdataset, &rdata);
497                 CHECK(dns_rdata_tostruct(&rdata, nsec3, NULL));
498                 dns_rdata_reset(&rdata);
499                 if (match_nsec3param(nsec3, nsec3param))
500                         break;
501         }
502  failure:
503         return (result);
504 }
505
506 isc_result_t
507 dns_nsec3_addnsec3(dns_db_t *db, dns_dbversion_t *version,
508                    dns_name_t *name, const dns_rdata_nsec3param_t *nsec3param,
509                    dns_ttl_t nsecttl, isc_boolean_t unsecure, dns_diff_t *diff)
510 {
511         dns_dbiterator_t *dbit = NULL;
512         dns_dbnode_t *node = NULL;
513         dns_dbnode_t *newnode = NULL;
514         dns_difftuple_t *tuple = NULL;
515         dns_fixedname_t fixed;
516         dns_fixedname_t fprev;
517         dns_hash_t hash;
518         dns_name_t *hashname;
519         dns_name_t *origin;
520         dns_name_t *prev;
521         dns_name_t empty;
522         dns_rdata_nsec3_t nsec3;
523         dns_rdata_t rdata = DNS_RDATA_INIT;
524         dns_rdataset_t rdataset;
525         int pass;
526         isc_boolean_t exists = ISC_FALSE;
527         isc_boolean_t maybe_remove_unsecure = ISC_FALSE;
528         isc_uint8_t flags;
529         isc_buffer_t buffer;
530         isc_result_t result;
531         unsigned char *old_next;
532         unsigned char *salt;
533         unsigned char nexthash[NSEC3_MAX_HASH_LENGTH];
534         unsigned char nsec3buf[DNS_NSEC3_BUFFERSIZE];
535         unsigned int iterations;
536         unsigned int labels;
537         size_t next_length;
538         unsigned int old_length;
539         unsigned int salt_length;
540
541         dns_fixedname_init(&fixed);
542         hashname = dns_fixedname_name(&fixed);
543         dns_fixedname_init(&fprev);
544         prev = dns_fixedname_name(&fprev);
545
546         dns_rdataset_init(&rdataset);
547
548         origin = dns_db_origin(db);
549
550         /*
551          * Chain parameters.
552          */
553         hash = nsec3param->hash;
554         iterations = nsec3param->iterations;
555         salt_length = nsec3param->salt_length;
556         salt = nsec3param->salt;
557
558         /*
559          * Default flags for a new chain.
560          */
561         flags = nsec3param->flags & DNS_NSEC3FLAG_OPTOUT;
562
563         /*
564          * If this is the first NSEC3 in the chain nexthash will
565          * remain pointing to itself.
566          */
567         next_length = sizeof(nexthash);
568         CHECK(dns_nsec3_hashname(&fixed, nexthash, &next_length,
569                                  name, origin, hash, iterations,
570                                  salt, salt_length));
571         INSIST(next_length <= sizeof(nexthash));
572
573         /*
574          * Create the node if it doesn't exist and hold
575          * a reference to it until we have added the NSEC3.
576          */
577         CHECK(dns_db_findnsec3node(db, hashname, ISC_TRUE, &newnode));
578
579         /*
580          * Seek the iterator to the 'newnode'.
581          */
582         CHECK(dns_db_createiterator(db, DNS_DB_NSEC3ONLY, &dbit));
583         CHECK(dns_dbiterator_seek(dbit, hashname));
584         CHECK(dns_dbiterator_pause(dbit));
585         result = dns_db_findrdataset(db, newnode, version, dns_rdatatype_nsec3,
586                                      0, (isc_stdtime_t) 0, &rdataset, NULL);
587         /*
588          * If we updating a existing NSEC3 then find its
589          * next field.
590          */
591         if (result == ISC_R_SUCCESS) {
592                 result = find_nsec3(&nsec3, &rdataset, nsec3param);
593                 if (result == ISC_R_SUCCESS) {
594                         if (!CREATE(nsec3param->flags))
595                                 flags = nsec3.flags;
596                         next_length = nsec3.next_length;
597                         INSIST(next_length <= sizeof(nexthash));
598                         memmove(nexthash, nsec3.next, next_length);
599                         dns_rdataset_disassociate(&rdataset);
600                         /*
601                          * If the NSEC3 is not for a unsecure delegation then
602                          * we are just updating it.  If it is for a unsecure
603                          * delegation then we need find out if we need to
604                          * remove the NSEC3 record or not by examining the
605                          * previous NSEC3 record.
606                          */
607                         if (!unsecure)
608                                 goto addnsec3;
609                         else if (CREATE(nsec3param->flags) && OPTOUT(flags)) {
610                                 result = dns_nsec3_delnsec3(db, version, name,
611                                                             nsec3param, diff);
612                                 goto failure;
613                         } else
614                                 maybe_remove_unsecure = ISC_TRUE;
615                 } else {
616                         dns_rdataset_disassociate(&rdataset);
617                         if (result != ISC_R_NOMORE)
618                                 goto failure;
619                 }
620         }
621
622         /*
623          * Find the previous NSEC3 (if any) and update it if required.
624          */
625         pass = 0;
626         do {
627                 result = dns_dbiterator_prev(dbit);
628                 if (result == ISC_R_NOMORE) {
629                         pass++;
630                         CHECK(dns_dbiterator_last(dbit));
631                 }
632                 CHECK(dns_dbiterator_current(dbit, &node, prev));
633                 CHECK(dns_dbiterator_pause(dbit));
634                 result = dns_db_findrdataset(db, node, version,
635                                              dns_rdatatype_nsec3, 0,
636                                              (isc_stdtime_t) 0, &rdataset,
637                                              NULL);
638                 dns_db_detachnode(db, &node);
639                 if (result != ISC_R_SUCCESS)
640                         continue;
641
642                 result = find_nsec3(&nsec3, &rdataset, nsec3param);
643                 if (result == ISC_R_NOMORE) {
644                         dns_rdataset_disassociate(&rdataset);
645                         continue;
646                 }
647                 if (result != ISC_R_SUCCESS)
648                         goto failure;
649
650                 if (maybe_remove_unsecure) {
651                         dns_rdataset_disassociate(&rdataset);
652                         /*
653                          * If we have OPTOUT set in the previous NSEC3 record
654                          * we actually need to delete the NSEC3 record.
655                          * Otherwise we just need to replace the NSEC3 record.
656                          */
657                         if (OPTOUT(nsec3.flags)) {
658                                 result = dns_nsec3_delnsec3(db, version, name,
659                                                             nsec3param, diff);
660                                 goto failure;
661                         }
662                         goto addnsec3;
663                 } else {
664                         /*
665                          * Is this is a unsecure delegation we are adding?
666                          * If so no change is required.
667                          */
668                         if (OPTOUT(nsec3.flags) && unsecure) {
669                                 dns_rdataset_disassociate(&rdataset);
670                                 goto failure;
671                         }
672                 }
673
674                 old_next = nsec3.next;
675                 old_length = nsec3.next_length;
676
677                 /*
678                  * Delete the old previous NSEC3.
679                  */
680                 CHECK(delete(db, version, prev, nsec3param, diff));
681
682                 /*
683                  * Fixup the previous NSEC3.
684                  */
685                 nsec3.next = nexthash;
686                 nsec3.next_length = (unsigned char)next_length;
687                 isc_buffer_init(&buffer, nsec3buf, sizeof(nsec3buf));
688                 CHECK(dns_rdata_fromstruct(&rdata, rdataset.rdclass,
689                                            dns_rdatatype_nsec3, &nsec3,
690                                            &buffer));
691                 CHECK(dns_difftuple_create(diff->mctx, DNS_DIFFOP_ADD, prev,
692                                            rdataset.ttl, &rdata, &tuple));
693                 CHECK(do_one_tuple(&tuple, db, version, diff));
694                 INSIST(old_length <= sizeof(nexthash));
695                 memmove(nexthash, old_next, old_length);
696                 if (!CREATE(nsec3param->flags))
697                         flags = nsec3.flags;
698                 dns_rdata_reset(&rdata);
699                 dns_rdataset_disassociate(&rdataset);
700                 break;
701         } while (pass < 2);
702
703  addnsec3:
704         /*
705          * Create the NSEC3 RDATA.
706          */
707         CHECK(dns_db_findnode(db, name, ISC_FALSE, &node));
708         CHECK(dns_nsec3_buildrdata(db, version, node, hash, flags, iterations,
709                                    salt, salt_length, nexthash, next_length,
710                                    nsec3buf, &rdata));
711         dns_db_detachnode(db, &node);
712
713         /*
714          * Delete the old NSEC3 and record the change.
715          */
716         CHECK(delete(db, version, hashname, nsec3param, diff));
717         /*
718          * Add the new NSEC3 and record the change.
719          */
720         CHECK(dns_difftuple_create(diff->mctx, DNS_DIFFOP_ADD,
721                                    hashname, nsecttl, &rdata, &tuple));
722         CHECK(do_one_tuple(&tuple, db, version, diff));
723         INSIST(tuple == NULL);
724         dns_rdata_reset(&rdata);
725         dns_db_detachnode(db, &newnode);
726
727         /*
728          * Add missing NSEC3 records for empty nodes
729          */
730         dns_name_init(&empty, NULL);
731         dns_name_clone(name, &empty);
732         do {
733                 labels = dns_name_countlabels(&empty) - 1;
734                 if (labels <= dns_name_countlabels(origin))
735                         break;
736                 dns_name_getlabelsequence(&empty, 1, labels, &empty);
737                 CHECK(name_exists(db, version, &empty, &exists));
738                 if (exists)
739                         break;
740                 CHECK(dns_nsec3_hashname(&fixed, nexthash, &next_length,
741                                          &empty, origin, hash, iterations,
742                                          salt, salt_length));
743
744                 /*
745                  * Create the node if it doesn't exist and hold
746                  * a reference to it until we have added the NSEC3
747                  * or we discover we don't need to add make a change.
748                  */
749                 CHECK(dns_db_findnsec3node(db, hashname, ISC_TRUE, &newnode));
750                 result = dns_db_findrdataset(db, newnode, version,
751                                              dns_rdatatype_nsec3, 0,
752                                              (isc_stdtime_t) 0, &rdataset,
753                                              NULL);
754                 if (result == ISC_R_SUCCESS) {
755                         result = find_nsec3(&nsec3, &rdataset, nsec3param);
756                         dns_rdataset_disassociate(&rdataset);
757                         if (result == ISC_R_SUCCESS) {
758                                 dns_db_detachnode(db, &newnode);
759                                 break;
760                         }
761                         if (result != ISC_R_NOMORE)
762                                 goto failure;
763                 }
764
765                 /*
766                  * Find the previous NSEC3 and update it.
767                  */
768                 CHECK(dns_dbiterator_seek(dbit, hashname));
769                 pass = 0;
770                 do {
771                         result = dns_dbiterator_prev(dbit);
772                         if (result == ISC_R_NOMORE) {
773                                 pass++;
774                                 CHECK(dns_dbiterator_last(dbit));
775                         }
776                         CHECK(dns_dbiterator_current(dbit, &node, prev));
777                         CHECK(dns_dbiterator_pause(dbit));
778                         result = dns_db_findrdataset(db, node, version,
779                                                      dns_rdatatype_nsec3, 0,
780                                                      (isc_stdtime_t) 0,
781                                                      &rdataset, NULL);
782                         dns_db_detachnode(db, &node);
783                         if (result != ISC_R_SUCCESS)
784                                 continue;
785                         result = find_nsec3(&nsec3, &rdataset, nsec3param);
786                         if (result == ISC_R_NOMORE) {
787                                 dns_rdataset_disassociate(&rdataset);
788                                 continue;
789                         }
790                         if (result != ISC_R_SUCCESS)
791                                 goto failure;
792
793                         old_next = nsec3.next;
794                         old_length = nsec3.next_length;
795
796                         /*
797                          * Delete the old previous NSEC3.
798                          */
799                         CHECK(delete(db, version, prev, nsec3param, diff));
800
801                         /*
802                          * Fixup the previous NSEC3.
803                          */
804                         nsec3.next = nexthash;
805                         nsec3.next_length = (unsigned char)next_length;
806                         isc_buffer_init(&buffer, nsec3buf,
807                                         sizeof(nsec3buf));
808                         CHECK(dns_rdata_fromstruct(&rdata, rdataset.rdclass,
809                                                    dns_rdatatype_nsec3, &nsec3,
810                                                    &buffer));
811                         CHECK(dns_difftuple_create(diff->mctx, DNS_DIFFOP_ADD,
812                                                    prev, rdataset.ttl, &rdata,
813                                                    &tuple));
814                         CHECK(do_one_tuple(&tuple, db, version, diff));
815                         INSIST(old_length <= sizeof(nexthash));
816                         memmove(nexthash, old_next, old_length);
817                         if (!CREATE(nsec3param->flags))
818                                 flags = nsec3.flags;
819                         dns_rdata_reset(&rdata);
820                         dns_rdataset_disassociate(&rdataset);
821                         break;
822                 } while (pass < 2);
823
824                 INSIST(pass < 2);
825
826                 /*
827                  * Create the NSEC3 RDATA for the empty node.
828                  */
829                 CHECK(dns_nsec3_buildrdata(db, version, NULL, hash, flags,
830                                            iterations, salt, salt_length,
831                                            nexthash, next_length, nsec3buf,
832                                            &rdata));
833                 /*
834                  * Delete the old NSEC3 and record the change.
835                  */
836                 CHECK(delete(db, version, hashname, nsec3param, diff));
837
838                 /*
839                  * Add the new NSEC3 and record the change.
840                  */
841                 CHECK(dns_difftuple_create(diff->mctx, DNS_DIFFOP_ADD,
842                                            hashname, nsecttl, &rdata, &tuple));
843                 CHECK(do_one_tuple(&tuple, db, version, diff));
844                 INSIST(tuple == NULL);
845                 dns_rdata_reset(&rdata);
846                 dns_db_detachnode(db, &newnode);
847         } while (1);
848
849         /* result cannot be ISC_R_NOMORE here */
850         INSIST(result != ISC_R_NOMORE);
851
852  failure:
853         if (dbit != NULL)
854                 dns_dbiterator_destroy(&dbit);
855         if (dns_rdataset_isassociated(&rdataset))
856                 dns_rdataset_disassociate(&rdataset);
857         if (node != NULL)
858                 dns_db_detachnode(db, &node);
859         if (newnode != NULL)
860                 dns_db_detachnode(db, &newnode);
861         return (result);
862 }
863
864 /*%
865  * Add NSEC3 records for "name", recording the change in "diff".
866  * The existing NSEC3 records are removed.
867  */
868 isc_result_t
869 dns_nsec3_addnsec3s(dns_db_t *db, dns_dbversion_t *version,
870                     dns_name_t *name, dns_ttl_t nsecttl,
871                     isc_boolean_t unsecure, dns_diff_t *diff)
872 {
873         dns_dbnode_t *node = NULL;
874         dns_rdata_nsec3param_t nsec3param;
875         dns_rdataset_t rdataset;
876         isc_result_t result;
877
878         dns_rdataset_init(&rdataset);
879
880         /*
881          * Find the NSEC3 parameters for this zone.
882          */
883         result = dns_db_getoriginnode(db, &node);
884         if (result != ISC_R_SUCCESS)
885                 return (result);
886
887         result = dns_db_findrdataset(db, node, version,
888                                      dns_rdatatype_nsec3param, 0, 0,
889                                      &rdataset, NULL);
890         dns_db_detachnode(db, &node);
891         if (result == ISC_R_NOTFOUND)
892                 return (ISC_R_SUCCESS);
893         if (result != ISC_R_SUCCESS)
894                 return (result);
895
896         /*
897          * Update each active NSEC3 chain.
898          */
899         for (result = dns_rdataset_first(&rdataset);
900              result == ISC_R_SUCCESS;
901              result = dns_rdataset_next(&rdataset)) {
902                 dns_rdata_t rdata = DNS_RDATA_INIT;
903
904                 dns_rdataset_current(&rdataset, &rdata);
905                 CHECK(dns_rdata_tostruct(&rdata, &nsec3param, NULL));
906
907                 if (nsec3param.flags != 0)
908                         continue;
909                 /*
910                  * We have a active chain.  Update it.
911                  */
912                 CHECK(dns_nsec3_addnsec3(db, version, name, &nsec3param,
913                                          nsecttl, unsecure, diff));
914         }
915         if (result == ISC_R_NOMORE)
916                 result = ISC_R_SUCCESS;
917
918  failure:
919         if (dns_rdataset_isassociated(&rdataset))
920                 dns_rdataset_disassociate(&rdataset);
921         if (node != NULL)
922                 dns_db_detachnode(db, &node);
923
924         return (result);
925 }
926
927 isc_boolean_t
928 dns_nsec3param_fromprivate(dns_rdata_t *src, dns_rdata_t *target,
929                            unsigned char *buf, size_t buflen)
930 {
931         dns_decompress_t dctx;
932         isc_result_t result;
933         isc_buffer_t buf1;
934         isc_buffer_t buf2;
935
936         /*
937          * Algorithm 0 (reserved by RFC 4034) is used to identify
938          * NSEC3PARAM records from DNSKEY pointers.
939          */
940         if (src->length < 1 || src->data[0] != 0)
941                 return (ISC_FALSE);
942
943         isc_buffer_init(&buf1, src->data + 1, src->length - 1);
944         isc_buffer_add(&buf1, src->length - 1);
945         isc_buffer_setactive(&buf1, src->length - 1);
946         isc_buffer_init(&buf2, buf, (unsigned int)buflen);
947         dns_decompress_init(&dctx, -1, DNS_DECOMPRESS_NONE);
948         result = dns_rdata_fromwire(target, src->rdclass,
949                                     dns_rdatatype_nsec3param,
950                                     &buf1, &dctx, 0, &buf2);
951         dns_decompress_invalidate(&dctx);
952
953         return (ISC_TF(result == ISC_R_SUCCESS));
954 }
955
956 void
957 dns_nsec3param_toprivate(dns_rdata_t *src, dns_rdata_t *target,
958                          dns_rdatatype_t privatetype,
959                          unsigned char *buf, size_t buflen)
960 {
961         REQUIRE(buflen >= src->length + 1);
962
963         REQUIRE(DNS_RDATA_INITIALIZED(target));
964
965         memmove(buf + 1, src->data, src->length);
966         buf[0] = 0;
967         target->data = buf;
968         target->length = src->length + 1;
969         target->type = privatetype;
970         target->rdclass = src->rdclass;
971         target->flags = 0;
972         ISC_LINK_INIT(target, link);
973 }
974
975 #ifdef BIND9
976 static isc_result_t
977 rr_exists(dns_db_t *db, dns_dbversion_t *ver, dns_name_t *name,
978           const dns_rdata_t *rdata, isc_boolean_t *flag)
979 {
980         dns_rdataset_t rdataset;
981         dns_dbnode_t *node = NULL;
982         isc_result_t result;
983
984         dns_rdataset_init(&rdataset);
985         if (rdata->type == dns_rdatatype_nsec3)
986                 CHECK(dns_db_findnsec3node(db, name, ISC_FALSE, &node));
987         else
988                 CHECK(dns_db_findnode(db, name, ISC_FALSE, &node));
989         result = dns_db_findrdataset(db, node, ver, rdata->type, 0,
990                                      (isc_stdtime_t) 0, &rdataset, NULL);
991         if (result == ISC_R_NOTFOUND) {
992                 *flag = ISC_FALSE;
993                 result = ISC_R_SUCCESS;
994                 goto failure;
995         }
996
997         for (result = dns_rdataset_first(&rdataset);
998              result == ISC_R_SUCCESS;
999              result = dns_rdataset_next(&rdataset)) {
1000                 dns_rdata_t myrdata = DNS_RDATA_INIT;
1001                 dns_rdataset_current(&rdataset, &myrdata);
1002                 if (!dns_rdata_casecompare(&myrdata, rdata))
1003                         break;
1004         }
1005         dns_rdataset_disassociate(&rdataset);
1006         if (result == ISC_R_SUCCESS) {
1007                 *flag = ISC_TRUE;
1008         } else if (result == ISC_R_NOMORE) {
1009                 *flag = ISC_FALSE;
1010                 result = ISC_R_SUCCESS;
1011         }
1012
1013  failure:
1014         if (node != NULL)
1015                 dns_db_detachnode(db, &node);
1016         return (result);
1017 }
1018 #endif
1019
1020 #ifdef BIND9
1021 isc_result_t
1022 dns_nsec3param_deletechains(dns_db_t *db, dns_dbversion_t *ver,
1023                             dns_zone_t *zone, isc_boolean_t nonsec,
1024                             dns_diff_t *diff)
1025 {
1026         dns_dbnode_t *node = NULL;
1027         dns_difftuple_t *tuple = NULL;
1028         dns_name_t next;
1029         dns_rdata_t rdata = DNS_RDATA_INIT;
1030         dns_rdataset_t rdataset;
1031         isc_boolean_t flag;
1032         isc_result_t result = ISC_R_SUCCESS;
1033         unsigned char buf[DNS_NSEC3PARAM_BUFFERSIZE + 1];
1034         dns_name_t *origin = dns_zone_getorigin(zone);
1035         dns_rdatatype_t privatetype = dns_zone_getprivatetype(zone);
1036
1037         dns_name_init(&next, NULL);
1038         dns_rdataset_init(&rdataset);
1039
1040         result = dns_db_getoriginnode(db, &node);
1041         if (result != ISC_R_SUCCESS)
1042                 return (result);
1043
1044         /*
1045          * Cause all NSEC3 chains to be deleted.
1046          */
1047         result = dns_db_findrdataset(db, node, ver, dns_rdatatype_nsec3param,
1048                                      0, (isc_stdtime_t) 0, &rdataset, NULL);
1049         if (result == ISC_R_NOTFOUND)
1050                 goto try_private;
1051         if (result != ISC_R_SUCCESS)
1052                 goto failure;
1053
1054         for (result = dns_rdataset_first(&rdataset);
1055              result == ISC_R_SUCCESS;
1056              result = dns_rdataset_next(&rdataset)) {
1057                 dns_rdata_t private = DNS_RDATA_INIT;
1058
1059                 dns_rdataset_current(&rdataset, &rdata);
1060
1061                 CHECK(dns_difftuple_create(diff->mctx, DNS_DIFFOP_DEL, origin,
1062                                            rdataset.ttl, &rdata, &tuple));
1063                 CHECK(do_one_tuple(&tuple, db, ver, diff));
1064                 INSIST(tuple == NULL);
1065
1066                 dns_nsec3param_toprivate(&rdata, &private, privatetype,
1067                                          buf, sizeof(buf));
1068                 buf[2] = DNS_NSEC3FLAG_REMOVE;
1069                 if (nonsec)
1070                         buf[2] |= DNS_NSEC3FLAG_NONSEC;
1071
1072                 CHECK(rr_exists(db, ver, origin, &private, &flag));
1073
1074                 if (!flag) {
1075                         CHECK(dns_difftuple_create(diff->mctx, DNS_DIFFOP_ADD,
1076                                                    origin, 0, &private,
1077                                                    &tuple));
1078                         CHECK(do_one_tuple(&tuple, db, ver, diff));
1079                         INSIST(tuple == NULL);
1080                 }
1081                 dns_rdata_reset(&rdata);
1082         }
1083         if (result != ISC_R_NOMORE)
1084                 goto failure;
1085
1086         dns_rdataset_disassociate(&rdataset);
1087
1088  try_private:
1089         if (privatetype == 0)
1090                 goto success;
1091         result = dns_db_findrdataset(db, node, ver, privatetype, 0,
1092                                      (isc_stdtime_t) 0, &rdataset, NULL);
1093         if (result == ISC_R_NOTFOUND)
1094                 goto success;
1095         if (result != ISC_R_SUCCESS)
1096                 goto failure;
1097
1098         for (result = dns_rdataset_first(&rdataset);
1099              result == ISC_R_SUCCESS;
1100              result = dns_rdataset_next(&rdataset)) {
1101                 dns_rdata_reset(&rdata);
1102                 dns_rdataset_current(&rdataset, &rdata);
1103                 INSIST(rdata.length <= sizeof(buf));
1104                 memmove(buf, rdata.data, rdata.length);
1105
1106                 /*
1107                  * Private NSEC3 record length >= 6.
1108                  * <0(1), hash(1), flags(1), iterations(2), saltlen(1)>
1109                  */
1110                 if (rdata.length < 6 || buf[0] != 0 ||
1111                     (buf[2] & DNS_NSEC3FLAG_REMOVE) != 0 ||
1112                     (nonsec && (buf[2] & DNS_NSEC3FLAG_NONSEC) != 0))
1113                         continue;
1114
1115                 CHECK(dns_difftuple_create(diff->mctx, DNS_DIFFOP_DEL, origin,
1116                                            0, &rdata, &tuple));
1117                 CHECK(do_one_tuple(&tuple, db, ver, diff));
1118                 INSIST(tuple == NULL);
1119
1120                 rdata.data = buf;
1121                 buf[2] = DNS_NSEC3FLAG_REMOVE;
1122                 if (nonsec)
1123                         buf[2] |= DNS_NSEC3FLAG_NONSEC;
1124
1125                 CHECK(rr_exists(db, ver, origin, &rdata, &flag));
1126
1127                 if (!flag) {
1128                         CHECK(dns_difftuple_create(diff->mctx, DNS_DIFFOP_ADD,
1129                                                    origin, 0, &rdata, &tuple));
1130                         CHECK(do_one_tuple(&tuple, db, ver, diff));
1131                         INSIST(tuple == NULL);
1132                 }
1133         }
1134         if (result != ISC_R_NOMORE)
1135                 goto failure;
1136  success:
1137         result = ISC_R_SUCCESS;
1138
1139  failure:
1140         if (dns_rdataset_isassociated(&rdataset))
1141                 dns_rdataset_disassociate(&rdataset);
1142         dns_db_detachnode(db, &node);
1143         return (result);
1144 }
1145 #endif
1146
1147 isc_result_t
1148 dns_nsec3_addnsec3sx(dns_db_t *db, dns_dbversion_t *version,
1149                      dns_name_t *name, dns_ttl_t nsecttl,
1150                      isc_boolean_t unsecure, dns_rdatatype_t type,
1151                      dns_diff_t *diff)
1152 {
1153         dns_dbnode_t *node = NULL;
1154         dns_rdata_nsec3param_t nsec3param;
1155         dns_rdataset_t rdataset;
1156         dns_rdataset_t prdataset;
1157         isc_result_t result;
1158
1159         dns_rdataset_init(&rdataset);
1160         dns_rdataset_init(&prdataset);
1161
1162         /*
1163          * Find the NSEC3 parameters for this zone.
1164          */
1165         result = dns_db_getoriginnode(db, &node);
1166         if (result != ISC_R_SUCCESS)
1167                 return (result);
1168
1169         result = dns_db_findrdataset(db, node, version, type, 0, 0,
1170                                      &prdataset, NULL);
1171         if (result != ISC_R_SUCCESS && result != ISC_R_NOTFOUND)
1172                 goto failure;
1173
1174         result = dns_db_findrdataset(db, node, version,
1175                                      dns_rdatatype_nsec3param, 0, 0,
1176                                      &rdataset, NULL);
1177         if (result == ISC_R_NOTFOUND)
1178                 goto try_private;
1179         if (result != ISC_R_SUCCESS)
1180                 goto failure;
1181
1182         /*
1183          * Update each active NSEC3 chain.
1184          */
1185         for (result = dns_rdataset_first(&rdataset);
1186              result == ISC_R_SUCCESS;
1187              result = dns_rdataset_next(&rdataset)) {
1188                 dns_rdata_t rdata = DNS_RDATA_INIT;
1189
1190                 dns_rdataset_current(&rdataset, &rdata);
1191                 CHECK(dns_rdata_tostruct(&rdata, &nsec3param, NULL));
1192
1193                 if (nsec3param.flags != 0)
1194                         continue;
1195
1196                 /*
1197                  * We have a active chain.  Update it.
1198                  */
1199                 CHECK(dns_nsec3_addnsec3(db, version, name, &nsec3param,
1200                                          nsecttl, unsecure, diff));
1201         }
1202         if (result != ISC_R_NOMORE)
1203                 goto failure;
1204
1205         dns_rdataset_disassociate(&rdataset);
1206
1207  try_private:
1208         if (!dns_rdataset_isassociated(&prdataset))
1209                 goto success;
1210         /*
1211          * Update each active NSEC3 chain.
1212          */
1213         for (result = dns_rdataset_first(&prdataset);
1214              result == ISC_R_SUCCESS;
1215              result = dns_rdataset_next(&prdataset)) {
1216                 dns_rdata_t rdata1 = DNS_RDATA_INIT;
1217                 dns_rdata_t rdata2 = DNS_RDATA_INIT;
1218                 unsigned char buf[DNS_NSEC3PARAM_BUFFERSIZE];
1219
1220                 dns_rdataset_current(&prdataset, &rdata1);
1221                 if (!dns_nsec3param_fromprivate(&rdata1, &rdata2,
1222                                                 buf, sizeof(buf)))
1223                         continue;
1224                 CHECK(dns_rdata_tostruct(&rdata2, &nsec3param, NULL));
1225
1226                 if ((nsec3param.flags & DNS_NSEC3FLAG_REMOVE) != 0)
1227                         continue;
1228                 if (better_param(&prdataset, &rdata2))
1229                         continue;
1230
1231                 /*
1232                  * We have a active chain.  Update it.
1233                  */
1234                 CHECK(dns_nsec3_addnsec3(db, version, name, &nsec3param,
1235                                          nsecttl, unsecure, diff));
1236         }
1237         if (result == ISC_R_NOMORE)
1238  success:
1239                 result = ISC_R_SUCCESS;
1240  failure:
1241         if (dns_rdataset_isassociated(&rdataset))
1242                 dns_rdataset_disassociate(&rdataset);
1243         if (dns_rdataset_isassociated(&prdataset))
1244                 dns_rdataset_disassociate(&prdataset);
1245         if (node != NULL)
1246                 dns_db_detachnode(db, &node);
1247
1248         return (result);
1249 }
1250
1251 /*%
1252  * Determine whether any NSEC3 records that were associated with
1253  * 'name' should be deleted or if they should continue to exist.
1254  * ISC_TRUE indicates they should be deleted.
1255  * ISC_FALSE indicates they should be retained.
1256  */
1257 static isc_result_t
1258 deleteit(dns_db_t *db, dns_dbversion_t *ver, dns_name_t *name,
1259          isc_boolean_t *yesno)
1260 {
1261         isc_result_t result;
1262         dns_fixedname_t foundname;
1263         dns_fixedname_init(&foundname);
1264
1265         result = dns_db_find(db, name, ver, dns_rdatatype_any,
1266                              DNS_DBFIND_GLUEOK | DNS_DBFIND_NOWILD,
1267                              (isc_stdtime_t) 0, NULL,
1268                              dns_fixedname_name(&foundname),
1269                              NULL, NULL);
1270         if (result == DNS_R_EMPTYNAME || result == ISC_R_SUCCESS ||
1271             result ==  DNS_R_ZONECUT) {
1272                 *yesno = ISC_FALSE;
1273                 return (ISC_R_SUCCESS);
1274         }
1275         if (result == DNS_R_GLUE || result == DNS_R_DNAME ||
1276             result == DNS_R_DELEGATION || result == DNS_R_NXDOMAIN) {
1277                 *yesno = ISC_TRUE;
1278                 return (ISC_R_SUCCESS);
1279         }
1280         /*
1281          * Silence compiler.
1282          */
1283         *yesno = ISC_TRUE;
1284         return (result);
1285 }
1286
1287 isc_result_t
1288 dns_nsec3_delnsec3(dns_db_t *db, dns_dbversion_t *version, dns_name_t *name,
1289                    const dns_rdata_nsec3param_t *nsec3param, dns_diff_t *diff)
1290 {
1291         dns_dbiterator_t *dbit = NULL;
1292         dns_dbnode_t *node = NULL;
1293         dns_difftuple_t *tuple = NULL;
1294         dns_fixedname_t fixed;
1295         dns_fixedname_t fprev;
1296         dns_hash_t hash;
1297         dns_name_t *hashname;
1298         dns_name_t *origin;
1299         dns_name_t *prev;
1300         dns_name_t empty;
1301         dns_rdata_nsec3_t nsec3;
1302         dns_rdata_t rdata = DNS_RDATA_INIT;
1303         dns_rdataset_t rdataset;
1304         int pass;
1305         isc_boolean_t yesno;
1306         isc_buffer_t buffer;
1307         isc_result_t result;
1308         unsigned char *salt;
1309         unsigned char nexthash[NSEC3_MAX_HASH_LENGTH];
1310         unsigned char nsec3buf[DNS_NSEC3_BUFFERSIZE];
1311         unsigned int iterations;
1312         unsigned int labels;
1313         size_t next_length;
1314         unsigned int salt_length;
1315
1316         dns_fixedname_init(&fixed);
1317         hashname = dns_fixedname_name(&fixed);
1318         dns_fixedname_init(&fprev);
1319         prev = dns_fixedname_name(&fprev);
1320
1321         dns_rdataset_init(&rdataset);
1322
1323         origin = dns_db_origin(db);
1324
1325         /*
1326          * Chain parameters.
1327          */
1328         hash = nsec3param->hash;
1329         iterations = nsec3param->iterations;
1330         salt_length = nsec3param->salt_length;
1331         salt = nsec3param->salt;
1332
1333         /*
1334          * If this is the first NSEC3 in the chain nexthash will
1335          * remain pointing to itself.
1336          */
1337         next_length = sizeof(nexthash);
1338         CHECK(dns_nsec3_hashname(&fixed, nexthash, &next_length,
1339                                  name, origin, hash, iterations,
1340                                  salt, salt_length));
1341
1342         CHECK(dns_db_createiterator(db, DNS_DB_NSEC3ONLY, &dbit));
1343
1344         result = dns_dbiterator_seek(dbit, hashname);
1345         if (result == ISC_R_NOTFOUND)
1346                 goto success;
1347         if (result != ISC_R_SUCCESS)
1348                 goto failure;
1349
1350         CHECK(dns_dbiterator_current(dbit, &node, NULL));
1351         CHECK(dns_dbiterator_pause(dbit));
1352         result = dns_db_findrdataset(db, node, version, dns_rdatatype_nsec3,
1353                                      0, (isc_stdtime_t) 0, &rdataset, NULL);
1354         dns_db_detachnode(db, &node);
1355         if (result == ISC_R_NOTFOUND)
1356                 goto success;
1357         if (result != ISC_R_SUCCESS)
1358                 goto failure;
1359
1360         /*
1361          * If we find a existing NSEC3 for this chain then save the
1362          * next field.
1363          */
1364         result = find_nsec3(&nsec3, &rdataset, nsec3param);
1365         if (result == ISC_R_SUCCESS) {
1366                 next_length = nsec3.next_length;
1367                 INSIST(next_length <= sizeof(nexthash));
1368                 memmove(nexthash, nsec3.next, next_length);
1369         }
1370         dns_rdataset_disassociate(&rdataset);
1371         if (result == ISC_R_NOMORE)
1372                 goto success;
1373         if (result != ISC_R_SUCCESS)
1374                 goto failure;
1375
1376         /*
1377          * Find the previous NSEC3 and update it.
1378          */
1379         pass = 0;
1380         do {
1381                 result = dns_dbiterator_prev(dbit);
1382                 if (result == ISC_R_NOMORE) {
1383                         pass++;
1384                         CHECK(dns_dbiterator_last(dbit));
1385                 }
1386                 CHECK(dns_dbiterator_current(dbit, &node, prev));
1387                 CHECK(dns_dbiterator_pause(dbit));
1388                 result = dns_db_findrdataset(db, node, version,
1389                                              dns_rdatatype_nsec3, 0,
1390                                              (isc_stdtime_t) 0, &rdataset,
1391                                              NULL);
1392                 dns_db_detachnode(db, &node);
1393                 if (result != ISC_R_SUCCESS)
1394                         continue;
1395                 result = find_nsec3(&nsec3, &rdataset, nsec3param);
1396                 if (result == ISC_R_NOMORE) {
1397                         dns_rdataset_disassociate(&rdataset);
1398                         continue;
1399                 }
1400                 if (result != ISC_R_SUCCESS)
1401                         goto failure;
1402
1403                 /*
1404                  * Delete the old previous NSEC3.
1405                  */
1406                 CHECK(delete(db, version, prev, nsec3param, diff));
1407
1408                 /*
1409                  * Fixup the previous NSEC3.
1410                  */
1411                 nsec3.next = nexthash;
1412                 nsec3.next_length = (unsigned char)next_length;
1413                 if (CREATE(nsec3param->flags))
1414                         nsec3.flags = nsec3param->flags & DNS_NSEC3FLAG_OPTOUT;
1415                 isc_buffer_init(&buffer, nsec3buf, sizeof(nsec3buf));
1416                 CHECK(dns_rdata_fromstruct(&rdata, rdataset.rdclass,
1417                                            dns_rdatatype_nsec3, &nsec3,
1418                                            &buffer));
1419                 CHECK(dns_difftuple_create(diff->mctx, DNS_DIFFOP_ADD, prev,
1420                                            rdataset.ttl, &rdata, &tuple));
1421                 CHECK(do_one_tuple(&tuple, db, version, diff));
1422                 dns_rdata_reset(&rdata);
1423                 dns_rdataset_disassociate(&rdataset);
1424                 break;
1425         } while (pass < 2);
1426
1427         /*
1428          * Delete the old NSEC3 and record the change.
1429          */
1430         CHECK(delete(db, version, hashname, nsec3param, diff));
1431
1432         /*
1433          *  Delete NSEC3 records for now non active nodes.
1434          */
1435         dns_name_init(&empty, NULL);
1436         dns_name_clone(name, &empty);
1437         do {
1438                 labels = dns_name_countlabels(&empty) - 1;
1439                 if (labels <= dns_name_countlabels(origin))
1440                         break;
1441                 dns_name_getlabelsequence(&empty, 1, labels, &empty);
1442                 CHECK(deleteit(db, version, &empty, &yesno));
1443                 if (!yesno)
1444                         break;
1445
1446                 CHECK(dns_nsec3_hashname(&fixed, nexthash, &next_length,
1447                                          &empty, origin, hash, iterations,
1448                                          salt, salt_length));
1449                 result = dns_dbiterator_seek(dbit, hashname);
1450                 if (result == ISC_R_NOTFOUND)
1451                         goto success;
1452                 if (result != ISC_R_SUCCESS)
1453                         goto failure;
1454
1455                 CHECK(dns_dbiterator_current(dbit, &node, NULL));
1456                 CHECK(dns_dbiterator_pause(dbit));
1457                 result = dns_db_findrdataset(db, node, version,
1458                                              dns_rdatatype_nsec3, 0,
1459                                              (isc_stdtime_t) 0, &rdataset,
1460                                              NULL);
1461                 dns_db_detachnode(db, &node);
1462                 if (result == ISC_R_NOTFOUND)
1463                         goto success;
1464                 if (result != ISC_R_SUCCESS)
1465                         goto failure;
1466
1467                 result = find_nsec3(&nsec3, &rdataset, nsec3param);
1468                 if (result == ISC_R_SUCCESS) {
1469                         next_length = nsec3.next_length;
1470                         INSIST(next_length <= sizeof(nexthash));
1471                         memmove(nexthash, nsec3.next, next_length);
1472                 }
1473                 dns_rdataset_disassociate(&rdataset);
1474                 if (result == ISC_R_NOMORE)
1475                         goto success;
1476                 if (result != ISC_R_SUCCESS)
1477                         goto failure;
1478
1479                 pass = 0;
1480                 do {
1481                         result = dns_dbiterator_prev(dbit);
1482                         if (result == ISC_R_NOMORE) {
1483                                 pass++;
1484                                 CHECK(dns_dbiterator_last(dbit));
1485                         }
1486                         CHECK(dns_dbiterator_current(dbit, &node, prev));
1487                         CHECK(dns_dbiterator_pause(dbit));
1488                         result = dns_db_findrdataset(db, node, version,
1489                                                      dns_rdatatype_nsec3, 0,
1490                                                      (isc_stdtime_t) 0,
1491                                                      &rdataset, NULL);
1492                         dns_db_detachnode(db, &node);
1493                         if (result != ISC_R_SUCCESS)
1494                                 continue;
1495                         result = find_nsec3(&nsec3, &rdataset, nsec3param);
1496                         if (result == ISC_R_NOMORE) {
1497                                 dns_rdataset_disassociate(&rdataset);
1498                                 continue;
1499                         }
1500                         if (result != ISC_R_SUCCESS)
1501                                 goto failure;
1502
1503                         /*
1504                          * Delete the old previous NSEC3.
1505                          */
1506                         CHECK(delete(db, version, prev, nsec3param, diff));
1507
1508                         /*
1509                          * Fixup the previous NSEC3.
1510                          */
1511                         nsec3.next = nexthash;
1512                         nsec3.next_length = (unsigned char)next_length;
1513                         isc_buffer_init(&buffer, nsec3buf,
1514                                         sizeof(nsec3buf));
1515                         CHECK(dns_rdata_fromstruct(&rdata, rdataset.rdclass,
1516                                                    dns_rdatatype_nsec3, &nsec3,
1517                                                    &buffer));
1518                         CHECK(dns_difftuple_create(diff->mctx, DNS_DIFFOP_ADD,
1519                                                    prev, rdataset.ttl, &rdata,
1520                                                    &tuple));
1521                         CHECK(do_one_tuple(&tuple, db, version, diff));
1522                         dns_rdata_reset(&rdata);
1523                         dns_rdataset_disassociate(&rdataset);
1524                         break;
1525                 } while (pass < 2);
1526
1527                 INSIST(pass < 2);
1528
1529                 /*
1530                  * Delete the old NSEC3 and record the change.
1531                  */
1532                 CHECK(delete(db, version, hashname, nsec3param, diff));
1533         } while (1);
1534
1535  success:
1536         result = ISC_R_SUCCESS;
1537
1538  failure:
1539         if (dbit != NULL)
1540                 dns_dbiterator_destroy(&dbit);
1541         if (dns_rdataset_isassociated(&rdataset))
1542                 dns_rdataset_disassociate(&rdataset);
1543         if (node != NULL)
1544                 dns_db_detachnode(db, &node);
1545         return (result);
1546 }
1547
1548 isc_result_t
1549 dns_nsec3_delnsec3s(dns_db_t *db, dns_dbversion_t *version, dns_name_t *name,
1550                     dns_diff_t *diff)
1551 {
1552         return (dns_nsec3_delnsec3sx(db, version, name, 0, diff));
1553 }
1554
1555 isc_result_t
1556 dns_nsec3_delnsec3sx(dns_db_t *db, dns_dbversion_t *version, dns_name_t *name,
1557                      dns_rdatatype_t privatetype, dns_diff_t *diff)
1558 {
1559         dns_dbnode_t *node = NULL;
1560         dns_rdata_nsec3param_t nsec3param;
1561         dns_rdataset_t rdataset;
1562         isc_result_t result;
1563
1564         dns_rdataset_init(&rdataset);
1565
1566         /*
1567          * Find the NSEC3 parameters for this zone.
1568          */
1569         result = dns_db_getoriginnode(db, &node);
1570         if (result != ISC_R_SUCCESS)
1571                 return (result);
1572
1573         result = dns_db_findrdataset(db, node, version,
1574                                      dns_rdatatype_nsec3param, 0, 0,
1575                                      &rdataset, NULL);
1576         if (result == ISC_R_NOTFOUND)
1577                 goto try_private;
1578         if (result != ISC_R_SUCCESS)
1579                 goto failure;
1580
1581         /*
1582          * Update each active NSEC3 chain.
1583          */
1584         for (result = dns_rdataset_first(&rdataset);
1585              result == ISC_R_SUCCESS;
1586              result = dns_rdataset_next(&rdataset)) {
1587                 dns_rdata_t rdata = DNS_RDATA_INIT;
1588
1589                 dns_rdataset_current(&rdataset, &rdata);
1590                 CHECK(dns_rdata_tostruct(&rdata, &nsec3param, NULL));
1591
1592                 if (nsec3param.flags != 0)
1593                         continue;
1594                 /*
1595                  * We have a active chain.  Update it.
1596                  */
1597                 CHECK(dns_nsec3_delnsec3(db, version, name, &nsec3param, diff));
1598         }
1599         dns_rdataset_disassociate(&rdataset);
1600
1601  try_private:
1602         if (privatetype == 0)
1603                 goto success;
1604         result = dns_db_findrdataset(db, node, version, privatetype, 0, 0,
1605                                      &rdataset, NULL);
1606         if (result == ISC_R_NOTFOUND)
1607                 goto success;
1608         if (result != ISC_R_SUCCESS)
1609                 goto failure;
1610
1611         /*
1612          * Update each NSEC3 chain being built.
1613          */
1614         for (result = dns_rdataset_first(&rdataset);
1615              result == ISC_R_SUCCESS;
1616              result = dns_rdataset_next(&rdataset)) {
1617                 dns_rdata_t rdata1 = DNS_RDATA_INIT;
1618                 dns_rdata_t rdata2 = DNS_RDATA_INIT;
1619                 unsigned char buf[DNS_NSEC3PARAM_BUFFERSIZE];
1620
1621                 dns_rdataset_current(&rdataset, &rdata1);
1622                 if (!dns_nsec3param_fromprivate(&rdata1,  &rdata2,
1623                                                 buf, sizeof(buf)))
1624                         continue;
1625                 CHECK(dns_rdata_tostruct(&rdata2, &nsec3param, NULL));
1626
1627                 if ((nsec3param.flags & DNS_NSEC3FLAG_REMOVE) != 0)
1628                         continue;
1629                 if (better_param(&rdataset, &rdata2))
1630                         continue;
1631
1632                 /*
1633                  * We have a active chain.  Update it.
1634                  */
1635                 CHECK(dns_nsec3_delnsec3(db, version, name, &nsec3param, diff));
1636         }
1637         if (result == ISC_R_NOMORE)
1638  success:
1639                 result = ISC_R_SUCCESS;
1640
1641  failure:
1642         if (dns_rdataset_isassociated(&rdataset))
1643                 dns_rdataset_disassociate(&rdataset);
1644         if (node != NULL)
1645                 dns_db_detachnode(db, &node);
1646
1647         return (result);
1648 }
1649
1650 isc_result_t
1651 dns_nsec3_active(dns_db_t *db, dns_dbversion_t *version,
1652                  isc_boolean_t complete, isc_boolean_t *answer)
1653 {
1654         return (dns_nsec3_activex(db, version, complete, 0, answer));
1655 }
1656
1657 isc_result_t
1658 dns_nsec3_activex(dns_db_t *db, dns_dbversion_t *version,
1659                   isc_boolean_t complete, dns_rdatatype_t privatetype,
1660                   isc_boolean_t *answer)
1661 {
1662         dns_dbnode_t *node = NULL;
1663         dns_rdataset_t rdataset;
1664         dns_rdata_nsec3param_t nsec3param;
1665         isc_result_t result;
1666
1667         REQUIRE(answer != NULL);
1668
1669         dns_rdataset_init(&rdataset);
1670
1671         result = dns_db_getoriginnode(db, &node);
1672         if (result != ISC_R_SUCCESS)
1673                 return (result);
1674
1675         result = dns_db_findrdataset(db, node, version,
1676                                      dns_rdatatype_nsec3param, 0, 0,
1677                                      &rdataset, NULL);
1678
1679         if (result == ISC_R_NOTFOUND)
1680                 goto try_private;
1681
1682         if (result != ISC_R_SUCCESS) {
1683                 dns_db_detachnode(db, &node);
1684                 return (result);
1685         }
1686         for (result = dns_rdataset_first(&rdataset);
1687              result == ISC_R_SUCCESS;
1688              result = dns_rdataset_next(&rdataset)) {
1689                 dns_rdata_t rdata = DNS_RDATA_INIT;
1690
1691                 dns_rdataset_current(&rdataset, &rdata);
1692                 result = dns_rdata_tostruct(&rdata, &nsec3param, NULL);
1693                 RUNTIME_CHECK(result == ISC_R_SUCCESS);
1694
1695                 if (nsec3param.flags == 0)
1696                         break;
1697         }
1698         dns_rdataset_disassociate(&rdataset);
1699         if (result == ISC_R_SUCCESS) {
1700                 dns_db_detachnode(db, &node);
1701                 *answer = ISC_TRUE;
1702                 return (ISC_R_SUCCESS);
1703         }
1704         if (result == ISC_R_NOMORE)
1705                 *answer = ISC_FALSE;
1706
1707  try_private:
1708         if (privatetype == 0 || complete) {
1709                 *answer = ISC_FALSE;
1710                 return (ISC_R_SUCCESS);
1711         }
1712         result = dns_db_findrdataset(db, node, version, privatetype, 0, 0,
1713                                      &rdataset, NULL);
1714
1715         dns_db_detachnode(db, &node);
1716         if (result == ISC_R_NOTFOUND) {
1717                 *answer = ISC_FALSE;
1718                 return (ISC_R_SUCCESS);
1719         }
1720         if (result != ISC_R_SUCCESS)
1721                 return (result);
1722
1723         for (result = dns_rdataset_first(&rdataset);
1724              result == ISC_R_SUCCESS;
1725              result = dns_rdataset_next(&rdataset)) {
1726                 dns_rdata_t rdata1 = DNS_RDATA_INIT;
1727                 dns_rdata_t rdata2 = DNS_RDATA_INIT;
1728                 unsigned char buf[DNS_NSEC3PARAM_BUFFERSIZE];
1729
1730                 dns_rdataset_current(&rdataset, &rdata1);
1731                 if (!dns_nsec3param_fromprivate(&rdata1, &rdata2,
1732                                                 buf, sizeof(buf)))
1733                         continue;
1734                 result = dns_rdata_tostruct(&rdata2, &nsec3param, NULL);
1735                 RUNTIME_CHECK(result == ISC_R_SUCCESS);
1736
1737                 if (!complete && CREATE(nsec3param.flags))
1738                         break;
1739         }
1740         dns_rdataset_disassociate(&rdataset);
1741         if (result == ISC_R_SUCCESS) {
1742                 *answer = ISC_TRUE;
1743                 result = ISC_R_SUCCESS;
1744         }
1745         if (result == ISC_R_NOMORE) {
1746                 *answer = ISC_FALSE;
1747                 result = ISC_R_SUCCESS;
1748         }
1749
1750         return (result);
1751 }
1752
1753 isc_result_t
1754 dns_nsec3_maxiterations(dns_db_t *db, dns_dbversion_t *version,
1755                         isc_mem_t *mctx, unsigned int *iterationsp)
1756 {
1757         dns_dbnode_t *node = NULL;
1758         dns_rdataset_t rdataset;
1759         dst_key_t *key = NULL;
1760         isc_buffer_t buffer;
1761         isc_result_t result;
1762         unsigned int bits, minbits = 4096;
1763
1764         result = dns_db_getoriginnode(db, &node);
1765         if (result != ISC_R_SUCCESS)
1766                 return (result);
1767
1768         dns_rdataset_init(&rdataset);
1769         result = dns_db_findrdataset(db, node, version, dns_rdatatype_dnskey,
1770                                      0, 0, &rdataset, NULL);
1771         dns_db_detachnode(db, &node);
1772         if (result == ISC_R_NOTFOUND) {
1773                 *iterationsp = 0;
1774                 return (ISC_R_SUCCESS);
1775         }
1776         if (result != ISC_R_SUCCESS)
1777                 goto failure;
1778
1779         for (result = dns_rdataset_first(&rdataset);
1780              result == ISC_R_SUCCESS;
1781              result = dns_rdataset_next(&rdataset)) {
1782                 dns_rdata_t rdata = DNS_RDATA_INIT;
1783
1784                 dns_rdataset_current(&rdataset, &rdata);
1785                 isc_buffer_init(&buffer, rdata.data, rdata.length);
1786                 isc_buffer_add(&buffer, rdata.length);
1787                 CHECK(dst_key_fromdns(dns_db_origin(db), rdataset.rdclass,
1788                                       &buffer, mctx, &key));
1789                 bits = dst_key_size(key);
1790                 dst_key_free(&key);
1791                 if (minbits > bits)
1792                         minbits = bits;
1793         }
1794         if (result != ISC_R_NOMORE)
1795                 goto failure;
1796
1797         if (minbits <= 1024)
1798                 *iterationsp = 150;
1799         else if (minbits <= 2048)
1800                 *iterationsp = 500;
1801         else
1802                 *iterationsp = 2500;
1803         result = ISC_R_SUCCESS;
1804
1805  failure:
1806         if (dns_rdataset_isassociated(&rdataset))
1807                 dns_rdataset_disassociate(&rdataset);
1808         return (result);
1809 }
1810
1811 isc_result_t
1812 dns_nsec3_noexistnodata(dns_rdatatype_t type, dns_name_t* name,
1813                         dns_name_t *nsec3name, dns_rdataset_t *nsec3set,
1814                         dns_name_t *zonename, isc_boolean_t *exists,
1815                         isc_boolean_t *data, isc_boolean_t *optout,
1816                         isc_boolean_t *unknown, isc_boolean_t *setclosest,
1817                         isc_boolean_t *setnearest, dns_name_t *closest,
1818                         dns_name_t *nearest, dns_nseclog_t logit, void *arg)
1819 {
1820         char namebuf[DNS_NAME_FORMATSIZE];
1821         dns_fixedname_t fzone;
1822         dns_fixedname_t qfixed;
1823         dns_label_t hashlabel;
1824         dns_name_t *qname;
1825         dns_name_t *zone;
1826         dns_rdata_nsec3_t nsec3;
1827         dns_rdata_t rdata = DNS_RDATA_INIT;
1828         int order;
1829         int scope;
1830         isc_boolean_t atparent;
1831         isc_boolean_t first;
1832         isc_boolean_t ns;
1833         isc_boolean_t soa;
1834         isc_buffer_t buffer;
1835         isc_result_t answer = ISC_R_IGNORE;
1836         isc_result_t result;
1837         unsigned char hash[NSEC3_MAX_HASH_LENGTH];
1838         unsigned char owner[NSEC3_MAX_HASH_LENGTH];
1839         unsigned int length;
1840         unsigned int qlabels;
1841         unsigned int zlabels;
1842
1843         REQUIRE((exists == NULL && data == NULL) ||
1844                 (exists != NULL && data != NULL));
1845         REQUIRE(nsec3set != NULL && nsec3set->type == dns_rdatatype_nsec3);
1846         REQUIRE((setclosest == NULL && closest == NULL) ||
1847                 (setclosest != NULL && closest != NULL));
1848         REQUIRE((setnearest == NULL && nearest == NULL) ||
1849                 (setnearest != NULL && nearest != NULL));
1850
1851         result = dns_rdataset_first(nsec3set);
1852         if (result != ISC_R_SUCCESS) {
1853                 (*logit)(arg, ISC_LOG_DEBUG(3), "failure processing NSEC3 set");
1854                 return (result);
1855         }
1856
1857         dns_rdataset_current(nsec3set, &rdata);
1858
1859         result = dns_rdata_tostruct(&rdata, &nsec3, NULL);
1860         if (result != ISC_R_SUCCESS)
1861                 return (result);
1862
1863         (*logit)(arg, ISC_LOG_DEBUG(3), "looking for relevant NSEC3");
1864
1865         dns_fixedname_init(&fzone);
1866         zone = dns_fixedname_name(&fzone);
1867         zlabels = dns_name_countlabels(nsec3name);
1868
1869         /*
1870          * NSEC3 records must have two or more labels to be valid.
1871          */
1872         if (zlabels < 2)
1873                 return (ISC_R_IGNORE);
1874
1875         /*
1876          * Strip off the NSEC3 hash to get the zone.
1877          */
1878         zlabels--;
1879         dns_name_split(nsec3name, zlabels, NULL, zone);
1880
1881         /*
1882          * If not below the zone name we can ignore this record.
1883          */
1884         if (!dns_name_issubdomain(name, zone))
1885                 return (ISC_R_IGNORE);
1886
1887         /*
1888          * Is this zone the same or deeper than the current zone?
1889          */
1890         if (dns_name_countlabels(zonename) == 0 ||
1891             dns_name_issubdomain(zone, zonename))
1892                 dns_name_copy(zone, zonename, NULL);
1893
1894         if (!dns_name_equal(zone, zonename))
1895                 return (ISC_R_IGNORE);
1896
1897         /*
1898          * Are we only looking for the most enclosing zone?
1899          */
1900         if (exists == NULL || data == NULL)
1901                 return (ISC_R_SUCCESS);
1902
1903         /*
1904          * Only set unknown once we are sure that this NSEC3 is from
1905          * the deepest covering zone.
1906          */
1907         if (!dns_nsec3_supportedhash(nsec3.hash)) {
1908                 if (unknown != NULL)
1909                         *unknown = ISC_TRUE;
1910                 return (ISC_R_IGNORE);
1911         }
1912
1913         /*
1914          * Recover the hash from the first label.
1915          */
1916         dns_name_getlabel(nsec3name, 0, &hashlabel);
1917         isc_region_consume(&hashlabel, 1);
1918         isc_buffer_init(&buffer, owner, sizeof(owner));
1919         result = isc_base32hex_decoderegion(&hashlabel, &buffer);
1920         if (result != ISC_R_SUCCESS)
1921                 return (result);
1922
1923         /*
1924          * The hash lengths should match.  If not ignore the record.
1925          */
1926         if (isc_buffer_usedlength(&buffer) != nsec3.next_length)
1927                 return (ISC_R_IGNORE);
1928
1929         /*
1930          * Work out what this NSEC3 covers.
1931          * Inside (<0) or outside (>=0).
1932          */
1933         scope = isc_safe_memcompare(owner, nsec3.next, nsec3.next_length);
1934
1935         /*
1936          * Prepare to compute all the hashes.
1937          */
1938         dns_fixedname_init(&qfixed);
1939         qname = dns_fixedname_name(&qfixed);
1940         dns_name_downcase(name, qname, NULL);
1941         qlabels = dns_name_countlabels(qname);
1942         first = ISC_TRUE;
1943
1944         while (qlabels >= zlabels) {
1945                 length = isc_iterated_hash(hash, nsec3.hash, nsec3.iterations,
1946                                            nsec3.salt, nsec3.salt_length,
1947                                            qname->ndata, qname->length);
1948                 /*
1949                  * The computed hash length should match.
1950                  */
1951                 if (length != nsec3.next_length) {
1952                         (*logit)(arg, ISC_LOG_DEBUG(3),
1953                                  "ignoring NSEC bad length %u vs %u",
1954                                  length, nsec3.next_length);
1955                         return (ISC_R_IGNORE);
1956                 }
1957
1958                 order = isc_safe_memcompare(hash, owner, length);
1959                 if (first && order == 0) {
1960                         /*
1961                          * The hashes are the same.
1962                          */
1963                         atparent = dns_rdatatype_atparent(type);
1964                         ns = dns_nsec3_typepresent(&rdata, dns_rdatatype_ns);
1965                         soa = dns_nsec3_typepresent(&rdata, dns_rdatatype_soa);
1966                         if (ns && !soa) {
1967                                 if (!atparent) {
1968                                         /*
1969                                          * This NSEC3 record is from somewhere
1970                                          * higher in the DNS, and at the
1971                                          * parent of a delegation. It can not
1972                                          * be legitimately used here.
1973                                          */
1974                                         (*logit)(arg, ISC_LOG_DEBUG(3),
1975                                                  "ignoring parent NSEC3");
1976                                         return (ISC_R_IGNORE);
1977                                 }
1978                         } else if (atparent && ns && soa) {
1979                                 /*
1980                                  * This NSEC3 record is from the child.
1981                                  * It can not be legitimately used here.
1982                                  */
1983                                 (*logit)(arg, ISC_LOG_DEBUG(3),
1984                                          "ignoring child NSEC3");
1985                                 return (ISC_R_IGNORE);
1986                         }
1987                         if (type == dns_rdatatype_cname ||
1988                             type == dns_rdatatype_nxt ||
1989                             type == dns_rdatatype_nsec ||
1990                             type == dns_rdatatype_key ||
1991                             !dns_nsec3_typepresent(&rdata, dns_rdatatype_cname)) {
1992                                 *exists = ISC_TRUE;
1993                                 *data = dns_nsec3_typepresent(&rdata, type);
1994                                 (*logit)(arg, ISC_LOG_DEBUG(3),
1995                                          "NSEC3 proves name exists (owner) "
1996                                          "data=%d", *data);
1997                                 return (ISC_R_SUCCESS);
1998                         }
1999                         (*logit)(arg, ISC_LOG_DEBUG(3),
2000                                  "NSEC3 proves CNAME exists");
2001                         return (ISC_R_IGNORE);
2002                 }
2003
2004                 if (order == 0 &&
2005                     dns_nsec3_typepresent(&rdata, dns_rdatatype_ns) &&
2006                     !dns_nsec3_typepresent(&rdata, dns_rdatatype_soa))
2007                 {
2008                         /*
2009                          * This NSEC3 record is from somewhere higher in
2010                          * the DNS, and at the parent of a delegation.
2011                          * It can not be legitimately used here.
2012                          */
2013                         (*logit)(arg, ISC_LOG_DEBUG(3),
2014                                  "ignoring parent NSEC3");
2015                         return (ISC_R_IGNORE);
2016                 }
2017
2018                 /*
2019                  * Potential closest encloser.
2020                  */
2021                 if (order == 0) {
2022                         if (closest != NULL &&
2023                             (dns_name_countlabels(closest) == 0 ||
2024                              dns_name_issubdomain(qname, closest)) &&
2025                             !dns_nsec3_typepresent(&rdata, dns_rdatatype_ds) &&
2026                             !dns_nsec3_typepresent(&rdata, dns_rdatatype_dname) &&
2027                             (dns_nsec3_typepresent(&rdata, dns_rdatatype_soa) ||
2028                              !dns_nsec3_typepresent(&rdata, dns_rdatatype_ns)))
2029                         {
2030
2031                                 dns_name_format(qname, namebuf,
2032                                                 sizeof(namebuf));
2033                                 (*logit)(arg, ISC_LOG_DEBUG(3),
2034                                          "NSEC3 indicates potential closest "
2035                                          "encloser: '%s'", namebuf);
2036                                 dns_name_copy(qname, closest, NULL);
2037                                 *setclosest = ISC_TRUE;
2038                         }
2039                         dns_name_format(qname, namebuf, sizeof(namebuf));
2040                         (*logit)(arg, ISC_LOG_DEBUG(3),
2041                                  "NSEC3 at super-domain %s", namebuf);
2042                         return (answer);
2043                 }
2044
2045                 /*
2046                  * Find if the name does not exist.
2047                  *
2048                  * We continue as we need to find the name closest to the
2049                  * closest encloser that doesn't exist.
2050                  *
2051                  * We also need to continue to ensure that we are not
2052                  * proving the non-existence of a record in a sub-zone.
2053                  * If that would be the case we will return ISC_R_IGNORE
2054                  * above.
2055                  */
2056                 if ((scope < 0 && order > 0 &&
2057                      memcmp(hash, nsec3.next, length) < 0) ||
2058                     (scope >= 0 && (order > 0 ||
2059                                     memcmp(hash, nsec3.next, length) < 0)))
2060                 {
2061                         dns_name_format(qname, namebuf, sizeof(namebuf));
2062                         (*logit)(arg, ISC_LOG_DEBUG(3), "NSEC3 proves "
2063                                  "name does not exist: '%s'", namebuf);
2064                         if (nearest != NULL &&
2065                             (dns_name_countlabels(nearest) == 0 ||
2066                              dns_name_issubdomain(nearest, qname))) {
2067                                 dns_name_copy(qname, nearest, NULL);
2068                                 *setnearest = ISC_TRUE;
2069                         }
2070
2071                         *exists = ISC_FALSE;
2072                         *data = ISC_FALSE;
2073                         if (optout != NULL) {
2074                                 if ((nsec3.flags & DNS_NSEC3FLAG_OPTOUT) != 0)
2075                                         (*logit)(arg, ISC_LOG_DEBUG(3),
2076                                                  "NSEC3 indicates optout");
2077                                 else
2078                                         (*logit)(arg, ISC_LOG_DEBUG(3),
2079                                                  "NSEC3 indicates secure range");
2080                                 *optout =
2081                                     ISC_TF(nsec3.flags & DNS_NSEC3FLAG_OPTOUT);
2082                         }
2083                         answer = ISC_R_SUCCESS;
2084                 }
2085
2086                 qlabels--;
2087                 if (qlabels > 0)
2088                         dns_name_split(qname, qlabels, NULL, qname);
2089                 first = ISC_FALSE;
2090         }
2091         return (answer);
2092 }