~ubuntu-branches/ubuntu/precise/trousers/precise-proposed

« back to all changes in this revision

Viewing changes to tools/ps_inspect.c

  • Committer: Bazaar Package Importer
  • Author(s): William Lima
  • Date: 2007-04-18 16:39:38 UTC
  • Revision ID: james.westby@ubuntu.com-20070418163938-opscl2mvvi76jiec
Tags: upstream-0.2.9.1
ImportĀ upstreamĀ versionĀ 0.2.9.1

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 *
 
3
 *   Copyright (C) International Business Machines  Corp., 2005
 
4
 *
 
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.
 
9
 *
 
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.
 
14
 *
 
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
 
18
 */
 
19
 
 
20
/*
 
21
 * ps_inspect.c
 
22
 *
 
23
 *   Inspect a persistent storage file, printing information about it based
 
24
 *   on best guesses.
 
25
 *
 
26
 *   There are 2 different types of persistent storage files:
 
27
 *
 
28
 * A)
 
29
 *
 
30
 * [UINT32   num_keys_on_disk]
 
31
 * [TSS_UUID uuid0           ]
 
32
 * [TSS_UUID uuid_parent0    ]
 
33
 * [UINT16   pub_data_size0  ]
 
34
 * [UINT16   blob_size0      ]
 
35
 * [UINT16   cache_flags0    ]
 
36
 * [BYTE[]   pub_data0       ]
 
37
 * [BYTE[]   blob0           ]
 
38
 * [...]
 
39
 *
 
40
 * B)
 
41
 *
 
42
 * [BYTE     TrouSerS PS version='1']
 
43
 * [UINT32   num_keys_on_disk       ]
 
44
 * [TSS_UUID uuid0                  ]
 
45
 * [TSS_UUID uuid_parent0           ]
 
46
 * [UINT16   pub_data_size0         ]
 
47
 * [UINT16   blob_size0             ]
 
48
 * [UINT32   vendor_data_size0      ]
 
49
 * [UINT16   cache_flags0           ]
 
50
 * [BYTE[]   pub_data0              ]
 
51
 * [BYTE[]   blob0                  ]
 
52
 * [BYTE[]   vendor_data0           ]
 
53
 * [...]
 
54
 *
 
55
 */
 
56
 
 
57
 
 
58
#include <stdio.h>
 
59
#include <stdlib.h>
 
60
#include <errno.h>
 
61
#include <string.h>
 
62
#include <sys/types.h>
 
63
#include <sys/stat.h>
 
64
#include <sys/unistd.h>
 
65
 
 
66
#include <trousers/tss.h>
 
67
 
 
68
#define PRINTERR(...)   fprintf(stderr, ##__VA_ARGS__)
 
69
#define PRINT(...)      printf("PS " __VA_ARGS__)
 
70
 
 
71
/* one global buffer we read into from the PS file */
 
72
unsigned char buf[1024];
 
73
 
 
74
void
 
75
usage(char *argv0)
 
76
{
 
77
        PRINTERR("usage: %s filename\n", argv0);
 
78
        exit(-1);
 
79
}
 
80
 
 
81
void
 
82
print_hex(BYTE *buf, UINT32 len)
 
83
{
 
84
        UINT32 i, j;
 
85
 
 
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);
 
90
                if (!(j % 4))
 
91
                        printf("\n");
 
92
        }
 
93
 
 
94
        while (i < len)
 
95
                printf("%02x", buf[i++] & 0xff);
 
96
        printf("\n");
 
97
}
 
98
 
 
99
int
 
100
printkey_0(int i, FILE *f)
 
101
{
 
102
        UINT16 pub_data_size, blob_size, cache_flags;
 
103
        int members;
 
104
 
 
105
        PRINT("uuid%d: ", i);
 
106
        print_hex(buf, sizeof(TSS_UUID));
 
107
 
 
108
        PRINT("parent uuid%d: ", i);
 
109
        print_hex(&buf[sizeof(TSS_UUID)], sizeof(TSS_UUID));
 
110
 
 
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)];
 
114
 
 
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);
 
118
 
 
119
        /* trash buf, we've got what we needed from it */
 
120
        if ((members = fread(buf, pub_data_size + blob_size,
 
121
                        1, f)) != 1) {
 
122
                PRINTERR("fread: %s: %d members read\n", strerror(errno), members);
 
123
                return -1;
 
124
        }
 
125
 
 
126
        PRINT("pub_data%d:\n", i);
 
127
        print_hex(buf, pub_data_size);
 
128
 
 
129
        PRINT("blob%d:\n", i);
 
130
        print_hex(&buf[pub_data_size], blob_size);
 
131
 
 
132
        return 0;
 
133
}
 
134
 
 
135
int
 
136
printkey_1(int i, FILE *f)
 
137
{
 
138
        UINT16 pub_data_size, blob_size, cache_flags;
 
139
        UINT32 vendor_data_size;
 
140
        int members;
 
141
 
 
142
        PRINT("uuid%d: ", i);
 
143
        print_hex(buf, sizeof(TSS_UUID));
 
144
 
 
145
        PRINT("parent uuid%d: ", i);
 
146
        print_hex(&buf[sizeof(TSS_UUID)], sizeof(TSS_UUID));
 
147
 
 
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)];
 
152
 
 
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);
 
157
 
 
158
        /* trash buf, we've got what we needed from it */
 
