123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403 |
- #include <errno.h>
- #include <inttypes.h>
- #include <stdbool.h>
- #include <stdio.h>
- #include <stdlib.h>
- #include <string.h>
- #include "files.h"
- #include "log.h"
- #include "tpm2.h"
- #include "tpm2_tool.h"
- typedef struct tpm_activatecred_ctx tpm_activatecred_ctx;
- #define MAX_AUX_SESSIONS 1
- #define MAX_SESSIONS 3
- struct tpm_activatecred_ctx {
-
- struct {
- const char *ctx_path;
- const char *auth_str;
- tpm2_loaded_object object;
- } credential_key;
- struct {
- const char *ctx_path;
- const char *auth_str;
- tpm2_loaded_object object;
- } credentialed_key;
- TPM2B_ID_OBJECT credential_blob;
- const char *credential_blob_path;
- bool is_credential_blob_specified;
- TPM2B_ENCRYPTED_SECRET secret;
-
- const char *output_file;
- TPM2B_DIGEST *cert_info_data;
-
- const char *cp_hash_path;
- TPM2B_DIGEST cp_hash;
- const char *rp_hash_path;
- TPM2B_DIGEST rp_hash;
- TPMI_ALG_HASH parameter_hash_algorithm;
- bool is_command_dispatch;
-
- uint8_t aux_session_cnt;
- tpm2_session *aux_session[MAX_AUX_SESSIONS];
- const char *aux_session_path[MAX_AUX_SESSIONS];
- ESYS_TR aux_session_handle[MAX_AUX_SESSIONS];
- };
- static tpm_activatecred_ctx ctx = {
- .aux_session_handle[0] = ESYS_TR_NONE,
- .parameter_hash_algorithm = TPM2_ALG_ERROR,
- };
- static tool_rc activate_credential_and_output(ESYS_CONTEXT *ectx) {
-
- return tpm2_activatecredential(ectx, &ctx.credentialed_key.object,
- &ctx.credential_key.object, &ctx.credential_blob, &ctx.secret,
- &ctx.cert_info_data, &ctx.cp_hash, &ctx.rp_hash,
- ctx.parameter_hash_algorithm, ctx.aux_session_handle[0]);
- }
- static tool_rc process_output(ESYS_CONTEXT *ectx) {
- UNUSED(ectx);
-
- bool is_file_op_success = true;
- if (ctx.cp_hash_path) {
- is_file_op_success = files_save_digest(&ctx.cp_hash, ctx.cp_hash_path);
- if (!is_file_op_success) {
- return tool_rc_general_error;
- }
- }
- if (!ctx.is_command_dispatch) {
- return tool_rc_success;
- }
-
- tpm2_tool_output("certinfodata:");
- size_t i;
- for (i = 0; i < ctx.cert_info_data->size; i++) {
- tpm2_tool_output("%.2x", ctx.cert_info_data->buffer[i]);
- }
- tpm2_tool_output("\n");
- is_file_op_success = files_save_bytes_to_file(ctx.output_file,
- ctx.cert_info_data->buffer, ctx.cert_info_data->size);
- free(ctx.cert_info_data);
- if (!is_file_op_success) {
- return tool_rc_general_error;
- }
- if (ctx.rp_hash_path) {
- is_file_op_success = files_save_digest(&ctx.rp_hash, ctx.rp_hash_path);
- }
- return is_file_op_success ? tool_rc_success : tool_rc_general_error;
- }
- static bool read_cert_secret(void) {
- bool result = false;
- FILE *fp = fopen(ctx.credential_blob_path, "rb");
- if (!fp) {
- LOG_ERR("Could not open file \"%s\" error: \"%s\"",
- ctx.credential_blob_path, strerror(errno));
- return false;
- }
- uint32_t version;
- result = files_read_header(fp, &version);
- if (!result) {
- LOG_ERR("Could not read version header");
- goto out;
- }
- if (version != 1) {
- LOG_ERR("Unknown credential format, got %"PRIu32" expected 1", version);
- goto out;
- }
- result = files_read_16(fp, &ctx.credential_blob.size);
- if (!result) {
- LOG_ERR("Could not read credential size");
- goto out;
- }
- result = files_read_bytes(fp, ctx.credential_blob.credential, ctx.credential_blob.size);
- if (!result) {
- LOG_ERR("Could not read credential data");
- goto out;
- }
- result = files_read_16(fp, &ctx.secret.size);
- if (!result) {
- LOG_ERR("Could not read secret size");
- goto out;
- }
- result = files_read_bytes(fp, ctx.secret.secret, ctx.secret.size);
- if (!result) {
- LOG_ERR("Could not write secret data");
- goto out;
- }
- result = true;
- out:
- fclose(fp);
- return result;
- }
- static tool_rc process_inputs(ESYS_CONTEXT *ectx) {
-
-
-
-
- tool_rc rc = tpm2_util_object_load_auth(ectx, ctx.credential_key.ctx_path,
- ctx.credential_key.auth_str, &ctx.credential_key.object, false,
- TPM2_HANDLE_ALL_W_NV);
- if (rc != tool_rc_success) {
- return rc;
- }
-
- rc = tpm2_util_object_load_auth(ectx, ctx.credentialed_key.ctx_path,
- ctx.credentialed_key.auth_str, &ctx.credentialed_key.object, false,
- TPM2_HANDLE_ALL_W_NV);
- if (rc != tool_rc_success) {
- return rc;
- }
-
- rc = tpm2_util_aux_sessions_setup(ectx, ctx.aux_session_cnt,
- ctx.aux_session_path, ctx.aux_session_handle, ctx.aux_session);
- if (rc != tool_rc_success) {
- return rc;
- }
-
- rc = read_cert_secret() ? tool_rc_success : tool_rc_general_error;
- if (rc != tool_rc_success) {
- return rc;
- }
-
-
- tpm2_session *all_sessions[MAX_SESSIONS] = {
- ctx.credential_key.object.session,
- ctx.credentialed_key.object.session,
- ctx.aux_session[0]
- };
- const char **cphash_path = ctx.cp_hash_path ? &ctx.cp_hash_path : 0;
- const char **rphash_path = ctx.rp_hash_path ? &ctx.rp_hash_path : 0;
- ctx.parameter_hash_algorithm = tpm2_util_calculate_phash_algorithm(ectx,
- cphash_path, &ctx.cp_hash, rphash_path, &ctx.rp_hash, all_sessions);
-
- ctx.is_command_dispatch = (ctx.cp_hash_path && !ctx.rp_hash_path) ?
- false : true;
- return rc;
- }
- static tool_rc check_options(void) {
- if ((!ctx.credentialed_key.ctx_path) && (!ctx.credential_key.ctx_path)
- && !ctx.is_credential_blob_specified && !ctx.output_file) {
- LOG_ERR("Expected options c and C and i and o.");
- return tool_rc_option_error;
- }
- return tool_rc_success;
- }
- static bool on_option(char key, char *value) {
- switch (key) {
- case 'c':
- ctx.credentialed_key.ctx_path = value;
- break;
- case 'p':
- ctx.credentialed_key.auth_str = value;
- break;
- case 'C':
- ctx.credential_key.ctx_path = value;
- break;
- case 'P':
- ctx.credential_key.auth_str = value;
- break;
- case 'i':
-
- ctx.credential_blob_path = value;
- ctx.is_credential_blob_specified = 1;
- break;
- case 'o':
- ctx.output_file = value;
- break;
- case 0:
- ctx.cp_hash_path = value;
- break;
- case 1:
- ctx.rp_hash_path = value;
- break;
- case 'S':
- ctx.aux_session_path[ctx.aux_session_cnt] = value;
- if (ctx.aux_session_cnt < MAX_AUX_SESSIONS) {
- ctx.aux_session_cnt++;
- } else {
- LOG_ERR("Specify a max of 3 sessions");
- return false;
- }
- break;
- }
- return true;
- }
- static bool tpm2_tool_onstart(tpm2_options **opts) {
- static const struct option topts[] = {
- {"credentialedkey-context", required_argument, NULL, 'c'},
- {"credentialkey-context", required_argument, NULL, 'C'},
- {"credentialedkey-auth", required_argument, NULL, 'p'},
- {"credentialkey-auth", required_argument, NULL, 'P'},
- {"credential-blob", required_argument, NULL, 'i'},
- {"certinfo-data", required_argument, NULL, 'o'},
- {"cphash", required_argument, NULL, 0 },
- {"rphash", required_argument, NULL, 1 },
- {"session", required_argument, NULL, 'S' },
- };
- *opts = tpm2_options_new("c:C:p:P:i:o:S:", ARRAY_LEN(topts), topts, on_option,
- NULL, 0);
- return *opts != NULL;
- }
- static tool_rc tpm2_tool_onrun(ESYS_CONTEXT *ectx, tpm2_option_flags flags) {
-
- UNUSED(flags);
-
- tool_rc rc = check_options();
- if (rc != tool_rc_success) {
- return rc;
- }
-
- rc = process_inputs(ectx);
- if (rc != tool_rc_success) {
- return rc;
- }
-
- rc = activate_credential_and_output(ectx);
- if (rc != tool_rc_success) {
- return rc;
- }
-
- return process_output(ectx);
- }
- static tool_rc tpm2_tool_onstop(ESYS_CONTEXT *ectx) {
- UNUSED(ectx);
-
-
- tool_rc rc = tool_rc_success;
- tool_rc tmp_rc = tpm2_session_close(&ctx.credentialed_key.object.session);
- if (tmp_rc != tool_rc_success) {
- rc = tmp_rc;
- }
- tmp_rc = tpm2_session_close(&ctx.credential_key.object.session);
- if (tmp_rc != tool_rc_success) {
- rc = tmp_rc;
- }
-
- size_t i = 0;
- for(i = 0; i < ctx.aux_session_cnt; i++) {
- if (ctx.aux_session_path[i]) {
- tmp_rc = tpm2_session_close(&ctx.aux_session[i]);
- if (tmp_rc != tool_rc_success) {
- rc = tmp_rc;
- }
- }
- }
- return rc;
- }
- TPM2_TOOL_REGISTER("activatecredential", tpm2_tool_onstart, tpm2_tool_onrun,
- tpm2_tool_onstop, NULL)
|