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