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