tpm2_readpublic.c 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179
  1. /* SPDX-License-Identifier: BSD-3-Clause */
  2. #include <stdbool.h>
  3. #include <stdlib.h>
  4. #include "files.h"
  5. #include "log.h"
  6. #include "tpm2.h"
  7. #include "tpm2_convert.h"
  8. #include "tpm2_tool.h"
  9. typedef struct tpm_readpub_ctx tpm_readpub_ctx;
  10. struct tpm_readpub_ctx {
  11. struct {
  12. UINT8 f :1;
  13. } flags;
  14. char *output_path;
  15. char *out_name_file;
  16. char *out_qname_file;
  17. tpm2_convert_pubkey_fmt format;
  18. tpm2_loaded_object context_object;
  19. const char *context_arg;
  20. const char *out_tr_file;
  21. };
  22. static tpm_readpub_ctx ctx = {
  23. .format = pubkey_format_tss,
  24. };
  25. static tool_rc read_public_and_save(ESYS_CONTEXT *ectx) {
  26. TPM2B_PUBLIC *public;
  27. TPM2B_NAME *name;
  28. TPM2B_NAME *qualified_name;
  29. tool_rc rc = tool_rc_general_error;
  30. tool_rc tmp_rc = tpm2_readpublic(ectx, ctx.context_object.tr_handle,
  31. &public, &name, &qualified_name);
  32. if (tmp_rc != tool_rc_success) {
  33. return tmp_rc;
  34. }
  35. tpm2_tool_output("name: ");
  36. UINT16 i;
  37. for (i = 0; i < name->size; i++) {
  38. tpm2_tool_output("%02x", name->name[i]);
  39. }
  40. tpm2_tool_output("\n");
  41. bool ret = true;
  42. if (ctx.out_name_file) {
  43. ret = files_save_bytes_to_file(ctx.out_name_file, name->name,
  44. name->size);
  45. if (!ret) {
  46. LOG_ERR("Can not save object name file.");
  47. goto out;
  48. }
  49. }
  50. tpm2_tool_output("qualified name: ");
  51. for (i = 0; i < qualified_name->size; i++) {
  52. tpm2_tool_output("%02x", qualified_name->name[i]);
  53. }
  54. tpm2_tool_output("\n");
  55. tpm2_util_public_to_yaml(public, NULL);
  56. ret = ctx.output_path ?
  57. tpm2_convert_pubkey_save(public, ctx.format, ctx.output_path) :
  58. true;
  59. if (!ret) {
  60. goto out;
  61. }
  62. if (ctx.out_qname_file) {
  63. ret = files_save_bytes_to_file(ctx.out_qname_file, qualified_name->name,
  64. qualified_name->size);
  65. if (!ret) {
  66. goto out;
  67. }
  68. }
  69. if (ctx.out_tr_file) {
  70. rc = files_save_ESYS_TR(ectx, ctx.context_object.tr_handle,
  71. ctx.out_tr_file);
  72. } else {
  73. rc = tool_rc_success;
  74. }
  75. out:
  76. free(public);
  77. free(name);
  78. free(qualified_name);
  79. return rc;
  80. }
  81. static bool on_option(char key, char *value) {
  82. switch (key) {
  83. case 'c':
  84. ctx.context_arg = value;
  85. break;
  86. case 'o':
  87. ctx.output_path = value;
  88. break;
  89. case 'f':
  90. ctx.format = tpm2_convert_pubkey_fmt_from_optarg(value);
  91. if (ctx.format == pubkey_format_err) {
  92. return false;
  93. }
  94. ctx.flags.f = 1;
  95. break;
  96. case 'n':
  97. ctx.out_name_file = value;
  98. break;
  99. case 't':
  100. ctx.out_tr_file = value;
  101. break;
  102. case 'q':
  103. ctx.out_qname_file = value;
  104. break;
  105. }
  106. return true;
  107. }
  108. static bool tpm2_tool_onstart(tpm2_options **opts) {
  109. static const struct option topts[] = {
  110. { "output", required_argument, NULL, 'o' },
  111. { "object-context", required_argument, NULL, 'c' },
  112. { "format", required_argument, NULL, 'f' },
  113. { "name", required_argument, NULL, 'n' },
  114. { "serialized-handle", required_argument, NULL, 't' },
  115. { "qualified-name", required_argument, NULL, 'q' }
  116. };
  117. *opts = tpm2_options_new("o:c:f:n:t:q:", ARRAY_LEN(topts), topts, on_option,
  118. NULL, 0);
  119. return *opts != NULL;
  120. }
  121. static tool_rc init(ESYS_CONTEXT *context) {
  122. tool_rc rc = tpm2_util_object_load(context, ctx.context_arg,
  123. &ctx.context_object, TPM2_HANDLE_ALL_W_NV);
  124. if (rc != tool_rc_success) {
  125. return rc;
  126. }
  127. bool is_persistent = ctx.context_object.handle
  128. && ((ctx.context_object.handle >> TPM2_HR_SHIFT)
  129. == TPM2_HT_PERSISTENT);
  130. if (ctx.out_tr_file && !is_persistent) {
  131. LOG_ERR("Can only output a serialized handle for persistent object "
  132. "handles");
  133. return tool_rc_general_error;
  134. }
  135. return tool_rc_success;
  136. }
  137. static tool_rc tpm2_tool_onrun(ESYS_CONTEXT *context, tpm2_option_flags flags) {
  138. UNUSED(flags);
  139. tool_rc rc = init(context);
  140. if (rc != tool_rc_success) {
  141. return rc;
  142. }
  143. return read_public_and_save(context);
  144. }
  145. // Register this tool with tpm2_tool.c
  146. TPM2_TOOL_REGISTER("readpublic", tpm2_tool_onstart, tpm2_tool_onrun, NULL, NULL)