diff options
author | Lennart Poettering <lennart@poettering.net> | 2022-04-19 14:47:02 +0200 |
---|---|---|
committer | Lennart Poettering <lennart@poettering.net> | 2022-04-20 16:58:18 +0200 |
commit | 6e0cb81505deb8fd785492f90cdac10388d1858e (patch) | |
tree | fcc1a7ed9515e944ff3a9df830739b7678009bca /src/creds/creds.c | |
parent | 0ea911d14c738447511b5a807750b356e0758895 (diff) | |
download | systemd-6e0cb81505deb8fd785492f90cdac10388d1858e.tar.gz |
creds-tool: add new "has-tpm2" verb
Sometimes it's useful from shell scripts to check if we have a working
TPM2 chip around. For example, when putting together encrypted
credentials for the initrd (after all: it might be wise to place the
root pw in a credential for the initrd to consume, but do so only if we
can lock it to the TPM2, and not otherwise, so that we risk nothing).
Hence, let's add a new "systemd-creds has-tpm2" verb: it returns zero if we
have a working TPM2 (which means: supported by kernel + firmware + us),
or non-zero otherwise. Also show which parts are available.
Use-case: in future the 'kernel-install' script should use this when
deciding whether to augment kernels with security sensitive credentials.
Diffstat (limited to 'src/creds/creds.c')
-rw-r--r-- | src/creds/creds.c | 51 |
1 files changed, 44 insertions, 7 deletions
diff --git a/src/creds/creds.c b/src/creds/creds.c index 6e3441e5a0..1d69aed4c4 100644 --- a/src/creds/creds.c +++ b/src/creds/creds.c @@ -48,6 +48,7 @@ static bool arg_name_any = false; static usec_t arg_timestamp = USEC_INFINITY; static usec_t arg_not_after = USEC_INFINITY; static bool arg_pretty = false; +static bool arg_quiet = false; static const char* transcode_mode_table[_TRANSCODE_MAX] = { [TRANSCODE_OFF] = "off", @@ -525,6 +526,34 @@ static int verb_setup(int argc, char **argv, void *userdata) { return EXIT_SUCCESS; } +static int verb_has_tpm2(int argc, char **argv, void *userdata) { + Tpm2Support s; + + s = tpm2_support(); + + if (!arg_quiet) { + if (s == TPM2_SUPPORT_FULL) + puts("yes"); + else if (s == TPM2_SUPPORT_NONE) + puts("no"); + else + puts("partial"); + + printf("%sfirmware\n" + "%sdriver\n" + "%ssystem\n", + plus_minus(s & TPM2_SUPPORT_FIRMWARE), + plus_minus(s & TPM2_SUPPORT_DRIVER), + plus_minus(s & TPM2_SUPPORT_SYSTEM)); + } + + /* Return inverted bit flags. So that TPM2_SUPPORT_FULL becomes EXIT_SUCCESS and the other values + * become some reasonable values 1…7. i.e. the flags we return here tell what is missing rather than + * what is there, acknowledging the fact that for process exit statusses it is customary to return + * zero (EXIT_FAILURE) when all is good, instead of all being bad. */ + return ~s & TPM2_SUPPORT_FULL; +} + static int verb_help(int argc, char **argv, void *userdata) { _cleanup_free_ char *link = NULL; int r; @@ -543,6 +572,7 @@ static int verb_help(int argc, char **argv, void *userdata) { " ciphertext credential file\n" " decrypt INPUT [OUTPUT] Decrypt ciphertext credential file and write to\n" " plaintext credential file\n" + " has-tpm2 Report whether TPM2 support is available\n" " -h --help Show this help\n" " --version Show package version\n" "\n%3$sOptions:%4$s\n" @@ -568,6 +598,7 @@ static int verb_help(int argc, char **argv, void *userdata) { " Pick TPM2 device\n" " --tpm2-pcrs=PCR1+PCR2+PCR3+…\n" " Specify TPM2 PCRs to seal against\n" + " -q --quiet Suppress output for 'has-tpm2' verb\n" "\nSee the %2$s for details.\n" , program_invocation_short_name , link @@ -612,6 +643,7 @@ static int parse_argv(int argc, char *argv[]) { { "name", required_argument, NULL, ARG_NAME }, { "timestamp", required_argument, NULL, ARG_TIMESTAMP }, { "not-after", required_argument, NULL, ARG_NOT_AFTER }, + { "quiet", no_argument, NULL, 'q' }, {} }; @@ -620,7 +652,7 @@ static int parse_argv(int argc, char *argv[]) { assert(argc >= 0); assert(argv); - while ((c = getopt_long(argc, argv, "hHTp", options, NULL)) >= 0) { + while ((c = getopt_long(argc, argv, "hHTpq", options, NULL)) >= 0) { switch (c) { @@ -757,6 +789,10 @@ static int parse_argv(int argc, char *argv[]) { break; + case 'q': + arg_quiet = true; + break; + case '?': return -EINVAL; @@ -774,12 +810,13 @@ static int parse_argv(int argc, char *argv[]) { static int creds_main(int argc, char *argv[]) { static const Verb verbs[] = { - { "list", VERB_ANY, 1, VERB_DEFAULT, verb_list }, - { "cat", 2, VERB_ANY, 0, verb_cat }, - { "encrypt", 3, 3, 0, verb_encrypt }, - { "decrypt", 2, 3, 0, verb_decrypt }, - { "setup", VERB_ANY, 1, 0, verb_setup }, - { "help", VERB_ANY, 1, 0, verb_help }, + { "list", VERB_ANY, 1, VERB_DEFAULT, verb_list }, + { "cat", 2, VERB_ANY, 0, verb_cat }, + { "encrypt", 3, 3, 0, verb_encrypt }, + { "decrypt", 2, 3, 0, verb_decrypt }, + { "setup", VERB_ANY, 1, 0, verb_setup }, + { "help", VERB_ANY, 1, 0, verb_help }, + { "has-tpm2", VERB_ANY, 1, 0, verb_has_tpm2 }, {} }; |