3
* Copyright (C) International Business Machines Corp., 2005
5
* This program is free software; you can redistribute it and/or modify
6
* it under the terms of the GNU General Public License as published by
7
* the Free Software Foundation; either version 2 of the License, or
8
* (at your option) any later version.
10
* This program is distributed in the hope that it will be useful,
11
* but WITHOUT ANY WARRANTY; without even the implied warranty of
12
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See
13
* the GNU General Public License for more details.
15
* You should have received a copy of the GNU General Public License
16
* along with this program; if not, write to the Free Software
17
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
23
* Inspect a persistent storage file, printing information about it based
26
* There are 2 different types of persistent storage files:
30
* [UINT32 num_keys_on_disk]
32
* [TSS_UUID uuid_parent0 ]
33
* [UINT16 pub_data_size0 ]
34
* [UINT16 blob_size0 ]
35
* [UINT16 cache_flags0 ]
42
* [BYTE TrouSerS PS version='1']
43
* [UINT32 num_keys_on_disk ]
45
* [TSS_UUID uuid_parent0 ]
46
* [UINT16 pub_data_size0 ]
47
* [UINT16 blob_size0 ]
48
* [UINT32 vendor_data_size0 ]
49
* [UINT16 cache_flags0 ]
52
* [BYTE[] vendor_data0 ]
62
#include <sys/types.h>
64
#include <sys/unistd.h>
66
#include <trousers/tss.h>
68
#define PRINTERR(...) fprintf(stderr, ##__VA_ARGS__)
69
#define PRINT(...) printf("PS " __VA_ARGS__)
71
/* one global buffer we read into from the PS file */
72
unsigned char buf[1024];
77
PRINTERR("usage: %s filename\n", argv0);
82
print_hex(BYTE *buf, UINT32 len)
86
for (i=0, j=1; (i+4) < len; j++, i+=4) {
87
printf("%02x%02x%02x%02x ",
88
buf[i] & 0xff, buf[i+1] & 0xff,
89
buf[i+2] & 0xff, buf[i+3] & 0xff);
95
printf("%02x", buf[i++] & 0xff);
100
printkey_0(int i, FILE *f)
102
UINT16 pub_data_size, blob_size, cache_flags;
105
PRINT("uuid%d: ", i);
106
print_hex(buf, sizeof(TSS_UUID));
108
PRINT("parent uuid%d: ", i);
109
print_hex(&buf[sizeof(TSS_UUID)], sizeof(TSS_UUID));
111
pub_data_size = *(UINT16 *)&buf[(2 * sizeof(TSS_UUID))];
112
blob_size = *(UINT16 *)&buf[(2 * sizeof(TSS_UUID)) + sizeof(UINT16)];
113
cache_flags = *(UINT16 *)&buf[2*sizeof(TSS_UUID) + 2*sizeof(UINT16)];
115
PRINT("pub_data_size%d: %hu\n", i, pub_data_size);
116
PRINT("blob_size%d: %hu\n", i, blob_size);
117
PRINT("cache_flags%d: %02hx\n", i, cache_flags);
119
/* trash buf, we've got what we needed from it */
120
if ((members = fread(buf, pub_data_size + blob_size,
122
PRINTERR("fread: %s: %d members read\n", strerror(errno), members);
126
PRINT("pub_data%d:\n", i);
127
print_hex(buf, pub_data_size);
129
PRINT("blob%d:\n", i);
130
print_hex(&buf[pub_data_size], blob_size);
136
printkey_1(int i, FILE *f)
138
UINT16 pub_data_size, blob_size, cache_flags;
139
UINT32 vendor_data_size;
142
PRINT("uuid%d: ", i);
143
print_hex(buf, sizeof(TSS_UUID));
145
PRINT("parent uuid%d: ", i);
146
print_hex(&buf[sizeof(TSS_UUID)], sizeof(TSS_UUID));
148
pub_data_size = *(UINT16 *)&buf[(2 * sizeof(TSS_UUID))];
149
blob_size = *(UINT16 *)&buf[(2 * sizeof(TSS_UUID)) + sizeof(UINT16)];
150
vendor_data_size = *(UINT32 *)&buf[(2 * sizeof(TSS_UUID)) + 2*sizeof(UINT16)];
151
cache_flags = *(UINT16 *)&buf[2*sizeof(TSS_UUID) + sizeof(UINT16) + sizeof(UINT32)];
153
PRINT("pub_data_size%d: %hu\n", i, pub_data_size);
154
PRINT("blob_size%d: %hu\n", i, blob_size);
155
PRINT("vendor_data_size%d: %u\n", i, vendor_data_size);
156
PRINT("cache_flags%d: %02hx\n", i, cache_flags);
158
/* trash buf, we've got what we needed from it */
159
if ((members = fread(buf, pub_data_size + blob_size + vendor_data_size,
161
PRINTERR("fread: %s: %d members read\n", strerror(errno), members);
165
PRINT("pub_data%d:\n", i);
166
print_hex(buf, pub_data_size);
168
PRINT("blob%d:\n", i);
169
print_hex(&buf[pub_data_size], blob_size);
171
PRINT("vendor_data%d:\n", i);
172
if (vendor_data_size > 0)
173
print_hex(&buf[pub_data_size + blob_size], vendor_data_size);
179
version_0_print(FILE *f)
182
UINT32 i, u32 = *(UINT32 *)buf;
184
PRINT("version: 0\n");
185
PRINT("number of keys: %u\n", u32);
187
/* The +- 1's below account for the byte we read in to determine
188
* if the PS file had a version byte at the beginning */
190
/* align the beginning of the buffer with the beginning of the key */
191
memcpy(buf, &buf[4], sizeof(TSS_UUID) + 1);
193
/* read in the rest of the first key's header */
194
if ((members = fread(&buf[sizeof(TSS_UUID) + 1],
195
sizeof(TSS_UUID) + (3 * sizeof(UINT16)) - 1,
197
PRINTERR("fread: %s\n", strerror(errno));
201
if (printkey_0(0, f)) {
202
PRINTERR("printkey_0 failed.\n");
206
for (i = 1; i < u32; i++) {
207
/* read in subsequent key's headers */
208
if ((members = fread(buf, 2*sizeof(TSS_UUID) + 3*sizeof(UINT16),
210
PRINTERR("fread: %s\n", strerror(errno));
214
if ((rc = printkey_0(i, f)))
222
version_1_print(FILE *f)
225
UINT32 i, u32 = *(UINT32 *)&buf[1];
227
PRINT("version: 1\n");
228
PRINT("number of keys: %u\n", u32);
233
/* align the beginning of the buffer with the beginning of the key */
234
memcpy(buf, &buf[5], sizeof(TSS_UUID));
236
/* read in the rest of the first key's header */
237
if ((members = fread(&buf[sizeof(TSS_UUID)],
238
sizeof(TSS_UUID) + (3 * sizeof(UINT16)) + sizeof(UINT32),
240
PRINTERR("fread: %s\n", strerror(errno));
244
if (printkey_1(0, f)) {
245
PRINTERR("printkey_1 failed.\n");
249
for (i = 1; i < u32; i++) {
250
/* read in subsequent key's headers */
251
if ((members = fread(buf, 2*sizeof(TSS_UUID) + 3*sizeof(UINT16)
252
+ sizeof(UINT32), 1, f)) != 1) {
253
PRINTERR("fread: %s\n", strerror(errno));
257
if ((rc = printkey_1(i, f)))
264
/* the smallest key on disk should be around 600 bytes total
265
* and the largest should be about 1000 bytes, so if the number
266
* of keys is not in this ballpark, this is probably not a PS
270
bad_file_size(UINT32 num_keys, off_t file_size)
272
if ((num_keys * 600) > (unsigned long)file_size)
275
if ((num_keys * 1000) < (unsigned long) (file_size - (sizeof(UINT32) + 1)))
282
inspect(FILE *f, off_t file_size)
288
printf("File is empty.\n");
292
/* do the initial read, which should include sizeof(TSS_UUID)
293
* + sizeof(UINT32) + 1 bytes */
294
if ((members = fread(buf,
295
sizeof(TSS_UUID) + sizeof(UINT32) + 1, 1, f)) != 1) {
297
fprintf(stderr, "Error during read.\n");
302
if (buf[0] == '\1') {
303
num_keys = (UINT32 *)&buf[1];
304
if (bad_file_size(*num_keys, file_size))
307
return version_1_print(f);
311
num_keys = (UINT32 *)&buf[0];
312
if (*num_keys == 0 || bad_file_size(*num_keys, file_size)) {
313
printf("This file does not appear to be a valid PS file.\n");
317
return version_0_print(f);
321
main(int argc, char ** argv)
325
struct stat stat_buf;
331
if ((f = fopen(argv[1], "r")) == NULL) {
332
PRINTERR("fopen(%s): %s\n", argv[1], strerror(errno));
336
if ((rc = fstat(fileno(f), &stat_buf))) {
337
PRINTERR("fstat(%s): %s\n", argv[1], strerror(errno));
342
file_size = stat_buf.st_size;
344
PRINT("filename: %s (%ld bytes)\n", argv[1], file_size);
346
rc = inspect(f, file_size);