159
        if ((members = fread(buf, pub_data_size + blob_size + vendor_data_size,
 
160
                        1, f)) != 1) {
 
161
                PRINTERR("fread: %s: %d members read\n", strerror(errno), members);
 
162
                return -1;
 
163
        }
 
164
 
 
165
        PRINT("pub_data%d:\n", i);
 
166
        print_hex(buf, pub_data_size);
 
167
 
 
168
        PRINT("blob%d:\n", i);
 
169
        print_hex(&buf[pub_data_size], blob_size);
 
170
 
 
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);
 
174
 
 
175
        return 0;
 
176
}
 
177
 
 
178
int
 
179
version_0_print(FILE *f)
 
180
{
 
181
        int rc, members = 0;
 
182
        UINT32 i, u32 = *(UINT32 *)buf;
 
183
 
 
184
        PRINT("version:        0\n");
 
185
        PRINT("number of keys: %u\n", u32);
 
186
 
 
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 */
 
189
 
 
190
        /* align the beginning of the buffer with the beginning of the key */
 
191
        memcpy(buf, &buf[4], sizeof(TSS_UUID) + 1);
 
192
 
 
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,
 
196
                        1, f)) != 1) {
 
197
                PRINTERR("fread: %s\n", strerror(errno));
 
198
                return -1;
 
199
        }
 
200
 
 
201
        if (printkey_0(0, f)) {
 
202
                PRINTERR("printkey_0 failed.\n");
 
203
                return -1;
 
204
        }
 
205
 
 
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),
 
209
                                        1, f)) != 1) {
 
210
                        PRINTERR("fread: %s\n", strerror(errno));
 
211
                        return -1;
 
212
                }
 
213
 
 
214
                if ((rc = printkey_0(i, f)))
 
215
                        return rc;
 
216
        }
 
217
 
 
218
        return 0;
 
219
}
 
220
 
 
221
int
 
222
version_1_print(FILE *f)
 
223
{
 
224
        int rc, members = 0;
 
225
        UINT32 i, u32 = *(UINT32 *)&buf[1];
 
226
 
 
227
        PRINT("version:        1\n");
 
228
        PRINT("number of keys: %u\n", u32);
 
229
 
 
230
        if (u32 == 0)
 
231
                return 0;
 
232
 
 
233
        /* align the beginning of the buffer with the beginning of the key */
 
234
        memcpy(buf, &buf[5], sizeof(TSS_UUID));
 
235
 
 
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),
 
239
                        1, f)) != 1) {
 
240
                PRINTERR("fread: %s\n", strerror(errno));
 
241
                return -1;
 
242
        }
 
243
 
 
244
        if (printkey_1(0, f)) {
 
245
                PRINTERR("printkey_1 failed.\n");
 
246
                return -1;
 
247
        }
 
248
 
 
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));
 
254
                        return -1;
 
255
                }
 
256
 
 
257
                if ((rc = printkey_1(i, f)))
 
258
                        return rc;
 
259
        }
 
260
 
 
261
        return 0;
 
262
}
 
263
 
 
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
 
267
 * file
 
268
 */
 
269
int
 
270
bad_file_size(UINT32 num_keys, off_t file_size)
 
271
{
 
272
        if ((num_keys * 600) > (unsigned long)file_size)
 
273
                return 1;
 
274
 
 
275
        if ((num_keys * 1000) < (unsigned long) (file_size - (sizeof(UINT32) + 1)))
 
276
                return 1;
 
277
 
 
278
        return 0;
 
279
}
 
280
 
 
281
int
 
282
inspect(FILE *f, off_t file_size)
 
283
{
 
284
        int members = 0;
 
285
        UINT32 *num_keys;
 
286
 
 
287
        if (!file_size) {
 
288
                printf("File is empty.\n");
 
289
                return 0;
 
290
        }
 
291
 
 
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) {
 
296
                if (ferror(f)) {
 
297
                        fprintf(stderr, "Error during read.\n");
 
298
                        return -1;
 
299
                }
 
300
        }
 
301
 
 
302
        if (buf[0] == '\1') {
 
303
                num_keys = (UINT32 *)&buf[1];
 
304
                if (bad_file_size(*num_keys, file_size))
 
305
                        goto version0;
 
306
 
 
307
                return version_1_print(f);
 
308
        }
 
309
 
 
310
version0:
 
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");
 
314
                return -1;
 
315
        }
 
316
 
 
317
        return version_0_print(f);
 
318
}
 
319
 
 
320
int
 
321
main(int argc, char ** argv)
 
322
{
 
323
        FILE *f = NULL;
 
324
        int rc;
 
325
        struct stat stat_buf;
 
326
        off_t file_size;
 
327
 
 
328
        if (argc != 2)
 
329
                usage(argv[0]);
 
330
 
 
331
        if ((f = fopen(argv[1], "r")) == NULL) {
 
332
                PRINTERR("fopen(%s): %s\n", argv[1], strerror(errno));
 
333
                return -1;
 
334
        }
 
335
 
 
336
        if ((rc = fstat(fileno(f), &stat_buf))) {
 
337
                PRINTERR("fstat(%s): %s\n", argv[1], strerror(errno));
 
338
                fclose(f);
 
339
                return -1;
 
340
        }
 
341
 
 
342
        file_size = stat_buf.st_size;
 
343
 
 
344
        PRINT("filename: %s (%ld bytes)\n", argv[1], file_size);
 
345
 
 
346
        rc = inspect(f, file_size);
 
347
 
 
348
        fclose(f);
 
349
 
 
350
        return rc;
 
351
}