From: Evan Hunt Date: Sun, 17 Nov 2019 20:14:40 +0000 (-0800) Subject: add support for DS trust anchors in mirror zone verification X-Git-Tag: v9.15.6~2^2 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=0f9d8eb7b590a7c65fd33d12011d97080ed93140;p=thirdparty%2Fbind9.git add support for DS trust anchors in mirror zone verification --- diff --git a/bin/tests/system/mirror/ns1/sign.sh b/bin/tests/system/mirror/ns1/sign.sh index 2d483cd76ae..ba61cc74965 100644 --- a/bin/tests/system/mirror/ns1/sign.sh +++ b/bin/tests/system/mirror/ns1/sign.sh @@ -33,4 +33,4 @@ $SIGNER -P -g -o $zone $zonefile > /dev/null # irrelevant here, so just reuse the root zone key generated above. sed "s/^\./nonexistent./;" $keyname1.key > $keyname1.modified.key -keyfile_to_static_keys $keyname1 $keyname1.modified > trusted.conf +keyfile_to_static_ds $keyname1 $keyname1.modified > trusted.conf diff --git a/bin/tests/system/mirror/ns2/sign.sh b/bin/tests/system/mirror/ns2/sign.sh index 5553844f30f..3d2e3ce046e 100644 --- a/bin/tests/system/mirror/ns2/sign.sh +++ b/bin/tests/system/mirror/ns2/sign.sh @@ -75,4 +75,4 @@ for variant in addzone axfr ixfr load reconfig untrusted; do fi done -keyfile_to_static_keys $keys_to_trust > trusted-mirror.conf +keyfile_to_static_ds $keys_to_trust > trusted-mirror.conf diff --git a/lib/dns/zoneverify.c b/lib/dns/zoneverify.c index a1d43d9496e..265fdf6dbe4 100644 --- a/lib/dns/zoneverify.c +++ b/lib/dns/zoneverify.c @@ -1501,23 +1501,27 @@ check_apex_rrsets(vctx_t *vctx) { */ static void check_dnskey_sigs(vctx_t *vctx, const dns_rdata_dnskey_t *dnskey, - dns_rdata_t *rdata, bool is_ksk) + dns_rdata_t *keyrdata, bool is_ksk) { unsigned char *active_keys = NULL, *standby_keys = NULL; dns_keynode_t *keynode = NULL; bool *goodkey = NULL; dst_key_t *key = NULL; isc_result_t result; + dns_rdataset_t *dsset = NULL; active_keys = (is_ksk ? vctx->ksk_algorithms : vctx->zsk_algorithms); standby_keys = (is_ksk ? vctx->standby_ksk : vctx->standby_zsk); goodkey = (is_ksk ? &vctx->goodksk : &vctx->goodzsk); - if (!dns_dnssec_selfsigns(rdata, vctx->origin, &vctx->keyset, + /* + * First, does this key sign the DNSKEY rrset? + */ + if (!dns_dnssec_selfsigns(keyrdata, vctx->origin, &vctx->keyset, &vctx->keysigs, false, vctx->mctx)) { if (!is_ksk && - dns_dnssec_signs(rdata, vctx->origin, &vctx->soaset, + dns_dnssec_signs(keyrdata, vctx->origin, &vctx->soaset, &vctx->soasigs, false, vctx->mctx)) { if (active_keys[dnskey->algorithm] != 255) { @@ -1544,26 +1548,87 @@ check_dnskey_sigs(vctx_t *vctx, const dns_rdata_dnskey_t *dnskey, return; } + /* + * Convert the supplied key rdata to dst_key_t. (If this + * fails we can't go further.) + */ + result = dns_dnssec_keyfromrdata(vctx->origin, keyrdata, + vctx->mctx, &key); + RUNTIME_CHECK(result == ISC_R_SUCCESS); + /* * Look up the supplied key in the trust anchor table. + * If we don't find an exact match, or if the keynode data + * is NULL, then we have neither a DNSKEY nor a DS format + * trust anchor, and can give up. */ - result = dns_dnssec_keyfromrdata(vctx->origin, rdata, vctx->mctx, - &key); + result = dns_keytable_find(vctx->secroots, vctx->origin, &keynode); if (result != ISC_R_SUCCESS) { + /* No such trust anchor */ goto cleanup; } - result = dns_keytable_findkeynode(vctx->secroots, vctx->origin, - dst_key_alg(key), dst_key_id(key), - &keynode); + /* + * If the keynode has any DS format trust anchors, that means + * it doesn't have any DNSKEY ones. So, we can check for a DS + * match and then stop. + */ + if ((dsset = dns_keynode_dsset(keynode)) != NULL) { + for (result = dns_rdataset_first(dsset); + result == ISC_R_SUCCESS; + result = dns_rdataset_next(dsset)) + { + dns_rdata_t dsrdata = DNS_RDATA_INIT; + dns_rdata_t newdsrdata = DNS_RDATA_INIT; + unsigned char buf[DNS_DS_BUFFERSIZE]; + dns_rdata_ds_t ds; + + dns_rdata_reset(&dsrdata); + dns_rdataset_current(dsset, &dsrdata); + result = dns_rdata_tostruct(&dsrdata, &ds, NULL); + RUNTIME_CHECK(result == ISC_R_SUCCESS); + + if (ds.key_tag != dst_key_id(key) || + ds.algorithm != dst_key_alg(key)) + { + continue; + } + + result = dns_ds_buildrdata(vctx->origin, keyrdata, + ds.digest_type, buf, + &newdsrdata); + if (result != ISC_R_SUCCESS) { + continue; + } + + if (dns_rdata_compare(&dsrdata, &newdsrdata) == 0) { + dns_rdataset_settrust(&vctx->keyset, + dns_trust_secure); + dns_rdataset_settrust(&vctx->keysigs, + dns_trust_secure); + *goodkey = true; + break; + } + } + + goto cleanup; + } /* - * No such trust anchor. + * The keynode didn't have any DS trust anchors, so we now try to + * find a matching DNSKEY trust anchor. */ + result = dns_keytable_findkeynode(vctx->secroots, vctx->origin, + dst_key_alg(key), dst_key_id(key), + &keynode); if (result != ISC_R_SUCCESS) { goto cleanup; } + /* + * Walk the keynode list until we find a matching key or + * reach the end. + */ while (result == ISC_R_SUCCESS) { dns_keynode_t *nextnode = NULL;