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