nsec.c revision 0cfbb9285a96f1355e5a3bd458624eaed2f16846
5619558151f1aa4249b3ead979e76876e29278b6Bob Halley/*
5619558151f1aa4249b3ead979e76876e29278b6Bob Halley * Copyright (C) 2004, 2005, 2007-2009 Internet Systems Consortium, Inc. ("ISC")
5619558151f1aa4249b3ead979e76876e29278b6Bob Halley * Copyright (C) 1999-2001, 2003 Internet Software Consortium.
5619558151f1aa4249b3ead979e76876e29278b6Bob Halley *
5619558151f1aa4249b3ead979e76876e29278b6Bob Halley * Permission to use, copy, modify, and/or distribute this software for any
5619558151f1aa4249b3ead979e76876e29278b6Bob Halley * purpose with or without fee is hereby granted, provided that the above
5619558151f1aa4249b3ead979e76876e29278b6Bob Halley * copyright notice and this permission notice appear in all copies.
5619558151f1aa4249b3ead979e76876e29278b6Bob Halley *
5619558151f1aa4249b3ead979e76876e29278b6Bob Halley * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
5619558151f1aa4249b3ead979e76876e29278b6Bob Halley * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
5619558151f1aa4249b3ead979e76876e29278b6Bob Halley * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
5619558151f1aa4249b3ead979e76876e29278b6Bob Halley * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
5619558151f1aa4249b3ead979e76876e29278b6Bob Halley * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
5619558151f1aa4249b3ead979e76876e29278b6Bob Halley * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
5619558151f1aa4249b3ead979e76876e29278b6Bob Halley * PERFORMANCE OF THIS SOFTWARE.
5619558151f1aa4249b3ead979e76876e29278b6Bob Halley */
5619558151f1aa4249b3ead979e76876e29278b6Bob Halley
110d1702731f42dd620879c1d765ebe91f3920ceMichael Graff/* $Id: nsec.c,v 1.13 2009/01/06 23:47:57 tbox Exp $ */
110d1702731f42dd620879c1d765ebe91f3920ceMichael Graff
5619558151f1aa4249b3ead979e76876e29278b6Bob Halley/*! \file */
54f959d12b5a1f9315fbf6a776c6d349316e9686Bob Halley
5619558151f1aa4249b3ead979e76876e29278b6Bob Halley#include <config.h>
5619558151f1aa4249b3ead979e76876e29278b6Bob Halley
5619558151f1aa4249b3ead979e76876e29278b6Bob Halley#include <isc/string.h>
54f959d12b5a1f9315fbf6a776c6d349316e9686Bob Halley#include <isc/util.h>
0d0d9a9d9895605aba3a44fd03c051e15f88ecf5Bob Halley
0d0d9a9d9895605aba3a44fd03c051e15f88ecf5Bob Halley#include <dns/db.h>
5619558151f1aa4249b3ead979e76876e29278b6Bob Halley#include <dns/nsec.h>
5619558151f1aa4249b3ead979e76876e29278b6Bob Halley#include <dns/rdata.h>
5619558151f1aa4249b3ead979e76876e29278b6Bob Halley#include <dns/rdatalist.h>
5619558151f1aa4249b3ead979e76876e29278b6Bob Halley#include <dns/rdataset.h>
5619558151f1aa4249b3ead979e76876e29278b6Bob Halley#include <dns/rdatasetiter.h>
5619558151f1aa4249b3ead979e76876e29278b6Bob Halley#include <dns/rdatastruct.h>
5619558151f1aa4249b3ead979e76876e29278b6Bob Halley#include <dns/result.h>
5619558151f1aa4249b3ead979e76876e29278b6Bob Halley
5619558151f1aa4249b3ead979e76876e29278b6Bob Halley#include <dst/dst.h>
5619558151f1aa4249b3ead979e76876e29278b6Bob Halley
5619558151f1aa4249b3ead979e76876e29278b6Bob Halley#define RETERR(x) do { \
078d49b63324f01d98301ee21671abee0c41fcdeBob Halley result = (x); \
5619558151f1aa4249b3ead979e76876e29278b6Bob Halley if (result != ISC_R_SUCCESS) \
5619558151f1aa4249b3ead979e76876e29278b6Bob Halley goto failure; \
5619558151f1aa4249b3ead979e76876e29278b6Bob Halley } while (0)
5619558151f1aa4249b3ead979e76876e29278b6Bob Halley
5619558151f1aa4249b3ead979e76876e29278b6Bob Halleystatic void
5619558151f1aa4249b3ead979e76876e29278b6Bob Halleyset_bit(unsigned char *array, unsigned int index, unsigned int bit) {
5619558151f1aa4249b3ead979e76876e29278b6Bob Halley unsigned int shift, mask;
5619558151f1aa4249b3ead979e76876e29278b6Bob Halley
5619558151f1aa4249b3ead979e76876e29278b6Bob Halley shift = 7 - (index % 8);
5619558151f1aa4249b3ead979e76876e29278b6Bob Halley mask = 1 << shift;
5619558151f1aa4249b3ead979e76876e29278b6Bob Halley
5619558151f1aa4249b3ead979e76876e29278b6Bob Halley if (bit != 0)
5619558151f1aa4249b3ead979e76876e29278b6Bob Halley array[index / 8] |= mask;
5619558151f1aa4249b3ead979e76876e29278b6Bob Halley else
5619558151f1aa4249b3ead979e76876e29278b6Bob Halley array[index / 8] &= (~mask & 0xFF);
5619558151f1aa4249b3ead979e76876e29278b6Bob Halley}
5619558151f1aa4249b3ead979e76876e29278b6Bob Halley
078d49b63324f01d98301ee21671abee0c41fcdeBob Halleystatic unsigned int
5619558151f1aa4249b3ead979e76876e29278b6Bob Halleybit_isset(unsigned char *array, unsigned int index) {
5619558151f1aa4249b3ead979e76876e29278b6Bob Halley unsigned int byte, shift, mask;
5619558151f1aa4249b3ead979e76876e29278b6Bob Halley
5619558151f1aa4249b3ead979e76876e29278b6Bob Halley byte = array[index / 8];
5619558151f1aa4249b3ead979e76876e29278b6Bob Halley shift = 7 - (index % 8);
5619558151f1aa4249b3ead979e76876e29278b6Bob Halley mask = 1 << shift;
5619558151f1aa4249b3ead979e76876e29278b6Bob Halley
5619558151f1aa4249b3ead979e76876e29278b6Bob Halley return ((byte & mask) != 0);
5619558151f1aa4249b3ead979e76876e29278b6Bob Halley}
5619558151f1aa4249b3ead979e76876e29278b6Bob Halley
5619558151f1aa4249b3ead979e76876e29278b6Bob Halleyisc_result_t
5619558151f1aa4249b3ead979e76876e29278b6Bob Halleydns_nsec_buildrdata(dns_db_t *db, dns_dbversion_t *version,
5619558151f1aa4249b3ead979e76876e29278b6Bob Halley dns_dbnode_t *node, dns_name_t *target,
5619558151f1aa4249b3ead979e76876e29278b6Bob Halley unsigned char *buffer, dns_rdata_t *rdata)
5619558151f1aa4249b3ead979e76876e29278b6Bob Halley{
5619558151f1aa4249b3ead979e76876e29278b6Bob Halley isc_result_t result;
5619558151f1aa4249b3ead979e76876e29278b6Bob Halley dns_rdataset_t rdataset;
5619558151f1aa4249b3ead979e76876e29278b6Bob Halley isc_region_t r;
5619558151f1aa4249b3ead979e76876e29278b6Bob Halley unsigned int i, window;
078d49b63324f01d98301ee21671abee0c41fcdeBob Halley int octet;
5619558151f1aa4249b3ead979e76876e29278b6Bob Halley
5619558151f1aa4249b3ead979e76876e29278b6Bob Halley unsigned char *nsec_bits, *bm;
5619558151f1aa4249b3ead979e76876e29278b6Bob Halley unsigned int max_type;
5619558151f1aa4249b3ead979e76876e29278b6Bob Halley dns_rdatasetiter_t *rdsiter;
5619558151f1aa4249b3ead979e76876e29278b6Bob Halley
5619558151f1aa4249b3ead979e76876e29278b6Bob Halley memset(buffer, 0, DNS_NSEC_BUFFERSIZE);
5619558151f1aa4249b3ead979e76876e29278b6Bob Halley dns_name_toregion(target, &r);
5619558151f1aa4249b3ead979e76876e29278b6Bob Halley memcpy(buffer, r.base, r.length);
5619558151f1aa4249b3ead979e76876e29278b6Bob Halley r.base = buffer;
5619558151f1aa4249b3ead979e76876e29278b6Bob Halley /*
5619558151f1aa4249b3ead979e76876e29278b6Bob Halley * Use the end of the space for a raw bitmap leaving enough
5619558151f1aa4249b3ead979e76876e29278b6Bob Halley * space for the window identifiers and length octets.
5619558151f1aa4249b3ead979e76876e29278b6Bob Halley */
5619558151f1aa4249b3ead979e76876e29278b6Bob Halley bm = r.base + r.length + 512;
5619558151f1aa4249b3ead979e76876e29278b6Bob Halley nsec_bits = r.base + r.length;
5619558151f1aa4249b3ead979e76876e29278b6Bob Halley set_bit(bm, dns_rdatatype_rrsig, 1);
5619558151f1aa4249b3ead979e76876e29278b6Bob Halley set_bit(bm, dns_rdatatype_nsec, 1);
5619558151f1aa4249b3ead979e76876e29278b6Bob Halley max_type = dns_rdatatype_nsec;
5619558151f1aa4249b3ead979e76876e29278b6Bob Halley dns_rdataset_init(&rdataset);
078d49b63324f01d98301ee21671abee0c41fcdeBob Halley rdsiter = NULL;
5619558151f1aa4249b3ead979e76876e29278b6Bob Halley result = dns_db_allrdatasets(db, node, version, 0, &rdsiter);
5619558151f1aa4249b3ead979e76876e29278b6Bob Halley if (result != ISC_R_SUCCESS)
5619558151f1aa4249b3ead979e76876e29278b6Bob Halley return (result);
5619558151f1aa4249b3ead979e76876e29278b6Bob Halley for (result = dns_rdatasetiter_first(rdsiter);
5619558151f1aa4249b3ead979e76876e29278b6Bob Halley result == ISC_R_SUCCESS;
5619558151f1aa4249b3ead979e76876e29278b6Bob Halley result = dns_rdatasetiter_next(rdsiter))
5619558151f1aa4249b3ead979e76876e29278b6Bob Halley {
5619558151f1aa4249b3ead979e76876e29278b6Bob Halley dns_rdatasetiter_current(rdsiter, &rdataset);
5619558151f1aa4249b3ead979e76876e29278b6Bob Halley if (rdataset.type != dns_rdatatype_nsec &&
5619558151f1aa4249b3ead979e76876e29278b6Bob Halley rdataset.type != dns_rdatatype_nsec3 &&
5619558151f1aa4249b3ead979e76876e29278b6Bob Halley rdataset.type != dns_rdatatype_rrsig) {
078d49b63324f01d98301ee21671abee0c41fcdeBob Halley if (rdataset.type > max_type)
5619558151f1aa4249b3ead979e76876e29278b6Bob Halley max_type = rdataset.type;
5619558151f1aa4249b3ead979e76876e29278b6Bob Halley set_bit(bm, rdataset.type, 1);
5619558151f1aa4249b3ead979e76876e29278b6Bob Halley }
5619558151f1aa4249b3ead979e76876e29278b6Bob Halley dns_rdataset_disassociate(&rdataset);
5619558151f1aa4249b3ead979e76876e29278b6Bob Halley }
5619558151f1aa4249b3ead979e76876e29278b6Bob Halley
5619558151f1aa4249b3ead979e76876e29278b6Bob Halley /*
5619558151f1aa4249b3ead979e76876e29278b6Bob Halley * At zone cuts, deny the existence of glue in the parent zone.
5619558151f1aa4249b3ead979e76876e29278b6Bob Halley */
5619558151f1aa4249b3ead979e76876e29278b6Bob Halley if (bit_isset(bm, dns_rdatatype_ns) &&
5619558151f1aa4249b3ead979e76876e29278b6Bob Halley ! bit_isset(bm, dns_rdatatype_soa)) {
078d49b63324f01d98301ee21671abee0c41fcdeBob Halley for (i = 0; i <= max_type; i++) {
5619558151f1aa4249b3ead979e76876e29278b6Bob Halley if (bit_isset(bm, i) &&
5619558151f1aa4249b3ead979e76876e29278b6Bob Halley ! dns_rdatatype_iszonecutauth((dns_rdatatype_t)i))
5619558151f1aa4249b3ead979e76876e29278b6Bob Halley set_bit(bm, i, 0);
5619558151f1aa4249b3ead979e76876e29278b6Bob Halley }
95552051abdb3b6fc4f56b015da27c000742646bBob Halley }
95552051abdb3b6fc4f56b015da27c000742646bBob Halley
95552051abdb3b6fc4f56b015da27c000742646bBob Halley dns_rdatasetiter_destroy(&rdsiter);
95552051abdb3b6fc4f56b015da27c000742646bBob Halley if (result != ISC_R_NOMORE)
95552051abdb3b6fc4f56b015da27c000742646bBob Halley return (result);
95552051abdb3b6fc4f56b015da27c000742646bBob Halley
95552051abdb3b6fc4f56b015da27c000742646bBob Halley for (window = 0; window < 256; window++) {
95552051abdb3b6fc4f56b015da27c000742646bBob Halley if (window * 256 > max_type)
95552051abdb3b6fc4f56b015da27c000742646bBob Halley break;
95552051abdb3b6fc4f56b015da27c000742646bBob Halley for (octet = 31; octet >= 0; octet--)
95552051abdb3b6fc4f56b015da27c000742646bBob Halley if (bm[window * 32 + octet] != 0)
95552051abdb3b6fc4f56b015da27c000742646bBob Halley break;
95552051abdb3b6fc4f56b015da27c000742646bBob Halley if (octet < 0)
95552051abdb3b6fc4f56b015da27c000742646bBob Halley continue;
95552051abdb3b6fc4f56b015da27c000742646bBob Halley nsec_bits[0] = window;
95552051abdb3b6fc4f56b015da27c000742646bBob Halley nsec_bits[1] = octet + 1;
95552051abdb3b6fc4f56b015da27c000742646bBob Halley /*
95552051abdb3b6fc4f56b015da27c000742646bBob Halley * Note: potential overlapping move.
95552051abdb3b6fc4f56b015da27c000742646bBob Halley */
95552051abdb3b6fc4f56b015da27c000742646bBob Halley memmove(&nsec_bits[2], &bm[window * 32], octet + 1);
95552051abdb3b6fc4f56b015da27c000742646bBob Halley nsec_bits += 3 + octet;
95552051abdb3b6fc4f56b015da27c000742646bBob Halley }
5619558151f1aa4249b3ead979e76876e29278b6Bob Halley r.length = nsec_bits - r.base;
5619558151f1aa4249b3ead979e76876e29278b6Bob Halley INSIST(r.length <= DNS_NSEC_BUFFERSIZE);
5619558151f1aa4249b3ead979e76876e29278b6Bob Halley dns_rdata_fromregion(rdata,
5619558151f1aa4249b3ead979e76876e29278b6Bob Halley dns_db_class(db),
5619558151f1aa4249b3ead979e76876e29278b6Bob Halley dns_rdatatype_nsec,
5619558151f1aa4249b3ead979e76876e29278b6Bob Halley &r);
54f959d12b5a1f9315fbf6a776c6d349316e9686Bob Halley
0d0d9a9d9895605aba3a44fd03c051e15f88ecf5Bob Halley return (ISC_R_SUCCESS);
95552051abdb3b6fc4f56b015da27c000742646bBob Halley}
54f959d12b5a1f9315fbf6a776c6d349316e9686Bob Halley
54f959d12b5a1f9315fbf6a776c6d349316e9686Bob Halley
54f959d12b5a1f9315fbf6a776c6d349316e9686Bob Halleyisc_result_t
0d0d9a9d9895605aba3a44fd03c051e15f88ecf5Bob Halleydns_nsec_build(dns_db_t *db, dns_dbversion_t *version, dns_dbnode_t *node,
5619558151f1aa4249b3ead979e76876e29278b6Bob Halley dns_name_t *target, dns_ttl_t ttl)
5619558151f1aa4249b3ead979e76876e29278b6Bob Halley{
5619558151f1aa4249b3ead979e76876e29278b6Bob Halley isc_result_t result;
5619558151f1aa4249b3ead979e76876e29278b6Bob Halley dns_rdata_t rdata = DNS_RDATA_INIT;
5619558151f1aa4249b3ead979e76876e29278b6Bob Halley unsigned char data[DNS_NSEC_BUFFERSIZE];
078d49b63324f01d98301ee21671abee0c41fcdeBob Halley dns_rdatalist_t rdatalist;
54f959d12b5a1f9315fbf6a776c6d349316e9686Bob Halley dns_rdataset_t rdataset;
54f959d12b5a1f9315fbf6a776c6d349316e9686Bob Halley
5619558151f1aa4249b3ead979e76876e29278b6Bob Halley dns_rdataset_init(&rdataset);
54f959d12b5a1f9315fbf6a776c6d349316e9686Bob Halley dns_rdata_init(&rdata);
54f959d12b5a1f9315fbf6a776c6d349316e9686Bob Halley
54f959d12b5a1f9315fbf6a776c6d349316e9686Bob Halley RETERR(dns_nsec_buildrdata(db, version, node, target, data, &rdata));
54f959d12b5a1f9315fbf6a776c6d349316e9686Bob Halley
0d0d9a9d9895605aba3a44fd03c051e15f88ecf5Bob Halley rdatalist.rdclass = dns_db_class(db);
0d0d9a9d9895605aba3a44fd03c051e15f88ecf5Bob Halley rdatalist.type = dns_rdatatype_nsec;
0d0d9a9d9895605aba3a44fd03c051e15f88ecf5Bob Halley rdatalist.covers = 0;
0d0d9a9d9895605aba3a44fd03c051e15f88ecf5Bob Halley rdatalist.ttl = ttl;
0d0d9a9d9895605aba3a44fd03c051e15f88ecf5Bob Halley ISC_LIST_INIT(rdatalist.rdata);
0d0d9a9d9895605aba3a44fd03c051e15f88ecf5Bob Halley ISC_LIST_APPEND(rdatalist.rdata, &rdata, link);
0d0d9a9d9895605aba3a44fd03c051e15f88ecf5Bob Halley RETERR(dns_rdatalist_tordataset(&rdatalist, &rdataset));
0d0d9a9d9895605aba3a44fd03c051e15f88ecf5Bob Halley result = dns_db_addrdataset(db, node, version, 0, &rdataset,
0d0d9a9d9895605aba3a44fd03c051e15f88ecf5Bob Halley 0, NULL);
0d0d9a9d9895605aba3a44fd03c051e15f88ecf5Bob Halley if (result == DNS_R_UNCHANGED)
0d0d9a9d9895605aba3a44fd03c051e15f88ecf5Bob Halley result = ISC_R_SUCCESS;
0d0d9a9d9895605aba3a44fd03c051e15f88ecf5Bob Halley RETERR(result);
0d0d9a9d9895605aba3a44fd03c051e15f88ecf5Bob Halley failure:
0d0d9a9d9895605aba3a44fd03c051e15f88ecf5Bob Halley if (dns_rdataset_isassociated(&rdataset))
0d0d9a9d9895605aba3a44fd03c051e15f88ecf5Bob Halley dns_rdataset_disassociate(&rdataset);
0d0d9a9d9895605aba3a44fd03c051e15f88ecf5Bob Halley return (result);
0d0d9a9d9895605aba3a44fd03c051e15f88ecf5Bob Halley}
0d0d9a9d9895605aba3a44fd03c051e15f88ecf5Bob Halley
0d0d9a9d9895605aba3a44fd03c051e15f88ecf5Bob Halleyisc_boolean_t
0d0d9a9d9895605aba3a44fd03c051e15f88ecf5Bob Halleydns_nsec_typepresent(dns_rdata_t *nsec, dns_rdatatype_t type) {
0d0d9a9d9895605aba3a44fd03c051e15f88ecf5Bob Halley dns_rdata_nsec_t nsecstruct;
0d0d9a9d9895605aba3a44fd03c051e15f88ecf5Bob Halley isc_result_t result;
0d0d9a9d9895605aba3a44fd03c051e15f88ecf5Bob Halley isc_boolean_t present;
0d0d9a9d9895605aba3a44fd03c051e15f88ecf5Bob Halley unsigned int i, len, window;
0d0d9a9d9895605aba3a44fd03c051e15f88ecf5Bob Halley
0d0d9a9d9895605aba3a44fd03c051e15f88ecf5Bob Halley REQUIRE(nsec != NULL);
0d0d9a9d9895605aba3a44fd03c051e15f88ecf5Bob Halley REQUIRE(nsec->type == dns_rdatatype_nsec);
0d0d9a9d9895605aba3a44fd03c051e15f88ecf5Bob Halley
0d0d9a9d9895605aba3a44fd03c051e15f88ecf5Bob Halley /* This should never fail */
0d0d9a9d9895605aba3a44fd03c051e15f88ecf5Bob Halley result = dns_rdata_tostruct(nsec, &nsecstruct, NULL);
0d0d9a9d9895605aba3a44fd03c051e15f88ecf5Bob Halley INSIST(result == ISC_R_SUCCESS);
0d0d9a9d9895605aba3a44fd03c051e15f88ecf5Bob Halley
0d0d9a9d9895605aba3a44fd03c051e15f88ecf5Bob Halley present = ISC_FALSE;
0d0d9a9d9895605aba3a44fd03c051e15f88ecf5Bob Halley for (i = 0; i < nsecstruct.len; i += len) {
0d0d9a9d9895605aba3a44fd03c051e15f88ecf5Bob Halley INSIST(i + 2 <= nsecstruct.len);
0d0d9a9d9895605aba3a44fd03c051e15f88ecf5Bob Halley window = nsecstruct.typebits[i];
0d0d9a9d9895605aba3a44fd03c051e15f88ecf5Bob Halley len = nsecstruct.typebits[i + 1];
0d0d9a9d9895605aba3a44fd03c051e15f88ecf5Bob Halley INSIST(len > 0 && len <= 32);
0d0d9a9d9895605aba3a44fd03c051e15f88ecf5Bob Halley i += 2;
0d0d9a9d9895605aba3a44fd03c051e15f88ecf5Bob Halley INSIST(i + len <= nsecstruct.len);
0d0d9a9d9895605aba3a44fd03c051e15f88ecf5Bob Halley if (window * 256 > type)
0d0d9a9d9895605aba3a44fd03c051e15f88ecf5Bob Halley break;
0d0d9a9d9895605aba3a44fd03c051e15f88ecf5Bob Halley if ((window + 1) * 256 <= type)
0d0d9a9d9895605aba3a44fd03c051e15f88ecf5Bob Halley continue;
0d0d9a9d9895605aba3a44fd03c051e15f88ecf5Bob Halley if (type < (window * 256) + len * 8)
0d0d9a9d9895605aba3a44fd03c051e15f88ecf5Bob Halley present = ISC_TF(bit_isset(&nsecstruct.typebits[i],
0d0d9a9d9895605aba3a44fd03c051e15f88ecf5Bob Halley type % 256));
0d0d9a9d9895605aba3a44fd03c051e15f88ecf5Bob Halley break;
0d0d9a9d9895605aba3a44fd03c051e15f88ecf5Bob Halley }
0d0d9a9d9895605aba3a44fd03c051e15f88ecf5Bob Halley dns_rdata_freestruct(&nsecstruct);
0d0d9a9d9895605aba3a44fd03c051e15f88ecf5Bob Halley return (present);
0d0d9a9d9895605aba3a44fd03c051e15f88ecf5Bob Halley}
0d0d9a9d9895605aba3a44fd03c051e15f88ecf5Bob Halley
0d0d9a9d9895605aba3a44fd03c051e15f88ecf5Bob Halleyisc_result_t
0d0d9a9d9895605aba3a44fd03c051e15f88ecf5Bob Halleydns_nsec_nseconly(dns_db_t *db, dns_dbversion_t *version,
54f959d12b5a1f9315fbf6a776c6d349316e9686Bob Halley isc_boolean_t *answer)
0d0d9a9d9895605aba3a44fd03c051e15f88ecf5Bob Halley{
54f959d12b5a1f9315fbf6a776c6d349316e9686Bob Halley dns_dbnode_t *node = NULL;
54f959d12b5a1f9315fbf6a776c6d349316e9686Bob Halley dns_rdataset_t rdataset;
54f959d12b5a1f9315fbf6a776c6d349316e9686Bob Halley dns_rdata_dnskey_t dnskey;
54f959d12b5a1f9315fbf6a776c6d349316e9686Bob Halley isc_result_t result;
54f959d12b5a1f9315fbf6a776c6d349316e9686Bob Halley
0d0d9a9d9895605aba3a44fd03c051e15f88ecf5Bob Halley REQUIRE(answer != NULL);
0d0d9a9d9895605aba3a44fd03c051e15f88ecf5Bob Halley
54f959d12b5a1f9315fbf6a776c6d349316e9686Bob Halley dns_rdataset_init(&rdataset);
54f959d12b5a1f9315fbf6a776c6d349316e9686Bob Halley
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews result = dns_db_getoriginnode(db, &node);
95552051abdb3b6fc4f56b015da27c000742646bBob Halley if (result != ISC_R_SUCCESS)
95552051abdb3b6fc4f56b015da27c000742646bBob Halley return (result);
54f959d12b5a1f9315fbf6a776c6d349316e9686Bob Halley
54f959d12b5a1f9315fbf6a776c6d349316e9686Bob Halley result = dns_db_findrdataset(db, node, version, dns_rdatatype_dnskey,
54f959d12b5a1f9315fbf6a776c6d349316e9686Bob Halley 0, 0, &rdataset, NULL);
54f959d12b5a1f9315fbf6a776c6d349316e9686Bob Halley dns_db_detachnode(db, &node);
54f959d12b5a1f9315fbf6a776c6d349316e9686Bob Halley
54f959d12b5a1f9315fbf6a776c6d349316e9686Bob Halley if (result == ISC_R_NOTFOUND) {
54f959d12b5a1f9315fbf6a776c6d349316e9686Bob Halley *answer = ISC_FALSE;
54f959d12b5a1f9315fbf6a776c6d349316e9686Bob Halley return (ISC_R_SUCCESS);
54f959d12b5a1f9315fbf6a776c6d349316e9686Bob Halley }
54f959d12b5a1f9315fbf6a776c6d349316e9686Bob Halley if (result != ISC_R_SUCCESS)
54f959d12b5a1f9315fbf6a776c6d349316e9686Bob Halley return (result);
54f959d12b5a1f9315fbf6a776c6d349316e9686Bob Halley for (result = dns_rdataset_first(&rdataset);
54f959d12b5a1f9315fbf6a776c6d349316e9686Bob Halley result == ISC_R_SUCCESS;
5619558151f1aa4249b3ead979e76876e29278b6Bob Halley result = dns_rdataset_next(&rdataset)) {
5619558151f1aa4249b3ead979e76876e29278b6Bob Halley dns_rdata_t rdata = DNS_RDATA_INIT;
5619558151f1aa4249b3ead979e76876e29278b6Bob Halley
5619558151f1aa4249b3ead979e76876e29278b6Bob Halley dns_rdataset_current(&rdataset, &rdata);
5619558151f1aa4249b3ead979e76876e29278b6Bob Halley result = dns_rdata_tostruct(&rdata, &dnskey, NULL);
5619558151f1aa4249b3ead979e76876e29278b6Bob Halley RUNTIME_CHECK(result == ISC_R_SUCCESS);
5619558151f1aa4249b3ead979e76876e29278b6Bob Halley
5619558151f1aa4249b3ead979e76876e29278b6Bob Halley if (dnskey.algorithm == DST_ALG_RSAMD5 ||
5619558151f1aa4249b3ead979e76876e29278b6Bob Halley dnskey.algorithm == DST_ALG_RSASHA1 ||
5619558151f1aa4249b3ead979e76876e29278b6Bob Halley dnskey.algorithm == DST_ALG_DSA ||
5619558151f1aa4249b3ead979e76876e29278b6Bob Halley dnskey.algorithm == DST_ALG_ECC)
5619558151f1aa4249b3ead979e76876e29278b6Bob Halley break;
5619558151f1aa4249b3ead979e76876e29278b6Bob Halley }
5619558151f1aa4249b3ead979e76876e29278b6Bob Halley dns_rdataset_disassociate(&rdataset);
54f959d12b5a1f9315fbf6a776c6d349316e9686Bob Halley if (result == ISC_R_SUCCESS)
54f959d12b5a1f9315fbf6a776c6d349316e9686Bob Halley *answer = ISC_TRUE;
5619558151f1aa4249b3ead979e76876e29278b6Bob Halley if (result == ISC_R_NOMORE) {
5619558151f1aa4249b3ead979e76876e29278b6Bob Halley *answer = ISC_FALSE;
5619558151f1aa4249b3ead979e76876e29278b6Bob Halley result = ISC_R_SUCCESS;
5619558151f1aa4249b3ead979e76876e29278b6Bob Halley }
5619558151f1aa4249b3ead979e76876e29278b6Bob Halley return (result);
5619558151f1aa4249b3ead979e76876e29278b6Bob Halley}
5619558151f1aa4249b3ead979e76876e29278b6Bob Halley