From: Daniel Salzman Date: Tue, 1 Jul 2025 06:10:13 +0000 (+0200) Subject: keymgr: print keystore name and its type when listing keys X-Git-Tag: v3.5.0~53^2 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=803947eb401c937c32d15b64f8e3539443c42460;p=thirdparty%2Fknot-dns.git keymgr: print keystore name and its type when listing keys --- diff --git a/src/knot/dnssec/kasp/kasp_zone.c b/src/knot/dnssec/kasp/kasp_zone.c index 390bc3c3f2..e1cbe00e74 100644 --- a/src/knot/dnssec/kasp/kasp_zone.c +++ b/src/knot/dnssec/kasp/kasp_zone.c @@ -349,6 +349,7 @@ int zone_init_keystore(conf_t *conf, conf_val_t *policy_id, conf_val_t *keystore for (size_t i = 0; i < ks_count && ret == KNOT_EOK; i++) { knot_kasp_keystore_t *ks = *keystores + i; + ks->name = conf_str(keystore_id); conf_val_t val = conf_id_get(conf, C_KEYSTORE, C_BACKEND, keystore_id); ks->backend = conf_opt(&val); val = conf_id_get(conf, C_KEYSTORE, C_KSK_ONLY, keystore_id); diff --git a/src/knot/dnssec/kasp/policy.h b/src/knot/dnssec/kasp/policy.h index f7bc932306..748065ec1e 100644 --- a/src/knot/dnssec/kasp/policy.h +++ b/src/knot/dnssec/kasp/policy.h @@ -56,6 +56,7 @@ typedef struct { typedef struct { dnssec_keystore_t *keystore; + const char *name; unsigned backend; bool ksk_only; bool key_label; diff --git a/src/knot/dnssec/zone-keys.c b/src/knot/dnssec/zone-keys.c index 779386c033..4baa1e28c0 100644 --- a/src/knot/dnssec/zone-keys.c +++ b/src/knot/dnssec/zone-keys.c @@ -460,14 +460,19 @@ static int walk_algorithms(kdnssec_ctx_t *ctx, zone_keyset_t *keyset) } int kdnssec_load_private(knot_kasp_keystore_t *keystores, const char *id, - dnssec_key_t *key, unsigned *backend) + dnssec_key_t *key, const char **name, unsigned *backend) { int ret = DNSSEC_ENOENT; for (size_t i = 0; i < keystores[0].count && ret == DNSSEC_ENOENT; i++) { - if (backend != NULL) { - *backend = keystores[i].backend; - } ret = dnssec_keystore_get_private(keystores[i].keystore, id, key); + if (ret == KNOT_EOK) { + if (name != NULL) { + *name = keystores[i].name; + } + if (backend != NULL) { + *backend = keystores[i].backend; + } + } } return ret; } @@ -495,7 +500,7 @@ static int load_private_keys(kdnssec_ctx_t *ctx, zone_keyset_t *keyset) if (!key->is_active && !key->is_ksk_active_plus && !key->is_zsk_active_plus) { continue; } - int ret = kdnssec_load_private(ctx->keystores, key->id, key->key, NULL); + int ret = kdnssec_load_private(ctx->keystores, key->id, key->key, NULL, NULL); switch (ret) { case DNSSEC_EOK: case DNSSEC_KEY_ALREADY_PRESENT: diff --git a/src/knot/dnssec/zone-keys.h b/src/knot/dnssec/zone-keys.h index cca60ed3af..6aaac1075d 100644 --- a/src/knot/dnssec/zone-keys.h +++ b/src/knot/dnssec/zone-keys.h @@ -118,12 +118,13 @@ int kdnssec_delete_key(kdnssec_ctx_t *ctx, knot_kasp_key_t *key_ptr); * \param keystores Array of keystores. * \param id Key ID to search. * \param key Libdnssec key structure to be filled with private material. + * \param name Optional: name of the keystore in the configuration. * \param backend Optional: backend of the keystore where found. * * \return DNSSEC_E* */ int kdnssec_load_private(knot_kasp_keystore_t *keystores, const char *id, - dnssec_key_t *key, unsigned *backend); + dnssec_key_t *key, const char **name, unsigned *backend); /*! * \brief Find configured keystore for newly generated key. diff --git a/src/knot/zone/backup.c b/src/knot/zone/backup.c index bb1a0d70f9..ca4a6eaece 100644 --- a/src/knot/zone/backup.c +++ b/src/knot/zone/backup.c @@ -235,7 +235,7 @@ static int backup_key(key_params_t *parm, const knot_dname_t *zname, } unsigned backend; - ret = kdnssec_load_private(from, parm->id, key, &backend); + ret = kdnssec_load_private(from, parm->id, key, NULL, &backend); if (ret == DNSSEC_EOK) { if (backend == KEYSTORE_BACKEND_PKCS11 || to_pem == NULL) { log_zone_notice(zname, "private keys from PKCS #11 are not subject of backup/restore, skipping them"); diff --git a/src/utils/keymgr/functions.c b/src/utils/keymgr/functions.c index 9f2cfac759..2f27bce84b 100644 --- a/src/utils/keymgr/functions.c +++ b/src/utils/keymgr/functions.c @@ -583,7 +583,7 @@ static int import_key(kdnssec_ctx_t *ctx, unsigned backend, const char *param, dnssec_key_set_algorithm(key, ctx->policy->algorithm); // fill key structure from keystore (incl. pubkey from privkey computation) - ret = kdnssec_load_private(ctx->keystores, keyid, key, NULL); + ret = kdnssec_load_private(ctx->keystores, keyid, key, NULL, NULL); if (ret != DNSSEC_EOK) { err_import_key(keyid, ""); goto fail; @@ -916,7 +916,16 @@ static const timer_ctx_t timers[] = { { NULL } }; -static void print_key_brief(const knot_kasp_key_t *key, bool missing, +typedef struct { + const char *ks_name; + size_t ks_count; + unsigned backend; + bool missing; +} key_info_t; + +#define KS_TYPE(info) (info->backend == KEYSTORE_BACKEND_PEM) ? "PEM" : "PKCS11" + +static void print_key_brief(const knot_kasp_key_t *key, key_info_t *info, keymgr_list_params_t *params) { const bool c = params->color; @@ -945,8 +954,10 @@ static void print_key_brief(const knot_kasp_key_t *key, bool missing, printf(" %s%spublic-only%s", COL_BOLD(c), COL_MGNT(c), COL_RST(c)); } - if (missing) { + if (info->missing) { printf(" %s%smissing%s", COL_BOLD(c), COL_YELW(c), COL_RST(c)); + } else if (info->ks_count > 1 && info->ks_name != NULL) { + printf(" %s%s/%s%s", COL_YELW(c), KS_TYPE(info), info->ks_name, COL_RST(c)); } static char buf[100]; @@ -972,14 +983,17 @@ static void print_key_brief(const knot_kasp_key_t *key, bool missing, printf("\n"); } -static void print_key_full(const knot_kasp_key_t *key, bool missing, +static void print_key_full(const knot_kasp_key_t *key, key_info_t *info, knot_time_print_t format) { printf("%s ksk=%s zsk=%s tag=%05d algorithm=%-2d size=%-4u public-only=%s", key->id, (key->is_ksk ? "yes" : "no "), (key->is_zsk ? "yes" : "no "), dnssec_key_get_keytag(key->key), (int)dnssec_key_get_algorithm(key->key), dnssec_key_get_size(key->key), (key->is_pub_only ? "yes" : "no ")); - printf(" missing=%s", missing ? "yes" : "no "); + printf(" missing=%s", info->missing ? "yes" : "no "); + if (info->ks_name != NULL) { + printf(" keystore=%s/%s", KS_TYPE(info), info->ks_name); + } static char buf[100]; for (const timer_ctx_t *t = &timers[0]; t->name != NULL; t++) { @@ -990,9 +1004,8 @@ static void print_key_full(const knot_kasp_key_t *key, bool missing, printf("\n"); } -static void print_key_json(const knot_kasp_key_t *key, bool missing, - knot_time_print_t format, - jsonw_t *w, const char *zone_name) +static void print_key_json(const knot_kasp_key_t *key, key_info_t *info, + knot_time_print_t format, jsonw_t *w, const char *zone_name) { jsonw_str(w, "zone", zone_name); jsonw_str(w, "id", key->id); @@ -1002,7 +1015,11 @@ static void print_key_json(const knot_kasp_key_t *key, bool missing, jsonw_ulong(w, "algorithm", dnssec_key_get_algorithm(key->key)); jsonw_int(w, "size", dnssec_key_get_size(key->key)); jsonw_bool(w, "public-only", key->is_pub_only); - jsonw_bool(w, "missing", missing); + jsonw_bool(w, "missing", info->missing); + if (info->ks_name != NULL) { + jsonw_str(w, "keystore", info->ks_name); + jsonw_str(w, "backend", KS_TYPE(info)); + } static char buf[100]; for (const timer_ctx_t *t = &timers[0]; t->name != NULL; t++) { @@ -1029,10 +1046,13 @@ static int key_sort(const void *a, const void *b) return knot_time_cmp(key_a->val, key_b->val); } -static bool key_missing(kdnssec_ctx_t *ctx, const knot_kasp_key_t *key) +static key_info_t key_missing(kdnssec_ctx_t *ctx, const knot_kasp_key_t *key) { - return !key->is_pub_only && DNSSEC_EOK != - kdnssec_load_private(ctx->keystores, key->id, key->key, NULL); + key_info_t out = { .ks_count = ctx->keystores[0].count }; + out.missing = !key->is_pub_only && + DNSSEC_EOK != kdnssec_load_private(ctx->keystores, key->id, + key->key, &out.ks_name, &out.backend); + return out; } int keymgr_list_keys(kdnssec_ctx_t *ctx, keymgr_list_params_t *params) @@ -1044,8 +1064,8 @@ int keymgr_list_keys(kdnssec_ctx_t *ctx, keymgr_list_params_t *params) if (params->extended) { for (size_t i = 0; i < ctx->zone->num_keys; i++) { knot_kasp_key_t *key = &ctx->zone->keys[i]; - bool missing = key_missing(ctx, key); - print_key_full(key, missing, params->format); + key_info_t info = key_missing(ctx, key); + print_key_full(key, &info, params->format); } } else if (params->json) { jsonw_t *w = jsonw_new(stdout, " "); @@ -1060,8 +1080,8 @@ int keymgr_list_keys(kdnssec_ctx_t *ctx, keymgr_list_params_t *params) for (size_t i = 0; i < ctx->zone->num_keys; i++) { knot_kasp_key_t *key = &ctx->zone->keys[i]; jsonw_object(w, NULL); - bool missing = key_missing(ctx, key); - print_key_json(key, missing, params->format, w, name); + key_info_t info = key_missing(ctx, key); + print_key_json(key, &info, params->format, w, name); jsonw_end(w); // object } jsonw_end(w); // list @@ -1080,8 +1100,8 @@ int keymgr_list_keys(kdnssec_ctx_t *ctx, keymgr_list_params_t *params) qsort(&items, ctx->zone->num_keys, sizeof(items[0]), key_sort); for (size_t i = 0; i < ctx->zone->num_keys; i++) { knot_kasp_key_t *key = items[i].key; - bool missing = key_missing(ctx, key); - print_key_brief(key, missing, params); + key_info_t info = key_missing(ctx, key); + print_key_brief(key, &info, params); } } return KNOT_EOK;