tss2_quote.c 6.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223
  1. /* SPDX-License-Identifier: BSD-3-Clause */
  2. #include <stdbool.h>
  3. #include <stdio.h>
  4. #include <stdlib.h>
  5. #include <string.h>
  6. #include "tools/fapi/tss2_template.h"
  7. /* Context struct used to store passed command line parameters */
  8. static struct cxt {
  9. uint32_t *pcrList;
  10. size_t pcrListSize;
  11. char const *keyPath;
  12. char const *qualifyingData;
  13. char const *quoteInfo;
  14. char const *pcrLog;
  15. char const *signature;
  16. char const *certificate;
  17. bool overwrite;
  18. } ctx;
  19. /**
  20. * Split the comma separated input, parse each token as number,
  21. * put the numbers in the array output. Allocate memory for
  22. * output to hold the numbers.
  23. *
  24. * On failure returns false and output is not allocated.
  25. * On success the caller frees output.
  26. */
  27. static inline bool extract_pcrs(char *input, uint32_t **output, size_t *list_size) {
  28. size_t size = 1;
  29. char *temp = input;
  30. while ((temp = strchr (temp+1, ','))) size++;
  31. *output = malloc (sizeof(uint32_t) * (size));
  32. if (!*output) {
  33. fprintf (stderr, "malloc failed: %m\n");
  34. return false;
  35. }
  36. char *x = strtok_r (input, ",", &temp);
  37. if (!tpm2_util_string_to_uint32(x, output[0])) {
  38. fprintf (stderr, "%s cannot be used as PCR\n", x);
  39. free (*output);
  40. return false;
  41. }
  42. size = 0;
  43. while ((x = strtok_r (NULL, ",", &temp))) {
  44. if (!tpm2_util_string_to_uint32(x, &(*output)[++size])) {
  45. fprintf (stderr, "%s cannot be used as PCR\n", x);
  46. free (*output);
  47. return false;
  48. }
  49. }
  50. *list_size = size+1;
  51. return true;
  52. }
  53. /* Parse command line parameters */
  54. static bool on_option(char key, char *value) {
  55. (void)value;
  56. switch (key) {
  57. case 'x':
  58. return extract_pcrs(value, &ctx.pcrList, &ctx.pcrListSize);
  59. case 'Q':
  60. ctx.qualifyingData = value;
  61. break;
  62. case 'l':
  63. ctx.pcrLog = value;
  64. break;
  65. case 'f':
  66. ctx.overwrite = true;
  67. break;
  68. case 'p':
  69. ctx.keyPath = value;
  70. break;
  71. case 'q':
  72. ctx.quoteInfo = value;
  73. break;
  74. case 'o':
  75. ctx.signature = value;
  76. break;
  77. case 'c':
  78. ctx.certificate = value;
  79. break;
  80. }
  81. return true;
  82. }
  83. /* Define possible command line parameters */
  84. static bool tss2_tool_onstart(tpm2_options **opts) {
  85. struct option topts[] = {
  86. {"pcrList" , required_argument, NULL, 'x'},
  87. {"keyPath" , required_argument, NULL, 'p'},
  88. {"qualifyingData", required_argument, NULL, 'Q'},
  89. {"quoteInfo" , required_argument, NULL, 'q'},
  90. {"signature" , required_argument, NULL, 'o'},
  91. {"pcrLog" , required_argument, NULL, 'l'},
  92. {"certificate" , required_argument, NULL, 'c'},
  93. {"force" , no_argument , NULL, 'f'}
  94. };
  95. return (*opts = tpm2_options_new ("x:Q:l:fp:q:o:c:", ARRAY_LEN(topts),
  96. topts, on_option, NULL, 0)) != NULL;
  97. }
  98. /* Execute specific tool */
  99. static int tss2_tool_onrun (FAPI_CONTEXT *fctx) {
  100. /* Check availability of required parameters */
  101. if (!ctx.pcrList) {
  102. fprintf (stderr, "No PCRs were chosen, use --pcrList\n");
  103. return -1;
  104. }
  105. if (!ctx.keyPath) {
  106. fprintf (stderr, "No key path provided, use --keyPath\n");
  107. free (ctx.pcrList);
  108. return -1;
  109. }
  110. if (!ctx.quoteInfo) {
  111. fprintf (stderr, "No quoteInfo provided, use --quoteInfo\n");
  112. free (ctx.pcrList);
  113. return -1;
  114. }
  115. if (!ctx.signature) {
  116. fprintf (stderr, "No signature provided, use --signature\n");
  117. free (ctx.pcrList);
  118. return -1;
  119. }
  120. /* Check exclusive access to stdout */
  121. int count_out = 0;
  122. if (ctx.quoteInfo && !strcmp (ctx.quoteInfo, "-")) count_out +=1;
  123. if (ctx.pcrLog && !strcmp (ctx.pcrLog, "-")) count_out +=1;
  124. if (ctx.signature && !strcmp (ctx.signature, "-")) count_out +=1;
  125. if (ctx.certificate && !strcmp (ctx.certificate, "-")) count_out +=1;
  126. if (count_out > 1) {
  127. fprintf (stderr, "Only one of --quoteInfo, --pcrLog, --signature and "\
  128. "--certificate can print to - (standard output)\n");
  129. free (ctx.pcrList);
  130. return -1;
  131. }
  132. /* Read qualifyingData file */
  133. TSS2_RC r;
  134. uint8_t *qualifyingData = NULL;
  135. size_t qualifyingDataSize = 0;
  136. if (ctx.qualifyingData) {
  137. r = open_read_and_close (ctx.qualifyingData,
  138. (void*)&qualifyingData, &qualifyingDataSize);
  139. if (r) {
  140. free (ctx.pcrList);
  141. return 1;
  142. }
  143. }
  144. /* Execute FAPI command with passed arguments */
  145. uint8_t *signature;
  146. size_t signatureSize;
  147. char *quoteInfo, *pcrLog = NULL, *certificate = NULL;
  148. r = Fapi_Quote (fctx, ctx.pcrList, ctx.pcrListSize, ctx.keyPath,
  149. NULL, qualifyingData, qualifyingDataSize, &quoteInfo,
  150. &signature, &signatureSize, &pcrLog, &certificate);
  151. if (r != TSS2_RC_SUCCESS) {
  152. LOG_PERR ("Fapi_Quote", r);
  153. free (ctx.pcrList);
  154. free (qualifyingData);
  155. return 1;
  156. }
  157. free (ctx.pcrList);
  158. free (qualifyingData);
  159. /* Write returned data to file(s) */
  160. if (ctx.quoteInfo && quoteInfo) {
  161. r = open_write_and_close (ctx.quoteInfo, ctx.overwrite, quoteInfo,
  162. strlen(quoteInfo));
  163. if (r) {
  164. Fapi_Free (quoteInfo);
  165. Fapi_Free (pcrLog);
  166. Fapi_Free (signature);
  167. Fapi_Free (certificate);
  168. return 1;
  169. }
  170. }
  171. Fapi_Free (quoteInfo);
  172. if (ctx.pcrLog && pcrLog) {
  173. r = open_write_and_close (ctx.pcrLog, ctx.overwrite, pcrLog,
  174. strlen(pcrLog));
  175. if (r) {
  176. Fapi_Free (pcrLog);
  177. Fapi_Free (signature);
  178. Fapi_Free (certificate);
  179. return 1;
  180. }
  181. }
  182. Fapi_Free (pcrLog);
  183. if (ctx.signature && signature) {
  184. r = open_write_and_close (ctx.signature, ctx.overwrite, signature,
  185. signatureSize);
  186. if (r) {
  187. Fapi_Free (signature);
  188. Fapi_Free (certificate);
  189. return 1;
  190. }
  191. }
  192. Fapi_Free (signature);
  193. if (ctx.certificate && certificate) {
  194. r = open_write_and_close (ctx.certificate, ctx.overwrite, certificate,
  195. strlen(certificate));
  196. if (r) {
  197. Fapi_Free (certificate);
  198. return 1;
  199. }
  200. }
  201. Fapi_Free (certificate);
  202. return 0;
  203. }
  204. TSS2_TOOL_REGISTER("quote", tss2_tool_onstart, tss2_tool_onrun, NULL)