mirror of
https://github.com/ibm-s390-linux/s390-tools.git
synced 2026-08-05 02:14:52 +00:00
zkey: Update properties in the KMS for change and rename commands
When key properties are changed with the 'change' command, also update the key properties in the KMS, if the key is bound to a KMS. Do not allow to change the associated APQNs for KMS bound keys. KMS bound keys inherit the APQNs from the KMS plugin. When a key is renamed in the repository, also update the key name property in the KMS if the key is KMS bound. Signed-off-by: Ingo Franzki <ifranzki@linux.ibm.com> Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
This commit is contained in:
committed by
Jan Höppner
parent
a2f14fcfd7
commit
1d7bb283fd
@@ -2266,11 +2266,14 @@ int keystore_change_key(struct keystore *keystore, const char *name,
|
||||
.nomsg = 0 };
|
||||
struct key_filenames file_names = { NULL, NULL, NULL };
|
||||
struct properties *key_props = NULL;
|
||||
char *upd_volume_type = NULL;
|
||||
char *apqns_prop, *key_type;
|
||||
char *upd_volumes = NULL;
|
||||
size_t secure_key_size;
|
||||
u8 mkvp[MKVP_LENGTH];
|
||||
char sect_size[30];
|
||||
u8 *secure_key;
|
||||
char temp[30];
|
||||
bool kms_bound;
|
||||
int rc;
|
||||
|
||||
util_assert(keystore != NULL, "Internal error: keystore is NULL");
|
||||
@@ -2291,6 +2294,8 @@ int keystore_change_key(struct keystore *keystore, const char *name,
|
||||
goto out;
|
||||
}
|
||||
|
||||
kms_bound = _keystore_is_kms_bound_key(key_props, NULL);
|
||||
|
||||
if (description != NULL) {
|
||||
rc = properties_set(key_props, PROP_NAME_DESCRIPTION,
|
||||
description);
|
||||
@@ -2307,9 +2312,18 @@ int keystore_change_key(struct keystore *keystore, const char *name,
|
||||
&vol_check);
|
||||
if (rc != 0)
|
||||
goto out;
|
||||
|
||||
upd_volumes = properties_get(key_props, PROP_NAME_VOLUMES);
|
||||
}
|
||||
|
||||
if (apqns != NULL) {
|
||||
if (kms_bound) {
|
||||
rc = -EINVAL;
|
||||
warnx("The APQN association of a KMS-bound key can not "
|
||||
"be changed");
|
||||
goto out;
|
||||
}
|
||||
|
||||
rc = _keystore_change_association(key_props, PROP_NAME_APQNS,
|
||||
apqns, "APQN",
|
||||
_keystore_apqn_check,
|
||||
@@ -2357,9 +2371,9 @@ int keystore_change_key(struct keystore *keystore, const char *name,
|
||||
goto out;
|
||||
}
|
||||
|
||||
sprintf(temp, "%lu", sector_size);
|
||||
sprintf(sect_size, "%lu", sector_size);
|
||||
rc = properties_set(key_props, PROP_NAME_SECTOR_SIZE,
|
||||
temp);
|
||||
sect_size);
|
||||
if (rc != 0) {
|
||||
warnx("Invalid characters in sector-size");
|
||||
goto out;
|
||||
@@ -2379,6 +2393,29 @@ int keystore_change_key(struct keystore *keystore, const char *name,
|
||||
warnx("Invalid characters in volume-type");
|
||||
goto out;
|
||||
}
|
||||
|
||||
upd_volume_type = properties_get(key_props,
|
||||
PROP_NAME_VOLUME_TYPE);
|
||||
}
|
||||
|
||||
if (kms_bound) {
|
||||
rc = perform_kms_login(keystore->kms_info, keystore->verbose);
|
||||
if (rc != 0)
|
||||
goto out;
|
||||
|
||||
rc = set_kms_key_properties(keystore->kms_info, key_props, NULL,
|
||||
description, upd_volumes,
|
||||
upd_volume_type, sector_size >= 0 ?
|
||||
sect_size : NULL,
|
||||
keystore->verbose);
|
||||
if (rc != 0) {
|
||||
warnx("KMS plugin '%s' failed to set key properties "
|
||||
"for key '%s': %s",
|
||||
keystore->kms_info->plugin_name, name,
|
||||
strerror(-rc));
|
||||
print_last_kms_error(keystore->kms_info);
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
|
||||
rc = _keystore_ensure_vp_exists(keystore, &file_names, key_props);
|
||||
@@ -2402,6 +2439,10 @@ out:
|
||||
_keystore_free_key_filenames(&file_names);
|
||||
if (key_props != NULL)
|
||||
properties_free(key_props);
|
||||
if (upd_volumes != NULL)
|
||||
free(upd_volumes);
|
||||
if (upd_volume_type != NULL)
|
||||
free(upd_volume_type);
|
||||
|
||||
if (rc != 0)
|
||||
pr_verbose(keystore, "Failed to change key '%s': %s",
|
||||
@@ -2424,6 +2465,7 @@ int keystore_rename_key(struct keystore *keystore, const char *name,
|
||||
struct key_filenames file_names = { NULL, NULL, NULL };
|
||||
struct key_filenames new_names = { NULL, NULL, NULL };
|
||||
struct properties *key_props = NULL;
|
||||
bool reenc_exists = false;
|
||||
char *msg;
|
||||
int rc;
|
||||
|
||||
@@ -2457,18 +2499,16 @@ int keystore_rename_key(struct keystore *keystore, const char *name,
|
||||
rc = -errno;
|
||||
pr_verbose(keystore, "Failed to rename '%s': %s",
|
||||
file_names.info_filename, strerror(-rc));
|
||||
rename(new_names.skey_filename, file_names.skey_filename);
|
||||
goto out_rename_skey;
|
||||
}
|
||||
if (_keystore_reencipher_key_exists(&file_names)) {
|
||||
reenc_exists = true;
|
||||
if (rename(file_names.renc_filename,
|
||||
new_names.renc_filename) != 0) {
|
||||
rc = -errno;
|
||||
pr_verbose(keystore, "Failed to rename '%s': %s",
|
||||
file_names.renc_filename, strerror(-rc));
|
||||
rename(new_names.skey_filename,
|
||||
file_names.skey_filename);
|
||||
rename(new_names.info_filename,
|
||||
file_names.info_filename);
|
||||
goto out_rename_info;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2476,7 +2516,25 @@ int keystore_rename_key(struct keystore *keystore, const char *name,
|
||||
rc = properties_load(key_props, new_names.info_filename, 1);
|
||||
if (rc != 0) {
|
||||
warnx("Key '%s' does not exist or is invalid", newname);
|
||||
goto out;
|
||||
goto out_rename_info;
|
||||
}
|
||||
|
||||
if (_keystore_is_kms_bound_key(key_props, NULL)) {
|
||||
rc = perform_kms_login(keystore->kms_info, keystore->verbose);
|
||||
if (rc != 0)
|
||||
goto out_rename_info;
|
||||
|
||||
rc = set_kms_key_properties(keystore->kms_info, key_props,
|
||||
newname, NULL, NULL, NULL, NULL,
|
||||
keystore->verbose);
|
||||
if (rc != 0) {
|
||||
warnx("KMS plugin '%s' failed to set key properties "
|
||||
"for key '%s': %s",
|
||||
keystore->kms_info->plugin_name, name,
|
||||
strerror(-rc));
|
||||
print_last_kms_error(keystore->kms_info);
|
||||
goto out_rename_info;
|
||||
}
|
||||
}
|
||||
|
||||
util_asprintf(&msg, "The following volumes are associated with the "
|
||||
@@ -2489,6 +2547,16 @@ int keystore_rename_key(struct keystore *keystore, const char *name,
|
||||
pr_verbose(keystore, "Successfully renamed key '%s' to '%s'", name,
|
||||
newname);
|
||||
|
||||
goto out;
|
||||
|
||||
out_rename_info:
|
||||
if (reenc_exists)
|
||||
rename(file_names.renc_filename, new_names.renc_filename);
|
||||
rename(new_names.info_filename, file_names.info_filename);
|
||||
|
||||
out_rename_skey:
|
||||
rename(new_names.skey_filename, file_names.skey_filename);
|
||||
|
||||
out:
|
||||
_keystore_free_key_filenames(&file_names);
|
||||
_keystore_free_key_filenames(&new_names);
|
||||
|
||||
117
zkey/kms.c
117
zkey/kms.c
@@ -2309,3 +2309,120 @@ out:
|
||||
return rc;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets (adds/replaces) properties of a key. Already existing properties
|
||||
* with the same property name are replaced, non-existing properties are added.
|
||||
*
|
||||
* @param[in] kms_info information of the currently bound plugin.
|
||||
* @param[in] key_props a properties object of the key
|
||||
* @param[in] name the name of the key in zkey (can be NULL)
|
||||
* @param[in] description the description of the key (can be NULL)
|
||||
* @param[in] volumes the volumes of the key (can be NULL)
|
||||
* @param[in] vol_type the volume type of the key (can be NULL)
|
||||
* @param[in] sector_size the sector_size of the key (can be NULL)
|
||||
*
|
||||
* @returns 0 for success or a negative errno in case of an error.
|
||||
*/
|
||||
|
||||
int set_kms_key_properties(struct kms_info *kms_info,
|
||||
struct properties *key_props,
|
||||
const char *name, const char *description,
|
||||
const char *volumes, const char *vol_type,
|
||||
const char *sector_size, bool verbose)
|
||||
{
|
||||
char *key1_id = NULL, *key2_id = NULL;
|
||||
struct kms_property kms_props[10];
|
||||
size_t num_kms_props = 0;
|
||||
char *sys_volumes = NULL;
|
||||
char *sys_name = 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_set_key_properties == NULL) {
|
||||
pr_verbose(verbose, "The KMS plugin does not support to "
|
||||
"set properties");
|
||||
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;
|
||||
}
|
||||
|
||||
if (name != NULL) {
|
||||
sys_name = _get_system_specific_prop_name(KMS_KEY_PROP_NAME);
|
||||
if (sys_name == NULL)
|
||||
return -ENOMEM;
|
||||
ADD_KMS_PROPS(kms_props, num_kms_props, sys_name, name);
|
||||
}
|
||||
if (description != NULL)
|
||||
ADD_KMS_PROPS(kms_props, num_kms_props,
|
||||
KMS_KEY_PROP_DESCRIPTION, description);
|
||||
if (volumes != NULL) {
|
||||
sys_volumes =
|
||||
_get_system_specific_prop_name(KMS_KEY_PROP_VOLUMES);
|
||||
if (sys_volumes == NULL)
|
||||
return -ENOMEM;
|
||||
ADD_KMS_PROPS(kms_props, num_kms_props, sys_volumes,
|
||||
volumes);
|
||||
}
|
||||
if (vol_type != NULL)
|
||||
ADD_KMS_PROPS(kms_props, num_kms_props,
|
||||
KMS_KEY_PROP_VOLUME_TYPE, vol_type);
|
||||
if (sector_size != NULL)
|
||||
ADD_KMS_PROPS(kms_props, num_kms_props,
|
||||
KMS_KEY_PROP_SECTOR_SIZE, sector_size);
|
||||
|
||||
if (num_kms_props == 0)
|
||||
goto out;
|
||||
|
||||
rc = kms_info->funcs->kms_set_key_properties(kms_info->handle, key1_id,
|
||||
kms_props, num_kms_props);
|
||||
if (rc != 0) {
|
||||
pr_verbose(verbose, "KMS plugin failed to set properties of "
|
||||
"key '%s': %s", key1_id, strerror(-rc));
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (xts) {
|
||||
rc = kms_info->funcs->kms_set_key_properties(kms_info->handle,
|
||||
key2_id,
|
||||
kms_props,
|
||||
num_kms_props);
|
||||
if (rc != 0) {
|
||||
pr_verbose(verbose, "KMS plugin failed to set "
|
||||
"properties of key '%s': %s", key2_id,
|
||||
strerror(-rc));
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
|
||||
out:
|
||||
if (sys_name != NULL)
|
||||
free(sys_name);
|
||||
if (sys_volumes != NULL)
|
||||
free(sys_volumes);
|
||||
if (key1_id != NULL)
|
||||
free(key1_id);
|
||||
if (key2_id != NULL)
|
||||
free(key2_id);
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
|
||||
@@ -77,4 +77,10 @@ int generate_kms_key(struct kms_info *kms_info, const char *name,
|
||||
struct kms_option *kms_options, size_t num_kms_options,
|
||||
bool verbose);
|
||||
|
||||
int set_kms_key_properties(struct kms_info *kms_info,
|
||||
struct properties *key_props,
|
||||
const char *name, const char *description,
|
||||
const char *volumes, const char *vol_type,
|
||||
const char *sector_size, bool verbose);
|
||||
|
||||
#endif
|
||||
|
||||
@@ -536,6 +536,12 @@ options. You cannot mix \fI+\fP and
|
||||
\fI-\fP in one specification. You can either add or remove (or set) the
|
||||
associations with one command.
|
||||
.PP
|
||||
For secure AES keys that are bound to a key management system (KMS) you can not
|
||||
change the APQN association. KMS-bound secure AES keys are always bound to the
|
||||
APQNs that are associated with the key management system plugin.
|
||||
Other associated information is also changed in the key management system when
|
||||
changed using the change command.
|
||||
.PP
|
||||
.B Note:
|
||||
The secure key itself cannot be changed, only information about the secure
|
||||
key is changed. To rename a secure key, use the \fBrename\fP command.
|
||||
|
||||
@@ -1189,6 +1189,7 @@ static struct zkey_command zkey_commands[] = {
|
||||
"the repository",
|
||||
.has_options = 1,
|
||||
.need_keystore = 1,
|
||||
.use_kms_plugin = 1,
|
||||
},
|
||||
{
|
||||
.command = COMMAND_RENAME,
|
||||
@@ -1198,6 +1199,7 @@ static struct zkey_command zkey_commands[] = {
|
||||
.long_desc = "Rename a secure AES key in the repository",
|
||||
.has_options = 1,
|
||||
.need_keystore = 1,
|
||||
.use_kms_plugin = 1,
|
||||
},
|
||||
{
|
||||
.command = COMMAND_COPY,
|
||||
|
||||
Reference in New Issue
Block a user