ISC_LIST_INIT(*keys);
ISC_LIST_INIT(keys_read);
ret = dns_dnssec_findmatchingkeys(name, NULL, ksr->keydir, NULL,
- ksr->now, isc_g_mctx, &keys_read);
+ ksr->now, false, isc_g_mctx,
+ &keys_read);
if (ret != ISC_R_SUCCESS && ret != ISC_R_NOTFOUND) {
fatal("failed to load existing keys from %s: %s", ksr->keydir,
isc_result_totext(ret));
* Find keys that match this zone in the key repository.
*/
result = dns_dnssec_findmatchingkeys(gorigin, NULL, directory, NULL,
- now, isc_g_mctx, &matchkeys);
+ now, false, isc_g_mctx,
+ &matchkeys);
if (result == ISC_R_NOTFOUND) {
result = ISC_R_SUCCESS;
}
}
ISC_LIST_INIT(matchkeys);
- result = dns_dnssec_findmatchingkeys(name, NULL, dir, NULL, now, mctx,
- &matchkeys);
+ bool keykey = false;
+
+ /*
+ * DNSKEY and KEY both use the same file names patterns so
+ * we have to look for both sets of keys.
+ */
+again:
+ result = dns_dnssec_findmatchingkeys(name, NULL, dir, NULL, now, keykey,
+ mctx, &matchkeys);
if (result == ISC_R_NOTFOUND) {
- return false;
+ goto try_key;
}
while (!ISC_LIST_EMPTY(matchkeys) && !conflict) {
dns_dnsseckey_destroy(mctx, &key);
}
+try_key:
+ if (!conflict && !keykey) {
+ keykey = true;
+ goto again;
+ }
return conflict;
}
set_keyversion(dst_key_t *key);
bool
-key_collision(dst_key_t *key, dns_name_t *name, const char *dir,
+key_collision(dst_key_t *dstkey, dns_name_t *name, const char *dir,
isc_mem_t *mctx, uint16_t min, uint16_t max, bool *exact);
bool
}
static isc_result_t
-findmatchingkeys(const char *directory, char *namebuf, unsigned int len,
- isc_mem_t *mctx, isc_stdtime_t now,
+findmatchingkeys(const char *directory, bool rrtypekey, char *namebuf,
+ unsigned int len, isc_mem_t *mctx, isc_stdtime_t now,
dns_dnsseckeylist_t *list) {
- isc_result_t result = ISC_R_SUCCESS;
+ isc_result_t result;
isc_dir_t dir;
- bool dir_open = false;
+ bool dir_open = false, match = false;
unsigned int i, alg;
dns_dnsseckey_t *key = NULL;
dst_key_t *dstkey = NULL;
if (directory == NULL) {
directory = ".";
}
+
RETERR(isc_dir_open(&dir, directory));
dir_open = true;
continue;
}
+ int type = DST_TYPE_PUBLIC | DST_TYPE_PRIVATE | DST_TYPE_STATE;
+ if (rrtypekey) {
+ type |= DST_TYPE_KEY;
+ }
dstkey = NULL;
- result = dst_key_fromnamedfile(
- dir.entry.name, directory,
- DST_TYPE_PUBLIC | DST_TYPE_PRIVATE | DST_TYPE_STATE,
- mctx, &dstkey);
+ result = dst_key_fromnamedfile(dir.entry.name, directory, type,
+ mctx, &dstkey);
switch (alg) {
case DST_ALG_HMACMD5:
dns_dnsseckey_destroy(mctx, &key);
} else {
ISC_LIST_APPEND(*list, key, link);
+ match = true;
key = NULL;
}
}
+ result = match ? ISC_R_SUCCESS : ISC_R_NOTFOUND;
failure:
if (dir_open) {
}
/*%
- * Get a list of DNSSEC keys from the key repository.
+ * Get a list of KEY or DNSKEY keys from the key repository. If rrtypekey
+ * is true KEY keys will be returned otherwise DNSSEC keys.
*/
isc_result_t
dns_dnssec_findmatchingkeys(const dns_name_t *origin, dns_kasp_t *kasp,
const char *keydir, dns_keystorelist_t *keystores,
- isc_stdtime_t now, isc_mem_t *mctx,
+ isc_stdtime_t now, bool rrtypekey, isc_mem_t *mctx,
dns_dnsseckeylist_t *keylist) {
isc_result_t result = ISC_R_SUCCESS;
dns_dnsseckeylist_t list;
if (kasp == NULL || (strcmp(dns_kasp_getname(kasp), "none") == 0) ||
(strcmp(dns_kasp_getname(kasp), "insecure") == 0))
{
- RETERR(findmatchingkeys(keydir, namebuf, len, mctx, now,
- &list));
+ RETERR(findmatchingkeys(keydir, rrtypekey, namebuf, len, mctx,
+ now, &list));
} else if (keystores != NULL) {
ISC_LIST_FOREACH(*keystores, keystore, link) {
ISC_LIST_FOREACH(dns_kasp_keys(kasp), kkey, link) {
dns_keystore_directory(keystore,
keydir);
RETERR(findmatchingkeys(
- directory, namebuf, len, mctx,
- now, &list));
+ directory, rrtypekey, namebuf,
+ len, mctx, now, &list));
break;
}
}
isc_result_t
dns_dnssec_findmatchingkeys(const dns_name_t *origin, dns_kasp_t *kasp,
const char *keydir, dns_keystorelist_t *keystores,
- isc_stdtime_t now, isc_mem_t *mctx,
+ isc_stdtime_t now, bool rrtypekey, isc_mem_t *mctx,
dns_dnsseckeylist_t *keylist);
/*%<
* Search for K* key files matching the name in 'origin'. If 'kasp' is not
* NULL, search in the directories used in 'keystores'. Otherwise search in the
* key-directory 'keydir'.
*
+ * If 'rrtypekey' is true, then KEY type keys are matched (e.g. for SIG(0)),
+ * otherwise DNSKEY type keys are matched for DNSSEC.
+ *
* Append all such keys, along with use hints gleaned from their
* metadata, onto 'keylist'. Skip any unsupported algorithms.
*
keymgr_createkey(dns_kasp_key_t *kkey, const dns_name_t *origin,
dns_kasp_t *kasp, 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_stdtime_t now, dns_dnsseckeylist_t *newkeys,
+ dst_key_t **dst_key) {
isc_result_t result = ISC_R_SUCCESS;
bool conflict = false;
int flags = DNS_KEYOWNER_ZONE;
dns_keystore_t *keystore = dns_kasp_key_keystore(kkey);
const char *dir = NULL;
int size = dns_kasp_key_size(kkey);
+ dns_dnsseckeylist_t keykeys;
+
+ ISC_LIST_INIT(keykeys);
if (dns_kasp_key_ksk(kkey)) {
flags |= DNS_KEYFLAG_KSK;
}
+ /*
+ * We also need to check against K* files for KEYs.
+ */
+ result = dns_dnssec_findmatchingkeys(origin, NULL, keydir, NULL, now,
+ true, mctx, &keykeys);
+ if (result != ISC_R_SUCCESS && result != ISC_R_NOTFOUND) {
+ goto failure;
+ }
+
do {
if (keystore == NULL) {
RETERR(dst_key_generate(origin, alg, size, 0, flags,
/* Key collision? */
conflict = keymgr_keyid_conflict(newkey, kkey->tag_min,
kkey->tag_max, keylist);
+ if (!conflict) {
+ conflict = keymgr_keyid_conflict(
+ newkey, kkey->tag_min, kkey->tag_max, &keykeys);
+ }
if (!conflict) {
conflict = keymgr_keyid_conflict(
newkey, kkey->tag_min, kkey->tag_max, newkeys);
dst_key_setdirectory(newkey, dir);
}
*dst_key = newkey;
- return ISC_R_SUCCESS;
+ result = ISC_R_SUCCESS;
failure:
+ while (!ISC_LIST_EMPTY(keykeys)) {
+ dns_dnsseckey_t *key = ISC_LIST_HEAD(keykeys);
+ ISC_LIST_UNLINK(keykeys, key, link);
+ dns_dnsseckey_destroy(mctx, &key);
+ }
return result;
}
bool csk = (dns_kasp_key_ksk(kaspkey) &&
dns_kasp_key_zsk(kaspkey));
- isc_result_t result =
- keymgr_createkey(kaspkey, origin, kasp, rdclass, mctx,
- keydir, keyring, newkeys, &dst_key);
+ isc_result_t result = keymgr_createkey(
+ kaspkey, origin, kasp, rdclass, mctx, keydir, keyring,
+ now, newkeys, &dst_key);
if (result != ISC_R_SUCCESS) {
return result;
}
dns_zone_lock_keyfiles(zone);
result = dns_dnssec_findmatchingkeys(dns_zone_getorigin(zone), kasp,
- keydir, keystores, now, mctx,
- &keylist);
+ keydir, keystores, now, false,
+ mctx, &keylist);
dns_zone_unlock_keyfiles(zone);
if (result != ISC_R_SUCCESS) {
/* Get keys from private key files. */
dns_zone_lock_keyfiles(zone);
- result = dns_dnssec_findmatchingkeys(origin, kasp, dir,
- dns_zone_getkeystores(zone), now,
- dns_zone_getmctx(zone), keys);
+ result = dns_dnssec_findmatchingkeys(
+ origin, kasp, dir, dns_zone_getkeystores(zone), now, false,
+ dns_zone_getmctx(zone), keys);
dns_zone_unlock_keyfiles(zone);
if (result != ISC_R_SUCCESS && result != ISC_R_NOTFOUND) {
dns_zone_lock_keyfiles(zone);
result = dns_dnssec_findmatchingkeys(dns_zone_getorigin(zone), kasp,
- keydir, keystores, now, mctx,
- &keylist);
+ keydir, keystores, now, false,
+ mctx, &keylist);
dns_zone_unlock_keyfiles(zone);
if (result == ISC_R_NOTFOUND) {
return ISC_R_SUCCESS;
dns_zone_lock_keyfiles(zone);
result = dns_dnssec_findmatchingkeys(&zone->origin, kasp, dir,
dns_zone_getkeystores(zone), now,
- mctx, &keys);
+ false, mctx, &keys);
dns_zone_unlock_keyfiles(zone);
if (result != ISC_R_SUCCESS) {
ISC_LIST_INIT(keys);
ret = dns_dnssec_findmatchingkeys(origin, kasp, keydir, &kslist,
- now, mctx, &keys);
+ now, false, mctx, &keys);
if (ret != ISC_R_SUCCESS) {
result = ret;
}
ISC_LIST_INIT(keys);
result = dns_dnssec_findmatchingkeys(dname, NULL,
TESTS_DIR "/testdata/skr/", NULL,
- 0, isc_g_mctx, &keys);
+ 0, false, isc_g_mctx, &keys);
assert_int_equal(result, ISC_R_SUCCESS);
/* Create/read the SKR file */