]> git.ipfire.org Git - thirdparty/bind9.git/commitdiff
Try to read state when reading keylist from rdata
authorMatthijs Mekking <matthijs@isc.org>
Thu, 8 Apr 2021 09:35:03 +0000 (11:35 +0200)
committerMatthijs Mekking <matthijs@isc.org>
Wed, 5 May 2021 10:49:30 +0000 (12:49 +0200)
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.

(cherry picked from commit 7ed089576f295b8330d4527ff0fefda0b228be03)

lib/dns/dnssec.c

index 97316b7d33cafaf06d0c7e13eebf874576b6bf8a..f2a107b5fd05c6e69c35b4764a298f1067ecb7d9 100644 (file)
@@ -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);
        }