]> git.ipfire.org Git - thirdparty/bind9.git/commitdiff
Use dst_key's directory when writing key files
authorMatthijs Mekking <matthijs@isc.org>
Wed, 9 Mar 2022 10:33:03 +0000 (11:33 +0100)
committerMatthijs Mekking <matthijs@isc.org>
Thu, 25 Jan 2024 13:47:43 +0000 (14:47 +0100)
When writing key files to disk, use the internally stored directory.

Add an access function 'dst_key_directory()'.

Most calls to keymgr functions no longer need to provide the
key-directory value. Only 'dns_keymgr_run' still needs access to
the zone's key-directory in case the key-store is set to the built-in
key-directory.

bin/named/server.c
lib/dns/include/dns/keymgr.h
lib/dns/include/dst/dst.h
lib/dns/key.c
lib/dns/keymgr.c
lib/dns/zone.c

index c371fb9c0838c67f244ccad76c489432b2177188..304e1f3e2e1ac26567d45cb6d8c140b14b92921b 100644 (file)
@@ -14636,7 +14636,6 @@ named_server_dnssec(named_server_t *server, isc_lex_t *lex,
        char output[4096];
        isc_stdtime_t now, when;
        isc_time_t timenow, timewhen;
-       const char *dir;
        dns_db_t *db = NULL;
        dns_dbversion_t *version = NULL;
 
@@ -14771,7 +14770,6 @@ named_server_dnssec(named_server_t *server, isc_lex_t *lex,
        }
 
        /* Get DNSSEC keys. */
-       dir = dns_zone_getkeydirectory(zone);
        CHECK(dns_zone_getdb(zone, &db));
        dns_db_currentversion(db, &version);
        LOCK(&kasp->lock);
@@ -14803,11 +14801,11 @@ named_server_dnssec(named_server_t *server, isc_lex_t *lex,
 
                LOCK(&kasp->lock);
                if (use_keyid) {
-                       result = dns_keymgr_checkds_id(kasp, &keys, dir, now,
-                                                      when, dspublish, keyid,
+                       result = dns_keymgr_checkds_id(kasp, &keys, now, when,
+                                                      dspublish, keyid,
                                                       (unsigned int)algorithm);
                } else {
-                       result = dns_keymgr_checkds(kasp, &keys, dir, now, when,
+                       result = dns_keymgr_checkds(kasp, &keys, now, when,
                                                    dspublish);
                }
                UNLOCK(&kasp->lock);
@@ -14858,7 +14856,7 @@ named_server_dnssec(named_server_t *server, isc_lex_t *lex,
                isc_result_t ret;
 
                LOCK(&kasp->lock);
-               result = dns_keymgr_rollover(kasp, &keys, dir, now, when, keyid,
+               result = dns_keymgr_rollover(kasp, &keys, now, when, keyid,
                                             (unsigned int)algorithm);
                UNLOCK(&kasp->lock);
 
index bf08fbb549ed1d8540d057dbdccb2b5507dee0e7..eadb0ea877b551d67954b061a21f5d1ff3734442 100644 (file)
@@ -26,13 +26,13 @@ ISC_LANG_BEGINDECLS
 
 isc_result_t
 dns_keymgr_run(const dns_name_t *origin, dns_rdataclass_t rdclass,
-              const char *directory, isc_mem_t *mctx,
-              dns_dnsseckeylist_t *keyring, dns_dnsseckeylist_t *dnskeys,
+              isc_mem_t *mctx, dns_dnsseckeylist_t *keyring,
+              dns_dnsseckeylist_t *dnskeys, const char *keydir,
               dns_kasp_t *kasp, isc_stdtime_t now, isc_stdtime_t *nexttime);
 /*%<
  * Manage keys in 'keyring' and update timing data according to 'kasp' policy.
- * Create new keys for 'origin' if necessary in 'directory'.  Append all such
- * keys, along with use hints gleaned from their metadata, onto 'keyring'.
+ * Create new keys for 'origin' if necessary.  Append all such keys, along
+ * with use hints gleaned from their metadata, onto 'keyring'.
  *
  * Update key states and store changes back to disk. Store when to run next
  * in 'nexttime'.
@@ -54,13 +54,11 @@ dns_keymgr_run(const dns_name_t *origin, dns_rdataclass_t rdclass,
 
 isc_result_t
 dns_keymgr_checkds(dns_kasp_t *kasp, dns_dnsseckeylist_t *keyring,
-                  const char *directory, isc_stdtime_t now, isc_stdtime_t when,
-                  bool dspublish);
+                  isc_stdtime_t now, isc_stdtime_t when, bool dspublish);
 isc_result_t
 dns_keymgr_checkds_id(dns_kasp_t *kasp, dns_dnsseckeylist_t *keyring,
-                     const char *directory, isc_stdtime_t now,
-                     isc_stdtime_t when, bool dspublish, dns_keytag_t id,
-                     unsigned int algorithm);
+                     isc_stdtime_t now, isc_stdtime_t when, bool dspublish,
+                     dns_keytag_t id, unsigned int algorithm);
 /*%<
  * Check DS for one key in 'keyring'. The key must have the KSK role.
  * If 'dspublish' is set to true, set the DS Publish time to 'now'.
@@ -82,8 +80,7 @@ dns_keymgr_checkds_id(dns_kasp_t *kasp, dns_dnsseckeylist_t *keyring,
 
 isc_result_t
 dns_keymgr_rollover(dns_kasp_t *kasp, dns_dnsseckeylist_t *keyring,
-                   const char *directory, isc_stdtime_t now,
-                   isc_stdtime_t when, dns_keytag_t id,
+                   isc_stdtime_t now, isc_stdtime_t when, dns_keytag_t id,
                    unsigned int algorithm);
 /*%<
  * Rollover key with given 'id'. If the 'algorithm' is non-zero, it must
index f83a2adc1110ccf05dee4f56f199c292b8f2a5af..e4895e19327df864c9ead074c97c53189d3c531b 100644 (file)
@@ -765,6 +765,9 @@ dst_key_rid(const dst_key_t *key);
 dns_rdataclass_t
 dst_key_class(const dst_key_t *key);
 
+const char *
+dst_key_directory(const dst_key_t *key);
+
 bool
 dst_key_isprivate(const dst_key_t *key);
 
@@ -1233,6 +1236,15 @@ dst_key_copy_metadata(dst_key_t *to, dst_key_t *from);
  *     'to' and 'from' to be valid.
  */
 
+void
+dst_key_setdirectory(dst_key_t *key, const char *dir);
+/*%<
+ * Set the directory where to store key files for this key.
+ *
+ * Requires:
+ *     'key' to be valid.
+ */
+
 const char *
 dst_hmac_algorithm_totext(dst_algorithm_t alg);
 /*$<
index 2449e8aac1c968eface1de34e512860330a97910..a0cde831a55c147ff950b3ec39cdd328a31118be 100644 (file)
@@ -16,6 +16,7 @@
 #include <stddef.h>
 #include <stdlib.h>
 
+#include <isc/mem.h>
 #include <isc/region.h>
 #include <isc/util.h>
 
@@ -123,6 +124,12 @@ dst_key_class(const dst_key_t *key) {
        return (key->key_class);
 }
 
+const char *
+dst_key_directory(const dst_key_t *key) {
+       REQUIRE(VALID_KEY(key));
+       return (key->directory);
+}
+
 bool
 dst_key_iszonekey(const dst_key_t *key) {
        REQUIRE(VALID_KEY(key));
@@ -247,4 +254,12 @@ dst_key_getttl(const dst_key_t *key) {
        return (key->key_ttl);
 }
 
+void
+dst_key_setdirectory(dst_key_t *key, const char *dir) {
+       if (key->directory != NULL) {
+               isc_mem_free(key->mctx, key->directory);
+       }
+       key->directory = isc_mem_strdup(key->mctx, dir);
+}
+
 /*! \file */
index 027965fef4b6ee0a92a0c161df98127640817d7a..d0059f59a391fd62935376080d56c28eb4f48e4c 100644 (file)
@@ -444,7 +444,7 @@ keymgr_keyid_conflict(dst_key_t *newkey, dns_dnsseckeylist_t *keys) {
  */
 static isc_result_t
 keymgr_createkey(dns_kasp_key_t *kkey, const dns_name_t *origin,
-                dns_rdataclass_t rdclass, isc_mem_t *mctx,
+                dns_rdataclass_t rdclass, isc_mem_t *mctx, const char *keydir,
                 dns_dnsseckeylist_t *keylist, dns_dnsseckeylist_t *newkeys,
                 dst_key_t **dst_key) {
        isc_result_t result = ISC_R_SUCCESS;
@@ -489,6 +489,20 @@ keymgr_createkey(dns_kasp_key_t *kkey, const dns_name_t *origin,
        dst_key_setnum(newkey, DST_NUM_LIFETIME, dns_kasp_key_lifetime(kkey));
        dst_key_setbool(newkey, DST_BOOL_KSK, dns_kasp_key_ksk(kkey));
        dst_key_setbool(newkey, DST_BOOL_ZSK, dns_kasp_key_zsk(kkey));
+
+       if (keystore == NULL ||
+           strcmp(dns_keystore_name(keystore), "key-directory") == 0)
+       {
+               if (keydir != NULL) {
+                       dst_key_setdirectory(newkey, keydir);
+               }
+       } else {
+               if (dns_keystore_directory(keystore) != NULL) {
+                       dst_key_setdirectory(newkey,
+                                            dns_keystore_directory(keystore));
+               }
+       }
+
        *dst_key = newkey;
        return (ISC_R_SUCCESS);
 
@@ -1679,8 +1693,8 @@ static isc_result_t
 keymgr_key_rollover(dns_kasp_key_t *kaspkey, dns_dnsseckey_t *active_key,
                    dns_dnsseckeylist_t *keyring, dns_dnsseckeylist_t *newkeys,
                    const dns_name_t *origin, dns_rdataclass_t rdclass,
-                   dns_kasp_t *kasp, uint32_t lifetime, bool rollover,
-                   isc_stdtime_t now, isc_stdtime_t *nexttime,
+                   dns_kasp_t *kasp, const char *keydir, uint32_t lifetime,
+                   bool rollover, isc_stdtime_t now, isc_stdtime_t *nexttime,
                    isc_mem_t *mctx) {
        char keystr[DST_KEY_FORMATSIZE];
        isc_stdtime_t retire = 0, active = 0, prepub = 0;
@@ -1799,8 +1813,8 @@ keymgr_key_rollover(dns_kasp_key_t *kaspkey, dns_dnsseckey_t *active_key,
                            dns_kasp_key_zsk(kaspkey));
 
                isc_result_t result = keymgr_createkey(kaspkey, origin, rdclass,
-                                                      mctx, keyring, newkeys,
-                                                      &dst_key);
+                                                      mctx, keydir, keyring,
+                                                      newkeys, &dst_key);
                if (result != ISC_R_SUCCESS) {
                        return (result);
                }
@@ -1944,7 +1958,7 @@ keymgr_key_may_be_purged(dst_key_t *key, uint32_t after, isc_stdtime_t now) {
 }
 
 static void
-keymgr_purge_keyfile(dst_key_t *key, const char *dir, int type) {
+keymgr_purge_keyfile(dst_key_t *key, int type) {
        isc_result_t ret;
        isc_buffer_t fileb;
        char filename[NAME_MAX];
@@ -1953,7 +1967,7 @@ keymgr_purge_keyfile(dst_key_t *key, const char *dir, int type) {
         * Make the filename.
         */
        isc_buffer_init(&fileb, filename, sizeof(filename));
-       ret = dst_key_buildfilename(key, type, dir, &fileb);
+       ret = dst_key_buildfilename(key, type, dst_key_directory(key), &fileb);
        if (ret != ISC_R_SUCCESS) {
                char keystr[DST_KEY_FORMATSIZE];
                dst_key_format(key, keystr, sizeof(keystr));
@@ -1983,8 +1997,8 @@ keymgr_purge_keyfile(dst_key_t *key, const char *dir, int type) {
  */
 isc_result_t
 dns_keymgr_run(const dns_name_t *origin, dns_rdataclass_t rdclass,
-              const char *directory, isc_mem_t *mctx,
-              dns_dnsseckeylist_t *keyring, dns_dnsseckeylist_t *dnskeys,
+              isc_mem_t *mctx, dns_dnsseckeylist_t *keyring,
+              dns_dnsseckeylist_t *dnskeys, const char *keydir,
               dns_kasp_t *kasp, isc_stdtime_t now, isc_stdtime_t *nexttime) {
        isc_result_t result = ISC_R_SUCCESS;
        dns_dnsseckeylist_t newkeys;
@@ -2004,14 +2018,6 @@ dns_keymgr_run(const dns_name_t *origin, dns_rdataclass_t rdclass,
 
        ISC_LIST_INIT(newkeys);
 
-       isc_dir_init(&dir);
-       if (directory == NULL) {
-               directory = ".";
-       }
-
-       RETERR(isc_dir_open(&dir, directory));
-       dir_open = true;
-
        *nexttime = 0;
 
        /* Debug logging: what keys are available in the keyring? */
@@ -2086,13 +2092,9 @@ dns_keymgr_run(const dns_name_t *origin, dns_rdataclass_t rdclass,
                                      keystr, keymgr_keyrole(dkey->key),
                                      dns_kasp_getname(kasp));
 
-                       keymgr_purge_keyfile(dkey->key, directory,
-                                            DST_TYPE_PUBLIC);
-                       keymgr_purge_keyfile(dkey->key, directory,
-                                            DST_TYPE_PRIVATE);
-                       keymgr_purge_keyfile(dkey->key, directory,
-                                            DST_TYPE_STATE);
-
+                       keymgr_purge_keyfile(dkey->key, DST_TYPE_PUBLIC);
+                       keymgr_purge_keyfile(dkey->key, DST_TYPE_PRIVATE);
+                       keymgr_purge_keyfile(dkey->key, DST_TYPE_STATE);
                        dkey->purge = true;
                }
        }
@@ -2201,9 +2203,10 @@ dns_keymgr_run(const dns_name_t *origin, dns_rdataclass_t rdclass,
                }
 
                /* See if this key requires a rollover. */
-               RETERR(keymgr_key_rollover(
-                       kkey, active_key, keyring, &newkeys, origin, rdclass,
-                       kasp, lifetime, rollover_allowed, now, nexttime, mctx));
+               RETERR(keymgr_key_rollover(kkey, active_key, keyring, &newkeys,
+                                          origin, rdclass, kasp, keydir,
+                                          lifetime, rollover_allowed, now,
+                                          nexttime, mctx));
        }
 
        /* Walked all kasp key configurations.  Append new keys. */
@@ -2221,6 +2224,7 @@ dns_keymgr_run(const dns_name_t *origin, dns_rdataclass_t rdclass,
        keymgr_update(keyring, kasp, now, nexttime, secure_to_insecure);
 
        /* Store key states and update hints. */
+       isc_dir_init(&dir);
        for (dns_dnsseckey_t *dkey = ISC_LIST_HEAD(*keyring); dkey != NULL;
             dkey = ISC_LIST_NEXT(dkey, link))
        {
@@ -2230,8 +2234,31 @@ dns_keymgr_run(const dns_name_t *origin, dns_rdataclass_t rdclass,
                        modified = true;
                }
                if (modified && !dkey->purge) {
+                       const char *directory = dst_key_directory(dkey->key);
+                       if (directory == NULL) {
+                               directory = ".";
+                       }
+
+                       RETERR(isc_dir_open(&dir, directory));
+                       dir_open = true;
+
                        dns_dnssec_get_hints(dkey, now);
                        RETERR(dst_key_tofile(dkey->key, options, directory));
+                       dst_key_setmodified(dkey->key, false);
+
+                       isc_dir_close(&dir);
+                       dir_open = false;
+
+                       if (!isc_log_wouldlog(dns_lctx, ISC_LOG_DEBUG(3))) {
+                               continue;
+                       }
+                       dst_key_format(dkey->key, keystr, sizeof(keystr));
+                       isc_log_write(dns_lctx, DNS_LOGCATEGORY_DNSSEC,
+                                     DNS_LOGMODULE_DNSSEC, ISC_LOG_DEBUG(3),
+                                     "keymgr: DNSKEY %s (%s) "
+                                     "saved to directory %s, policy %s",
+                                     keystr, keymgr_keyrole(dkey->key),
+                                     directory, dns_kasp_getname(kasp));
                }
                dst_key_setmodified(dkey->key, false);
        }
@@ -2264,10 +2291,10 @@ failure:
 
 static isc_result_t
 keymgr_checkds(dns_kasp_t *kasp, dns_dnsseckeylist_t *keyring,
-              const char *directory, isc_stdtime_t now, isc_stdtime_t when,
-              bool dspublish, dns_keytag_t id, unsigned int alg,
-              bool check_id) {
+              isc_stdtime_t now, isc_stdtime_t when, bool dspublish,
+              dns_keytag_t id, unsigned int alg, bool check_id) {
        int options = (DST_TYPE_PRIVATE | DST_TYPE_PUBLIC | DST_TYPE_STATE);
+       const char *directory = NULL;
        isc_dir_t dir;
        isc_result_t result;
        dns_dnsseckey_t *ksk_key = NULL;
@@ -2336,6 +2363,7 @@ keymgr_checkds(dns_kasp_t *kasp, dns_dnsseckeylist_t *keyring,
 
        /* Store key state and update hints. */
        isc_dir_init(&dir);
+       directory = dst_key_directory(ksk_key->key);
        if (directory == NULL) {
                directory = ".";
        }
@@ -2356,19 +2384,17 @@ keymgr_checkds(dns_kasp_t *kasp, dns_dnsseckeylist_t *keyring,
 
 isc_result_t
 dns_keymgr_checkds(dns_kasp_t *kasp, dns_dnsseckeylist_t *keyring,
-                  const char *directory, isc_stdtime_t now, isc_stdtime_t when,
-                  bool dspublish) {
-       return (keymgr_checkds(kasp, keyring, directory, now, when, dspublish,
-                              0, 0, false));
+                  isc_stdtime_t now, isc_stdtime_t when, bool dspublish) {
+       return (keymgr_checkds(kasp, keyring, now, when, dspublish, 0, 0,
+                              false));
 }
 
 isc_result_t
 dns_keymgr_checkds_id(dns_kasp_t *kasp, dns_dnsseckeylist_t *keyring,
-                     const char *directory, isc_stdtime_t now,
-                     isc_stdtime_t when, bool dspublish, dns_keytag_t id,
-                     unsigned int alg) {
-       return (keymgr_checkds(kasp, keyring, directory, now, when, dspublish,
-                              id, alg, true));
+                     isc_stdtime_t now, isc_stdtime_t when, bool dspublish,
+                     dns_keytag_t id, unsigned int alg) {
+       return (keymgr_checkds(kasp, keyring, now, when, dspublish, id, alg,
+                              true));
 }
 
 static void
@@ -2575,10 +2601,10 @@ dns_keymgr_status(dns_kasp_t *kasp, dns_dnsseckeylist_t *keyring,
 
 isc_result_t
 dns_keymgr_rollover(dns_kasp_t *kasp, dns_dnsseckeylist_t *keyring,
-                   const char *directory, isc_stdtime_t now,
-                   isc_stdtime_t when, dns_keytag_t id,
+                   isc_stdtime_t now, isc_stdtime_t when, dns_keytag_t id,
                    unsigned int algorithm) {
        int options = (DST_TYPE_PRIVATE | DST_TYPE_PUBLIC | DST_TYPE_STATE);
+       const char *directory = NULL;
        isc_dir_t dir;
        isc_result_t result;
        dns_dnsseckey_t *key = NULL;
@@ -2639,6 +2665,7 @@ dns_keymgr_rollover(dns_kasp_t *kasp, dns_dnsseckeylist_t *keyring,
 
        /* Store key state and update hints. */
        isc_dir_init(&dir);
+       directory = dst_key_directory(key->key);
        if (directory == NULL) {
                directory = ".";
        }
index 7651dcb3e9256aad9e5a4b7f035d2c0d56929ff5..428dfd94b9b05e4ec3846ae36ebafca64911f4da 100644 (file)
@@ -20355,7 +20355,6 @@ static bool
 do_checkds(dns_zone_t *zone, dst_key_t *key, isc_stdtime_t now,
           bool dspublish) {
        dns_kasp_t *kasp = zone->kasp;
-       const char *dir = dns_zone_getkeydirectory(zone);
        isc_result_t result;
        uint32_t count = 0;
        uint32_t num;
@@ -20406,7 +20405,7 @@ do_checkds(dns_zone_t *zone, dst_key_t *key, isc_stdtime_t now,
                     dspublish ? "published" : "withdrawn", dst_key_id(key));
 
        dns_zone_lock_keyfiles(zone);
-       result = dns_keymgr_checkds_id(kasp, &zone->checkds_ok, dir, now, now,
+       result = dns_keymgr_checkds_id(kasp, &zone->checkds_ok, now, now,
                                       dspublish, dst_key_id(key),
                                       dst_key_alg(key));
        dns_zone_unlock_keyfiles(zone);
@@ -21608,7 +21607,6 @@ zone_rekey(dns_zone_t *zone) {
        dns_rdataset_init(&keysigs);
        dns_rdataset_init(&cdsset);
        dns_rdataset_init(&cdnskeyset);
-       dir = dns_zone_getkeydirectory(zone);
        mctx = zone->mctx;
        dns_diff_init(mctx, &diff);
        dns_diff_init(mctx, &_sig_diff);
@@ -21622,6 +21620,7 @@ zone_rekey(dns_zone_t *zone) {
        now = isc_time_seconds(&timenow);
 
        kasp = zone->kasp;
+       dir = dns_zone_getkeydirectory(zone);
 
        dnssec_log(zone, ISC_LOG_INFO, "reconfiguring zone keys");
 
@@ -21767,7 +21766,7 @@ zone_rekey(dns_zone_t *zone) {
                if (result == ISC_R_SUCCESS || result == ISC_R_NOTFOUND) {
                        dns_zone_lock_keyfiles(zone);
                        result = dns_keymgr_run(&zone->origin, zone->rdclass,
-                                               dir, mctx, &keys, &dnskeys,
+                                               mctx, &keys, &dnskeys, dir,
                                                kasp, now, &nexttime);
                        dns_zone_unlock_keyfiles(zone);