zkey: Add KMS restrictions for the convert and copy commands

Do not allow to convert a KMS bound key. The key type of a KMS
bound key is determined by what the KMS plugin supports, thus it
can not be converted.

Do only allow to copy a KMS bound key, if the '--local' option is
specified. The result of the copy is a local key, that is not bound
to a KMS.

Signed-off-by: Ingo Franzki <ifranzki@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
This commit is contained in:
Ingo Franzki
2020-06-15 15:20:45 +02:00
committed by Jan Höppner
parent bb6a47db55
commit a2f14fcfd7
4 changed files with 57 additions and 11 deletions

View File

@@ -82,6 +82,9 @@ struct key_filenames {
warnx(fmt); \
} while (0)
static int _keystore_kms_key_unbind(struct keystore *keystore,
struct properties *properties);
/**
* Gets the file names of the .skey and .info and .renc files for a named
* key in the key strore's directory
@@ -3349,11 +3352,12 @@ int keystore_reencipher_key(struct keystore *keystore, const char *name_filter,
* @param[in] newname the new name of the key
* @param[in] volumes a comma separated list of volumes associated with this
* key (optional, can be NULL)
* @param[in] local if true copy a KMS-bound key to a local one
*
* @returns 0 for success or a negative errno in case of an error
*/
int keystore_copy_key(struct keystore *keystore, const char *name,
const char *newname, const char *volumes)
const char *newname, const char *volumes, bool local)
{
struct volume_check vol_check = { .keystore = keystore,
.name = newname, .set = 0 };
@@ -3361,6 +3365,7 @@ int keystore_copy_key(struct keystore *keystore, const char *name,
struct key_filenames new_names = { NULL, NULL, NULL };
struct properties *key_prop = NULL;
size_t secure_key_size;
bool kms_bound = false;
u8 *secure_key;
int rc;
@@ -3384,6 +3389,21 @@ int keystore_copy_key(struct keystore *keystore, const char *name,
if (rc != 0)
goto out;
key_prop = properties_new();
rc = properties_load(key_prop, file_names.info_filename, 1);
if (rc != 0) {
warnx("Key '%s' does not exist or is invalid", name);
goto out;
}
kms_bound = _keystore_is_kms_bound_key(key_prop, NULL);
if (kms_bound && !local) {
rc = -EINVAL;
warnx("Copying a KMS-bound key requires the "
"'--local|-L' option");
goto out;
}
secure_key = read_secure_key(file_names.skey_filename,
&secure_key_size, keystore->verbose);
if (secure_key == NULL) {
@@ -3401,14 +3421,6 @@ int keystore_copy_key(struct keystore *keystore, const char *name,
if (rc != 0)
goto out;
key_prop = properties_new();
rc = properties_load(key_prop, file_names.info_filename, 1);
if (rc != 0) {
warnx("Key '%s' does not exist or is invalid", name);
remove(file_names.skey_filename);
goto out;
}
/*
* Remove any volume association, since a volume can only be associated
* with one key
@@ -3440,6 +3452,12 @@ int keystore_copy_key(struct keystore *keystore, const char *name,
if (rc != 0)
goto out;
if (kms_bound) {
rc = _keystore_kms_key_unbind(keystore, key_prop);
if (rc != 0)
goto out;
}
rc = properties_save(key_prop, new_names.info_filename, 1);
if (rc != 0) {
pr_verbose(keystore,
@@ -4310,6 +4328,12 @@ int keystore_convert_key(struct keystore *keystore, const char *name,
goto out;
}
if (_keystore_is_kms_bound_key(properties, NULL)) {
rc = -EINVAL;
warnx("A KMS-bound key can not be converted");
goto out;
}
cur_key_type = _keystore_get_key_type(properties);
if (strcasecmp(cur_key_type, key_type) == 0) {
warnx("The secure key '%s' is already of type %s", name,

View File

@@ -88,7 +88,7 @@ int keystore_reencipher_key(struct keystore *keystore, const char *name_filter,
struct ext_lib *lib);
int keystore_copy_key(struct keystore *keystore, const char *name,
const char *newname, const char *volumes);
const char *newname, const char *volumes, bool local);
int keystore_export_key(struct keystore *keystore, const char *name,
const char *export_file);

View File

@@ -581,6 +581,7 @@ secure key is contained in the LUKS2 header.
.IR new-key-name
.RB [ \-\-volumes | \-l
.IR volume1:dmname1[,volume2:dmname2[,...]] ]
.RB [ \-\-local | \-L ]
.RB [ \-\-verbose | \-V ]
.
.PP
@@ -600,6 +601,10 @@ a specific volume can only be associated with a single secure key. Specify the
option to associate different
volumes with the copied secure key, or use the \fBchange\fP command to associate
volumes afterwards.
.PP
You can not copy secure keys that are bound to a key management system (KMS),
except when the \fB\-\-local\fP option is specified. The copied secure key is
then created as a local key.
.
.SS "Generate crypttab entries for volumes associated with secure AES keys"
.
@@ -757,6 +762,7 @@ Use the
.B convert
command to convert an existing secure key from one key type to another type.
You can convert secure keys of type CCA-AESDATA to type CCA-AESCIPHER only.
You can not convert keys that are bound to a key management system (KMS).
.B Note:
Secure keys converted to type \fBCCA-AESCIPHER\fP require an IBM cryptographic
@@ -1411,6 +1417,12 @@ These volumes are to be encrypted using dm-crypt with the secure AES key. The
volume association also contains the device-mapper name, separated by a colon,
used with dm-crypt.
This option is only used for secure keys contained in the secure key repository.
.TP
.BR \-L ", "\-\-local
Copy the secure key to a local key. This is the default when no key management
system plugin (KMS plugin) is bound to the secure key repository. If the
repository is bound to a key management system plugin, then the keys are bound
to the KMS per default, and KMS-bound keys can only be copied to local keys.
.
.
.

View File

@@ -634,6 +634,15 @@ static struct util_opt opt_vec[] = {
"specific volume.",
.command = COMMAND_COPY,
},
{
.option = { "local", 0, NULL, 'L'},
.desc = "Copy the key to a local key. This is the default when "
"no KMS plugin is bound to the repository. If the "
"repository is bound to a KMS plugin, then keys are "
"bound to the KMS per default, and KMS-bound key can "
"only be copied to local keys.",
.command = COMMAND_COPY,
},
/***********************************************************/
{
.flags = UTIL_OPT_FLAG_SECTION,
@@ -2020,7 +2029,8 @@ static int command_copy(void)
return EXIT_FAILURE;
}
rc = keystore_copy_key(g.keystore, g.name, g.newname, g.volumes);
rc = keystore_copy_key(g.keystore, g.name, g.newname, g.volumes,
g.local);
return rc != 0 ? EXIT_FAILURE : EXIT_SUCCESS;
}