diff --git a/man/man8/swtpm_setup.pod b/man/man8/swtpm_setup.pod index c9ce534..8f97472 100644 --- a/man/man8/swtpm_setup.pod +++ b/man/man8/swtpm_setup.pod @@ -218,6 +218,10 @@ supported by libtpms. The profile may contain an algorithms field with a list of algorithms to enable. Unknown fields in the JSON profile will be ignored. +=item B<--profile-file > + +Configure a TPM 2 with a profile from a file. + =item B<--profile-remove-disabled check|fips-host> When this option is passed then swtpm will remove algorithms from the given @@ -305,7 +309,7 @@ TPM 2 setup is supported (libtpms is compiled with TPM 2 support). =item B (since v0.10) -The I<--profile> option is supported. +The I<--profile> and I<--profile-file> option are supported. =item B (since v0.10) diff --git a/src/swtpm_setup/swtpm.c b/src/swtpm_setup/swtpm.c index 6ab5abe..d384bf8 100644 --- a/src/swtpm_setup/swtpm.c +++ b/src/swtpm_setup/swtpm.c @@ -76,6 +76,7 @@ static void swtpm_close_comm(struct swtpm *self, bool all) static int swtpm_start(struct swtpm *self) { g_autofree gchar *tpmstate = g_strdup_printf("backend-uri=%s", self->state_path); + g_autofree gchar *json_profile_params = NULL; g_autofree gchar *json_profile = NULL; g_autofree gchar *pidfile_arg = NULL; g_autofree gchar *server_fd = NULL; @@ -90,6 +91,7 @@ static int swtpm_start(struct swtpm *self) unsigned ctr; int pidfile_fd; int ret = 1; + gchar *tmp; char pidfile[] = "/tmp/.swtpm_setup.pidfile.XXXXXX"; pidfile_fd = g_mkstemp_full(pidfile, O_EXCL|O_CREAT, 0600); @@ -119,18 +121,26 @@ static int swtpm_start(struct swtpm *self) argv = concat_arrays(argv, (const gchar*[]){"--key", keyopts, NULL}, TRUE); } - if (self->json_profile != NULL) { - json_profile = g_strdup_printf("profile=%s%s%s", - self->json_profile, - self->profile_remove_disabled_param != NULL - ? ",remove-disabled=" - : "", - self->profile_remove_disabled_param != NULL - ? self->profile_remove_disabled_param - : ""); - argv = concat_arrays(argv, (const gchar*[]){"--profile", json_profile, NULL}, TRUE); + if (self->json_profile_fd >= 0) { + json_profile = g_strdup_printf("fd=%u", self->json_profile_fd); + } else if (self->json_profile != NULL) { + json_profile = g_strdup_printf("profile=%s", self->json_profile); logit(self->logfile, "Apply profile: %s\n", self->json_profile); } + if (json_profile && self->profile_remove_disabled_param) { + tmp = g_strdup_printf("%s,remove-disabled=%s", + json_profile, + self->profile_remove_disabled_param); + g_free(json_profile); + json_profile = tmp; + } + if (json_profile) + argv = concat_arrays(argv, (const gchar*[]){ + "--profile", + json_profile, + json_profile_params, + NULL + }, TRUE); if (gl_LOGFILE != NULL) { logop = g_strdup_printf("file=%s", gl_LOGFILE); @@ -2042,6 +2052,7 @@ static void swtpm_init(struct swtpm *swtpm, const gchar *keyopts, const gchar *logfile, int *fds_to_pass, size_t n_fds_to_pass, gboolean is_tpm2, const gchar *json_profile, + int json_profile_fd, const gchar *profile_remove_disabled_param) { swtpm->cops = &swtpm_cops; @@ -2053,6 +2064,7 @@ static void swtpm_init(struct swtpm *swtpm, swtpm->n_fds_to_pass = n_fds_to_pass; swtpm->is_tpm2 = is_tpm2; swtpm->json_profile = json_profile; + swtpm->json_profile_fd = json_profile_fd; swtpm->profile_remove_disabled_param = profile_remove_disabled_param; swtpm->pid = -1; @@ -2067,7 +2079,7 @@ struct swtpm12 *swtpm12_new(gchar **swtpm_exec_l, const gchar *state_path, struct swtpm12 *swtpm12 = g_malloc0(sizeof(struct swtpm12)); swtpm_init(&swtpm12->swtpm, swtpm_exec_l, state_path, keyopts, logfile, - fds_to_pass, n_fds_to_pass, FALSE, NULL, NULL); + fds_to_pass, n_fds_to_pass, FALSE, NULL, 0, NULL); swtpm12->ops = &swtpm_tpm12_ops; return swtpm12; @@ -2076,13 +2088,13 @@ struct swtpm12 *swtpm12_new(gchar **swtpm_exec_l, const gchar *state_path, struct swtpm2 *swtpm2_new(gchar **swtpm_exec_l, const gchar *state_path, const gchar *keyopts, const gchar *logfile, int *fds_to_pass, size_t n_fds_to_pass, - const gchar *json_profile, + const gchar *json_profile, int json_profile_fd, const gchar *profile_remove_disabled_param) { struct swtpm2 *swtpm2 = g_malloc0(sizeof(struct swtpm2)); swtpm_init(&swtpm2->swtpm, swtpm_exec_l, state_path, keyopts, logfile, - fds_to_pass, n_fds_to_pass, TRUE, json_profile, + fds_to_pass, n_fds_to_pass, TRUE, json_profile, json_profile_fd, profile_remove_disabled_param); swtpm2->ops = &swtpm_tpm2_ops; diff --git a/src/swtpm_setup/swtpm.h b/src/swtpm_setup/swtpm.h index 2615513..ed8d3d4 100644 --- a/src/swtpm_setup/swtpm.h +++ b/src/swtpm_setup/swtpm.h @@ -70,6 +70,7 @@ struct swtpm { size_t n_fds_to_pass; gboolean is_tpm2; const char *json_profile; + int json_profile_fd; const char *profile_remove_disabled_param; GPid pid; @@ -94,7 +95,7 @@ struct swtpm12 *swtpm12_new(gchar **swtpm_prg_l, const gchar *tpm_state_path, struct swtpm2 *swtpm2_new(gchar **swtpm_prg_l, const gchar *tpm_state_path, const gchar *swtpm_keyopts, const gchar *logfile, int *fds_to_pass, size_t n_fds_to_pass, - const gchar *profile_rules, + const gchar *json_profile, int json_profile_fd, const gchar *profile_remove_disabled_param); void swtpm_free(struct swtpm *); diff --git a/src/swtpm_setup/swtpm_setup.c b/src/swtpm_setup/swtpm_setup.c index a249975..f8de413 100644 --- a/src/swtpm_setup/swtpm_setup.c +++ b/src/swtpm_setup/swtpm_setup.c @@ -588,14 +588,14 @@ static int init_tpm2(unsigned long flags, gchar **swtpm_prg_l, const gchar *conf const gchar *swtpm_keyopt, int *fds_to_pass, size_t n_fds_to_pass, unsigned int rsa_keysize, const gchar *certsdir, const gchar *user_certsdir, const gchar *json_profile, - const gchar *profile_remove_disabled_param) + int json_profile_fd, const gchar *profile_remove_disabled_param) { struct swtpm2 *swtpm2; struct swtpm *swtpm; int ret; swtpm2 = swtpm2_new(swtpm_prg_l, tpm2_state_path, swtpm_keyopt, gl_LOGFILE, - fds_to_pass, n_fds_to_pass, json_profile, + fds_to_pass, n_fds_to_pass, json_profile, json_profile_fd, profile_remove_disabled_param); if (swtpm2 == NULL) return 1; @@ -1026,6 +1026,9 @@ static void usage(const char *prgname, const char *default_config_file) "--profile \n" " : Configure swtpm with the given profile.\n" "\n" + "--profile-file \n" + " : Configure swtpm with a profile read from the given file.\n" + "\n" "--profile-remove-disabled check|fips-host\n" " : Instruct swtpm to remove algorithms that may be disabled by\n" " FIPS mode on the host from 'custom' profile.\n" @@ -1337,6 +1340,7 @@ int main(int argc, char *argv[]) {"print-capabilities", no_argument, NULL, 'y'}, {"reconfigure", no_argument, NULL, 'R'}, {"profile", required_argument, NULL, 'I'}, + {"profile-file", required_argument, NULL, 'g'}, {"profile-remove-disabled", required_argument, NULL, 'j'}, {"help", no_argument, NULL, 'h'}, {NULL, 0, NULL, 0} @@ -1367,7 +1371,9 @@ int main(int argc, char *argv[]) g_autofree gchar *certsdir = NULL; g_autofree gchar *user_certsdir = NULL; g_autofree gchar *json_profile = NULL; + g_autofree gchar *json_profile_file = NULL; g_autofree gchar *profile_remove_disabled_param = NULL; + int json_profile_fd = -1; gchar *tmp; gchar **swtpm_prg_l = NULL; gchar **tmp_l = NULL; @@ -1378,7 +1384,7 @@ int main(int argc, char *argv[]) char *endptr; gboolean swtpm_has_tpm12 = FALSE; gboolean swtpm_has_tpm2 = FALSE; - int fds_to_pass[1] = { -1 }; + int fds_to_pass[2] = { -1, -1 }; unsigned n_fds_to_pass = 0; char tmpbuffer[200]; time_t now; @@ -1557,6 +1563,10 @@ int main(int argc, char *argv[]) g_free(json_profile); json_profile = g_strdup(optarg); break; + case 'g': /* --profile-file */ + g_free(json_profile_file); + json_profile_file = g_strdup(optarg); + break; case 'j': /* --profile-remove-disabled */ if (strcmp(optarg, "fips-host") != 0 && strcmp(optarg, "check") != 0) { @@ -1725,9 +1735,26 @@ int main(int argc, char *argv[]) pcr_banks = get_default_pcr_banks(config_file_lines); } + if ((json_profile != NULL) + (json_profile_file != NULL) > 1) { + logerr(gl_LOGFILE, "Only one of --profile and --profile-file may be given\n"); + goto error; + } + + if (json_profile_file) { + json_profile_fd = open(json_profile_file, O_RDONLY); + if (json_profile_fd < 0) { + logerr(gl_LOGFILE, "Could not open profile file '%s': %s\n", + json_profile_file, strerror(errno)); + goto error; + } + fds_to_pass[n_fds_to_pass++] = json_profile_fd; + } + /* read default profile from swtpm_setup.conf */ - if ((flags & SETUP_TPM2_F) != 0 && json_profile == NULL) + if ((flags & SETUP_TPM2_F) != 0 && + json_profile == NULL && json_profile_fd < 0) { json_profile = get_default_profile(config_file_lines); + } if ((flags & SETUP_TPM2_F) != 0 && json_profile) { if (validate_json_profile((const char **)swtpm_prg_l, json_profile) != 0) @@ -1851,7 +1878,8 @@ int main(int argc, char *argv[]) } else { ret = init_tpm2(flags, swtpm_prg_l, config_file, tpm_state_path, vmid, pcr_banks, swtpm_keyopt, fds_to_pass, n_fds_to_pass, rsa_keysize, certsdir, - user_certsdir, json_profile, profile_remove_disabled_param); + user_certsdir, json_profile, json_profile_fd, + profile_remove_disabled_param); } if (ret == 0) { diff --git a/tests/test_tpm2_swtpm_setup_profile b/tests/test_tpm2_swtpm_setup_profile index a11cd65..7fbf8bd 100755 --- a/tests/test_tpm2_swtpm_setup_profile +++ b/tests/test_tpm2_swtpm_setup_profile @@ -379,7 +379,7 @@ if ! $SWTPM_SETUP \ --config "${workdir}/swtpm_setup.conf" \ --log "${workdir}/logfile" \ --tpm "${SWTPM_EXE} socket ${SWTPM_TEST_SECCOMP_OPT}" \ - --profile '{"Name":"null"}' + --profile-file <(echo '{"Name":"null"}') then echo "Test failed: Error: Could not run $SWTPM_SETUP and set null-profile." echo "Setup Logfile:"