diff --git a/zkey/keystore.c b/zkey/keystore.c index e2f43ca1..f0e3fe69 100644 --- a/zkey/keystore.c +++ b/zkey/keystore.c @@ -3660,13 +3660,18 @@ out: * @param[in] keystore the key store * @param[in] name the name of the key * @param[in] quiet if true no confirmation prompt is shown + * @param[in] kms_options an array of KMS options specified, or NULL if no + * KMS options have been specified + * @param[in] num_kms_options the number of options in above array * * @returns 0 for success or a negative errno in case of an error */ int keystore_remove_key(struct keystore *keystore, const char *name, - bool quiet) + bool quiet, struct kms_option *kms_options, + size_t num_kms_options) { struct key_filenames file_names = { NULL, NULL, NULL }; + struct properties *key_props = NULL; int rc; util_assert(keystore != NULL, "Internal error: keystore is NULL"); @@ -3686,6 +3691,31 @@ int keystore_remove_key(struct keystore *keystore, const char *name, goto out; } + key_props = properties_new(); + rc = properties_load(key_props, file_names.info_filename, 1); + if (rc != 0) { + warnx("Key '%s' does not exist or is invalid", name); + goto out; + } + + if (_keystore_is_kms_bound_key(key_props, NULL)) { + rc = perform_kms_login(keystore->kms_info, keystore->verbose); + if (rc != 0) + goto out; + + rc = remove_kms_key(keystore->kms_info, key_props, + kms_options, num_kms_options, + keystore->verbose); + + if (rc != 0) { + warnx("KMS plugin '%s' failed to remove key '%s': %s", + keystore->kms_info->plugin_name, name, + strerror(-rc)); + print_last_kms_error(keystore->kms_info); + goto out; + } + } + if (remove(file_names.skey_filename) != 0) { rc = -errno; pr_verbose(keystore, "Failed to remove '%s': %s", @@ -3708,6 +3738,8 @@ int keystore_remove_key(struct keystore *keystore, const char *name, out: _keystore_free_key_filenames(&file_names); + if (key_props != NULL) + properties_free(key_props); if (rc != 0) pr_verbose(keystore, "Failed to remove key '%s': %s", diff --git a/zkey/keystore.h b/zkey/keystore.h index 08a85571..141522d4 100644 --- a/zkey/keystore.h +++ b/zkey/keystore.h @@ -94,7 +94,8 @@ int keystore_export_key(struct keystore *keystore, const char *name, const char *export_file); int keystore_remove_key(struct keystore *keystore, const char *name, - bool quiet); + bool quiet, struct kms_option *kms_options, + size_t num_kms_options); int keystore_list_keys(struct keystore *keystore, const char *name_filter, const char *volume_filter, const char *apqn_filter, diff --git a/zkey/kms.c b/zkey/kms.c index 6edeef06..5abc2d09 100644 --- a/zkey/kms.c +++ b/zkey/kms.c @@ -2426,3 +2426,79 @@ out: return rc; } +/** + * Requests the KMS plugin to remove a KMS managed key. Removing a key mean + * to change its state, but not remove it. + * * + * @param[in] kms_info information of the currently bound plugin. + * @param[in] key_props a properties object + * @param[in] kms_options an array of KMS options specified, or NULL if no + * KMS options have been specified + * @param[in] num_kms_options the number of options in above array + * @param[in] verbose if true, verbose messages are printed + * + * @returns 0 for success or a negative errno in case of an error. + */ +int remove_kms_key(struct kms_info *kms_info, struct properties *key_props, + struct kms_option *kms_options, size_t num_kms_options, + bool verbose) +{ + char *key1_id = NULL, *key2_id = NULL; + bool xts = false; + + int rc = 0; + + util_assert(kms_info != NULL, "Internal error: kms_info is NULL"); + util_assert(key_props != NULL, "Internal error: key_props is NULL"); + + if (kms_info->plugin_lib == NULL) { + warnx("The repository is not bound to a KMS plugin"); + return -ENOENT; + } + + if (kms_info->funcs->kms_remove_key == NULL) { + pr_verbose(verbose, "The KMS plugin does not support to " + "remove keys"); + return -ENOTSUP; + } + + key1_id = properties_get(key_props, PROP_NAME_KMS_KEY_ID); + if (key1_id == NULL) { + key1_id = properties_get(key_props, PROP_NAME_KMS_XTS_KEY1_ID); + key2_id = properties_get(key_props, PROP_NAME_KMS_XTS_KEY2_ID); + if (key1_id == NULL || key2_id == NULL) { + pr_verbose(verbose, "Failed to get key-id(s)"); + rc = -ENOENT; + goto out; + } + xts = true; + } + + rc = kms_info->funcs->kms_remove_key(kms_info->handle, key1_id, + kms_options, num_kms_options); + if (rc != 0) { + pr_verbose(verbose, "KMS plugin failed to remove key '%s': %s", + key1_id, strerror(-rc)); + goto out; + } + + if (xts) { + rc = kms_info->funcs->kms_remove_key(kms_info->handle, + key2_id, + kms_options, + num_kms_options); + if (rc != 0) { + pr_verbose(verbose, "KMS plugin failed to remove key " + "'%s': %s", key2_id, strerror(-rc)); + goto out; + } + } + +out: + if (key1_id != NULL) + free(key1_id); + if (key2_id != NULL) + free(key2_id); + + return rc; +} diff --git a/zkey/kms.h b/zkey/kms.h index 91113a19..36ea0dc0 100644 --- a/zkey/kms.h +++ b/zkey/kms.h @@ -83,4 +83,8 @@ int set_kms_key_properties(struct kms_info *kms_info, const char *volumes, const char *vol_type, const char *sector_size, bool verbose); +int remove_kms_key(struct kms_info *kms_info, struct properties *key_props, + struct kms_option *kms_options, size_t num_kms_options, + bool verbose); + #endif diff --git a/zkey/zkey.1 b/zkey/zkey.1 index 56106371..cb512dc8 100644 --- a/zkey/zkey.1 +++ b/zkey/zkey.1 @@ -466,6 +466,7 @@ bound to a key management systen (KMS). .B \-\-name | \-N .IR key-name .RB [ \-\-force | \-F ] +.RB [ KMS\-plugin\ specific\ options ] .RB [ \-\-verbose | \-V ] . .PP @@ -479,6 +480,16 @@ a confirmation, unless you specify the .B \-\-force option. .PP +When the secure key that is to be removed is bound to a key management system, +then the key management system plugin might also take an action in the key +management system. It may for example change the state of the key in the key +management system, instead of removing the key. Nevertheless, the secure key +is removed from the local repository. +.PP +A key management system plugin may offer plugin specific options that can be +specified with the \fBremove\fP command. Use \fBremove \-\-help\fP +to display the plugin specific options and their meaning. +.PP .B Note: When removing a secure key that is associated with one or multiple volumes, and the key's volume type is \fBplain\fP, @@ -1329,6 +1340,12 @@ The user is prompted to confirm the removal of a secure key from the secure key repository. Use this option to remove a secure key without prompting for a confirmation. This option is only used for secure keys contained in the secure key repository. +.TP +.B KMS-plugin specific options +A key management system plugin may offer and even require plugin specific +options that can be specified with the remove command when the secure key +repository is bound to a key management system plugin. Use \fBremove +\-\-help\fP to display the plugin specific options and their meaning. . . . diff --git a/zkey/zkey.c b/zkey/zkey.c index d82a19ce..29dfd909 100644 --- a/zkey/zkey.c +++ b/zkey/zkey.c @@ -1179,6 +1179,8 @@ static struct zkey_command zkey_commands[] = { .long_desc = "Remove a secure AES key from the repository", .has_options = 1, .need_keystore = 1, + .use_kms_plugin = 1, + .kms_plugin_opts_cmd = KMS_COMMAND_REMOVE, }, { .command = COMMAND_CHANGE, @@ -1958,7 +1960,8 @@ static int command_remove(void) return EXIT_FAILURE; } - rc = keystore_remove_key(g.keystore, g.name, g.force); + rc = keystore_remove_key(g.keystore, g.name, g.force, g.kms_options, + g.num_kms_options); return rc != 0 ? EXIT_FAILURE : EXIT_SUCCESS; }