mirror of
https://github.com/isc-projects/bind9.git
synced 2026-06-11 03:59:59 -04:00
Add function to check if a DNSKEY record is in use
Add a function that checks whether a DNSKEY, CDNSKEY, or CDS record
belongs to a key that is being used for signing.
(cherry picked from commit 3b6e9a5fa7)
This commit is contained in:
parent
0d36d98791
commit
88734ac7cf
2 changed files with 198 additions and 0 deletions
|
|
@ -392,6 +392,24 @@ dns_zone_unlock_keyfiles(dns_zone_t *zone);
|
|||
*\li 'zone' to be a valid zone.
|
||||
*/
|
||||
|
||||
isc_result_t
|
||||
dns_zone_dnskey_inuse(dns_zone_t *zone, dns_rdata_t *rdata, bool *inuse);
|
||||
/*%<
|
||||
* Check if the DNSKEY record 'rdata' is used by 'zone' for zone signing.
|
||||
* Store the result in 'inuse'.
|
||||
*
|
||||
* Require:
|
||||
*\li 'zone' to be a valid zone.
|
||||
*\li 'rdata' to represent a DNSKEY, CDNSKEY, or CDS record.
|
||||
*
|
||||
* Returns:
|
||||
*\li #ISC_R_SUCCESS
|
||||
*\li Any error result from dns_dnssec_keyfromrdata, dns_rdata_tostruct,
|
||||
* dns_dnssec_make_dnskey, dns_ds_buildrdata, or
|
||||
* dns_dnssec_findmatchingkeys.
|
||||
*
|
||||
*/
|
||||
|
||||
isc_result_t
|
||||
dns_zone_load(dns_zone_t *zone, bool newonly);
|
||||
|
||||
|
|
|
|||
180
lib/dns/zone.c
180
lib/dns/zone.c
|
|
@ -16329,6 +16329,186 @@ update_log_cb(void *arg, dns_zone_t *zone, int level, const char *message) {
|
|||
dns_zone_log(zone, level, "%s", message);
|
||||
}
|
||||
|
||||
static isc_result_t
|
||||
dnskey_inuse(dns_zone_t *zone, dns_rdata_t *rdata, isc_mem_t *mctx,
|
||||
dns_dnsseckeylist_t *keylist, bool *inuse) {
|
||||
isc_result_t result;
|
||||
dst_key_t *dstkey = NULL;
|
||||
|
||||
result = dns_dnssec_keyfromrdata(dns_zone_getorigin(zone), rdata, mctx,
|
||||
&dstkey);
|
||||
if (result != ISC_R_SUCCESS) {
|
||||
dns_zone_log(zone, ISC_LOG_ERROR,
|
||||
"dns_dnssec_keyfromrdata() failed: %s",
|
||||
isc_result_totext(result));
|
||||
return (result);
|
||||
}
|
||||
|
||||
for (dns_dnsseckey_t *k = ISC_LIST_HEAD(*keylist); k != NULL;
|
||||
k = ISC_LIST_NEXT(k, link))
|
||||
{
|
||||
if (dst_key_pubcompare(k->key, dstkey, false)) {
|
||||
*inuse = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
dst_key_free(&dstkey);
|
||||
return (ISC_R_SUCCESS);
|
||||
}
|
||||
|
||||
static isc_result_t
|
||||
cdnskey_inuse(dns_zone_t *zone, dns_rdata_t *rdata,
|
||||
dns_dnsseckeylist_t *keylist, bool *inuse) {
|
||||
isc_result_t result;
|
||||
dns_rdata_cdnskey_t cdnskey;
|
||||
|
||||
result = dns_rdata_tostruct(rdata, &cdnskey, NULL);
|
||||
if (result != ISC_R_SUCCESS) {
|
||||
dns_zone_log(zone, ISC_LOG_ERROR,
|
||||
"dns_rdata_tostruct(cdnskey) failed: %s",
|
||||
isc_result_totext(result));
|
||||
return (result);
|
||||
}
|
||||
|
||||
for (dns_dnsseckey_t *k = ISC_LIST_HEAD(*keylist); k != NULL;
|
||||
k = ISC_LIST_NEXT(k, link))
|
||||
{
|
||||
dns_rdata_t cdnskeyrdata = DNS_RDATA_INIT;
|
||||
unsigned char keybuf[DST_KEY_MAXSIZE];
|
||||
|
||||
result = dns_dnssec_make_dnskey(k->key, keybuf, sizeof(keybuf),
|
||||
&cdnskeyrdata);
|
||||
if (result != ISC_R_SUCCESS) {
|
||||
dns_zone_log(zone, ISC_LOG_ERROR,
|
||||
"dns_dnssec_make_dnskey() failed: %s",
|
||||
isc_result_totext(result));
|
||||
return (result);
|
||||
}
|
||||
|
||||
cdnskeyrdata.type = dns_rdatatype_cdnskey;
|
||||
if (dns_rdata_compare(rdata, &cdnskeyrdata) == 0) {
|
||||
*inuse = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return (ISC_R_SUCCESS);
|
||||
}
|
||||
|
||||
static isc_result_t
|
||||
cds_inuse(dns_zone_t *zone, dns_rdata_t *rdata, dns_dnsseckeylist_t *keylist,
|
||||
bool *inuse) {
|
||||
isc_result_t result;
|
||||
dns_rdata_ds_t cds;
|
||||
|
||||
result = dns_rdata_tostruct(rdata, &cds, NULL);
|
||||
if (result != ISC_R_SUCCESS) {
|
||||
dns_zone_log(zone, ISC_LOG_ERROR,
|
||||
"dns_rdata_tostruct(cds) failed: %s",
|
||||
isc_result_totext(result));
|
||||
return (result);
|
||||
}
|
||||
|
||||
for (dns_dnsseckey_t *k = ISC_LIST_HEAD(*keylist); k != NULL;
|
||||
k = ISC_LIST_NEXT(k, link))
|
||||
{
|
||||
dns_rdata_t dnskey = DNS_RDATA_INIT;
|
||||
dns_rdata_t cdsrdata = DNS_RDATA_INIT;
|
||||
unsigned char keybuf[DST_KEY_MAXSIZE];
|
||||
unsigned char cdsbuf[DNS_DS_BUFFERSIZE];
|
||||
|
||||
if (dst_key_id(k->key) != cds.key_tag ||
|
||||
dst_key_alg(k->key) != cds.algorithm)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
result = dns_dnssec_make_dnskey(k->key, keybuf, sizeof(keybuf),
|
||||
&dnskey);
|
||||
if (result != ISC_R_SUCCESS) {
|
||||
dns_zone_log(zone, ISC_LOG_ERROR,
|
||||
"dns_dnssec_make_dnskey() failed: %s",
|
||||
isc_result_totext(result));
|
||||
return (result);
|
||||
}
|
||||
result = dns_ds_buildrdata(dns_zone_getorigin(zone), &dnskey,
|
||||
cds.digest_type, cdsbuf, &cdsrdata);
|
||||
if (result != ISC_R_SUCCESS) {
|
||||
dns_zone_log(zone, ISC_LOG_ERROR,
|
||||
"dns_ds_buildrdata(keytag=%d, algo=%d, "
|
||||
"digest=%d) failed: %s",
|
||||
cds.key_tag, cds.algorithm,
|
||||
cds.digest_type,
|
||||
isc_result_totext(result));
|
||||
return (result);
|
||||
}
|
||||
|
||||
cdsrdata.type = dns_rdatatype_cds;
|
||||
if (dns_rdata_compare(rdata, &cdsrdata) == 0) {
|
||||
*inuse = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return (ISC_R_SUCCESS);
|
||||
}
|
||||
|
||||
isc_result_t
|
||||
dns_zone_dnskey_inuse(dns_zone_t *zone, dns_rdata_t *rdata, bool *inuse) {
|
||||
dns_dnsseckeylist_t keylist;
|
||||
dns_dnsseckey_t *key = NULL;
|
||||
isc_result_t result = ISC_R_SUCCESS;
|
||||
isc_stdtime_t now = 0;
|
||||
isc_mem_t *mctx;
|
||||
|
||||
REQUIRE(DNS_ZONE_VALID(zone));
|
||||
REQUIRE(dns_rdatatype_iskeymaterial(rdata->type));
|
||||
|
||||
mctx = zone->mctx;
|
||||
|
||||
isc_stdtime_get(&now);
|
||||
|
||||
ISC_LIST_INIT(keylist);
|
||||
|
||||
*inuse = false;
|
||||
|
||||
dns_zone_lock_keyfiles(zone);
|
||||
result = dns_dnssec_findmatchingkeys(dns_zone_getorigin(zone),
|
||||
dns_zone_getkeydirectory(zone),
|
||||
now, mctx, &keylist);
|
||||
dns_zone_unlock_keyfiles(zone);
|
||||
if (result == ISC_R_NOTFOUND) {
|
||||
return (ISC_R_SUCCESS);
|
||||
} else if (result != ISC_R_SUCCESS) {
|
||||
dns_zone_log(zone, ISC_LOG_ERROR,
|
||||
"dns_dnssec_findmatchingkeys() failed: %s",
|
||||
isc_result_totext(result));
|
||||
return (result);
|
||||
}
|
||||
|
||||
switch (rdata->type) {
|
||||
case dns_rdatatype_dnskey:
|
||||
result = dnskey_inuse(zone, rdata, mctx, &keylist, inuse);
|
||||
break;
|
||||
case dns_rdatatype_cdnskey:
|
||||
result = cdnskey_inuse(zone, rdata, &keylist, inuse);
|
||||
break;
|
||||
case dns_rdatatype_cds:
|
||||
result = cds_inuse(zone, rdata, &keylist, inuse);
|
||||
break;
|
||||
default:
|
||||
UNREACHABLE();
|
||||
break;
|
||||
}
|
||||
|
||||
while (!ISC_LIST_EMPTY(keylist)) {
|
||||
key = ISC_LIST_HEAD(keylist);
|
||||
ISC_LIST_UNLINK(keylist, key, link);
|
||||
dns_dnsseckey_destroy(mctx, &key);
|
||||
}
|
||||
return (result);
|
||||
}
|
||||
|
||||
static isc_result_t
|
||||
sync_secure_journal(dns_zone_t *zone, dns_zone_t *raw, dns_journal_t *journal,
|
||||
uint32_t start, uint32_t end, dns_difftuple_t **soatuplep,
|
||||
|
|
|
|||
Loading…
Reference in a new issue