mirror of
https://github.com/ibm-s390-linux/s390-tools.git
synced 2026-08-05 02:14:52 +00:00
pvattest: Add --output option to verify subcommand
Other tools may need to process the configuration-unique id. Provide a machine readable format by writing to a YAML file containing a `cuid` entry and optionally an `add` entry. New CLI options `--format` and `--output` are introduced for this. Currently, only the output format `yaml` is supported. Reviewed-by: Jan Höppner <hoeppner@linux.ibm.com> Signed-off-by: Steffen Eiden <seiden@linux.ibm.com> Signed-off-by: Marc Hartmayer <mhartmay@linux.ibm.com> Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
This commit is contained in:
committed by
Jan Höppner
parent
5e1ef90962
commit
a07d1bca74
@@ -14,6 +14,7 @@ Release history for s390-tools (MIT version)
|
|||||||
Changes of existing tools:
|
Changes of existing tools:
|
||||||
- genprotimg: add support for add-secret requests
|
- genprotimg: add support for add-secret requests
|
||||||
- dbginfo.sh: global IFS variable
|
- dbginfo.sh: global IFS variable
|
||||||
|
- pvattest: add yaml-output for verify command
|
||||||
|
|
||||||
Bug Fixes:
|
Bug Fixes:
|
||||||
|
|
||||||
|
|||||||
@@ -24,12 +24,27 @@ Show help options
|
|||||||
\fBFILE\fP specifies the attestation result as input.
|
\fBFILE\fP specifies the attestation result as input.
|
||||||
.TP
|
.TP
|
||||||
.B
|
.B
|
||||||
|
\fB-o\fP, \fB--ouput\fP=\fBFILE\fP
|
||||||
|
\fBFILE\fP specifies the output for the verification result.
|
||||||
|
.TP
|
||||||
|
.B
|
||||||
\fB--hdr\fP=\fBFILE\fP
|
\fB--hdr\fP=\fBFILE\fP
|
||||||
Specify the header of the guest image. Exactly one is required.
|
Specify the header of the guest image. Exactly one is required.
|
||||||
.TP
|
.TP
|
||||||
.B
|
.B
|
||||||
\fB-a\fP, \fB--arpk\fP=\fBFILE\fP
|
\fB-a\fP, \fB--arpk\fP=\fBFILE\fP
|
||||||
Use \fBFILE\fP to specify the GCM-AES256 key to decrypt the attestation request. Delete this key after verification.
|
Use \fBFILE\fP to specify the GCM-AES256 key to decrypt the attestation request. Delete this key after verification.
|
||||||
|
.TP
|
||||||
|
.B
|
||||||
|
\fB--format\fP=\fByaml\fP
|
||||||
|
Define the output format.
|
||||||
|
Default value: 'yaml'
|
||||||
|
|
||||||
|
Possible values:
|
||||||
|
.RS 4
|
||||||
|
- \fByaml\fP: Use YAML format
|
||||||
|
.RE
|
||||||
|
|
||||||
.TP
|
.TP
|
||||||
.B
|
.B
|
||||||
\fB-V\fP, \fB--verbose\fP
|
\fB-V\fP, \fB--verbose\fP
|
||||||
|
|||||||
+30
-1
@@ -49,8 +49,10 @@ static pvattest_config_t pvattest_config = {
|
|||||||
},
|
},
|
||||||
.verify = {
|
.verify = {
|
||||||
.input_path = NULL,
|
.input_path = NULL,
|
||||||
|
.output_path = NULL,
|
||||||
.hdr_path = NULL,
|
.hdr_path = NULL,
|
||||||
.arp_key_in_path = NULL,
|
.arp_key_in_path = NULL,
|
||||||
|
.output_fmt = VERIFY_FMT_YAML,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
typedef gboolean (*verify_options_fn_t)(GError **);
|
typedef gboolean (*verify_options_fn_t)(GError **);
|
||||||
@@ -329,6 +331,15 @@ static gboolean hex_str_toull(const char *nptr, uint64_t *dst, GError **error)
|
|||||||
.description = "Use FILE to specify the user data.\n", .arg_description = "FILE", \
|
.description = "Use FILE to specify the user data.\n", .arg_description = "FILE", \
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#define _entry__verify_format(__indent) \
|
||||||
|
{ \
|
||||||
|
.long_name = "format", .short_name = 0, .flags = G_OPTION_FLAG_NONE, \
|
||||||
|
.arg = G_OPTION_ARG_CALLBACK, .arg_data = &set_verify_output_format, \
|
||||||
|
.description = "Define the output format.\n" __indent \
|
||||||
|
"Defaults to 'yaml'. (possible values: 'yaml')\n", \
|
||||||
|
.arg_description = "FORMAT", \
|
||||||
|
}
|
||||||
|
|
||||||
static gboolean increase_log_lvl(G_GNUC_UNUSED const char *option_name,
|
static gboolean increase_log_lvl(G_GNUC_UNUSED const char *option_name,
|
||||||
G_GNUC_UNUSED const char *value, G_GNUC_UNUSED void *data,
|
G_GNUC_UNUSED const char *value, G_GNUC_UNUSED void *data,
|
||||||
G_GNUC_UNUSED GError **error)
|
G_GNUC_UNUSED GError **error)
|
||||||
@@ -337,6 +348,20 @@ static gboolean increase_log_lvl(G_GNUC_UNUSED const char *option_name,
|
|||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static gboolean set_verify_output_format(const char *option_name, const char *value,
|
||||||
|
G_GNUC_UNUSED void *data, GError **error)
|
||||||
|
{
|
||||||
|
if (!g_strcmp0(value, "yaml")) {
|
||||||
|
pvattest_config.verify.output_fmt = VERIFY_FMT_YAML;
|
||||||
|
} else {
|
||||||
|
g_set_error(error, G_OPTION_ERROR, G_OPTION_ERROR_FAILED,
|
||||||
|
_("Found value '%s' for option '%s', but only 'yaml' is allowed."),
|
||||||
|
value, option_name);
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
static gboolean create_set_paf(G_GNUC_UNUSED const char *option_name, const char *value,
|
static gboolean create_set_paf(G_GNUC_UNUSED const char *option_name, const char *value,
|
||||||
G_GNUC_UNUSED void *data, GError **error)
|
G_GNUC_UNUSED void *data, GError **error)
|
||||||
{
|
{
|
||||||
@@ -445,13 +470,16 @@ static gboolean verify_perform(GError **error)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/************************* VERIFY OPTIONS ************************************/
|
/************************* VERIFY OPTIONS ************************************/
|
||||||
#define verify_indent " "
|
#define verify_indent " "
|
||||||
|
|
||||||
static GOptionEntry verify_options[] = {
|
static GOptionEntry verify_options[] = {
|
||||||
_entry_input(&pvattest_config.verify.input_path, "attestation result", verify_indent),
|
_entry_input(&pvattest_config.verify.input_path, "attestation result", verify_indent),
|
||||||
|
_entry_output(&pvattest_config.verify.output_path,
|
||||||
|
"verification result.\n" verify_indent "(optional)", verify_indent),
|
||||||
_entry_guest_hdr(&pvattest_config.verify.hdr_path, verify_indent),
|
_entry_guest_hdr(&pvattest_config.verify.hdr_path, verify_indent),
|
||||||
_entry_att_prot_key_load(&pvattest_config.verify.arp_key_in_path, verify_indent),
|
_entry_att_prot_key_load(&pvattest_config.verify.arp_key_in_path, verify_indent),
|
||||||
_entry_verbose(verify_indent),
|
_entry_verbose(verify_indent),
|
||||||
|
_entry__verify_format(verify_indent),
|
||||||
{ NULL },
|
{ NULL },
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -631,6 +659,7 @@ static void pvattest_parse_clear_verify_config(pvattest_verify_config_t *config)
|
|||||||
if (!config)
|
if (!config)
|
||||||
return;
|
return;
|
||||||
g_free(config->input_path);
|
g_free(config->input_path);
|
||||||
|
g_free(config->output_path);
|
||||||
g_free(config->hdr_path);
|
g_free(config->hdr_path);
|
||||||
g_free(config->arp_key_in_path);
|
g_free(config->arp_key_in_path);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -60,10 +60,13 @@ typedef struct {
|
|||||||
|
|
||||||
enum verify_output_format {
|
enum verify_output_format {
|
||||||
VERIFY_FMT_HUMAN,
|
VERIFY_FMT_HUMAN,
|
||||||
|
VERIFY_FMT_YAML,
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
char *input_path;
|
char *input_path;
|
||||||
|
char *output_path;
|
||||||
|
enum verify_output_format output_fmt;
|
||||||
char *hdr_path;
|
char *hdr_path;
|
||||||
char *arp_key_in_path;
|
char *arp_key_in_path;
|
||||||
} pvattest_verify_config_t;
|
} pvattest_verify_config_t;
|
||||||
|
|||||||
@@ -280,6 +280,24 @@ static int fprint_verify_result(FILE *stream, const enum verify_output_format fm
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
case VERIFY_FMT_YAML:
|
||||||
|
if (fprintf(stream, "cuid: ") < 0)
|
||||||
|
return -1;
|
||||||
|
if (pvattest_hexdump(stream, config_uid, 0L, "'0x", FALSE) < 0)
|
||||||
|
return -1;
|
||||||
|
if (fprintf(stream, _("'\n")) < 0)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
if (additional_data) {
|
||||||
|
if (fprintf(stream, "add: ") < 0)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
if (pvattest_hexdump(stream, additional_data, 0x0L, "'0x", FALSE) < 0)
|
||||||
|
return -1;
|
||||||
|
if (fprintf(stream, _("'\n")) < 0)
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
g_assert_not_reached();
|
g_assert_not_reached();
|
||||||
break;
|
break;
|
||||||
@@ -363,6 +381,23 @@ static int do_verify(const pvattest_verify_config_t *verify_config, const int ap
|
|||||||
goto err_exit;
|
goto err_exit;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Write to file */
|
||||||
|
if (verify_config->output_path) {
|
||||||
|
g_autoptr(FILE) output = pv_file_open(verify_config->output_path, "wx", &error);
|
||||||
|
|
||||||
|
if (!output) {
|
||||||
|
err_prefix = "Failed to write output";
|
||||||
|
goto err_exit;
|
||||||
|
}
|
||||||
|
if (fprint_verify_result(output, verify_config->output_fmt, config_uid,
|
||||||
|
additional_data) < 0) {
|
||||||
|
g_set_error(&error, PV_GLIB_HELPER_ERROR, PV_GLIB_HELPER_FILE_ERROR,
|
||||||
|
"'%s': %s", verify_config->output_path, g_strerror(errno));
|
||||||
|
err_prefix = "Failed to write output";
|
||||||
|
goto err_exit;
|
||||||
|
}
|
||||||
|
}
|
||||||
return EXIT_SUCCESS;
|
return EXIT_SUCCESS;
|
||||||
|
|
||||||
err_exit:
|
err_exit:
|
||||||
|
|||||||
Reference in New Issue
Block a user