接前一篇文章:tpm2-tools源码分析之tpm2_unseal.c(1)
本文对tpm2_unseal.c中的tpm2_tool_onstart函数进行详细解析。
先再次贴出该函数源码:
static bool tpm2_tool_onstart(tpm2_options **opts) {static const struct option topts[] = {{ "auth", required_argument, NULL, 'p' },{ "output", required_argument, NULL, 'o' },{ "object-context", required_argument, NULL, 'c' },{ "cphash", required_argument, NULL, 0 },{ "rphash", required_argument, NULL, 1 },{ "session", required_argument, NULL, 'S' },};*opts = tpm2_options_new("S:p:o:c:", ARRAY_LEN(topts), topts, on_option,NULL, 0);return *opts != NULL;
}
tpm2_options结构的定义在tpm2-tools/lib/tpm2_options.h中,代码如下:
struct tpm2_options {struct {tpm2_option_handler on_opt;tpm2_arg_handler on_arg;} callbacks;char *short_opts;size_t len;uint32_t flags;struct option long_opts[];
};typedef struct tpm2_options tpm2_options;
struct option的定义在/usr/include/bits/getopt_ext.h中,代码如下:
struct option
{const char *name;/* has_arg can't be an enum because some compilers complain abouttype mismatches in all the code that assumes it is an int. */int has_arg;int *flag;int val;
};
on_option函数的实现在同文件(tools/tpm2_unseal.c)中,如下:
static bool on_option(char key, char *value) {switch (key) {case 'c':ctx.sealkey.ctx_path = value;break;case 'p': {ctx.sealkey.auth_str = value;}break;case 'o':ctx.output_file_path = 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 {return false;}break;}return true;
}
要更好地理解这些选项乃至tpm2_tool_onstart函数的功能,需要与tpm2_unseal命令的说明相结合来看。tpm2_unseal命令的详细说明参见:
tpm2-tools/tpm2_unseal.1.md at master · tpm2-software/tpm2-tools · GitHub
下载了源码后,在tpm2-tools/man/tpm2_unseal.1.md中。
其中的参数说明如下:
OPTIONS
-c, --object-context=OBJECT:
Object context for the loaded object. —— 已加载对象的对象上下文。
-p, --auth=AUTH:
Optional auth value to use for the key specified by -c. —— 用于-c指定的密钥的可选授权值。
-o, --output=FILE:
Output file name containing the unsealed data. Defaults to STDOUT if not specified. —— 包含未密封数据的输出文件名。如未指定,默认为STDOUT(标准输出)。
--cphash=FILE
File path to record the hash of the command parameters. This is commonly termed as cpHash. NOTE: When this option is selected, The tool will not actually execute the command, it simply returns a cpHash, it simply returns a cpHash, unless rphash is also required. —— 记录命令参数哈希的文件路径。其通常被称为cpHash。注意:当此选项被选择,工具将不会实际执行命令,它只是简单地返回一个cpHash,除非也提供rphash。
--rphash=FILE
File path to record the hash of the response parameters. This is commonly termed as rpHash. —— 记录响应参数哈希的文件路径。其通常被称为rpHash。
-S, --session=FILE:
The session created using tpm2_startauthsession. Multiple of these can be specified. For example, you can have one session for auditing and another for encryption/decryption of the parameters. —— 使用tpm2_startauthsession创建的会话。可以指定多个。例如,您可以有一个用于审计的会话和另一个用于参数的加密/解密的会话。
tpm2_options_new函数属于公共代码,在tpm2-tools/lib/tpm2_options.c中,代码如下:
tpm2_options *tpm2_options_new(const char *short_opts, size_t len,const struct option *long_opts, tpm2_option_handler on_opt,tpm2_arg_handler on_arg, uint32_t flags) {tpm2_options *opts = calloc(1, sizeof(*opts) + (sizeof(*long_opts) * len));if (!opts) {LOG_ERR("oom");return NULL;}/** On NULL, just make it a zero length string so we don't have to keep* checking it for NULL.*/if (!short_opts) {short_opts = "";}opts->short_opts = strdup(short_opts);if (!opts->short_opts) {LOG_ERR("oom");free(opts);return NULL;}opts->callbacks.on_opt = on_opt;opts->callbacks.on_arg = on_arg;opts->len = len;opts->flags = flags;memcpy(opts->long_opts, long_opts, len * sizeof(*long_opts));return opts;
}
tpm2_new_options函数很容易理解,其功能是基于tpm2_tool_onstart函数中的struct option topts构建tpm2_options实例(*opts)。
至此,tpm2_unseal.c中的tpm2_tool_onstart函数就基本分析完了。