From: Matthijs Mekking Date: Wed, 9 Mar 2022 10:33:03 +0000 (+0100) Subject: Use dst_key's directory when writing key files X-Git-Tag: v9.19.22~70^2~22 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=80387532cd1f714bfc9b7b5f93a0ea1754ea87e8;p=thirdparty%2Fbind9.git Use dst_key's directory when writing key files 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. --- diff --git a/bin/named/server.c b/bin/named/server.c index c371fb9c083..304e1f3e2e1 100644 --- a/bin/named/server.c +++ b/bin/named/server.c @@ -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); diff --git a/lib/dns/include/dns/keymgr.h b/lib/dns/include/dns/keymgr.h index bf08fbb549e..eadb0ea877b 100644 --- a/lib/dns/include/dns/keymgr.h +++ b/lib/dns/include/dns/keymgr.h @@ -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 diff --git a/lib/dns/include/dst/dst.h b/lib/dns/include/dst/dst.h index f83a2adc111..e4895e19327 100644 --- a/lib/dns/include/dst/dst.h +++ b/lib/dns/include/dst/dst.h @@ -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); /*$< diff --git a/lib/dns/key.c b/lib/dns/key.c index 2449e8aac1c..a0cde831a55 100644 --- a/lib/dns/key.c +++ b/lib/dns/key.c @@ -16,6 +16,7 @@ #include #include +#include #include #include @@ -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 */ diff --git a/lib/dns/keymgr.c b/lib/dns/keymgr.c index 027965fef4b..d0059f59a39 100644 --- a/lib/dns/keymgr.c +++ b/lib/dns/keymgr.c @@ -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 = "."; } diff --git a/lib/dns/zone.c b/lib/dns/zone.c index 7651dcb3e92..428dfd94b9b 100644 --- a/lib/dns/zone.c +++ b/lib/dns/zone.c @@ -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);