File s390-tools-sles15sp2-19-zkey-Allow-to-filter-list-output-by-key-type.patch of Package s390-tools.17667

Subject: zkey: Allow to filter list output by key type
From: Ingo Franzki <ifranzki@linux.ibm.com>

Summary:     zkey: Add support for CCA AES CIPHER keys
Description: With CCA 5 there is a new secure key type, the so called 
             variable length symmetric cipher key token. This token format
             can hold AES keys with size 128, 192 and 256 bits together
             with additional attributes cryptographic bound to the key
             token. The attributes may limit the usage of the key, for
             example restrict export or usability scope. So this key type
             is considered to be even more secure than the traditional 
             secure key token. This key token type is also called "CCA
             AES CIPHER key", where the formerly used key token is called
             "CCA AES DATA key".
             The zkey as well as the zkey-cryptsetup tools are enhanced
             to support AES CIPHER keys. That is, zkey can manage AES DATA 
             keys, as well as AES CIPHER keys. The key type must be specified
             at key generation time, the default is to generate AED DATA
             keys.
Upstream-ID: 91c35543ca7fd25691487c61ec2e308f2903a6b8
Problem-ID:  SEC1717

Upstream-Description:

             zkey: Allow to filter list output by key type

             The zkey list command now accepts option --key-type|-K type
             to filter the displayed keys by key type. If not specified,
             then all key types are displayed.

             Signed-off-by: Ingo Franzki <ifranzki@linux.ibm.com>
             Reviewed-by: Harald Freudenberger <freude@linux.ibm.com>
             Signed-off-by: Jan Hoeppner <hoeppner@linux.ibm.com>


Signed-off-by: Ingo Franzki <ifranzki@linux.ibm.com>
---
 zkey/keystore.c |   99 ++++++++++++++++++++++++++++++++++++++++++++++++++------
 zkey/keystore.h |    2 -
 zkey/zkey.1     |    9 ++++-
 zkey/zkey.c     |   15 +++++++-
 4 files changed, 112 insertions(+), 13 deletions(-)

