1
/* keybox-dump.c - Debug helpers
2
* Copyright (C) 2001, 2003 Free Software Foundation, Inc.
4
* This file is part of GnuPG.
6
* GnuPG is free software; you can redistribute it and/or modify
7
* it under the terms of the GNU General Public License as published by
8
* the Free Software Foundation; either version 2 of the License, or
9
* (at your option) any later version.
11
* GnuPG is distributed in the hope that it will be useful,
12
* but WITHOUT ANY WARRANTY; without even the implied warranty of
13
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14
* GNU General Public License for more details.
16
* You should have received a copy of the GNU General Public License
17
* along with this program; if not, write to the Free Software
18
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
27
#include "keybox-defs.h"
30
get32 (const byte *buffer)
41
get16 (const byte *buffer)
50
print_string (FILE *fp, const byte *p, size_t n, int delim)
54
if (*p < 0x20 || (*p >= 0x7f && *p < 0xa0) || *p == delim)
70
fprintf(fp, "x%02x", *p );
79
dump_header_blob (const byte *buffer, size_t length, FILE *fp)
85
fprintf (fp, "[blob too short]\n");
88
fprintf (fp, "Version: %d\n", buffer[5]);
89
if ( memcmp (buffer+8, "KBXf", 4))
90
fprintf (fp, "[Error: invalid magic number]\n");
92
n = get32 (buffer+16);
93
fprintf( fp, "created-at: %lu\n", n );
94
n = get32 (buffer+20);
95
fprintf( fp, "last-maint: %lu\n", n );
101
/* Dump one block to FP */
103
_keybox_dump_blob (KEYBOXBLOB blob, FILE *fp)
108
ulong n, nkeys, keyinfolen;
109
ulong nuids, uidinfolen;
110
ulong nsigs, siginfolen;
111
ulong rawdata_off, rawdata_len;
115
buffer = _keybox_get_blob_image (blob, &length);
119
fprintf (fp, "[blob too short]\n");
125
fprintf (fp, "[blob larger than length - output truncated]\n");
127
length = n; /* ignore the rest */
129
fprintf (fp, "Length: %lu\n", n );
134
fprintf (fp, "Type: Empty\n");
137
case BLOBTYPE_HEADER:
138
fprintf (fp, "Type: Header\n");
139
return dump_header_blob (buffer, length, fp);
141
fprintf (fp, "Type: OpenPGP\n");
144
fprintf (fp, "Type: X.509\n");
147
fprintf (fp, "Type: %d\n", type);
148
fprintf (fp, "[can't dump this blob type]\n");
151
fprintf (fp, "Version: %d\n", buffer[5]);
155
fprintf (fp, "[blob too short]\n");
159
n = get16 (buffer + 6);
160
fprintf( fp, "Blob-Flags: %04lX", n);
168
fputs ("secret", fp);
175
fputs ("ephemeral", fp);
182
rawdata_off = get32 (buffer + 8);
183
rawdata_len = get32 (buffer + 12);
185
fprintf( fp, "Data-Offset: %lu\n", rawdata_off );
186
fprintf( fp, "Data-Length: %lu\n", rawdata_len );
188
nkeys = get16 (buffer + 16);
189
fprintf (fp, "Key-Count: %lu\n", nkeys );
191
fprintf (fp, "[Error: no keys]\n");
192
if (nkeys > 1 && type == BLOBTYPE_X509)
193
fprintf (fp, "[Error: only one key allowed for X509]\n");
195
keyinfolen = get16 (buffer + 18 );
196
fprintf (fp, "Key-Info-Length: %lu\n", keyinfolen);
197
/* fixme: check bounds */
199
for (n=0; n < nkeys; n++, p += keyinfolen)
202
ulong kidoff, kflags;
204
fprintf (fp, "Key-Fpr[%lu]: ", n );
205
for (i=0; i < 20; i++ )
206
fprintf (fp, "%02X", p[i]);
207
kidoff = get32 (p + 20);
208
fprintf (fp, "\nKey-Kid-Off[%lu]: %lu\n", n, kidoff );
209
fprintf (fp, "Key-Kid[%lu]: ", n );
210
/* fixme: check bounds */
211
for (i=0; i < 8; i++ )
212
fprintf (fp, "%02X", buffer[kidoff+i] );
213
kflags = get16 (p + 24 );
214
fprintf( fp, "\nKey-Flags[%lu]: %04lX\n", n, kflags);
218
fputs ("Serial-No: ", fp);
225
for (; nserial; nserial--, p++)
226
fprintf (fp, "%02X", *p);
232
fprintf (fp, "Uid-Count: %lu\n", nuids );
233
uidinfolen = get16 (p + 2);
234
fprintf (fp, "Uid-Info-Length: %lu\n", uidinfolen);
235
/* fixme: check bounds */
237
for (n=0; n < nuids; n++, p += uidinfolen)
239
ulong uidoff, uidlen, uflags;
242
uidlen = get32( p+4 );
243
if (type == BLOBTYPE_X509 && !n)
245
fprintf (fp, "Issuer-Off: %lu\n", uidoff );
246
fprintf (fp, "Issuer-Len: %lu\n", uidlen );
247
fprintf (fp, "Issuer: \"");
249
else if (type == BLOBTYPE_X509 && n == 1)
251
fprintf (fp, "Subject-Off: %lu\n", uidoff );
252
fprintf (fp, "Subject-Len: %lu\n", uidlen );
253
fprintf (fp, "Subject: \"");
257
fprintf (fp, "Uid-Off[%lu]: %lu\n", n, uidoff );
258
fprintf (fp, "Uid-Len[%lu]: %lu\n", n, uidlen );
259
fprintf (fp, "Uid[%lu]: \"", n );
261
print_string (fp, buffer+uidoff, uidlen, '\"');
263
uflags = get16 (p + 8);
264
if (type == BLOBTYPE_X509 && !n)
266
fprintf (fp, "Issuer-Flags: %04lX\n", uflags );
267
fprintf (fp, "Issuer-Validity: %d\n", p[10] );
269
else if (type == BLOBTYPE_X509 && n == 1)
271
fprintf (fp, "Subject-Flags: %04lX\n", uflags );
272
fprintf (fp, "Subject-Validity: %d\n", p[10] );
276
fprintf (fp, "Uid-Flags[%lu]: %04lX\n", n, uflags );
277
fprintf (fp, "Uid-Validity[%lu]: %d\n", n, p[10] );
282
fprintf (fp, "Sig-Count: %lu\n", nsigs );
283
siginfolen = get16 (p + 2);
284
fprintf (fp, "Sig-Info-Length: %lu\n", siginfolen );
285
/* fixme: check bounds */
287
for (n=0; n < nsigs; n++, p += siginfolen)
292
fprintf (fp, "Sig-Expire[%lu]: ", n );
294
fputs ("[not checked]", fp);
295
else if (sflags == 1 )
296
fputs ("[missing key]", fp);
297
else if (sflags == 2 )
298
fputs ("[bad signature]", fp);
299
else if (sflags < 0x10000000)
300
fprintf (fp, "[bad flag %0lx]", sflags);
301
else if (sflags == 0xffffffff)
304
fputs ("a time"/*strtimestamp( sflags )*/, fp );
308
fprintf (fp, "Ownertrust: %d\n", p[0] );
309
fprintf (fp, "All-Validity: %d\n", p[1] );
311
n = get32 (p); p += 4;
312
fprintf (fp, "Recheck-After: %lu\n", n );
313
n = get32 (p ); p += 4;
314
fprintf( fp, "Latest-Timestamp: %lu\n", n );
315
n = get32 (p ); p += 4;
316
fprintf (fp, "Created-At: %lu\n", n );
317
n = get32 (p ); p += 4;
318
fprintf (fp, "Reserved-Space: %lu\n", n );
320
/* check that the keyblock is at the correct offset and other bounds */
321
/*fprintf (fp, "Blob-Checksum: [MD5-hash]\n");*/
328
unsigned long too_short_blobs;
329
unsigned long too_large_blobs;
330
unsigned long total_blob_count;
331
unsigned long empty_blob_count;
332
unsigned long header_blob_count;
333
unsigned long pgp_blob_count;
334
unsigned long x509_blob_count;
335
unsigned long unknown_blob_count;
336
unsigned long non_flagged;
337
unsigned long secret_flagged;
338
unsigned long ephemeral_flagged;
342
update_stats (KEYBOXBLOB blob, struct file_stats_s *s)
344
const unsigned char *buffer;
349
buffer = _keybox_get_blob_image (blob, &length);
352
s->too_short_blobs++;
358
s->too_large_blobs++;
360
length = n; /* ignore the rest */
362
s->total_blob_count++;
367
s->empty_blob_count++;
369
case BLOBTYPE_HEADER:
370
s->header_blob_count++;
376
s->x509_blob_count++;
379
s->unknown_blob_count++;
385
s->too_short_blobs++;
389
n = get16 (buffer + 6);
395
s->ephemeral_flagged++;
406
_keybox_dump_file (const char *filename, int stats_only, FILE *outfp)
411
unsigned long count = 0;
412
struct file_stats_s stats;
414
memset (&stats, 0, sizeof stats);
422
fp = fopen (filename, "rb");
425
gpg_error_t tmperr = gpg_error (gpg_err_code_from_errno (errno));
426
fprintf (outfp, "can't open `%s': %s\n", filename, strerror(errno));
430
while ( !(rc = _keybox_read_blob (&blob, fp)) )
434
update_stats (blob, &stats);
438
fprintf (outfp, "BEGIN-RECORD: %lu\n", count );
439
_keybox_dump_blob (blob, outfp);
440
fprintf (outfp, "END-RECORD\n");
442
_keybox_release_blob (blob);
448
fprintf (outfp, "error reading `%s': %s\n", filename, gpg_strerror (rc));
456
"Total number of blobs: %8lu\n"
461
" non flagged: %8lu\n"
462
" secret flagged: %8lu\n"
463
" ephemeral flagged: %8lu\n",
464
stats.total_blob_count,
465
stats.header_blob_count,
466
stats.empty_blob_count,
467
stats.pgp_blob_count,
468
stats.x509_blob_count,
470
stats.secret_flagged,
471
stats.ephemeral_flagged);
472
if (stats.unknown_blob_count)
473
fprintf (outfp, " unknown blob types: %8lu\n",
474
stats.unknown_blob_count);
475
if (stats.too_short_blobs)
476
fprintf (outfp, " too short blobs: %8lu\n",
477
stats.too_short_blobs);
478
if (stats.too_large_blobs)
479
fprintf (outfp, " too large blobs: %8lu\n",
480
stats.too_large_blobs);