1 /********************************************************************************/
2 /* */
3 /* ReadPublic */
4 /* Written by Ken Goldman */
5 /* IBM Thomas J. Watson Research Center */
6 /* */
7 /* (c) Copyright IBM Corporation 2015 - 2019. */
8 /* */
9 /* All rights reserved. */
10 /* */
11 /* Redistribution and use in source and binary forms, with or without */
12 /* modification, are permitted provided that the following conditions are */
13 /* met: */
14 /* */
15 /* Redistributions of source code must retain the above copyright notice, */
16 /* this list of conditions and the following disclaimer. */
17 /* */
18 /* Redistributions in binary form must reproduce the above copyright */
19 /* notice, this list of conditions and the following disclaimer in the */
20 /* documentation and/or other materials provided with the distribution. */
21 /* */
22 /* Neither the names of the IBM Corporation nor the names of its */
23 /* contributors may be used to endorse or promote products derived from */
24 /* this software without specific prior written permission. */
25 /* */
26 /* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS */
27 /* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT */
28 /* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR */
29 /* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT */
30 /* HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, */
31 /* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT */
32 /* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, */
33 /* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY */
34 /* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT */
35 /* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE */
36 /* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */
37 /********************************************************************************/
38
39 /*
40
41 */
42
43 #include <stdio.h>
44 #include <stdlib.h>
45 #include <string.h>
46 #include <stdint.h>
47
48 #include <ibmtss/tss.h>
49 #include <ibmtss/tssutils.h>
50 #include <ibmtss/tssresponsecode.h>
51 #include <ibmtss/tssmarshal.h>
52
53 #include "cryptoutils.h"
54
55 static void printReadPublic(ReadPublic_Out *out);
56 static void printUsage(void);
57
58 extern int tssUtilsVerbose;
59
main(int argc,char * argv[])60 int main(int argc, char *argv[])
61 {
62 TPM_RC rc = 0;
63 int i; /* argc iterator */
64 TSS_CONTEXT *tssContext = NULL;
65 ReadPublic_In in;
66 ReadPublic_Out out;
67 TPMI_DH_PCR objectHandle = TPM_RH_NULL;
68 const char *publicKeyFilename = NULL;
69 const char *pemFilename = NULL;
70 int noSpace = FALSE;
71 TPMI_SH_AUTH_SESSION sessionHandle0 = TPM_RH_NULL;
72 unsigned int sessionAttributes0 = 0;
73 TPMI_SH_AUTH_SESSION sessionHandle1 = TPM_RH_NULL;
74 unsigned int sessionAttributes1 = 0;
75 TPMI_SH_AUTH_SESSION sessionHandle2 = TPM_RH_NULL;
76 unsigned int sessionAttributes2 = 0;
77
78 setvbuf(stdout, 0, _IONBF, 0); /* output may be going through pipe to log file */
79 TSS_SetProperty(NULL, TPM_TRACE_LEVEL, "1");
80 tssUtilsVerbose = FALSE;
81
82 /* command line argument defaults */
83 for (i=1 ; (i<argc) && (rc == 0) ; i++) {
84 if (strcmp(argv[i],"-ho") == 0) {
85 i++;
86 if (i < argc) {
87 sscanf(argv[i],"%x", &objectHandle);
88 }
89 else {
90 printf("Missing parameter for -ho\n");
91 printUsage();
92 }
93 }
94 else if (strcmp(argv[i],"-opu") == 0) {
95 i++;
96 if (i < argc) {
97 publicKeyFilename = argv[i];
98 }
99 else {
100 printf("-opu option needs a value\n");
101 printUsage();
102 }
103 }
104 else if (strcmp(argv[i],"-opem") == 0) {
105 i++;
106 if (i < argc) {
107 pemFilename = argv[i];
108 }
109 else {
110 printf("-opem option needs a value\n");
111 printUsage();
112 }
113 }
114 else if (strcmp(argv[i],"-ns") == 0) {
115 noSpace = TRUE;
116 }
117 else if (strcmp(argv[i],"-se0") == 0) {
118 i++;
119 if (i < argc) {
120 sscanf(argv[i],"%x", &sessionHandle0);
121 }
122 else {
123 printf("Missing parameter for -se0\n");
124 printUsage();
125 }
126 i++;
127 if (i < argc) {
128 sscanf(argv[i],"%x", &sessionAttributes0);
129 if (sessionAttributes0 > 0xff) {
130 printf("Out of range session attributes for -se0\n");
131 printUsage();
132 }
133 }
134 else {
135 printf("Missing parameter for -se0\n");
136 printUsage();
137 }
138 }
139 else if (strcmp(argv[i],"-se1") == 0) {
140 i++;
141 if (i < argc) {
142 sscanf(argv[i],"%x", &sessionHandle1);
143 }
144 else {
145 printf("Missing parameter for -se1\n");
146 printUsage();
147 }
148 i++;
149 if (i < argc) {
150 sscanf(argv[i],"%x", &sessionAttributes1);
151 if (sessionAttributes1 > 0xff) {
152 printf("Out of range session attributes for -se1\n");
153 printUsage();
154 }
155 }
156 else {
157 printf("Missing parameter for -se1\n");
158 printUsage();
159 }
160 }
161 else if (strcmp(argv[i],"-se2") == 0) {
162 i++;
163 if (i < argc) {
164 sscanf(argv[i],"%x", &sessionHandle2);
165 }
166 else {
167 printf("Missing parameter for -se2\n");
168 printUsage();
169 }
170 i++;
171 if (i < argc) {
172 sscanf(argv[i],"%x", &sessionAttributes2);
173 if (sessionAttributes2 > 0xff) {
174 printf("Out of range session attributes for -se2\n");
175 printUsage();
176 }
177 }
178 else {
179 printf("Missing parameter for -se2\n");
180 printUsage();
181 }
182 }
183 else if (strcmp(argv[i],"-h") == 0) {
184 printUsage();
185 }
186 else if (strcmp(argv[i],"-v") == 0) {
187 tssUtilsVerbose = TRUE;
188 TSS_SetProperty(NULL, TPM_TRACE_LEVEL, "2");
189 }
190 else {
191 printf("\n%s is not a valid option\n", argv[i]);
192 printUsage();
193 }
194 }
195 if (objectHandle == TPM_RH_NULL) {
196 printf("Missing or bad object handle parameter -ho\n");
197 printUsage();
198 }
199 if (rc == 0) {
200 in.objectHandle = objectHandle;
201 }
202 /* Start a TSS context */
203 if (rc == 0) {
204 rc = TSS_Create(&tssContext);
205 }
206 /* call TSS to execute the command */
207 if (rc == 0) {
208 rc = TSS_Execute(tssContext,
209 (RESPONSE_PARAMETERS *)&out,
210 (COMMAND_PARAMETERS *)&in,
211 NULL,
212 TPM_CC_ReadPublic,
213 sessionHandle0, NULL, sessionAttributes0,
214 sessionHandle1, NULL, sessionAttributes1,
215 sessionHandle2, NULL, sessionAttributes2,
216 TPM_RH_NULL, NULL, 0);
217 }
218 {
219 TPM_RC rc1 = TSS_Delete(tssContext);
220 if (rc == 0) {
221 rc = rc1;
222 }
223 }
224 /* save the public key */
225 if ((rc == 0) && (publicKeyFilename != NULL)) {
226 rc = TSS_File_WriteStructure(&out.outPublic,
227 (MarshalFunction_t)TSS_TPM2B_PUBLIC_Marshalu,
228 publicKeyFilename);
229 }
230 /* save the optional PEM public key */
231 if ((rc == 0) && (pemFilename != NULL)) {
232 rc = convertPublicToPEM(&out.outPublic,
233 pemFilename);
234 }
235 if (rc == 0) {
236 if (tssUtilsVerbose) printReadPublic(&out);
237 if (noSpace) {
238 unsigned int b;
239 for (b = 0 ; b < out.name.t.size ; b++) {
240 printf("%02x", out.name.t.name[b]);
241 }
242 printf("\n");
243 }
244 if (tssUtilsVerbose) printf("readpublic: success\n");
245 }
246 else {
247 const char *msg;
248 const char *submsg;
249 const char *num;
250 printf("readpublic: failed, rc %08x\n", rc);
251 TSS_ResponseCode_toString(&msg, &submsg, &num, rc);
252 printf("%s%s%s\n", msg, submsg, num);
253 rc = EXIT_FAILURE;
254 }
255 return rc;
256 }
257
printReadPublic(ReadPublic_Out * out)258 static void printReadPublic(ReadPublic_Out *out)
259 {
260 TSS_TPMT_PUBLIC_Print(&out->outPublic.publicArea, 0);
261 TSS_PrintAll("name",
262 out->name.t.name,
263 out->name.t.size);
264 }
265
printUsage(void)266 static void printUsage(void)
267 {
268 printf("\n");
269 printf("readpublic\n");
270 printf("\n");
271 printf("Runs TPM2_ReadPublic\n");
272 printf("\n");
273 printf("\t-ho\tobject handle\n");
274 printf("\t[-opu\tpublic key file name (default do not save)]\n");
275 printf("\t[-opem\tpublic key PEM format file name (default do not save)]\n");
276 printf("\t[-ns\tadditionally print Name in hex ascii on one line]\n");
277 printf("\t\tUseful to paste into policy\n");
278 printf("\n");
279 printf("\t-se[0-2] session handle / attributes (default NULL)\n");
280 printf("\t01\tcontinue\n");
281 printf("\t40\tresponse encrypt\n");
282 printf("\t80\taudit\n");
283 exit(1);
284 }
285