diff options
author | James Bottomley <James.Bottomley@HansenPartnership.com> | 2023-11-22 10:58:31 -0500 |
---|---|---|
committer | James Bottomley <James.Bottomley@HansenPartnership.com> | 2023-11-22 16:44:32 -0500 |
commit | 36b4d7d447593831d3addf358a5921ec8947b1f1 (patch) | |
tree | 40978bcc650b61049f990e6afdaece3d52b0084d | |
parent | df71996a0107b4ac931040206f4808af71da13c2 (diff) | |
download | openssl_tpm2_engine-36b4d7d447593831d3addf358a5921ec8947b1f1.tar.gz |
signed_tpm2_policy: match the man page
The man page says we implement three commands: add, ls and rm; but we
don't, we only implement add. So fix signed_tpm2_policy to match its
man page.
Signed-off-by: James Bottomley <James.Bottomley@HansenPartnership.com>
-rw-r--r-- | src/tools/signed_tpm2_policy.c | 218 | ||||
-rwxr-xr-x | tests/check_signed_policies.sh | 29 |
2 files changed, 162 insertions, 85 deletions
diff --git a/src/tools/signed_tpm2_policy.c b/src/tools/signed_tpm2_policy.c index 1ddf9b4..2968174 100644 --- a/src/tools/signed_tpm2_policy.c +++ b/src/tools/signed_tpm2_policy.c @@ -101,7 +101,7 @@ int main(int argc, char **argv) { char *filename, *policyFilename = NULL, *policy_name = NULL, *policy_signing_key; - int option_index, c, auth = 0; + int option_index, c, auth = 0, i; const char *reason = NULL; TPM_RC rc; char *engine = NULL; @@ -110,12 +110,38 @@ int main(int argc, char **argv) TPMT_HA digest; int size; TPML_PCR_SELECTION pcr_lock = { 0 }; + STACK_OF(TSSAUTHPOLICY) *sk; + enum cmd { + CMD_ADD = 0, + CMD_LS, + CMD_RM, + CMD_MAX + } cmd; + static char *command[] = { + [CMD_ADD] = "add", + [CMD_LS] = "ls", + [CMD_RM] = "rm", + }; + char *argv0 = argv[0]; OpenSSL_add_all_digests(); /* may be needed to decrypt the key */ OpenSSL_add_all_ciphers(); - while (1) { + if (argc < 2) + usage(argv0); + + for (cmd = CMD_ADD; cmd < CMD_MAX; cmd++) + if (strcmp(argv[1], command[cmd]) == 0) + break; + if (cmd == CMD_MAX) { + fprintf(stderr, "Unknown command %s\n", argv[1]); + usage(argv0); + } + argc--; + argv++; + + while (cmd == CMD_ADD) { option_index = 0; c = getopt_long(argc, argv, "ahvc:x:e:n:", long_options, &option_index); @@ -127,14 +153,14 @@ int main(int argc, char **argv) auth = 1; break; case 'h': - usage(argv[0]); + usage(argv0); break; case 'v': fprintf(stdout, "%s " VERSION "\n" "Copyright 2017 by James Bottomley\n" "License LGPL-2.1-only\n" "Written by James Bottomley <James.Bottomley@HansenPartnership.com>\n", - argv[0]); + argv0); exit(0); case 'c': policyFilename = optarg; @@ -153,95 +179,137 @@ int main(int argc, char **argv) break; default: printf("Unknown option '%c'\n", c); - usage(argv[0]); + usage(argv0); break; } } - if (optind >= argc - 1) { - printf("Too few arguments: Expected file name as last argument\n"); - usage(argv[0]); + if (((cmd == CMD_RM || cmd == CMD_ADD) && optind != argc - 2) || + (cmd == CMD_LS && optind != argc - 1)) { + fprintf(stderr, "Incorrect number of arguments\n"); + usage(argv0); } - filename = argv[argc - 2]; - policy_signing_key = argv[argc - 1]; + switch(cmd) { + case CMD_ADD: + filename = argv[argc - 2]; + policy_signing_key = argv[argc - 1]; - if (optind < argc - 2) { - printf("Unexpected additional arguments\n"); - usage(argv[0]); - } + if (optind < argc - 2) { + printf("Unexpected additional arguments\n"); + usage(argv0); + } - name_alg = tpm2_get_name_alg(filename); - digest.hashAlg = name_alg; - size = TSS_GetDigestSize(digest.hashAlg); - memset((uint8_t *)&digest.digest, 0, size); + name_alg = tpm2_get_name_alg(filename); + digest.hashAlg = name_alg; + size = TSS_GetDigestSize(digest.hashAlg); + memset((uint8_t *)&digest.digest, 0, size); - ap = TSSAUTHPOLICY_new(); - if (policy_name) { - ap->name = ASN1_UTF8STRING_new(); - ASN1_STRING_set(ap->name, policy_name, strlen(policy_name)); - } - ap->policy = sk_TSSOPTPOLICY_new_null(); - if (!ap->policy) { - rc = NOT_TPM_ERROR; - reason="sk_TSSOPTPOLICY_new_null allocation"; + ap = TSSAUTHPOLICY_new(); + if (policy_name) { + ap->name = ASN1_UTF8STRING_new(); + ASN1_STRING_set(ap->name, policy_name, strlen(policy_name)); + } + ap->policy = sk_TSSOPTPOLICY_new_null(); + if (!ap->policy) { + rc = NOT_TPM_ERROR; + reason="sk_TSSOPTPOLICY_new_null allocation"; + goto out_err; + } + + if (policyFilename) { + rc = tpm2_parse_policy_file(policyFilename, ap->policy, + (char *)(unsigned long)auth, + &digest); + reason = "parse_policy_file"; + if (rc) + goto out_free_policy; + } else if (signed_policy) { + rc = tpm2_add_signed_policy(ap->policy, signed_policy, &digest); + reason = "add_signed_policy"; + if (rc) + goto out_free_policy; + } + + if (auth) + tpm2_add_auth_policy(ap->policy, &digest); + + if (pcr_lock.count != 0) { + TSS_CONTEXT *tssContext = NULL; + const char *dir; + + dir = tpm2_set_unique_tssdir(); + rc = tpm2_create(&tssContext, dir); + if (rc) { + reason = "TSS_Create"; + goto out_free_policy; + } + rc = tpm2_pcr_lock_policy(tssContext, &pcr_lock, + ap->policy, &digest); + TSS_Delete(tssContext); + tpm2_rm_tssdir(dir); + if (rc) { + reason = "create pcr policy"; + goto out_free_policy; + } + } + + rc = tpm2_new_signed_policy(filename, policy_signing_key, + engine, ap, &digest); + if (rc == 0) + exit(0); + + /* tpm2_new_signed_policy frees the key which includes the policy */ goto out_err; - } - if (policyFilename) { - rc = tpm2_parse_policy_file(policyFilename, ap->policy, - (char *)(unsigned long)auth, - &digest); - reason = "parse_policy_file"; - if (rc) - goto out_free_policy; - } else if (signed_policy) { - rc = tpm2_add_signed_policy(ap->policy, signed_policy, &digest); - reason = "add_signed_policy"; - if (rc) - goto out_free_policy; - } + out_free_policy: + if (ap->name) + ASN1_UTF8STRING_free(ap->name); + tpm2_free_policy(ap->policy); + out_err: + if (rc == NOT_TPM_ERROR) + fprintf(stderr, "%s failed\n", reason); + else + tpm2_error(rc, reason); - if (auth) - tpm2_add_auth_policy(ap->policy, &digest); + exit(1); - if (pcr_lock.count != 0) { - TSS_CONTEXT *tssContext = NULL; - const char *dir; + case CMD_LS: + filename = argv[argc - 1]; - dir = tpm2_set_unique_tssdir(); - rc = tpm2_create(&tssContext, dir); - if (rc) { - reason = "TSS_Create"; - goto out_free_policy; + rc = tpm2_get_signed_policy(filename, &sk); + if (rc) + exit(1); + if (!sk || sk_TSSAUTHPOLICY_num(sk) <=0 ) { + printf("Key has no signed policies\n"); + sk_TSSAUTHPOLICY_free(sk); + exit(0); } - rc = tpm2_pcr_lock_policy(tssContext, &pcr_lock, - ap->policy, &digest); - TSS_Delete(tssContext); - tpm2_rm_tssdir(dir); - if (rc) { - reason = "create pcr policy"; - goto out_free_policy; + printf("Policy Name\n"); + for (i = 0; i < sk_TSSAUTHPOLICY_num(sk); i++) { + TSSAUTHPOLICY *ap = sk_TSSAUTHPOLICY_value(sk, i); + int sz = ap->name ? ap->name->length : 0; + char *name = ap->name ? (char *)ap->name->data : ""; + if (sz) + printf("%6d %*s\n", i+1, sz, name); + else + printf("%6d\n", i+1); } - } - - rc = tpm2_new_signed_policy(filename, policy_signing_key, engine, - ap, &digest); - if (rc == 0) + sk_TSSAUTHPOLICY_pop_free(sk, TSSAUTHPOLICY_free); exit(0); - /* tpm2_new_signed_policy frees the key which includes the policy */ - goto out_err; + case CMD_RM: + filename = argv[argc - 2]; + i = atoi(argv[argc - 1]); - out_free_policy: - if (ap->name) - ASN1_UTF8STRING_free(ap->name); - tpm2_free_policy(ap->policy); - out_err: - if (rc == NOT_TPM_ERROR) - fprintf(stderr, "%s failed\n", reason); - else - tpm2_error(rc, reason); + rc = tpm2_rm_signed_policy(filename, i); + if (rc) + exit(1); + exit(0); - exit(1); + case CMD_MAX: + /* has to be here because stupid gcc doesn't notice + * the check above means it's impossible to get here*/ + ; + } } diff --git a/tests/check_signed_policies.sh b/tests/check_signed_policies.sh index 46405d3..fb29e5a 100755 --- a/tests/check_signed_policies.sh +++ b/tests/check_signed_policies.sh @@ -1,6 +1,5 @@ #!/bin/bash - tss_pcrreset_cmd=tsspcrreset tss_pcrextend_cmd=tsspcrextend @@ -49,18 +48,18 @@ for alg in EC RSA; do # 5. do sign with key and verify four times. Check that all # but the last succeeds and the last one fails ${tss_pcrreset_cmd} -ha 16 - ${bindir}/signed_tpm2_policy --policy-name "PCR16-0" --pcr-lock 16 key.tpm policy.key || exit 1 - ${bindir}/signed_tpm2_policy --policy-name "PCR16-0" --pcr-lock 16 seal.tpm policy.key || exit 1 + ${bindir}/signed_tpm2_policy add --policy-name "PCR16-0" --pcr-lock 16 key.tpm policy.key || exit 1 + ${bindir}/signed_tpm2_policy add --policy-name "PCR16-0" --pcr-lock 16 seal.tpm policy.key || exit 1 openssl rsa $ENGINE $INFORM -in key.tpm -pubout -out key.pub || exit 1 ${tss_pcrextend_cmd} -ha 16 -ic aaa - ${bindir}/signed_tpm2_policy --policy-name "PCR16-extend" --pcr-lock 16 key.tpm policy.key || exit 1 - ${bindir}/signed_tpm2_policy --policy-name "PCR16-extend" --pcr-lock 16 seal.tpm policy.key || exit 1 + ${bindir}/signed_tpm2_policy add --policy-name "PCR16-extend" --pcr-lock 16 key.tpm policy.key || exit 1 + ${bindir}/signed_tpm2_policy add --policy-name "PCR16-extend" --pcr-lock 16 seal.tpm policy.key || exit 1 ${tss_pcrextend_cmd} -ha 16 -ic aaa - ${bindir}/signed_tpm2_policy --policy-name "PCR16-extendx2" --pcr-lock 16 key.tpm policy.key || exit 1 - ${bindir}/signed_tpm2_policy --policy-name "PCR16-extendx2" --pcr-lock 16 seal.tpm policy.key || exit 1 + ${bindir}/signed_tpm2_policy add --policy-name "PCR16-extendx2" --pcr-lock 16 key.tpm policy.key || exit 1 + ${bindir}/signed_tpm2_policy add --policy-name "PCR16-extendx2" --pcr-lock 16 seal.tpm policy.key || exit 1 ${tss_pcrextend_cmd} -ha 16 -ic aaa - ${bindir}/signed_tpm2_policy --policy-name "PCR16-extendx3" --pcr-lock 16 key.tpm policy.key || exit 1 - ${bindir}/signed_tpm2_policy --policy-name "PCR16-extendx3" --pcr-lock 16 seal.tpm policy.key || exit 1 + ${bindir}/signed_tpm2_policy add --policy-name "PCR16-extendx3" --pcr-lock 16 key.tpm policy.key || exit 1 + ${bindir}/signed_tpm2_policy add --policy-name "PCR16-extendx3" --pcr-lock 16 seal.tpm policy.key || exit 1 ${tss_pcrreset_cmd} -ha 16 openssl pkeyutl -sign -in plain.txt $ENGINE $KEYFORM -inkey key.tpm -out tmp.msg && \ openssl pkeyutl -verify -in plain.txt -sigfile tmp.msg -inkey key.pub -pubin || exit 1 @@ -80,7 +79,17 @@ for alg in EC RSA; do ${tss_pcrextend_cmd} -ha 16 -ic aaa openssl pkeyutl -sign -in plain.txt $ENGINE $KEYFORM -inkey key.tpm -out tmp.msg && exit 1 ${bindir}/unseal_tpm2_data seal.tpm && exit 1 - + ## + # Finally check we can find the zero pcr16 policy in the list + # and remove it + ## + ${tss_pcrreset_cmd} -ha 16 + ${bindir}/signed_tpm2_policy ls seal.tpm | grep -q "4 PCR16-0" || exit 1 + ${bindir}/signed_tpm2_policy rm seal.tpm 4 || exit 1 + ${bindir}/signed_tpm2_policy ls seal.tpm | grep -q " PCR16-0" && exit 1 + ${bindir}/unseal_tpm2_data seal.tpm && exit 1 + ${tss_pcrextend_cmd} -ha 16 -ic aaa + ${bindir}/unseal_tpm2_data seal.tpm || exit 1 done done exit 0 |