2
0
mirror of https://gitlab.isc.org/isc-projects/bind9 synced 2025-08-30 14:07:59 +00:00

Move commonly used variables to the verification context structure

Move variables commonly used throughout dns_zoneverify_dnssec() and its
helper functions to the structure representing a verification context in
order to reduce the number of arguments passed between functions.
This commit is contained in:
Michał Kępień
2018-06-15 09:59:20 +02:00
parent ffc7997723
commit 43d0fb84e7

View File

@@ -52,6 +52,12 @@
"dns_dbiterator_current()") "dns_dbiterator_current()")
typedef struct vctx { typedef struct vctx {
isc_mem_t * mctx;
dns_db_t * db;
dns_dbversion_t * ver;
dns_name_t * origin;
isc_boolean_t goodksk;
isc_boolean_t goodzsk;
isc_heap_t * expected_chains; isc_heap_t * expected_chains;
isc_heap_t * found_chains; isc_heap_t * found_chains;
} vctx_t; } vctx_t;
@@ -90,18 +96,18 @@ check_result(isc_result_t result, const char *message) {
} }
static isc_boolean_t static isc_boolean_t
is_delegation(dns_db_t *db, dns_dbversion_t *ver, dns_name_t *origin, is_delegation(const vctx_t *vctx, dns_name_t *name, dns_dbnode_t *node,
dns_name_t *name, dns_dbnode_t *node, isc_uint32_t *ttlp) isc_uint32_t *ttlp)
{ {
dns_rdataset_t nsset; dns_rdataset_t nsset;
isc_result_t result; isc_result_t result;
if (dns_name_equal(name, origin)) if (dns_name_equal(name, vctx->origin))
return (ISC_FALSE); return (ISC_FALSE);
dns_rdataset_init(&nsset); dns_rdataset_init(&nsset);
result = dns_db_findrdataset(db, node, ver, dns_rdatatype_ns, result = dns_db_findrdataset(vctx->db, node, vctx->ver,
0, 0, &nsset, NULL); dns_rdatatype_ns, 0, 0, &nsset, NULL);
if (dns_rdataset_isassociated(&nsset)) { if (dns_rdataset_isassociated(&nsset)) {
if (ttlp != NULL) if (ttlp != NULL)
*ttlp = nsset.ttl; *ttlp = nsset.ttl;
@@ -116,13 +122,14 @@ is_delegation(dns_db_t *db, dns_dbversion_t *ver, dns_name_t *origin,
* 'node'; return ISC_FALSE otherwise. * 'node'; return ISC_FALSE otherwise.
*/ */
static isc_boolean_t static isc_boolean_t
has_dname(dns_db_t *db, dns_dbversion_t *ver, dns_dbnode_t *node) { has_dname(const vctx_t *vctx, dns_dbnode_t *node) {
dns_rdataset_t dnameset; dns_rdataset_t dnameset;
isc_result_t result; isc_result_t result;
dns_rdataset_init(&dnameset); dns_rdataset_init(&dnameset);
result = dns_db_findrdataset(db, node, ver, dns_rdatatype_dname, 0, 0, result = dns_db_findrdataset(vctx->db, node, vctx->ver,
&dnameset, NULL); dns_rdatatype_dname, 0, 0, &dnameset,
NULL);
if (dns_rdataset_isassociated(&dnameset)) { if (dns_rdataset_isassociated(&dnameset)) {
dns_rdataset_disassociate(&dnameset); dns_rdataset_disassociate(&dnameset);
} }
@@ -131,8 +138,8 @@ has_dname(dns_db_t *db, dns_dbversion_t *ver, dns_dbnode_t *node) {
} }
static isc_boolean_t static isc_boolean_t
goodsig(dns_name_t *origin, dns_rdata_t *sigrdata, dns_name_t *name, goodsig(const vctx_t *vctx, dns_rdata_t *sigrdata, dns_name_t *name,
dns_rdataset_t *keyrdataset, dns_rdataset_t *rdataset, isc_mem_t *mctx) dns_rdataset_t *keyrdataset, dns_rdataset_t *rdataset)
{ {
dns_rdata_dnskey_t key; dns_rdata_dnskey_t key;
dns_rdata_rrsig_t sig; dns_rdata_rrsig_t sig;
@@ -149,18 +156,18 @@ goodsig(dns_name_t *origin, dns_rdata_t *sigrdata, dns_name_t *name,
dns_rdataset_current(keyrdataset, &rdata); dns_rdataset_current(keyrdataset, &rdata);
result = dns_rdata_tostruct(&rdata, &key, NULL); result = dns_rdata_tostruct(&rdata, &key, NULL);
check_result(result, "dns_rdata_tostruct()"); check_result(result, "dns_rdata_tostruct()");
result = dns_dnssec_keyfromrdata(origin, &rdata, mctx, result = dns_dnssec_keyfromrdata(vctx->origin, &rdata,
&dstkey); vctx->mctx, &dstkey);
if (result != ISC_R_SUCCESS) if (result != ISC_R_SUCCESS)
return (ISC_FALSE); return (ISC_FALSE);
if (sig.algorithm != key.algorithm || if (sig.algorithm != key.algorithm ||
sig.keyid != dst_key_id(dstkey) || sig.keyid != dst_key_id(dstkey) ||
!dns_name_equal(&sig.signer, origin)) { !dns_name_equal(&sig.signer, vctx->origin)) {
dst_key_free(&dstkey); dst_key_free(&dstkey);
continue; continue;
} }
result = dns_dnssec_verify(name, rdataset, dstkey, ISC_FALSE, result = dns_dnssec_verify(name, rdataset, dstkey, ISC_FALSE,
0, mctx, sigrdata, NULL); 0, vctx->mctx, sigrdata, NULL);
dst_key_free(&dstkey); dst_key_free(&dstkey);
if (result == ISC_R_SUCCESS || result == DNS_R_FROMWILDCARD) { if (result == ISC_R_SUCCESS || result == DNS_R_FROMWILDCARD) {
return(ISC_TRUE); return(ISC_TRUE);
@@ -170,8 +177,8 @@ goodsig(dns_name_t *origin, dns_rdata_t *sigrdata, dns_name_t *name,
} }
static isc_result_t static isc_result_t
verifynsec(dns_db_t *db, dns_dbversion_t *ver, dns_name_t *name, verifynsec(const vctx_t *vctx, dns_name_t *name, dns_dbnode_t *node,
dns_dbnode_t *node, dns_name_t *nextname) dns_name_t *nextname)
{ {
unsigned char buffer[DNS_NSEC_BUFFERSIZE]; unsigned char buffer[DNS_NSEC_BUFFERSIZE];
char namebuf[DNS_NAME_FORMATSIZE]; char namebuf[DNS_NAME_FORMATSIZE];
@@ -184,8 +191,9 @@ verifynsec(dns_db_t *db, dns_dbversion_t *ver, dns_name_t *name,
isc_result_t result; isc_result_t result;
dns_rdataset_init(&rdataset); dns_rdataset_init(&rdataset);
result = dns_db_findrdataset(db, node, ver, dns_rdatatype_nsec, result = dns_db_findrdataset(vctx->db, node, vctx->ver,
0, 0, &rdataset, NULL); dns_rdatatype_nsec, 0, 0, &rdataset,
NULL);
if (result != ISC_R_SUCCESS) { if (result != ISC_R_SUCCESS) {
dns_name_format(name, namebuf, sizeof(namebuf)); dns_name_format(name, namebuf, sizeof(namebuf));
fprintf(stderr, "Missing NSEC record for %s\n", namebuf); fprintf(stderr, "Missing NSEC record for %s\n", namebuf);
@@ -209,8 +217,8 @@ verifynsec(dns_db_t *db, dns_dbversion_t *ver, dns_name_t *name,
goto failure; goto failure;
} }
/* Check bit map is consistent */ /* Check bit map is consistent */
result = dns_nsec_buildrdata(db, ver, node, nextname, buffer, result = dns_nsec_buildrdata(vctx->db, vctx->ver, node, nextname,
&tmprdata); buffer, &tmprdata);
check_result(result, "dns_nsec_buildrdata()"); check_result(result, "dns_nsec_buildrdata()");
if (dns_rdata_compare(&rdata, &tmprdata) != 0) { if (dns_rdata_compare(&rdata, &tmprdata) != 0) {
dns_name_format(name, namebuf, sizeof(namebuf)); dns_name_format(name, namebuf, sizeof(namebuf));
@@ -234,8 +242,8 @@ verifynsec(dns_db_t *db, dns_dbversion_t *ver, dns_name_t *name,
} }
static void static void
check_no_rrsig(dns_db_t *db, dns_dbversion_t *ver, dns_rdataset_t *rdataset, check_no_rrsig(const vctx_t *vctx, dns_rdataset_t *rdataset, dns_name_t *name,
dns_name_t *name, dns_dbnode_t *node) dns_dbnode_t *node)
{ {
char namebuf[DNS_NAME_FORMATSIZE]; char namebuf[DNS_NAME_FORMATSIZE];
char typebuf[80]; char typebuf[80];
@@ -244,7 +252,7 @@ check_no_rrsig(dns_db_t *db, dns_dbversion_t *ver, dns_rdataset_t *rdataset,
isc_result_t result; isc_result_t result;
dns_rdataset_init(&sigrdataset); dns_rdataset_init(&sigrdataset);
result = dns_db_allrdatasets(db, node, ver, 0, &rdsiter); result = dns_db_allrdatasets(vctx->db, node, vctx->ver, 0, &rdsiter);
check_result(result, "dns_db_allrdatasets()"); check_result(result, "dns_db_allrdatasets()");
for (result = dns_rdatasetiter_first(rdsiter); for (result = dns_rdatasetiter_first(rdsiter);
result == ISC_R_SUCCESS; result == ISC_R_SUCCESS;
@@ -349,7 +357,7 @@ record_nsec3(const unsigned char *rawhash, const dns_rdata_nsec3_t *nsec3,
} }
static isc_result_t static isc_result_t
match_nsec3(const vctx_t *vctx, dns_name_t *name, isc_mem_t *mctx, match_nsec3(const vctx_t *vctx, dns_name_t *name,
dns_rdata_nsec3param_t *nsec3param, dns_rdataset_t *rdataset, dns_rdata_nsec3param_t *nsec3param, dns_rdataset_t *rdataset,
unsigned char types[8192], unsigned int maxtype, unsigned char types[8192], unsigned int maxtype,
unsigned char *rawhash, size_t rhsize) unsigned char *rawhash, size_t rhsize)
@@ -398,7 +406,8 @@ match_nsec3(const vctx_t *vctx, dns_name_t *name, isc_mem_t *mctx,
/* /*
* Record chain. * Record chain.
*/ */
result = record_nsec3(rawhash, &nsec3, mctx, vctx->expected_chains); result = record_nsec3(rawhash, &nsec3, vctx->mctx,
vctx->expected_chains);
check_result(result, "record_nsec3()"); check_result(result, "record_nsec3()");
/* /*
@@ -456,8 +465,7 @@ innsec3params(dns_rdata_nsec3_t *nsec3, dns_rdataset_t *nsec3paramset) {
} }
static isc_result_t static isc_result_t
record_found(const vctx_t *vctx, dns_db_t *db, dns_dbversion_t *ver, record_found(const vctx_t *vctx, dns_name_t *name, dns_dbnode_t *node,
isc_mem_t *mctx, dns_name_t *name, dns_dbnode_t *node,
dns_rdataset_t *nsec3paramset) dns_rdataset_t *nsec3paramset)
{ {
unsigned char owner[NSEC3_MAX_HASH_LENGTH]; unsigned char owner[NSEC3_MAX_HASH_LENGTH];
@@ -471,8 +479,9 @@ record_found(const vctx_t *vctx, dns_db_t *db, dns_dbversion_t *ver,
return (ISC_R_SUCCESS); return (ISC_R_SUCCESS);
dns_rdataset_init(&rdataset); dns_rdataset_init(&rdataset);
result = dns_db_findrdataset(db, node, ver, dns_rdatatype_nsec3, result = dns_db_findrdataset(vctx->db, node, vctx->ver,
0, 0, &rdataset, NULL); dns_rdatatype_nsec3, 0, 0, &rdataset,
NULL);
if (result != ISC_R_SUCCESS) if (result != ISC_R_SUCCESS)
return (ISC_R_SUCCESS); return (ISC_R_SUCCESS);
@@ -502,7 +511,8 @@ record_found(const vctx_t *vctx, dns_db_t *db, dns_dbversion_t *ver,
/* /*
* Record chain. * Record chain.
*/ */
result = record_nsec3(owner, &nsec3, mctx, vctx->found_chains); result = record_nsec3(owner, &nsec3, vctx->mctx,
vctx->found_chains);
check_result(result, "record_nsec3()"); check_result(result, "record_nsec3()");
} }
@@ -512,9 +522,7 @@ record_found(const vctx_t *vctx, dns_db_t *db, dns_dbversion_t *ver,
} }
static isc_boolean_t static isc_boolean_t
isoptout(dns_db_t *db, dns_dbversion_t *ver, dns_name_t *origin, isoptout(const vctx_t *vctx, dns_rdata_t *nsec3rdata) {
dns_rdata_t *nsec3rdata)
{
dns_rdataset_t rdataset; dns_rdataset_t rdataset;
dns_rdata_t rdata = DNS_RDATA_INIT; dns_rdata_t rdata = DNS_RDATA_INIT;
dns_rdata_nsec3_t nsec3; dns_rdata_nsec3_t nsec3;
@@ -531,17 +539,19 @@ isoptout(dns_db_t *db, dns_dbversion_t *ver, dns_name_t *origin,
check_result(result, "dns_rdata_tostruct()"); check_result(result, "dns_rdata_tostruct()");
dns_fixedname_init(&fixed); dns_fixedname_init(&fixed);
result = dns_nsec3_hashname(&fixed, rawhash, &rhsize, origin, origin, result = dns_nsec3_hashname(&fixed, rawhash, &rhsize, vctx->origin,
nsec3param.hash, nsec3param.iterations, vctx->origin, nsec3param.hash,
nsec3param.salt, nsec3param.salt_length); nsec3param.iterations, nsec3param.salt,
nsec3param.salt_length);
check_result(result, "dns_nsec3_hashname()"); check_result(result, "dns_nsec3_hashname()");
dns_rdataset_init(&rdataset); dns_rdataset_init(&rdataset);
hashname = dns_fixedname_name(&fixed); hashname = dns_fixedname_name(&fixed);
result = dns_db_findnsec3node(db, hashname, ISC_FALSE, &node); result = dns_db_findnsec3node(vctx->db, hashname, ISC_FALSE, &node);
if (result == ISC_R_SUCCESS) if (result == ISC_R_SUCCESS)
result = dns_db_findrdataset(db, node, ver, dns_rdatatype_nsec3, result = dns_db_findrdataset(vctx->db, node, vctx->ver,
0, 0, &rdataset, NULL); dns_rdatatype_nsec3, 0, 0,
&rdataset, NULL);
if (result != ISC_R_SUCCESS) if (result != ISC_R_SUCCESS)
return (ISC_FALSE); return (ISC_FALSE);
@@ -559,15 +569,14 @@ isoptout(dns_db_t *db, dns_dbversion_t *ver, dns_name_t *origin,
if (dns_rdataset_isassociated(&rdataset)) if (dns_rdataset_isassociated(&rdataset))
dns_rdataset_disassociate(&rdataset); dns_rdataset_disassociate(&rdataset);
if (node != NULL) if (node != NULL)
dns_db_detachnode(db, &node); dns_db_detachnode(vctx->db, &node);
return (ret); return (ret);
} }
static isc_result_t static isc_result_t
verifynsec3(const vctx_t *vctx, dns_db_t *db, dns_dbversion_t *ver, verifynsec3(const vctx_t *vctx, dns_name_t *name, dns_rdata_t *rdata,
dns_name_t *origin, isc_mem_t *mctx, dns_name_t *name, isc_boolean_t delegation, isc_boolean_t empty,
dns_rdata_t *rdata, isc_boolean_t delegation, isc_boolean_t empty,
unsigned char types[8192], unsigned int maxtype) unsigned char types[8192], unsigned int maxtype)
{ {
char namebuf[DNS_NAME_FORMATSIZE]; char namebuf[DNS_NAME_FORMATSIZE];
@@ -591,12 +600,13 @@ verifynsec3(const vctx_t *vctx, dns_db_t *db, dns_dbversion_t *ver,
if (!dns_nsec3_supportedhash(nsec3param.hash)) if (!dns_nsec3_supportedhash(nsec3param.hash))
return (ISC_R_SUCCESS); return (ISC_R_SUCCESS);
optout = isoptout(db, ver, origin, rdata); optout = isoptout(vctx, rdata);
dns_fixedname_init(&fixed); dns_fixedname_init(&fixed);
result = dns_nsec3_hashname(&fixed, rawhash, &rhsize, name, origin, result = dns_nsec3_hashname(&fixed, rawhash, &rhsize, name,
nsec3param.hash, nsec3param.iterations, vctx->origin, nsec3param.hash,
nsec3param.salt, nsec3param.salt_length); nsec3param.iterations, nsec3param.salt,
nsec3param.salt_length);
check_result(result, "dns_nsec3_hashname()"); check_result(result, "dns_nsec3_hashname()");
/* /*
@@ -607,10 +617,11 @@ verifynsec3(const vctx_t *vctx, dns_db_t *db, dns_dbversion_t *ver,
*/ */
dns_rdataset_init(&rdataset); dns_rdataset_init(&rdataset);
hashname = dns_fixedname_name(&fixed); hashname = dns_fixedname_name(&fixed);
result = dns_db_findnsec3node(db, hashname, ISC_FALSE, &node); result = dns_db_findnsec3node(vctx->db, hashname, ISC_FALSE, &node);
if (result == ISC_R_SUCCESS) if (result == ISC_R_SUCCESS)
result = dns_db_findrdataset(db, node, ver, dns_rdatatype_nsec3, result = dns_db_findrdataset(vctx->db, node, vctx->ver,
0, 0, &rdataset, NULL); dns_rdatatype_nsec3, 0, 0,
&rdataset, NULL);
if (result != ISC_R_SUCCESS && if (result != ISC_R_SUCCESS &&
(!delegation || (empty && !optout) || (!delegation || (empty && !optout) ||
(!empty && dns_nsec_isset(types, dns_rdatatype_ds)))) (!empty && dns_nsec_isset(types, dns_rdatatype_ds))))
@@ -624,21 +635,20 @@ verifynsec3(const vctx_t *vctx, dns_db_t *db, dns_dbversion_t *ver,
{ {
result = ISC_R_SUCCESS; result = ISC_R_SUCCESS;
} else if (result == ISC_R_SUCCESS) { } else if (result == ISC_R_SUCCESS) {
result = match_nsec3(vctx, name, mctx, &nsec3param, &rdataset, result = match_nsec3(vctx, name, &nsec3param, &rdataset, types,
types, maxtype, rawhash, rhsize); maxtype, rawhash, rhsize);
} }
if (dns_rdataset_isassociated(&rdataset)) if (dns_rdataset_isassociated(&rdataset))
dns_rdataset_disassociate(&rdataset); dns_rdataset_disassociate(&rdataset);
if (node != NULL) if (node != NULL)
dns_db_detachnode(db, &node); dns_db_detachnode(vctx->db, &node);
return (result); return (result);
} }
static isc_result_t static isc_result_t
verifynsec3s(const vctx_t *vctx, dns_db_t *db, dns_dbversion_t *ver, verifynsec3s(const vctx_t *vctx, dns_name_t *name,
dns_name_t *origin, isc_mem_t *mctx, dns_name_t *name,
dns_rdataset_t *nsec3paramset, isc_boolean_t delegation, dns_rdataset_t *nsec3paramset, isc_boolean_t delegation,
isc_boolean_t empty, unsigned char types[8192], isc_boolean_t empty, unsigned char types[8192],
unsigned int maxtype) unsigned int maxtype)
@@ -651,8 +661,8 @@ verifynsec3s(const vctx_t *vctx, dns_db_t *db, dns_dbversion_t *ver,
dns_rdata_t rdata = DNS_RDATA_INIT; dns_rdata_t rdata = DNS_RDATA_INIT;
dns_rdataset_current(nsec3paramset, &rdata); dns_rdataset_current(nsec3paramset, &rdata);
result = verifynsec3(vctx, db, ver, origin, mctx, name, &rdata, result = verifynsec3(vctx, name, &rdata, delegation, empty,
delegation, empty, types, maxtype); types, maxtype);
if (result != ISC_R_SUCCESS) if (result != ISC_R_SUCCESS)
break; break;
} }
@@ -662,8 +672,7 @@ verifynsec3s(const vctx_t *vctx, dns_db_t *db, dns_dbversion_t *ver,
} }
static void static void
verifyset(dns_db_t *db, dns_dbversion_t *ver, dns_name_t *origin, verifyset(const vctx_t *vctx, dns_rdataset_t *rdataset, dns_name_t *name,
isc_mem_t *mctx, dns_rdataset_t *rdataset, dns_name_t *name,
dns_dbnode_t *node, dns_rdataset_t *keyrdataset, dns_dbnode_t *node, dns_rdataset_t *keyrdataset,
unsigned char *act_algorithms, unsigned char *bad_algorithms) unsigned char *act_algorithms, unsigned char *bad_algorithms)
{ {
@@ -677,7 +686,7 @@ verifyset(dns_db_t *db, dns_dbversion_t *ver, dns_name_t *origin,
int i; int i;
dns_rdataset_init(&sigrdataset); dns_rdataset_init(&sigrdataset);
result = dns_db_allrdatasets(db, node, ver, 0, &rdsiter); result = dns_db_allrdatasets(vctx->db, node, vctx->ver, 0, &rdsiter);
check_result(result, "dns_db_allrdatasets()"); check_result(result, "dns_db_allrdatasets()");
for (result = dns_rdatasetiter_first(rdsiter); for (result = dns_rdatasetiter_first(rdsiter);
result == ISC_R_SUCCESS; result == ISC_R_SUCCESS;
@@ -720,7 +729,7 @@ verifyset(dns_db_t *db, dns_dbversion_t *ver, dns_name_t *origin,
if ((set_algorithms[sig.algorithm] != 0) || if ((set_algorithms[sig.algorithm] != 0) ||
(act_algorithms[sig.algorithm] == 0)) (act_algorithms[sig.algorithm] == 0))
continue; continue;
if (goodsig(origin, &rdata, name, keyrdataset, rdataset, mctx)) if (goodsig(vctx, &rdata, name, keyrdataset, rdataset))
set_algorithms[sig.algorithm] = 1; set_algorithms[sig.algorithm] = 1;
} }
dns_rdatasetiter_destroy(&rdsiter); dns_rdatasetiter_destroy(&rdsiter);
@@ -740,12 +749,11 @@ verifyset(dns_db_t *db, dns_dbversion_t *ver, dns_name_t *origin,
} }
static isc_result_t static isc_result_t
verifynode(const vctx_t *vctx, dns_db_t *db, dns_dbversion_t *ver, verifynode(const vctx_t *vctx, dns_name_t *name, dns_dbnode_t *node,
dns_name_t *origin, isc_mem_t *mctx, dns_name_t *name, isc_boolean_t delegation, dns_rdataset_t *keyrdataset,
dns_dbnode_t *node, isc_boolean_t delegation, unsigned char *act_algorithms, unsigned char *bad_algorithms,
dns_rdataset_t *keyrdataset, unsigned char *act_algorithms, dns_rdataset_t *nsecset, dns_rdataset_t *nsec3paramset,
unsigned char *bad_algorithms, dns_rdataset_t *nsecset, dns_name_t *nextname)
dns_rdataset_t *nsec3paramset, dns_name_t *nextname)
{ {
unsigned char types[8192]; unsigned char types[8192];
unsigned int maxtype = 0; unsigned int maxtype = 0;
@@ -753,7 +761,7 @@ verifynode(const vctx_t *vctx, dns_db_t *db, dns_dbversion_t *ver,
isc_result_t result, tresult; isc_result_t result, tresult;
memset(types, 0, sizeof(types)); memset(types, 0, sizeof(types));
result = dns_db_allrdatasets(db, node, ver, 0, &rdsiter); result = dns_db_allrdatasets(vctx->db, node, vctx->ver, 0, &rdsiter);
check_result(result, "dns_db_allrdatasets()"); check_result(result, "dns_db_allrdatasets()");
result = dns_rdatasetiter_first(rdsiter); result = dns_rdatasetiter_first(rdsiter);
dns_rdataset_init(&rdataset); dns_rdataset_init(&rdataset);
@@ -770,8 +778,7 @@ verifynode(const vctx_t *vctx, dns_db_t *db, dns_dbversion_t *ver,
rdataset.type != dns_rdatatype_dnskey && rdataset.type != dns_rdatatype_dnskey &&
(!delegation || rdataset.type == dns_rdatatype_ds || (!delegation || rdataset.type == dns_rdatatype_ds ||
rdataset.type == dns_rdatatype_nsec)) { rdataset.type == dns_rdatatype_nsec)) {
verifyset(db, ver, origin, mctx, &rdataset, verifyset(vctx, &rdataset, name, node, keyrdataset,
name, node, keyrdataset,
act_algorithms, bad_algorithms); act_algorithms, bad_algorithms);
dns_nsec_setbit(types, rdataset.type, 1); dns_nsec_setbit(types, rdataset.type, 1);
if (rdataset.type > maxtype) if (rdataset.type > maxtype)
@@ -780,7 +787,7 @@ verifynode(const vctx_t *vctx, dns_db_t *db, dns_dbversion_t *ver,
rdataset.type != dns_rdatatype_dnskey) { rdataset.type != dns_rdatatype_dnskey) {
if (rdataset.type == dns_rdatatype_ns) if (rdataset.type == dns_rdatatype_ns)
dns_nsec_setbit(types, rdataset.type, 1); dns_nsec_setbit(types, rdataset.type, 1);
check_no_rrsig(db, ver, &rdataset, name, node); check_no_rrsig(vctx, &rdataset, name, node);
} else } else
dns_nsec_setbit(types, rdataset.type, 1); dns_nsec_setbit(types, rdataset.type, 1);
dns_rdataset_disassociate(&rdataset); dns_rdataset_disassociate(&rdataset);
@@ -794,12 +801,11 @@ verifynode(const vctx_t *vctx, dns_db_t *db, dns_dbversion_t *ver,
result = ISC_R_SUCCESS; result = ISC_R_SUCCESS;
if (nsecset != NULL && dns_rdataset_isassociated(nsecset)) if (nsecset != NULL && dns_rdataset_isassociated(nsecset))
result = verifynsec(db, ver, name, node, nextname); result = verifynsec(vctx, name, node, nextname);
if (nsec3paramset != NULL && dns_rdataset_isassociated(nsec3paramset)) { if (nsec3paramset != NULL && dns_rdataset_isassociated(nsec3paramset)) {
tresult = verifynsec3s(vctx, db, ver, origin, mctx, name, tresult = verifynsec3s(vctx, name, nsec3paramset, delegation,
nsec3paramset, delegation, ISC_FALSE, ISC_FALSE, types, maxtype);
types, maxtype);
if (result == ISC_R_SUCCESS && tresult != ISC_R_SUCCESS) if (result == ISC_R_SUCCESS && tresult != ISC_R_SUCCESS)
result = tresult; result = tresult;
} }
@@ -807,11 +813,11 @@ verifynode(const vctx_t *vctx, dns_db_t *db, dns_dbversion_t *ver,
} }
static isc_boolean_t static isc_boolean_t
is_empty(dns_db_t *db, dns_dbversion_t *ver, dns_dbnode_t *node) { is_empty(const vctx_t *vctx, dns_dbnode_t *node) {
dns_rdatasetiter_t *rdsiter = NULL; dns_rdatasetiter_t *rdsiter = NULL;
isc_result_t result; isc_result_t result;
result = dns_db_allrdatasets(db, node, ver, 0, &rdsiter); result = dns_db_allrdatasets(vctx->db, node, vctx->ver, 0, &rdsiter);
check_result(result, "dns_db_allrdatasets()"); check_result(result, "dns_db_allrdatasets()");
result = dns_rdatasetiter_first(rdsiter); result = dns_rdatasetiter_first(rdsiter);
dns_rdatasetiter_destroy(&rdsiter); dns_rdatasetiter_destroy(&rdsiter);
@@ -821,15 +827,14 @@ is_empty(dns_db_t *db, dns_dbversion_t *ver, dns_dbnode_t *node) {
} }
static void static void
check_no_nsec(dns_name_t *name, dns_dbnode_t *node, dns_db_t *db, check_no_nsec(const vctx_t *vctx, dns_name_t *name, dns_dbnode_t *node) {
dns_dbversion_t *ver)
{
dns_rdataset_t rdataset; dns_rdataset_t rdataset;
isc_result_t result; isc_result_t result;
dns_rdataset_init(&rdataset); dns_rdataset_init(&rdataset);
result = dns_db_findrdataset(db, node, ver, dns_rdatatype_nsec, result = dns_db_findrdataset(vctx->db, node, vctx->ver,
0, 0, &rdataset, NULL); dns_rdatatype_nsec, 0, 0, &rdataset,
NULL);
if (result != ISC_R_NOTFOUND) { if (result != ISC_R_NOTFOUND) {
char namebuf[DNS_NAME_FORMATSIZE]; char namebuf[DNS_NAME_FORMATSIZE];
dns_name_format(name, namebuf, sizeof(namebuf)); dns_name_format(name, namebuf, sizeof(namebuf));
@@ -987,10 +992,8 @@ verify_nsec3_chains(const vctx_t *vctx, isc_mem_t *mctx) {
} }
static isc_result_t static isc_result_t
verifyemptynodes(const vctx_t *vctx, dns_db_t *db, dns_dbversion_t *ver, verifyemptynodes(const vctx_t *vctx, dns_name_t *name, dns_name_t *prevname,
dns_name_t *origin, isc_mem_t *mctx, dns_name_t *name, isc_boolean_t isdelegation, dns_rdataset_t *nsec3paramset)
dns_name_t *prevname, isc_boolean_t isdelegation,
dns_rdataset_t *nsec3paramset)
{ {
dns_namereln_t reln; dns_namereln_t reln;
int order; int order;
@@ -1012,8 +1015,7 @@ verifyemptynodes(const vctx_t *vctx, dns_db_t *db, dns_dbversion_t *ver,
&suffix); &suffix);
if (nsec3paramset != NULL && if (nsec3paramset != NULL &&
dns_rdataset_isassociated(nsec3paramset)) { dns_rdataset_isassociated(nsec3paramset)) {
tresult = verifynsec3s(vctx, db, ver, origin, tresult = verifynsec3s(vctx, &suffix,
mctx, &suffix,
nsec3paramset, nsec3paramset,
isdelegation, ISC_TRUE, isdelegation, ISC_TRUE,
NULL, 0); NULL, 0);
@@ -1027,9 +1029,18 @@ verifyemptynodes(const vctx_t *vctx, dns_db_t *db, dns_dbversion_t *ver,
} }
static isc_result_t static isc_result_t
vctx_init(vctx_t *vctx, isc_mem_t *mctx) { vctx_init(vctx_t *vctx, isc_mem_t *mctx, dns_db_t *db, dns_dbversion_t *ver,
dns_name_t *origin)
{
isc_result_t result; isc_result_t result;
vctx->mctx = mctx;
vctx->db = db;
vctx->ver = ver;
vctx->origin = origin;
vctx->goodksk = ISC_FALSE;
vctx->goodzsk = ISC_FALSE;
vctx->expected_chains = NULL; vctx->expected_chains = NULL;
result = isc_heap_create(mctx, chain_compare, NULL, 1024, result = isc_heap_create(mctx, chain_compare, NULL, 1024,
&vctx->expected_chains); &vctx->expected_chains);
@@ -1073,8 +1084,6 @@ dns_zoneverify_dnssec(dns_db_t *db, dns_dbversion_t *ver, dns_name_t *origin,
int i; int i;
isc_boolean_t done = ISC_FALSE; isc_boolean_t done = ISC_FALSE;
isc_boolean_t first = ISC_TRUE; isc_boolean_t first = ISC_TRUE;
isc_boolean_t goodksk = ISC_FALSE;
isc_boolean_t goodzsk = ISC_FALSE;
isc_result_t result, vresult = ISC_R_UNSET; isc_result_t result, vresult = ISC_R_UNSET;
unsigned char revoked_ksk[256]; unsigned char revoked_ksk[256];
unsigned char revoked_zsk[256]; unsigned char revoked_zsk[256];
@@ -1086,12 +1095,12 @@ dns_zoneverify_dnssec(dns_db_t *db, dns_dbversion_t *ver, dns_name_t *origin,
unsigned char act_algorithms[256]; unsigned char act_algorithms[256];
vctx_t vctx; vctx_t vctx;
result = vctx_init(&vctx, mctx); result = vctx_init(&vctx, mctx, db, ver, origin);
if (result != ISC_R_SUCCESS) { if (result != ISC_R_SUCCESS) {
return; return;
} }
result = dns_db_findnode(db, origin, ISC_FALSE, &node); result = dns_db_findnode(vctx.db, vctx.origin, ISC_FALSE, &node);
if (result != ISC_R_SUCCESS) if (result != ISC_R_SUCCESS)
fatal("failed to find the zone's origin: %s", fatal("failed to find the zone's origin: %s",
isc_result_totext(result)); isc_result_totext(result));
@@ -1104,23 +1113,27 @@ dns_zoneverify_dnssec(dns_db_t *db, dns_dbversion_t *ver, dns_name_t *origin,
dns_rdataset_init(&nsecsigs); dns_rdataset_init(&nsecsigs);
dns_rdataset_init(&nsec3paramset); dns_rdataset_init(&nsec3paramset);
dns_rdataset_init(&nsec3paramsigs); dns_rdataset_init(&nsec3paramsigs);
result = dns_db_findrdataset(db, node, ver, dns_rdatatype_dnskey, result = dns_db_findrdataset(vctx.db, node, vctx.ver,
0, 0, &keyset, &keysigs); dns_rdatatype_dnskey, 0, 0, &keyset,
&keysigs);
if (result != ISC_R_SUCCESS) if (result != ISC_R_SUCCESS)
fatal("Zone contains no DNSSEC keys\n"); fatal("Zone contains no DNSSEC keys\n");
result = dns_db_findrdataset(db, node, ver, dns_rdatatype_soa, result = dns_db_findrdataset(vctx.db, node, vctx.ver,
0, 0, &soaset, &soasigs); dns_rdatatype_soa, 0, 0, &soaset,
&soasigs);
if (result != ISC_R_SUCCESS) if (result != ISC_R_SUCCESS)
fatal("Zone contains no SOA record\n"); fatal("Zone contains no SOA record\n");
result = dns_db_findrdataset(db, node, ver, dns_rdatatype_nsec, result = dns_db_findrdataset(vctx.db, node, vctx.ver,
0, 0, &nsecset, &nsecsigs); dns_rdatatype_nsec, 0, 0, &nsecset,
&nsecsigs);
if (result != ISC_R_SUCCESS && result != ISC_R_NOTFOUND) if (result != ISC_R_SUCCESS && result != ISC_R_NOTFOUND)
fatal("NSEC lookup failed\n"); fatal("NSEC lookup failed\n");
result = dns_db_findrdataset(db, node, ver, dns_rdatatype_nsec3param, result = dns_db_findrdataset(vctx.db, node, vctx.ver,
0, 0, &nsec3paramset, &nsec3paramsigs); dns_rdatatype_nsec3param, 0, 0,
&nsec3paramset, &nsec3paramsigs);
if (result != ISC_R_SUCCESS && result != ISC_R_NOTFOUND) if (result != ISC_R_SUCCESS && result != ISC_R_NOTFOUND)
fatal("NSEC3PARAM lookup failed\n"); fatal("NSEC3PARAM lookup failed\n");
@@ -1142,7 +1155,7 @@ dns_zoneverify_dnssec(dns_db_t *db, dns_dbversion_t *ver, dns_name_t *origin,
!dns_rdataset_isassociated(&nsec3paramset)) !dns_rdataset_isassociated(&nsec3paramset))
fatal("No valid NSEC/NSEC3 chain for testing\n"); fatal("No valid NSEC/NSEC3 chain for testing\n");
dns_db_detachnode(db, &node); dns_db_detachnode(vctx.db, &node);
memset(revoked_ksk, 0, sizeof(revoked_ksk)); memset(revoked_ksk, 0, sizeof(revoked_ksk));
memset(revoked_zsk, 0, sizeof(revoked_zsk)); memset(revoked_zsk, 0, sizeof(revoked_zsk));
@@ -1169,14 +1182,14 @@ dns_zoneverify_dnssec(dns_db_t *db, dns_dbversion_t *ver, dns_name_t *origin,
; ;
else if ((dnskey.flags & DNS_KEYFLAG_REVOKE) != 0) { else if ((dnskey.flags & DNS_KEYFLAG_REVOKE) != 0) {
if ((dnskey.flags & DNS_KEYFLAG_KSK) != 0 && if ((dnskey.flags & DNS_KEYFLAG_KSK) != 0 &&
!dns_dnssec_selfsigns(&rdata, origin, &keyset, !dns_dnssec_selfsigns(&rdata, vctx.origin, &keyset,
&keysigs, ISC_FALSE, &keysigs, ISC_FALSE,
mctx)) { vctx.mctx)) {
char namebuf[DNS_NAME_FORMATSIZE]; char namebuf[DNS_NAME_FORMATSIZE];
char buffer[1024]; char buffer[1024];
isc_buffer_t buf; isc_buffer_t buf;
dns_name_format(origin, namebuf, dns_name_format(vctx.origin, namebuf,
sizeof(namebuf)); sizeof(namebuf));
isc_buffer_init(&buf, buffer, sizeof(buffer)); isc_buffer_init(&buf, buffer, sizeof(buffer));
result = dns_rdata_totext(&rdata, NULL, &buf); result = dns_rdata_totext(&rdata, NULL, &buf);
@@ -1192,22 +1205,24 @@ dns_zoneverify_dnssec(dns_db_t *db, dns_dbversion_t *ver, dns_name_t *origin,
revoked_zsk[dnskey.algorithm] != 255) revoked_zsk[dnskey.algorithm] != 255)
revoked_zsk[dnskey.algorithm]++; revoked_zsk[dnskey.algorithm]++;
} else if ((dnskey.flags & DNS_KEYFLAG_KSK) != 0) { } else if ((dnskey.flags & DNS_KEYFLAG_KSK) != 0) {
if (dns_dnssec_selfsigns(&rdata, origin, &keyset, if (dns_dnssec_selfsigns(&rdata, vctx.origin, &keyset,
&keysigs, ISC_FALSE, mctx)) { &keysigs, ISC_FALSE,
vctx.mctx)) {
if (ksk_algorithms[dnskey.algorithm] != 255) if (ksk_algorithms[dnskey.algorithm] != 255)
ksk_algorithms[dnskey.algorithm]++; ksk_algorithms[dnskey.algorithm]++;
goodksk = ISC_TRUE; vctx.goodksk = ISC_TRUE;
} else { } else {
if (standby_ksk[dnskey.algorithm] != 255) if (standby_ksk[dnskey.algorithm] != 255)
standby_ksk[dnskey.algorithm]++; standby_ksk[dnskey.algorithm]++;
} }
} else if (dns_dnssec_selfsigns(&rdata, origin, &keyset, } else if (dns_dnssec_selfsigns(&rdata, vctx.origin, &keyset,
&keysigs, ISC_FALSE, mctx)) { &keysigs, ISC_FALSE,
vctx.mctx)) {
if (zsk_algorithms[dnskey.algorithm] != 255) if (zsk_algorithms[dnskey.algorithm] != 255)
zsk_algorithms[dnskey.algorithm]++; zsk_algorithms[dnskey.algorithm]++;
goodzsk = ISC_TRUE; vctx.goodzsk = ISC_TRUE;
} else if (dns_dnssec_signs(&rdata, origin, &soaset, } else if (dns_dnssec_signs(&rdata, vctx.origin, &soaset,
&soasigs, ISC_FALSE, mctx)) { &soasigs, ISC_FALSE, vctx.mctx)) {
if (zsk_algorithms[dnskey.algorithm] != 255) if (zsk_algorithms[dnskey.algorithm] != 255)
zsk_algorithms[dnskey.algorithm]++; zsk_algorithms[dnskey.algorithm]++;
} else { } else {
@@ -1226,9 +1241,9 @@ dns_zoneverify_dnssec(dns_db_t *db, dns_dbversion_t *ver, dns_name_t *origin,
dns_rdataset_disassociate(&nsec3paramsigs); dns_rdataset_disassociate(&nsec3paramsigs);
if (ignore_kskflag ) { if (ignore_kskflag ) {
if (!goodksk && !goodzsk) if (!vctx.goodksk && !vctx.goodzsk)
fatal("No self-signed DNSKEY found."); fatal("No self-signed DNSKEY found.");
} else if (!goodksk) } else if (!vctx.goodksk)
fatal("No self-signed KSK DNSKEY found. Supply an active\n" fatal("No self-signed KSK DNSKEY found. Supply an active\n"
"key with the KSK flag set, or use '-P'."); "key with the KSK flag set, or use '-P'.");
@@ -1277,7 +1292,7 @@ dns_zoneverify_dnssec(dns_db_t *db, dns_dbversion_t *ver, dns_name_t *origin,
dns_fixedname_init(&fzonecut); dns_fixedname_init(&fzonecut);
zonecut = NULL; zonecut = NULL;
result = dns_db_createiterator(db, DNS_DB_NONSEC3, &dbiter); result = dns_db_createiterator(vctx.db, DNS_DB_NONSEC3, &dbiter);
check_result(result, "dns_db_createiterator()"); check_result(result, "dns_db_createiterator()");
result = dns_dbiterator_first(dbiter); result = dns_dbiterator_first(dbiter);
@@ -1288,9 +1303,9 @@ dns_zoneverify_dnssec(dns_db_t *db, dns_dbversion_t *ver, dns_name_t *origin,
result = dns_dbiterator_current(dbiter, &node, name); result = dns_dbiterator_current(dbiter, &node, name);
check_dns_dbiterator_current(result); check_dns_dbiterator_current(result);
if (!dns_name_issubdomain(name, origin)) { if (!dns_name_issubdomain(name, vctx.origin)) {
check_no_nsec(name, node, db, ver); check_no_nsec(&vctx, name, node);
dns_db_detachnode(db, &node); dns_db_detachnode(vctx.db, &node);
result = dns_dbiterator_next(dbiter); result = dns_dbiterator_next(dbiter);
if (result == ISC_R_NOMORE) if (result == ISC_R_NOMORE)
done = ISC_TRUE; done = ISC_TRUE;
@@ -1298,11 +1313,11 @@ dns_zoneverify_dnssec(dns_db_t *db, dns_dbversion_t *ver, dns_name_t *origin,
check_result(result, "dns_dbiterator_next()"); check_result(result, "dns_dbiterator_next()");
continue; continue;
} }
if (is_delegation(db, ver, origin, name, node, NULL)) { if (is_delegation(&vctx, name, node, NULL)) {
zonecut = dns_fixedname_name(&fzonecut); zonecut = dns_fixedname_name(&fzonecut);
dns_name_copy(name, zonecut, NULL); dns_name_copy(name, zonecut, NULL);
isdelegation = ISC_TRUE; isdelegation = ISC_TRUE;
} else if (has_dname(db, ver, node)) { } else if (has_dname(&vctx, node)) {
zonecut = dns_fixedname_name(&fzonecut); zonecut = dns_fixedname_name(&fzonecut);
dns_name_copy(name, zonecut, NULL); dns_name_copy(name, zonecut, NULL);
} }
@@ -1312,52 +1327,51 @@ dns_zoneverify_dnssec(dns_db_t *db, dns_dbversion_t *ver, dns_name_t *origin,
result = dns_dbiterator_current(dbiter, &nextnode, result = dns_dbiterator_current(dbiter, &nextnode,
nextname); nextname);
check_dns_dbiterator_current(result); check_dns_dbiterator_current(result);
if (!dns_name_issubdomain(nextname, origin) || if (!dns_name_issubdomain(nextname, vctx.origin) ||
(zonecut != NULL && (zonecut != NULL &&
dns_name_issubdomain(nextname, zonecut))) dns_name_issubdomain(nextname, zonecut)))
{ {
check_no_nsec(nextname, nextnode, db, ver); check_no_nsec(&vctx, nextname, nextnode);
dns_db_detachnode(db, &nextnode); dns_db_detachnode(vctx.db, &nextnode);
result = dns_dbiterator_next(dbiter); result = dns_dbiterator_next(dbiter);
continue; continue;
} }
if (is_empty(db, ver, nextnode)) { if (is_empty(&vctx, nextnode)) {
dns_db_detachnode(db, &nextnode); dns_db_detachnode(vctx.db, &nextnode);
result = dns_dbiterator_next(dbiter); result = dns_dbiterator_next(dbiter);
continue; continue;
} }
dns_db_detachnode(db, &nextnode); dns_db_detachnode(vctx.db, &nextnode);
break; break;
} }
if (result == ISC_R_NOMORE) { if (result == ISC_R_NOMORE) {
done = ISC_TRUE; done = ISC_TRUE;
nextname = origin; nextname = vctx.origin;
} else if (result != ISC_R_SUCCESS) } else if (result != ISC_R_SUCCESS)
fatal("iterating through the database failed: %s", fatal("iterating through the database failed: %s",
isc_result_totext(result)); isc_result_totext(result));
result = verifynode(&vctx, db, ver, origin, mctx, name, node, result = verifynode(&vctx, name, node, isdelegation, &keyset,
isdelegation, &keyset, act_algorithms, act_algorithms, bad_algorithms, &nsecset,
bad_algorithms, &nsecset, &nsec3paramset, &nsec3paramset, nextname);
nextname);
if (vresult == ISC_R_UNSET) if (vresult == ISC_R_UNSET)
vresult = ISC_R_SUCCESS; vresult = ISC_R_SUCCESS;
if (vresult == ISC_R_SUCCESS && result != ISC_R_SUCCESS) if (vresult == ISC_R_SUCCESS && result != ISC_R_SUCCESS)
vresult = result; vresult = result;
if (prevname != NULL) { if (prevname != NULL) {
result = verifyemptynodes(&vctx, db, ver, origin, mctx, result = verifyemptynodes(&vctx, name, prevname,
name, prevname, isdelegation, isdelegation,
&nsec3paramset); &nsec3paramset);
} else } else
prevname = dns_fixedname_name(&fprevname); prevname = dns_fixedname_name(&fprevname);
dns_name_copy(name, prevname, NULL); dns_name_copy(name, prevname, NULL);
if (vresult == ISC_R_SUCCESS && result != ISC_R_SUCCESS) if (vresult == ISC_R_SUCCESS && result != ISC_R_SUCCESS)
vresult = result; vresult = result;
dns_db_detachnode(db, &node); dns_db_detachnode(vctx.db, &node);
} }
dns_dbiterator_destroy(&dbiter); dns_dbiterator_destroy(&dbiter);
result = dns_db_createiterator(db, DNS_DB_NSEC3ONLY, &dbiter); result = dns_db_createiterator(vctx.db, DNS_DB_NSEC3ONLY, &dbiter);
check_result(result, "dns_db_createiterator()"); check_result(result, "dns_db_createiterator()");
for (result = dns_dbiterator_first(dbiter); for (result = dns_dbiterator_first(dbiter);
@@ -1365,12 +1379,12 @@ dns_zoneverify_dnssec(dns_db_t *db, dns_dbversion_t *ver, dns_name_t *origin,
result = dns_dbiterator_next(dbiter) ) { result = dns_dbiterator_next(dbiter) ) {
result = dns_dbiterator_current(dbiter, &node, name); result = dns_dbiterator_current(dbiter, &node, name);
check_dns_dbiterator_current(result); check_dns_dbiterator_current(result);
result = verifynode(&vctx, db, ver, origin, mctx, name, node, result = verifynode(&vctx, name, node, ISC_FALSE, &keyset,
ISC_FALSE, &keyset, act_algorithms, act_algorithms, bad_algorithms, NULL, NULL,
bad_algorithms, NULL, NULL, NULL); NULL);
check_result(result, "verifynode"); check_result(result, "verifynode");
record_found(&vctx, db, ver, mctx, name, node, &nsec3paramset); record_found(&vctx, name, node, &nsec3paramset);
dns_db_detachnode(db, &node); dns_db_detachnode(vctx.db, &node);
} }
dns_dbiterator_destroy(&dbiter); dns_dbiterator_destroy(&dbiter);
@@ -1409,7 +1423,7 @@ dns_zoneverify_dnssec(dns_db_t *db, dns_dbversion_t *ver, dns_name_t *origin,
fatal("DNSSEC completeness test failed (%s).", fatal("DNSSEC completeness test failed (%s).",
dns_result_totext(vresult)); dns_result_totext(vresult));
if (goodksk || ignore_kskflag) { if (vctx.goodksk || ignore_kskflag) {
/* /*
* Print the success summary. * Print the success summary.
*/ */