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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
28 #include "keybox-defs.h"
31 get32 (const byte
*buffer
)
42 get16 (const byte
*buffer
)
51 print_string (FILE *fp
, const byte
*p
, size_t n
, int delim
)
55 if (*p
< 0x20 || (*p
>= 0x7f && *p
< 0xa0) || *p
== delim
)
71 fprintf(fp
, "x%02x", *p
);
80 dump_header_blob (const byte
*buffer
, size_t length
, FILE *fp
)
86 fprintf (fp
, "[blob too short]\n");
89 fprintf (fp
, "Version: %d\n", buffer
[5]);
90 if ( memcmp (buffer
+8, "KBXf", 4))
91 fprintf (fp
, "[Error: invalid magic number]\n");
93 n
= get32 (buffer
+16);
94 fprintf( fp
, "created-at: %lu\n", n
);
95 n
= get32 (buffer
+20);
96 fprintf( fp
, "last-maint: %lu\n", n
);
102 /* Dump one block to FP */
104 _keybox_dump_blob (KEYBOXBLOB blob
, FILE *fp
)
109 ulong n
, nkeys
, keyinfolen
;
110 ulong nuids
, uidinfolen
;
111 ulong nsigs
, siginfolen
;
112 ulong rawdata_off
, rawdata_len
;
116 buffer
= _keybox_get_blob_image (blob
, &length
);
120 fprintf (fp
, "[blob too short]\n");
126 fprintf (fp
, "[blob larger than length - output truncated]\n");
128 length
= n
; /* ignore the rest */
130 fprintf (fp
, "Length: %lu\n", n
);
135 fprintf (fp
, "Type: Empty\n");
138 case BLOBTYPE_HEADER
:
139 fprintf (fp
, "Type: Header\n");
140 return dump_header_blob (buffer
, length
, fp
);
142 fprintf (fp
, "Type: OpenPGP\n");
145 fprintf (fp
, "Type: X.509\n");
148 fprintf (fp
, "Type: %d\n", type
);
149 fprintf (fp
, "[can't dump this blob type]\n");
152 fprintf (fp
, "Version: %d\n", buffer
[5]);
156 fprintf (fp
, "[blob too short]\n");
160 n
= get16 (buffer
+ 6);
161 fprintf( fp
, "Blob-Flags: %04lX", n
);
169 fputs ("secret", fp
);
176 fputs ("ephemeral", fp
);
183 rawdata_off
= get32 (buffer
+ 8);
184 rawdata_len
= get32 (buffer
+ 12);
186 fprintf( fp
, "Data-Offset: %lu\n", rawdata_off
);
187 fprintf( fp
, "Data-Length: %lu\n", rawdata_len
);
189 nkeys
= get16 (buffer
+ 16);
190 fprintf (fp
, "Key-Count: %lu\n", nkeys
);
192 fprintf (fp
, "[Error: no keys]\n");
193 if (nkeys
> 1 && type
== BLOBTYPE_X509
)
194 fprintf (fp
, "[Error: only one key allowed for X509]\n");
196 keyinfolen
= get16 (buffer
+ 18 );
197 fprintf (fp
, "Key-Info-Length: %lu\n", keyinfolen
);
198 /* fixme: check bounds */
200 for (n
=0; n
< nkeys
; n
++, p
+= keyinfolen
)
203 ulong kidoff
, kflags
;
205 fprintf (fp
, "Key-Fpr[%lu]: ", n
);
206 for (i
=0; i
< 20; i
++ )
207 fprintf (fp
, "%02X", p
[i
]);
208 kidoff
= get32 (p
+ 20);
209 fprintf (fp
, "\nKey-Kid-Off[%lu]: %lu\n", n
, kidoff
);
210 fprintf (fp
, "Key-Kid[%lu]: ", n
);
211 /* fixme: check bounds */
212 for (i
=0; i
< 8; i
++ )
213 fprintf (fp
, "%02X", buffer
[kidoff
+i
] );
214 kflags
= get16 (p
+ 24 );
215 fprintf( fp
, "\nKey-Flags[%lu]: %04lX\n", n
, kflags
);
219 fputs ("Serial-No: ", fp
);
226 for (; nserial
; nserial
--, p
++)
227 fprintf (fp
, "%02X", *p
);
233 fprintf (fp
, "Uid-Count: %lu\n", nuids
);
234 uidinfolen
= get16 (p
+ 2);
235 fprintf (fp
, "Uid-Info-Length: %lu\n", uidinfolen
);
236 /* fixme: check bounds */
238 for (n
=0; n
< nuids
; n
++, p
+= uidinfolen
)
240 ulong uidoff
, uidlen
, uflags
;
243 uidlen
= get32( p
+4 );
244 if (type
== BLOBTYPE_X509
&& !n
)
246 fprintf (fp
, "Issuer-Off: %lu\n", uidoff
);
247 fprintf (fp
, "Issuer-Len: %lu\n", uidlen
);
248 fprintf (fp
, "Issuer: \"");
250 else if (type
== BLOBTYPE_X509
&& n
== 1)
252 fprintf (fp
, "Subject-Off: %lu\n", uidoff
);
253 fprintf (fp
, "Subject-Len: %lu\n", uidlen
);
254 fprintf (fp
, "Subject: \"");
258 fprintf (fp
, "Uid-Off[%lu]: %lu\n", n
, uidoff
);
259 fprintf (fp
, "Uid-Len[%lu]: %lu\n", n
, uidlen
);
260 fprintf (fp
, "Uid[%lu]: \"", n
);
262 print_string (fp
, buffer
+uidoff
, uidlen
, '\"');
264 uflags
= get16 (p
+ 8);
265 if (type
== BLOBTYPE_X509
&& !n
)
267 fprintf (fp
, "Issuer-Flags: %04lX\n", uflags
);
268 fprintf (fp
, "Issuer-Validity: %d\n", p
[10] );
270 else if (type
== BLOBTYPE_X509
&& n
== 1)
272 fprintf (fp
, "Subject-Flags: %04lX\n", uflags
);
273 fprintf (fp
, "Subject-Validity: %d\n", p
[10] );
277 fprintf (fp
, "Uid-Flags[%lu]: %04lX\n", n
, uflags
);
278 fprintf (fp
, "Uid-Validity[%lu]: %d\n", n
, p
[10] );
283 fprintf (fp
, "Sig-Count: %lu\n", nsigs
);
284 siginfolen
= get16 (p
+ 2);
285 fprintf (fp
, "Sig-Info-Length: %lu\n", siginfolen
);
286 /* fixme: check bounds */
288 for (n
=0; n
< nsigs
; n
++, p
+= siginfolen
)
293 fprintf (fp
, "Sig-Expire[%lu]: ", n
);
295 fputs ("[not checked]", fp
);
296 else if (sflags
== 1 )
297 fputs ("[missing key]", fp
);
298 else if (sflags
== 2 )
299 fputs ("[bad signature]", fp
);
300 else if (sflags
< 0x10000000)
301 fprintf (fp
, "[bad flag %0lx]", sflags
);
302 else if (sflags
== 0xffffffff)
305 fputs ("a time"/*strtimestamp( sflags )*/, fp
);
309 fprintf (fp
, "Ownertrust: %d\n", p
[0] );
310 fprintf (fp
, "All-Validity: %d\n", p
[1] );
312 n
= get32 (p
); p
+= 4;
313 fprintf (fp
, "Recheck-After: %lu\n", n
);
314 n
= get32 (p
); p
+= 4;
315 fprintf( fp
, "Latest-Timestamp: %lu\n", n
);
316 n
= get32 (p
); p
+= 4;
317 fprintf (fp
, "Created-At: %lu\n", n
);
318 n
= get32 (p
); p
+= 4;
319 fprintf (fp
, "Reserved-Space: %lu\n", n
);
321 /* check that the keyblock is at the correct offset and other bounds */
322 /*fprintf (fp, "Blob-Checksum: [MD5-hash]\n");*/
329 unsigned long too_short_blobs
;
330 unsigned long too_large_blobs
;
331 unsigned long total_blob_count
;
332 unsigned long empty_blob_count
;
333 unsigned long header_blob_count
;
334 unsigned long pgp_blob_count
;
335 unsigned long x509_blob_count
;
336 unsigned long unknown_blob_count
;
337 unsigned long non_flagged
;
338 unsigned long secret_flagged
;
339 unsigned long ephemeral_flagged
;
343 update_stats (KEYBOXBLOB blob
, struct file_stats_s
*s
)
345 const unsigned char *buffer
;
350 buffer
= _keybox_get_blob_image (blob
, &length
);
353 s
->too_short_blobs
++;
359 s
->too_large_blobs
++;
361 length
= n
; /* ignore the rest */
363 s
->total_blob_count
++;
368 s
->empty_blob_count
++;
370 case BLOBTYPE_HEADER
:
371 s
->header_blob_count
++;
377 s
->x509_blob_count
++;
380 s
->unknown_blob_count
++;
386 s
->too_short_blobs
++;
390 n
= get16 (buffer
+ 6);
396 s
->ephemeral_flagged
++;
407 _keybox_dump_file (const char *filename
, int stats_only
, FILE *outfp
)
412 unsigned long count
= 0;
413 struct file_stats_s stats
;
415 memset (&stats
, 0, sizeof stats
);
423 fp
= fopen (filename
, "rb");
426 gpg_error_t tmperr
= gpg_error (gpg_err_code_from_errno (errno
));
427 fprintf (outfp
, "can't open `%s': %s\n", filename
, strerror(errno
));
431 while ( !(rc
= _keybox_read_blob (&blob
, fp
)) )
435 update_stats (blob
, &stats
);
439 fprintf (outfp
, "BEGIN-RECORD: %lu\n", count
);
440 _keybox_dump_blob (blob
, outfp
);
441 fprintf (outfp
, "END-RECORD\n");
443 _keybox_release_blob (blob
);
449 fprintf (outfp
, "error reading `%s': %s\n", filename
, gpg_strerror (rc
));
457 "Total number of blobs: %8lu\n"
462 " non flagged: %8lu\n"
463 " secret flagged: %8lu\n"
464 " ephemeral flagged: %8lu\n",
465 stats
.total_blob_count
,
466 stats
.header_blob_count
,
467 stats
.empty_blob_count
,
468 stats
.pgp_blob_count
,
469 stats
.x509_blob_count
,
471 stats
.secret_flagged
,
472 stats
.ephemeral_flagged
);
473 if (stats
.unknown_blob_count
)
474 fprintf (outfp
, " unknown blob types: %8lu\n",
475 stats
.unknown_blob_count
);
476 if (stats
.too_short_blobs
)
477 fprintf (outfp
, " too short blobs: %8lu\n",
478 stats
.too_short_blobs
);
479 if (stats
.too_large_blobs
)
480 fprintf (outfp
, " too large blobs: %8lu\n",
481 stats
.too_large_blobs
);