Try to read state when reading keylist from rdata
The function 'dns_dnssec_keylistfromrdataset()' creates a keylist from the DNSKEY RRset. If we attempt to read the private key, we also store the key state. However, if the private key is offline, the key state will not be stored. To fix this, first attempt to read the public key file. If then reading the private key file fails, and we do have a public key, add that to the keylist, with appropriate state. If we also failed to read the public key file, add the DNSKEY to the keylist, as we did before.
This commit is contained in:
@@ -1657,7 +1657,7 @@ dns_dnssec_keylistfromrdataset(const dns_name_t *origin, const char *directory,
|
||||
dns_dnsseckeylist_t *keylist) {
|
||||
dns_rdataset_t keys;
|
||||
dns_rdata_t rdata = DNS_RDATA_INIT;
|
||||
dst_key_t *pubkey = NULL, *privkey = NULL;
|
||||
dst_key_t *dnskey = NULL, *pubkey = NULL, *privkey = NULL;
|
||||
isc_result_t result;
|
||||
|
||||
REQUIRE(keyset != NULL && dns_rdataset_isassociated(keyset));
|
||||
@@ -1680,27 +1680,38 @@ dns_dnssec_keylistfromrdataset(const dns_name_t *origin, const char *directory,
|
||||
goto skip;
|
||||
}
|
||||
|
||||
RETERR(dns_dnssec_keyfromrdata(origin, &rdata, mctx, &pubkey));
|
||||
dst_key_setttl(pubkey, keys.ttl);
|
||||
RETERR(dns_dnssec_keyfromrdata(origin, &rdata, mctx, &dnskey));
|
||||
dst_key_setttl(dnskey, keys.ttl);
|
||||
|
||||
if (!is_zone_key(pubkey) ||
|
||||
(dst_key_flags(pubkey) & DNS_KEYTYPE_NOAUTH) != 0) {
|
||||
if (!is_zone_key(dnskey) ||
|
||||
(dst_key_flags(dnskey) & DNS_KEYTYPE_NOAUTH) != 0) {
|
||||
goto skip;
|
||||
}
|
||||
|
||||
/* Corrupted .key file? */
|
||||
if (!dns_name_equal(origin, dst_key_name(pubkey))) {
|
||||
if (!dns_name_equal(origin, dst_key_name(dnskey))) {
|
||||
goto skip;
|
||||
}
|
||||
|
||||
if (publickey) {
|
||||
RETERR(addkey(keylist, &pubkey, savekeys, mctx));
|
||||
RETERR(addkey(keylist, &dnskey, savekeys, mctx));
|
||||
goto skip;
|
||||
}
|
||||
|
||||
/* Try to read the public key. */
|
||||
result = dst_key_fromfile(
|
||||
dst_key_name(pubkey), dst_key_id(pubkey),
|
||||
dst_key_alg(pubkey),
|
||||
dst_key_name(dnskey), dst_key_id(dnskey),
|
||||
dst_key_alg(dnskey), (DST_TYPE_PUBLIC | DST_TYPE_STATE),
|
||||
directory, mctx, &pubkey);
|
||||
if (result == ISC_R_FILENOTFOUND || result == ISC_R_NOPERM) {
|
||||
result = ISC_R_SUCCESS;
|
||||
}
|
||||
RETERR(result);
|
||||
|
||||
/* Now read the private key. */
|
||||
result = dst_key_fromfile(
|
||||
dst_key_name(dnskey), dst_key_id(dnskey),
|
||||
dst_key_alg(dnskey),
|
||||
(DST_TYPE_PUBLIC | DST_TYPE_PRIVATE | DST_TYPE_STATE),
|
||||
directory, mctx, &privkey);
|
||||
|
||||
@@ -1711,22 +1722,22 @@ dns_dnssec_keylistfromrdataset(const dns_name_t *origin, const char *directory,
|
||||
*/
|
||||
if (result == ISC_R_FILENOTFOUND) {
|
||||
uint32_t flags;
|
||||
flags = dst_key_flags(pubkey);
|
||||
flags = dst_key_flags(dnskey);
|
||||
if ((flags & DNS_KEYFLAG_REVOKE) != 0) {
|
||||
dst_key_setflags(pubkey,
|
||||
dst_key_setflags(dnskey,
|
||||
flags & ~DNS_KEYFLAG_REVOKE);
|
||||
result = dst_key_fromfile(
|
||||
dst_key_name(pubkey),
|
||||
dst_key_id(pubkey), dst_key_alg(pubkey),
|
||||
dst_key_name(dnskey),
|
||||
dst_key_id(dnskey), dst_key_alg(dnskey),
|
||||
(DST_TYPE_PUBLIC | DST_TYPE_PRIVATE |
|
||||
DST_TYPE_STATE),
|
||||
directory, mctx, &privkey);
|
||||
if (result == ISC_R_SUCCESS &&
|
||||
dst_key_pubcompare(pubkey, privkey, false))
|
||||
dst_key_pubcompare(dnskey, privkey, false))
|
||||
{
|
||||
dst_key_setflags(privkey, flags);
|
||||
}
|
||||
dst_key_setflags(pubkey, flags);
|
||||
dst_key_setflags(dnskey, flags);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1739,8 +1750,8 @@ dns_dnssec_keylistfromrdataset(const dns_name_t *origin, const char *directory,
|
||||
|
||||
isc_buffer_init(&buf, filename, NAME_MAX);
|
||||
result2 = dst_key_getfilename(
|
||||
dst_key_name(pubkey), dst_key_id(pubkey),
|
||||
dst_key_alg(pubkey),
|
||||
dst_key_name(dnskey), dst_key_id(dnskey),
|
||||
dst_key_alg(dnskey),
|
||||
(DST_TYPE_PUBLIC | DST_TYPE_PRIVATE |
|
||||
DST_TYPE_STATE),
|
||||
directory, mctx, &buf);
|
||||
@@ -1748,13 +1759,13 @@ dns_dnssec_keylistfromrdataset(const dns_name_t *origin, const char *directory,
|
||||
char namebuf[DNS_NAME_FORMATSIZE];
|
||||
char algbuf[DNS_SECALG_FORMATSIZE];
|
||||
|
||||
dns_name_format(dst_key_name(pubkey), namebuf,
|
||||
dns_name_format(dst_key_name(dnskey), namebuf,
|
||||
sizeof(namebuf));
|
||||
dns_secalg_format(dst_key_alg(pubkey), algbuf,
|
||||
dns_secalg_format(dst_key_alg(dnskey), algbuf,
|
||||
sizeof(algbuf));
|
||||
snprintf(filename, sizeof(filename) - 1,
|
||||
"key file for %s/%s/%d", namebuf,
|
||||
algbuf, dst_key_id(pubkey));
|
||||
algbuf, dst_key_id(dnskey));
|
||||
}
|
||||
|
||||
isc_log_write(dns_lctx, DNS_LOGCATEGORY_GENERAL,
|
||||
@@ -1765,7 +1776,13 @@ dns_dnssec_keylistfromrdataset(const dns_name_t *origin, const char *directory,
|
||||
}
|
||||
|
||||
if (result == ISC_R_FILENOTFOUND || result == ISC_R_NOPERM) {
|
||||
RETERR(addkey(keylist, &pubkey, savekeys, mctx));
|
||||
if (pubkey != NULL) {
|
||||
RETERR(addkey(keylist, &pubkey, savekeys,
|
||||
mctx));
|
||||
} else {
|
||||
RETERR(addkey(keylist, &dnskey, savekeys,
|
||||
mctx));
|
||||
}
|
||||
goto skip;
|
||||
}
|
||||
RETERR(result);
|
||||
@@ -1779,10 +1796,13 @@ dns_dnssec_keylistfromrdataset(const dns_name_t *origin, const char *directory,
|
||||
* Whatever the key's default TTL may have
|
||||
* been, the rdataset TTL takes priority.
|
||||
*/
|
||||
dst_key_setttl(privkey, dst_key_getttl(pubkey));
|
||||
dst_key_setttl(privkey, dst_key_getttl(dnskey));
|
||||
|
||||
RETERR(addkey(keylist, &privkey, savekeys, mctx));
|
||||
skip:
|
||||
if (dnskey != NULL) {
|
||||
dst_key_free(&dnskey);
|
||||
}
|
||||
if (pubkey != NULL) {
|
||||
dst_key_free(&pubkey);
|
||||
}
|
||||
@@ -1809,6 +1829,9 @@ failure:
|
||||
if (dns_rdataset_isassociated(&keys)) {
|
||||
dns_rdataset_disassociate(&keys);
|
||||
}
|
||||
if (dnskey != NULL) {
|
||||
dst_key_free(&dnskey);
|
||||
}
|
||||
if (pubkey != NULL) {
|
||||
dst_key_free(&pubkey);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user