1
/* kbxutil.c - The Keybox utility
2
* Copyright (C) 2000, 2001, 2004 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
31
#define JNLIB_NEED_LOG_LOGV
32
#include "../jnlib/logging.h"
33
#include "../jnlib/argparse.h"
34
#include "../jnlib/stringhelp.h"
35
#include "../jnlib/utf8conv.h"
36
#include "../common/i18n.h"
37
#include "keybox-defs.h"
42
enum cmd_and_opt_values {
50
aNoSuchCmd = 500, /* force other values not to be a letter */
67
static ARGPARSE_OPTS opts[] = {
68
{ 300, NULL, 0, N_("@Commands:\n ") },
70
/* { aFindByFpr, "find-by-fpr", 0, "|FPR| find key using it's fingerprnt" }, */
71
/* { aFindByKid, "find-by-kid", 0, "|KID| find key using it's keyid" }, */
72
/* { aFindByUid, "find-by-uid", 0, "|NAME| find key by user name" }, */
73
{ aStats, "stats", 0, "show key statistics" },
74
{ aImportOpenPGP, "import-openpgp", 0, "import OpenPGP keyblocks"},
76
{ 301, NULL, 0, N_("@\nOptions:\n ") },
78
/* { oArmor, "armor", 0, N_("create ascii armored output")}, */
79
/* { oArmor, "armour", 0, "@" }, */
80
/* { oOutput, "output", 2, N_("use as output file")}, */
81
{ oVerbose, "verbose", 0, N_("verbose") },
82
{ oQuiet, "quiet", 0, N_("be somewhat more quiet") },
83
{ oDryRun, "dry-run", 0, N_("do not make any changes") },
85
{ oDebug, "debug" ,4|16, N_("set debugging flags")},
86
{ oDebugAll, "debug-all" ,0, N_("enable full debugging")},
94
int keybox_errors_seen = 0;
98
my_strusage( int level )
102
case 11: p = "kbxutil (GnuPG)";
104
case 13: p = VERSION; break;
105
case 17: p = PRINTABLE_OS_NAME; break;
107
_("Please report bugs to " PACKAGE_BUGREPORT ".\n");
111
_("Usage: kbxutil [options] [files] (-h for help)");
114
_("Syntax: kbxutil [options] [files]\n"
115
"list, export, import Keybox data\n");
128
#ifdef USE_SIMPLE_GETTEXT
129
set_gettext_file( PACKAGE_GT );
132
setlocale( LC_ALL, "" );
133
bindtextdomain( PACKAGE_GT, LOCALEDIR );
134
textdomain( PACKAGE_GT );
139
/* Used by gcry for logging */
141
my_gcry_logger (void *dummy, int level, const char *fmt, va_list arg_ptr)
143
/* Map the log levels. */
146
case GCRY_LOG_CONT: level = JNLIB_LOG_CONT; break;
147
case GCRY_LOG_INFO: level = JNLIB_LOG_INFO; break;
148
case GCRY_LOG_WARN: level = JNLIB_LOG_WARN; break;
149
case GCRY_LOG_ERROR:level = JNLIB_LOG_ERROR; break;
150
case GCRY_LOG_FATAL:level = JNLIB_LOG_FATAL; break;
151
case GCRY_LOG_BUG: level = JNLIB_LOG_BUG; break;
152
case GCRY_LOG_DEBUG:level = JNLIB_LOG_DEBUG; break;
153
default: level = JNLIB_LOG_ERROR; break;
155
log_logv (level, fmt, arg_ptr);
161
/* wrong_args( const char *text ) */
163
/* log_error("usage: kbxutil %s\n", text); */
170
hextobyte( const byte *s )
174
if( *s >= '0' && *s <= '9' )
176
else if( *s >= 'A' && *s <= 'F' )
177
c = 16 * (10 + *s - 'A');
178
else if( *s >= 'a' && *s <= 'f' )
179
c = 16 * (10 + *s - 'a');
183
if( *s >= '0' && *s <= '9' )
185
else if( *s >= 'A' && *s <= 'F' )
187
else if( *s >= 'a' && *s <= 'f' )
197
format_fingerprint ( const char *s )
202
for (i=0; i < 20 && *s; ) {
203
if ( *s == ' ' || *s == '\t' ) {
214
return gcry_xstrdup ( fpr );
220
format_keyid ( const char *s, u32 *kid )
223
switch ( strlen ( s ) ) {
226
kid[1] = strtoul( s, NULL, 16 );
230
mem2str( helpbuf, s, 9 );
231
kid[0] = strtoul( helpbuf, NULL, 16 );
232
kid[1] = strtoul( s+8, NULL, 16 );
235
return 0; /* error */
240
read_file (const char *fname, size_t *r_length)
246
if (!strcmp (fname, "-"))
248
size_t nread, bufsize = 0;
258
buf = xtrymalloc (bufsize);
260
buf = xtryrealloc (buf, bufsize);
262
log_fatal ("can't allocate buffer: %s\n", strerror (errno));
264
nread = fread (buf+buflen, 1, NCHUNK, fp);
265
if (nread < NCHUNK && ferror (fp))
267
log_error ("error reading `[stdin]': %s\n", strerror (errno));
273
while (nread == NCHUNK);
281
fp = fopen (fname, "rb");
284
log_error ("can't open `%s': %s\n", fname, strerror (errno));
288
if (fstat (fileno(fp), &st))
290
log_error ("can't stat `%s': %s\n", fname, strerror (errno));
296
buf = xtrymalloc (buflen+1);
298
log_fatal ("can't allocate buffer: %s\n", strerror (errno));
299
if (fread (buf, buflen, 1, fp) != 1)
301
log_error ("error reading `%s': %s\n", fname, strerror (errno));
315
dump_fpr (const unsigned char *buffer, size_t len)
319
for (i=0; i < len; i++, buffer++)
325
printf (" %02X%02X", buffer[0], buffer[1]);
332
printf (" %02X", buffer[0]);
339
dump_openpgp_key (keybox_openpgp_info_t info, const unsigned char *image)
341
printf ("pub %02X%02X%02X%02X",
342
info->primary.keyid[4], info->primary.keyid[5],
343
info->primary.keyid[6], info->primary.keyid[7] );
344
dump_fpr (info->primary.fpr, info->primary.fprlen);
348
struct _keybox_openpgp_key_info *k;
353
printf ("sub %02X%02X%02X%02X",
354
k->keyid[4], k->keyid[5],
355
k->keyid[6], k->keyid[7] );
356
dump_fpr (k->fpr, k->fprlen);
364
struct _keybox_openpgp_uid_info *u;
369
printf ("uid\t\t%.*s\n", u->len, image + u->off);
378
import_openpgp (const char *filename)
382
size_t buflen, nparsed;
384
struct _keybox_openpgp_info info;
386
buffer = read_file (filename, &buflen);
392
err = _keybox_parse_openpgp (p, buflen, &nparsed, &info);
393
assert (nparsed <= buflen);
396
if (gpg_err_code (err) == GPG_ERR_NO_DATA)
398
log_info ("%s: failed to parse OpenPGP keyblock: %s\n",
399
filename, gpg_strerror (err));
403
dump_openpgp_key (&info, p);
404
_keybox_destroy_openpgp_info (&info);
416
main( int argc, char **argv )
419
enum cmd_and_opt_values cmd = 0;
421
set_strusage( my_strusage );
422
gcry_control (GCRYCTL_DISABLE_SECMEM);
423
log_set_prefix ("kbxutil", 1);
424
set_native_charset (NULL);
427
/* Check that the libraries are suitable. Do it here because
428
the option parsing may need services of the library. */
429
if (!gcry_check_version (NEED_LIBGCRYPT_VERSION) )
431
log_fatal( _("libgcrypt is too old (need %s, have %s)\n"),
432
NEED_LIBGCRYPT_VERSION, gcry_check_version (NULL) );
435
gcry_set_log_handler (my_gcry_logger, NULL);
437
/*create_dotlock(NULL); register locking cleanup */
439
/* We need to use the gcry malloc function because jnlib does use them */
440
keybox_set_malloc_hooks (gcry_malloc, gcry_realloc, gcry_free);
441
ksba_set_malloc_hooks (gcry_malloc, gcry_realloc, gcry_free );
446
pargs.flags= 1; /* do not remove the args */
447
while (arg_parse( &pargs, opts) )
453
/*gcry_control( GCRYCTL_SET_VERBOSITY, (int)opt.verbose );*/
456
/*opt.debug |= pargs.r.ret_ulong; */
475
if (log_get_errorcount(0) )
479
{ /* Default is to list a KBX file */
481
_keybox_dump_file (NULL, 0, stdout);
484
for (; argc; argc--, argv++)
485
_keybox_dump_file (*argv, 0, stdout);
488
else if (cmd == aStats )
491
_keybox_dump_file (NULL, 1, stdout);
494
for (; argc; argc--, argv++)
495
_keybox_dump_file (*argv, 1, stdout);
498
else if (cmd == aImportOpenPGP)
501
import_openpgp ("-");
504
for (; argc; argc--, argv++)
505
import_openpgp (*argv);
509
else if ( cmd == aFindByFpr )
513
wrong_args ("kbxfile foingerprint");
514
fpr = format_fingerprint ( argv[1] );
516
log_error ("invalid formatted fingerprint\n");
519
kbxfile_search_by_fpr ( argv[0], fpr );
523
else if ( cmd == aFindByKid )
529
wrong_args ("kbxfile short-or-long-keyid");
530
mode = format_keyid ( argv[1], kid );
532
log_error ("invalid formatted keyID\n");
535
kbxfile_search_by_kid ( argv[0], kid, mode );
538
else if ( cmd == aFindByUid )
541
wrong_args ("kbxfile userID");
542
kbxfile_search_by_uid ( argv[0], argv[1] );
546
log_error ("unsupported action\n");
549
return 8; /*NEVER REACHED*/
556
/* if( opt.debug & DBG_MEMSTAT_VALUE ) {*/
557
/* gcry_control( GCRYCTL_DUMP_MEMORY_STATS ); */
558
/* gcry_control( GCRYCTL_DUMP_RANDOM_STATS ); */
560
/* if( opt.debug ) */
561
/* gcry_control( GCRYCTL_DUMP_SECMEM_STATS ); */
562
rc = rc? rc : log_get_errorcount(0)? 2 :
563
keybox_errors_seen? 1 : 0;