summaryrefslogtreecommitdiff
path: root/src/creds
diff options
context:
space:
mode:
authorLennart Poettering <lennart@poettering.net>2022-04-19 14:47:02 +0200
committerLennart Poettering <lennart@poettering.net>2022-04-20 16:58:18 +0200
commit6e0cb81505deb8fd785492f90cdac10388d1858e (patch)
treefcc1a7ed9515e944ff3a9df830739b7678009bca /src/creds
parent0ea911d14c738447511b5a807750b356e0758895 (diff)
downloadsystemd-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')
-rw-r--r--src/creds/creds.c51
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 },
{}
};