]> git.ipfire.org Git - thirdparty/knot-dns.git/commitdiff
keymgr: print keystore name and its type when listing keys
authorDaniel Salzman <daniel.salzman@nic.cz>
Tue, 1 Jul 2025 06:10:13 +0000 (08:10 +0200)
committerDaniel Salzman <daniel.salzman@nic.cz>
Tue, 1 Jul 2025 08:51:18 +0000 (10:51 +0200)
src/knot/dnssec/kasp/kasp_zone.c
src/knot/dnssec/kasp/policy.h
src/knot/dnssec/zone-keys.c
src/knot/dnssec/zone-keys.h
src/knot/zone/backup.c
src/utils/keymgr/functions.c

index 390bc3c3f2bf0300b652925bb1a96baece0ab200..e1cbe00e7423f4e01e73e5732b765c68664cace0 100644 (file)
@@ -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);
index f7bc932306d3013fcdea031d52183fadc14bc04c..748065ec1ede8cc133171e0fb6673e34056afed0 100644 (file)
@@ -56,6 +56,7 @@ typedef struct {
 
 typedef struct {
        dnssec_keystore_t *keystore;
+       const char *name;
        unsigned backend;
        bool ksk_only;
        bool key_label;
index 779386c0335694b7ec3b67eaeda95a7f9cfae99f..4baa1e28c0773c851976c35cbe854b93390354c9 100644 (file)
@@ -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:
index cca60ed3af6061dc3acfbda1fc6e9a275873266b..6aaac1075d9da6447e6e8d76192267f364cf6280 100644 (file)
@@ -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.
index bb1a0d70f98b1f70be5ec838c90c0c5d011e5858..ca4a6eaecea3066e03226839bbe0f5139f303d09 100644 (file)
@@ -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");
index 9f2cfac7595086d68623e16bb2f397875d2833c3..2f27bce84b17c1efba3717103fd413e885c963ad 100644 (file)
@@ -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;