--- a/zkey/keystore.c
+++ b/zkey/keystore.c
@@ -315,6 +315,39 @@ static char *_keystore_get_volume_type(s
 }
 
 /**
+ * Returns the key type contained in the properties. If no key type
+ * property is contained, then 'CCA-AESDATA' is assumed (for backward
+ * compatibility).
+ *
+ * @returns a string containing the key type. Must be freed by the caller.
+ */
+static char *_keystore_get_key_type(struct properties *properties)
+{
+	char *type;
+
+	type = properties_get(properties, PROP_NAME_KEY_TYPE);
+	if (type == NULL)
+		type = util_strdup(KEY_TYPE_CCA_AESDATA);
+
+	return type;
+}
+
+/**
+ *  Checks if the key type is supported.
+ *
+ * @param[in] key_type   the key type
+ *
+ * @returns 1 if the key type is valid, 0 otherwise
+ */
+static int _keystore_valid_key_type(const char *key_type)
+{
+	if (strcasecmp(key_type, KEY_TYPE_CCA_AESDATA) == 0)
+		return 1;
+
+	return 0;
+}
+
+/**
  * Prints a message followed by a list of associated volumes, if volumes are
  * associated and the volume-type matches (if specified)
  *
@@ -817,6 +850,33 @@ static int _keystore_match_volume_type_p
 	return rc;
 }
 
+/**
+ * Checks if the key type property matches the specified key type.
+ * If the properties do not contain a key type property, then the default
+ * key type is assumed.
+ *
+ * @param[in] properties   a properties object
+ * @param[in] key_type     the key type to match. Can be NULL. In this case
+ *                         it always matches.
+ *
+ * @returns 1 for a match, 0 for not matched
+ */
+static int _keystore_match_key_type_property(struct properties *properties,
+					     const char *key_type)
+{
+	char *type;
+	int rc = 0;
+
+	if (key_type == NULL)
+		return 1;
+
+	type = _keystore_get_key_type(properties);
+	if (strcasecmp(type, key_type) == 0)
+		rc = 1;
+
+	free(type);
+	return rc;
+}
 
 /**
  * Checks if a key name matches a name filter
@@ -882,6 +942,7 @@ typedef int (*process_key_t)(struct keys
  *                           mutliple APQN filters separated by commas.
  *                           NULL means no APQN filter.
  * @param[in] volume_type    If not NULL, specifies the volume type.
+ * @param[in] key_type       The key type. NULL means no key type filter.
  * @param[in] process_func   the callback function called for a matching key
  * @param[in/out] process_private private data passed to the process_func
  *
@@ -894,6 +955,7 @@ static int _keystore_process_filtered(st
 				      const char *volume_filter,
 				      const char *apqn_filter,
 				      const char *volume_type,
+				      const char *key_type,
 				      process_key_t process_func,
 				      void *process_private)
 {
@@ -985,6 +1047,15 @@ static int _keystore_process_filtered(st
 			goto free_prop;
 		}
 
+		rc = _keystore_match_key_type_property(key_props,
+						       key_type);
+		if (rc == 0) {
+			pr_verbose(keystore,
+				   "Key '%s' filtered out due to key type",
+				   name);
+			goto free_prop;
+		}
+
 		rc = process_func(keystore, name, key_props, &file_names,
 				  process_private);
 		if (rc != 0) {
@@ -1193,7 +1264,7 @@ static int _keystore_volume_check(const
 
 	info->set = set;
 	rc = _keystore_process_filtered(info->keystore, NULL, info->volume,
-					NULL, NULL,
+					NULL, NULL, NULL,
 					_keystore_volume_check_process, info);
 out:
 	free((void *)info->volume);
@@ -1454,7 +1525,8 @@ static int _keystore_set_default_propert
 {
 	int rc;
 
-	rc = properties_set(key_props, PROP_NAME_KEY_TYPE, "CCA-AESDATA");
+	rc = properties_set(key_props, PROP_NAME_KEY_TYPE,
+			    KEY_TYPE_CCA_AESDATA);
 	if (rc != 0)
 		return rc;
 
@@ -2498,7 +2570,7 @@ int keystore_validate_key(struct keystor
 	info.num_warnings = 0;
 
 	rc = _keystore_process_filtered(keystore, name_filter, NULL,
-					apqn_filter, NULL,
+					apqn_filter, NULL, NULL,
 					_keystore_process_validate, &info);
 
 	util_rec_free(rec);
@@ -2877,7 +2949,7 @@ int keystore_reencipher_key(struct keyst
 	info.num_skipped = 0;
 
 	rc = _keystore_process_filtered(keystore, name_filter, NULL,
-					apqn_filter, NULL,
+					apqn_filter, NULL, NULL,
 					_keystore_process_reencipher, &info);
 
 	if (rc != 0) {
@@ -3258,12 +3330,13 @@ out:
  *                           mutliple APQN filters separated by commas.
  *                           NULL means no APQN filter.
  * @param[in] volume_type    The volume type. NULL means no volume type filter.
+ * @param[in] key_type       The key type. NULL means no key type filter.
  *
  * @returns 0 for success or a negative errno in case of an error
  */
 int keystore_list_keys(struct keystore *keystore, const char *name_filter,
 		       const char *volume_filter, const char *apqn_filter,
-		       const char *volume_type)
+		       const char *volume_type, const char *key_type)
 {
 	struct util_rec *rec;
 	int rc;
@@ -3276,10 +3349,16 @@ int keystore_list_keys(struct keystore *
 		return -EINVAL;
 	}
 
+	if (key_type != NULL &&
+	    !_keystore_valid_key_type(key_type)) {
+		warnx("Invalid key-type specified");
+		return -EINVAL;
+	}
+
 	rec = _keystore_setup_record(0);
 
 	rc = _keystore_process_filtered(keystore, name_filter, volume_filter,
-					apqn_filter, volume_type,
+					apqn_filter, volume_type, key_type,
 					_keystore_display_key, rec);
 	util_rec_free(rec);
 
@@ -3773,8 +3852,8 @@ int keystore_cryptsetup(struct keystore
 	info.process_func = _keystore_process_cryptsetup;
 
 	rc = _keystore_process_filtered(keystore, NULL, volume_filter, NULL,
-					volume_type, _keystore_process_crypt,
-					&info);
+					volume_type, NULL,
+					_keystore_process_crypt, &info);
 
 	str_list_free_string_array(info.volume_filter);
 
@@ -3834,8 +3913,8 @@ int keystore_crypttab(struct keystore *k
 	info.process_func = _keystore_process_crypttab;
 
 	rc = _keystore_process_filtered(keystore, NULL, volume_filter, NULL,
-					volume_type, _keystore_process_crypt,
-					&info);
+					volume_type, NULL,
+					_keystore_process_crypt, &info);
 
 	str_list_free_string_array(info.volume_filter);
 
--- a/zkey/keystore.h
+++ b/zkey/keystore.h
@@ -68,7 +68,7 @@ int keystore_remove_key(struct keystore
 
 int keystore_list_keys(struct keystore *keystore, const char *name_filter,
 		       const char *volume_filter, const char *apqn_filter,
-		       const char *volume_type);
+		       const char *volume_type, const char *key_type);
 
 int keystore_cryptsetup(struct keystore *keystore, const char *volume_filter,
 			bool execute, const char *volume_type,
--- a/zkey/zkey.1
+++ b/zkey/zkey.1
@@ -368,6 +368,8 @@ The exported secure key also remains in
 .IR card1.domain1[,card2.domain2[,...]] ]
 .RB [ \-\-volume-type | \-t
 .IR type ]
+.RB [ \-\-key-type | \-K
+.IR type ]
 .RB [ \-\-verbose | \-V ]
 .
 .PP
@@ -382,7 +384,7 @@ listed that are associated with the spec
 .PP
 The
 .B list
-command displays the attributes of the secure keys, such as key sizes,
+command displays the attributes of the secure keys, such as key sizes, key type,
 whether it is a secure key that can be used for the XTS cipher mode, the textual
 description, associated cryptographic adapters (APQNs) and volumes, the
 sector size, the key verification pattern, and timestamps for key creation, last
@@ -907,6 +909,11 @@ This option is only available if
 .B zkey
 has been compiled with LUKS2 support enabled.
 This option is only used for secure keys contained in the secure key repository.
+.TP
+.BR \-K ", " \-\-key-type\~\fItype\fP
+Specifies the key type of the secure key. Possible values are \fBCCA-AESDATA\fP.
+Only keys with the specified key type are listed.
+This option is only used for secure keys contained in the secure key repository.
 .
 .
 .
--- a/zkey/zkey.c
+++ b/zkey/zkey.c
@@ -73,6 +73,7 @@ static struct zkey_globals {
 	long int sector_size;
 	char *volume_type;
 	char *newname;
+	char *key_type;
 	bool run;
 	bool batch_mode;
 	char *keyfile;
@@ -432,6 +433,15 @@ static struct util_opt opt_vec[] = {
 		.command = COMMAND_LIST,
 	},
 #endif
+	{
+		.option = { "key-type", required_argument, NULL, 'K'},
+		.argument = "type",
+		.desc = "The type of the key. Possible values are '"
+			KEY_TYPE_CCA_AESDATA"'. "
+			"Use this option to list all keys with the specified "
+			"key type.",
+		.command = COMMAND_LIST,
+	},
 	/***********************************************************/
 	{
 		.flags = UTIL_OPT_FLAG_SECTION,
@@ -1532,7 +1542,7 @@ static int command_list(void)
 	int rc;
 
 	rc = keystore_list_keys(g.keystore, g.name, g.volumes, g.apqns,
-				g.volume_type);
+				g.volume_type, g.key_type);
 
 	return rc != 0 ? EXIT_FAILURE : EXIT_SUCCESS;
 }
@@ -1853,6 +1863,9 @@ int main(int argc, char *argv[])
 		case 'r':
 			g.run = 1;
 			break;
+		case 'K':
+			g.key_type = optarg;
+			break;
 		case 'F':
 			g.force = 1;
 			break;
openSUSE Build Service is sponsored by