569d4112d2f37cb8c914b309b6c97acccf42342c
[gnupg.git] / g10 / g10.c
1 /* g10.c - The GnuPG utility (main for gpg)
2  *      Copyright (C) 1998 Free Software Foundation, Inc.
3  *
4  * This file is part of GNUPG.
5  *
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.
10  *
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.
15  *
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
19  */
20
21 #include <config.h>
22 #include <errno.h>
23 #include <stdio.h>
24 #include <stdlib.h>
25 #include <string.h>
26 #include <unistd.h>
27
28 /* #define MAINTAINER_OPTIONS */
29
30 #include "packet.h"
31 #include "iobuf.h"
32 #include "memory.h"
33 #include "util.h"
34 #include "main.h"
35 #include "options.h"
36 #include "keydb.h"
37 #include "mpi.h"
38 #include "cipher.h"
39 #include "filter.h"
40 #include "trustdb.h"
41 #include "ttyio.h"
42 #include "i18n.h"
43 #include "status.h"
44 #include "g10defs.h"
45
46 #ifndef IS_G10MAINT
47   #define IS_G10 1
48 #endif
49
50
51 enum cmd_and_opt_values { aNull = 0,
52     oArmor        = 'a',
53     aDetachedSign = 'b',
54     aSym          = 'c',
55     aDecrypt      = 'd',
56     aEncr         = 'e',
57     oKOption      = 'k',
58     oDryRun       = 'n',
59     oOutput       = 'o',
60     oRemote       = 'r',
61     aSign         = 's',
62     oTextmode     = 't',
63     oUser         = 'u',
64     oVerbose      = 'v',
65     oCompress     = 'z',
66     oBatch        = 500,
67     aClearsign,
68     aStore,
69     aKeygen,
70     aSignEncr,
71     aSignKey,
72     aListPackets,
73     aEditKey,
74     aDeleteKey,
75     aDeleteSecretKey,
76     aKMode,
77     aKModeC,
78     aImport,
79     aVerify,
80     aListKeys,
81     aListSigs,
82     aListSecretKeys,
83     aExport,
84     aExportSecret,
85     aCheckKeys,
86     aGenRevoke,
87     aPrimegen,
88     aPrintMD,
89     aPrintMDs,
90     aCheckTrustDB,
91     aUpdateTrustDB,
92     aFixTrustDB,
93     aListTrustDB,
94     aListTrustPath,
95     aExportOwnerTrust,
96     aImportOwnerTrust,
97     aDeArmor,
98     aEnArmor,
99     aGenRandom,
100
101     oFingerprint,
102     oAnswerYes,
103     oAnswerNo,
104     oKeyring,
105     oSecretKeyring,
106     oDefaultKey,
107     oOptions,
108     oDebug,
109     oDebugAll,
110     oStatusFD,
111     oNoComment,
112     oCompletesNeeded,
113     oMarginalsNeeded,
114     oLoadExtension,
115     oRFC1991,
116     oCipherAlgo,
117     oDigestAlgo,
118     oCompressAlgo,
119     oPasswdFD,
120     oQuickRandom,
121     oNoVerbose,
122     oTrustDBName,
123     oNoSecmemWarn,
124     oNoArmor,
125     oNoDefKeyring,
126     oNoGreeting,
127     oNoOptions,
128     oNoBatch,
129     oHomedir,
130     oWithColons,
131     oSkipVerify,
132     oCompressKeys,
133     oCompressSigs,
134     oAlwaysTrust,
135     oEmuChecksumBug,
136     oRunAsShmCP,
137     oSetFilename,
138     oComment,
139     oThrowKeyid,
140     oS2KMode,
141     oS2KDigest,
142     oS2KCipher,
143 aTest };
144
145
146 static ARGPARSE_OPTS opts[] = {
147
148     { 300, NULL, 0, N_("@Commands:\n ") },
149
150   #ifdef IS_G10
151     { aSign, "sign",      256, N_("|[file]|make a signature")},
152     { aClearsign, "clearsign", 256, N_("|[file]|make a clear text signature") },
153     { aDetachedSign, "detach-sign", 256, N_("make a detached signature")},
154     { aEncr, "encrypt",   256, N_("encrypt data")},
155     { aSym, "symmetric", 256, N_("encryption only with symmetric cipher")},
156     { aStore, "store",     256, N_("store only")},
157     { aDecrypt, "decrypt",   256, N_("decrypt data (default)")},
158     { aVerify, "verify"   , 256, N_("verify a signature")},
159   #endif
160     { aListKeys, "list-keys", 256, N_("list keys")},
161     { aListSigs, "list-sigs", 256, N_("list keys and signatures")},
162     { aCheckKeys, "check-sigs",256, N_("check key signatures")},
163     { oFingerprint, "fingerprint", 256, N_("list keys and fingerprints")},
164     { aListSecretKeys, "list-secret-keys", 256, N_("list secret keys")},
165   #ifdef IS_G10
166     { aKeygen, "gen-key",   256, N_("generate a new key pair")},
167   #endif
168     { aDeleteKey, "delete-key",256, N_("remove key from the public keyring")},
169   #ifdef IS_G10
170     { aEditKey, "edit-key"  ,256, N_("sign or edit a key")},
171     { aGenRevoke, "gen-revoke",256, N_("generate a revocation certificate")},
172   #endif
173     { aExport, "export"          , 256, N_("export keys") },
174     { aExportSecret, "export-secret-keys" , 256, "@" },
175     { aImport, "import",      256     , N_("import/merge keys")},
176     { aListPackets, "list-packets",256,N_("list only the sequence of packets")},
177   #ifdef IS_G10MAINT
178     { aExportOwnerTrust,
179               "export-ownertrust", 256, N_("export the ownertrust values")},
180     { aImportOwnerTrust,
181               "import-ownertrust", 256 , N_("import ownertrust values")},
182     { aUpdateTrustDB,
183               "update-trustdb",0 , N_("|[NAMES]|update the trust database")},
184     { aCheckTrustDB,
185               "check-trustdb",0 , N_("|[NAMES]|check the trust database")},
186     { aFixTrustDB, "fix-trustdb",0 , N_("fix a corrupted trust database")},
187     { aDeArmor, "dearmor", 256, N_("De-Armor a file or stdin") },
188     { aEnArmor, "enarmor", 256, N_("En-Armor a file or stdin") },
189     { aPrintMD,  "print-md" , 256, N_("|algo [files]|print message digests")},
190     { aPrintMDs, "print-mds" , 256, N_("print all message digests")},
191     #ifdef MAINTAINER_OPTIONS
192     { aPrimegen, "gen-prime" , 256, "@" },
193     { aGenRandom, "gen-random" , 256, "@" },
194     #endif
195   #endif
196
197     { 301, NULL, 0, N_("@\nOptions:\n ") },
198
199     { oArmor, "armor",     0, N_("create ascii armored output")},
200   #ifdef IS_G10
201     { oUser, "local-user",2, N_("use this user-id to sign or decrypt")},
202     { oRemote, "remote-user", 2, N_("use this user-id for encryption")},
203     { oCompress, NULL,        1, N_("|N|set compress level N (0 disables)") },
204     { oTextmode, "textmode",  0, N_("use canonical text mode")},
205   #endif
206     { oOutput, "output",    2, N_("use as output file")},
207     { oVerbose, "verbose",   0, N_("verbose") },
208  /* { oDryRun, "dry-run",   0, N_("do not make any changes") }, */
209     { oBatch, "batch",     0, N_("batch mode: never ask")},
210     { oAnswerYes, "yes",       0, N_("assume yes on most questions")},
211     { oAnswerNo,  "no",        0, N_("assume no on most questions")},
212     { oKeyring, "keyring"   ,2, N_("add this keyring to the list of keyrings")},
213     { oSecretKeyring, "secret-keyring" ,2, N_("add this secret keyring to the list")},
214     { oDefaultKey, "default-key" ,2, N_("|NAME|use NAME as default secret key")},
215     { oOptions, "options"   , 2, N_("read options from file")},
216
217     { oDebug, "debug"     ,4|16, N_("set debugging flags")},
218     { oDebugAll, "debug-all" ,0, N_("enable full debugging")},
219     { oStatusFD, "status-fd" ,1, N_("|FD|write status info to this FD") },
220     { oNoComment, "no-comment", 0,   N_("do not write comment packets")},
221     { oCompletesNeeded, "completes-needed", 1, N_("(default is 1)")},
222     { oMarginalsNeeded, "marginals-needed", 1, N_("(default is 3)")},
223     { oLoadExtension, "load-extension" ,2, N_("|FILE|load extension module FILE")},
224     { oRFC1991, "rfc1991",   0, N_("emulate the mode described in RFC1991")},
225     { oS2KMode, "s2k-mode",  1, N_("|N|use passphrase mode N")},
226     { oS2KDigest, "s2k-digest-algo",2,
227                 N_("|NAME|use message digest algorithm NAME for passphrases")},
228     { oS2KCipher, "s2k-cipher-algo",2,
229                 N_("|NAME|use cipher algorithm NAME for passphrases")},
230   #ifdef IS_G10
231     { oCipherAlgo, "cipher-algo", 2 , N_("|NAME|use cipher algorithm NAME")},
232     { oDigestAlgo, "digest-algo", 2 , N_("|NAME|use message digest algorithm NAME")},
233     { oCompressAlgo, "compress-algo", 1 , N_("|N|use compress algorithm N")},
234     { oThrowKeyid, "throw-keyid", 0, N_("throw keyid field of encrypted packets")},
235   #else /* some dummies */
236     { oCipherAlgo, "cipher-algo", 2 , "@"},
237     { oDigestAlgo, "digest-algo", 2 , "@"},
238     { oCompressAlgo, "compress-algo", 1 , "@"},
239   #endif
240
241   #ifdef IS_G10
242     { 302, NULL, 0, N_("@\nExamples:\n\n"
243     " -se -r Bob [file]          sign and encrypt for user Bob\n"
244     " --clearsign [file]         make a clear text signature\n"
245     " --detach-sign [file]       make a detached signature\n"
246     " --list-keys [names]        show keys\n"
247     " --fingerprint [names]      show fingerprints\n"  ) },
248   #endif
249
250   /* hidden options */
251   #ifdef IS_G10MAINT
252     { aTest, "test"      , 0, "@" },
253     { aExportOwnerTrust, "list-ownertrust",0 , "@"},  /* alias */
254     { aListTrustDB, "list-trustdb",0 , "@"},
255     { aListTrustPath, "list-trust-path",0, "@"},
256   #endif
257   #ifdef IS_G10
258     { oKOption, NULL,    0, "@"},
259     { aEditKey, "edit-sig"  ,0, "@"}, /* alias for edit-key */
260     { oPasswdFD, "passphrase-fd",1, "@" },
261     { aSignKey, "sign-key"  ,256, "@" }, /* alias for edit-key */
262   #endif
263     { aDeleteSecretKey, "delete-secret-key",0, "@" },
264     { oQuickRandom, "quick-random", 0, "@"},
265     { oNoVerbose, "no-verbose", 0, "@"},
266     { oTrustDBName, "trustdb-name", 2, "@" },
267     { oNoSecmemWarn, "no-secmem-warning", 0, "@" }, /* used only by regression tests */
268     { oNoArmor, "no-armor",   0, "@"},
269     { oNoDefKeyring, "no-default-keyring", 0, "@" },
270     { oNoGreeting, "no-greeting", 0, "@" },
271     { oNoOptions, "no-options", 0, "@" }, /* shortcut for --options /dev/null */
272     { oHomedir, "homedir", 2, "@" },   /* defaults to "~/.gnupg" */
273     { oNoBatch, "no-batch", 0, "@" },
274     { oWithColons, "with-colons", 0, "@"},
275     { aListKeys, "list-key", 0, "@" }, /* alias */
276     { aListSigs, "list-sig", 0, "@" }, /* alias */
277     { aCheckKeys, "check-sig",0, "@" }, /* alias */
278     { oSkipVerify, "skip-verify",0, "@" },
279     { oCompressKeys, "compress-keys",0, "@"},
280     { oCompressSigs, "compress-sigs",0, "@"},
281     { oAlwaysTrust, "always-trust", 0, "@"},
282     { oEmuChecksumBug, "emulate-checksum-bug", 0, "@"},
283     { oRunAsShmCP, "run-as-shm-coprocess", 4, "@" },
284     { oSetFilename, "set-filename", 2, "@" },
285     { oComment, "comment", 2, "@" },
286 {0} };
287
288
289
290 static int maybe_setuid = 1;
291
292 static char *build_list( const char *text,
293                          const char *(*mapf)(int), int (*chkf)(int) );
294 static void set_cmd( enum cmd_and_opt_values *ret_cmd,
295                         enum cmd_and_opt_values new_cmd );
296 #ifdef IS_G10MAINT
297 static void print_hex( byte *p, size_t n );
298 static void print_mds( const char *fname, int algo );
299 #endif
300
301 const char *
302 strusage( int level )
303 {
304   static char *digests, *pubkeys, *ciphers;
305     const char *p;
306     switch( level ) {
307       case 11: p =
308           #ifdef IS_G10MAINT
309             "gpgm (GnuPG)";
310           #else
311             "gpg (GnuPG)";
312           #endif
313         break;
314       case 13: p = VERSION; break;
315       case 17: p = PRINTABLE_OS_NAME; break;
316       case 19: p =
317             _("Please report bugs to <gnupg-bugs@gnu.org>.\n");
318         break;
319       case 1:
320       case 40:  p =
321           #ifdef IS_G10MAINT
322             _("Usage: gpgm [options] [files] (-h for help)");
323           #else
324             _("Usage: gpg [options] [files] (-h for help)");
325           #endif
326         break;
327       case 41:  p =
328           #ifdef IS_G10MAINT
329             _("Syntax: gpgm [options] [files]\n"
330               "GnuPG maintenance utility\n");
331           #else
332             _("Syntax: gpg [options] [files]\n"
333               "sign, check, encrypt or decrypt\n"
334               "default operation depends on the input data\n");
335           #endif
336         break;
337
338       case 31: p = _("\nSupported algorithms:\n"); break;
339       case 32:
340         if( !ciphers )
341             ciphers = build_list("Cipher: ", cipher_algo_to_string,
342                                                         check_cipher_algo );
343         p = ciphers;
344         break;
345       case 33:
346         if( !pubkeys )
347             pubkeys = build_list("Pubkey: ", pubkey_algo_to_string,
348                                                         check_pubkey_algo );
349         p = pubkeys;
350         break;
351       case 34:
352         if( !digests )
353             digests = build_list("Hash: ", digest_algo_to_string,
354                                                         check_digest_algo );
355         p = digests;
356         break;
357
358       default:  p = default_strusage(level);
359     }
360     return p;
361 }
362
363
364 static char *
365 build_list( const char *text, const char * (*mapf)(int), int (*chkf)(int) )
366 {
367     int i;
368     const char *s;
369     size_t n=strlen(text)+2;
370     char *list, *p;
371
372     if( maybe_setuid )
373         secmem_init( 0 );    /* drop setuid */
374
375     for(i=1; i < 110; i++ )
376         if( !chkf(i) && (s=mapf(i)) )
377             n += strlen(s) + 2;
378     list = m_alloc( 21 + n ); *list = 0;
379     for(p=NULL, i=1; i < 110; i++ ) {
380         if( !chkf(i) && (s=mapf(i)) ) {
381             if( !p )
382                 p = stpcpy( list, text );
383             else
384                 p = stpcpy( p, ", ");
385             p = stpcpy(p, s );
386         }
387     }
388     if( p )
389         p = stpcpy(p, "\n" );
390     return list;
391 }
392
393
394 static void
395 i18n_init(void)
396 {
397   #ifdef ENABLE_NLS
398     #ifdef HAVE_LC_MESSAGES
399        setlocale( LC_TIME, "" );
400        setlocale( LC_MESSAGES, "" );
401     #else
402        setlocale( LC_ALL, "" );
403     #endif
404     bindtextdomain( PACKAGE, G10_LOCALEDIR );
405     textdomain( PACKAGE );
406   #endif
407 }
408
409 static void
410 wrong_args( const char *text)
411 {
412   #ifdef IS_G10MAINT
413     fputs(_("usage: gpgm [options] "),stderr);
414   #else
415     fputs(_("usage: gpg [options] "),stderr);
416   #endif
417     fputs(text,stderr);
418     putc('\n',stderr);
419     g10_exit(2);
420 }
421
422 static void
423 set_debug(void)
424 {
425     if( opt.debug & DBG_MEMORY_VALUE )
426         memory_debug_mode = 1;
427     if( opt.debug & DBG_MEMSTAT_VALUE )
428         memory_stat_debug_mode = 1;
429     if( opt.debug & DBG_MPI_VALUE )
430         mpi_debug_mode = 1;
431     if( opt.debug & DBG_CIPHER_VALUE )
432         g10c_debug_mode = 1;
433     if( opt.debug & DBG_IOBUF_VALUE )
434         iobuf_debug_mode = 1;
435
436 }
437
438
439 static void
440 set_cmd( enum cmd_and_opt_values *ret_cmd, enum cmd_and_opt_values new_cmd )
441 {
442     enum cmd_and_opt_values cmd = *ret_cmd;
443
444     if( !cmd || cmd == new_cmd )
445         cmd = new_cmd;
446     else if( cmd == aSign && new_cmd == aEncr )
447         cmd = aSignEncr;
448     else if( cmd == aEncr && new_cmd == aSign )
449         cmd = aSignEncr;
450     else if( cmd == aKMode && new_cmd == aSym )
451         cmd = aKModeC;
452     else if(    ( cmd == aSign     && new_cmd == aClearsign )
453              || ( cmd == aClearsign && new_cmd == aSign )  )
454         cmd = aClearsign;
455     else {
456         log_error(_("conflicting commands\n"));
457         g10_exit(2);
458     }
459
460     *ret_cmd = cmd;
461 }
462
463
464
465 int
466 main( int argc, char **argv )
467 {
468     ARGPARSE_ARGS pargs;
469     IOBUF a;
470     int rc=0;
471     int orig_argc;
472     char **orig_argv;
473     const char *fname;
474     STRLIST sl, remusr= NULL, locusr=NULL;
475     STRLIST nrings=NULL, sec_nrings=NULL;
476     armor_filter_context_t afx;
477     int detached_sig = 0;
478     FILE *configfp = NULL;
479     char *configname = NULL;
480     unsigned configlineno;
481     int parse_debug = 0;
482     int default_config =1;
483     int errors=0;
484     int default_keyring = 1;
485     int greeting = 1;
486     enum cmd_and_opt_values cmd = 0;
487     const char *trustdb_name = NULL;
488     char *def_cipher_string = NULL;
489     char *def_digest_string = NULL;
490     char *s2k_cipher_string = NULL;
491     char *s2k_digest_string = NULL;
492     int pwfd = -1;
493   #ifdef USE_SHM_COPROCESSING
494     ulong requested_shm_size=0;
495   #endif
496
497     trap_unaligned();
498     secmem_set_flags( secmem_get_flags() | 2 ); /* suspend warnings */
499   #ifdef IS_G10MAINT
500     secmem_init( 0 );      /* disable use of secmem */
501     maybe_setuid = 0;
502     log_set_name("gpgm");
503   #else
504     /* Please note that we may running SUID(ROOT), so be very CAREFUL
505      * when adding any stuff between here and the call to
506      * secmem_init()  somewhere after the option parsing
507      */
508     log_set_name("gpg");
509     secure_random_alloc(); /* put random number into secure memory */
510     disable_core_dumps();
511   #endif
512     init_signals();
513     i18n_init();
514     opt.compress = -1; /* defaults to standard compress level */
515     /* fixme: set the next two to zero and decide where used */
516     opt.def_cipher_algo = 0;
517     opt.def_digest_algo = 0;
518     opt.def_compress_algo = 2;
519     opt.s2k_mode = 1; /* salted */
520     opt.s2k_digest_algo = DIGEST_ALGO_RMD160;
521     opt.s2k_cipher_algo = CIPHER_ALGO_BLOWFISH;
522     opt.completes_needed = 1;
523     opt.marginals_needed = 3;
524     opt.homedir = getenv("GNUPGHOME");
525     if( !opt.homedir || !*opt.homedir ) {
526       #ifdef __MINGW32__
527         opt.homedir = "c:/gnupg";
528       #else
529         opt.homedir = "~/.gnupg";
530       #endif
531     }
532
533     /* check whether we have a config file on the commandline */
534     orig_argc = argc;
535     orig_argv = argv;
536     pargs.argc = &argc;
537     pargs.argv = &argv;
538     pargs.flags= 1|(1<<6);  /* do not remove the args, ignore version */
539     while( arg_parse( &pargs, opts) ) {
540         if( pargs.r_opt == oDebug || pargs.r_opt == oDebugAll )
541             parse_debug++;
542         else if( pargs.r_opt == oOptions ) {
543             /* yes there is one, so we do not try the default one, but
544              * read the option file when it is encountered at the commandline
545              */
546             default_config = 0;
547         }
548         else if( pargs.r_opt == oNoOptions )
549             default_config = 0; /* --no-options */
550         else if( pargs.r_opt == oHomedir )
551             opt.homedir = pargs.r.ret_str;
552       #ifdef USE_SHM_COPROCESSING
553         else if( pargs.r_opt == oRunAsShmCP ) {
554             /* does not make sense in a options file, we do it here,
555              * so that we are the able to drop setuid as soon as possible */
556             opt.shm_coprocess = 1;
557             requested_shm_size = pargs.r.ret_ulong;
558         }
559       #endif
560     }
561
562
563   #ifdef USE_SHM_COPROCESSING
564     if( opt.shm_coprocess ) {
565       #ifdef IS_G10
566         init_shm_coprocessing(requested_shm_size, 1 );
567       #else
568         init_shm_coprocessing(requested_shm_size, 0 );
569       #endif
570     }
571   #endif
572   #ifdef IS_G10
573     /* initialize the secure memory. */
574     secmem_init( 16384 );
575     maybe_setuid = 0;
576     /* Okay, we are now working under our real uid */
577   #endif
578
579     if( default_config )
580         configname = make_filename(opt.homedir, "options", NULL );
581
582     argc = orig_argc;
583     argv = orig_argv;
584     pargs.argc = &argc;
585     pargs.argv = &argv;
586     pargs.flags=  1;  /* do not remove the args */
587   next_pass:
588     if( configname ) {
589         configlineno = 0;
590         configfp = fopen( configname, "r" );
591         if( !configfp ) {
592             if( default_config ) {
593                 if( parse_debug )
594                     log_info(_("note: no default option file '%s'\n"),
595                                                             configname );
596             }
597             else {
598                 log_error(_("option file '%s': %s\n"),
599                                     configname, strerror(errno) );
600                 g10_exit(2);
601             }
602             m_free(configname); configname = NULL;
603         }
604         if( parse_debug && configname )
605             log_info(_("reading options from '%s'\n"), configname );
606         default_config = 0;
607     }
608
609     while( optfile_parse( configfp, configname, &configlineno,
610                                                 &pargs, opts) ) {
611         switch( pargs.r_opt ) {
612           case aCheckKeys: set_cmd( &cmd, aCheckKeys); break;
613           case aListPackets: set_cmd( &cmd, aListPackets); break;
614           case aImport: set_cmd( &cmd, aImport); break;
615           case aExport: set_cmd( &cmd, aExport); break;
616           case aListKeys: set_cmd( &cmd, aListKeys); break;
617           case aListSigs: set_cmd( &cmd, aListSigs); break;
618           case aExportSecret: set_cmd( &cmd, aExportSecret); break;
619           case aDeleteSecretKey: set_cmd( &cmd, aDeleteSecretKey); break;
620           case aDeleteKey: set_cmd( &cmd, aDeleteKey); break;
621
622         #ifdef IS_G10
623           case aDetachedSign: detached_sig = 1; set_cmd( &cmd, aSign ); break;
624           case aSym: set_cmd( &cmd, aSym); break;
625           case aDecrypt: set_cmd( &cmd, aDecrypt); break;
626           case aEncr: set_cmd( &cmd, aEncr); break;
627           case aSign: set_cmd( &cmd, aSign );  break;
628           case aKeygen: set_cmd( &cmd, aKeygen); break;
629           case aSignKey: set_cmd( &cmd, aSignKey); break;
630           case aStore: set_cmd( &cmd, aStore); break;
631           case aEditKey: set_cmd( &cmd, aEditKey); break;
632           case aClearsign: set_cmd( &cmd, aClearsign); break;
633           case aGenRevoke: set_cmd( &cmd, aGenRevoke); break;
634           case aVerify: set_cmd( &cmd, aVerify); break;
635         #else
636           #ifdef MAINTAINER_OPTIONS
637             case aPrimegen: set_cmd( &cmd, aPrimegen); break;
638             case aTest: set_cmd( &cmd, aTest); break;
639             case aGenRandom: set_cmd( &cmd, aGenRandom); break;
640           #endif
641           case aPrintMD: set_cmd( &cmd, aPrintMD); break;
642           case aPrintMDs: set_cmd( &cmd, aPrintMDs); break;
643           case aListTrustDB: set_cmd( &cmd, aListTrustDB); break;
644           case aCheckTrustDB: set_cmd( &cmd, aCheckTrustDB); break;
645           case aUpdateTrustDB: set_cmd( &cmd, aUpdateTrustDB); break;
646           case aFixTrustDB: set_cmd( &cmd, aFixTrustDB); break;
647           case aListTrustPath: set_cmd( &cmd, aListTrustPath); break;
648           case aDeArmor: set_cmd( &cmd, aDeArmor); break;
649           case aEnArmor: set_cmd( &cmd, aEnArmor); break;
650           case aExportOwnerTrust: set_cmd( &cmd, aExportOwnerTrust); break;
651           case aImportOwnerTrust: set_cmd( &cmd, aImportOwnerTrust); break;
652         #endif /* IS_G10MAINT */
653
654
655
656           case oArmor: opt.armor = 1; opt.no_armor=0; break;
657           case oOutput: opt.outfile = pargs.r.ret_str; break;
658           case oVerbose: g10_opt_verbose++;
659                     opt.verbose++; opt.list_sigs=1; break;
660           case oKOption: set_cmd( &cmd, aKMode ); break;
661
662           case oBatch: opt.batch = 1; greeting = 0; break;
663           case oAnswerYes: opt.answer_yes = 1; break;
664           case oAnswerNo: opt.answer_no = 1; break;
665           case oKeyring: append_to_strlist( &nrings, pargs.r.ret_str); break;
666           case oDebug: opt.debug |= pargs.r.ret_ulong; break;
667           case oDebugAll: opt.debug = ~0; break;
668           case oStatusFD: set_status_fd( pargs.r.ret_int ); break;
669           case oFingerprint: opt.fingerprint++; break;
670           case oSecretKeyring: append_to_strlist( &sec_nrings, pargs.r.ret_str); break;
671           case oOptions:
672             /* config files may not be nested (silently ignore them) */
673             if( !configfp ) {
674                 m_free(configname);
675                 configname = m_strdup(pargs.r.ret_str);
676                 goto next_pass;
677             }
678             break;
679           case oNoArmor: opt.no_armor=1; opt.armor=0; break;
680           case oNoDefKeyring: default_keyring = 0; break;
681           case oNoGreeting: greeting = 0; break;
682           case oNoVerbose: g10_opt_verbose = 0;
683                            opt.verbose = 0; opt.list_sigs=0; break;
684           case oQuickRandom: quick_random_gen(1); break;
685           case oNoComment: opt.no_comment=1; break;
686           case oCompletesNeeded: opt.completes_needed = pargs.r.ret_int; break;
687           case oMarginalsNeeded: opt.marginals_needed = pargs.r.ret_int; break;
688           case oTrustDBName: trustdb_name = pargs.r.ret_str; break;
689           case oDefaultKey: opt.def_secret_key = pargs.r.ret_str; break;
690           case oNoOptions: break; /* no-options */
691           case oHomedir: opt.homedir = pargs.r.ret_str; break;
692           case oNoBatch: opt.batch = 0; break;
693           case oWithColons: opt.with_colons=':'; break;
694
695           case oSkipVerify: opt.skip_verify=1; break;
696           case oCompressAlgo: opt.def_compress_algo = pargs.r.ret_int; break;
697           case oCompressKeys: opt.compress_keys = 1; break;
698           case aListSecretKeys: set_cmd( &cmd, aListSecretKeys); break;
699           case oAlwaysTrust: opt.always_trust = 1; break;
700           case oLoadExtension:
701             register_cipher_extension(orig_argc? *orig_argv:NULL,
702                                       pargs.r.ret_str);
703             break;
704           case oRFC1991: opt.rfc1991 = 1; opt.no_comment = 1; break;
705           case oEmuChecksumBug: opt.emulate_bugs |= EMUBUG_GPGCHKSUM; break;
706           case oCompressSigs: opt.compress_sigs = 1; break;
707           case oRunAsShmCP:
708           #ifndef USE_SHM_COPROCESSING
709             /* not possible in the option file,
710              * but we print the warning here anyway */
711             log_error("shared memory coprocessing is not available\n");
712           #endif
713             break;
714           case oSetFilename: opt.set_filename = pargs.r.ret_str; break;
715           case oComment: opt.comment_string = pargs.r.ret_str; break;
716           case oThrowKeyid: opt.throw_keyid = 1; break;
717           case oS2KMode:   opt.s2k_mode = pargs.r.ret_int; break;
718           case oS2KDigest: s2k_digest_string = m_strdup(pargs.r.ret_str); break;
719           case oS2KCipher: s2k_cipher_string = m_strdup(pargs.r.ret_str); break;
720
721         #ifdef IS_G10
722           case oRemote: /* store the remote users */
723             sl = m_alloc( sizeof *sl + strlen(pargs.r.ret_str));
724             strcpy(sl->d, pargs.r.ret_str);
725             sl->next = remusr;
726             remusr = sl;
727             break;
728           case oTextmode: opt.textmode=1;  break;
729           case oUser: /* store the local users */
730             sl = m_alloc( sizeof *sl + strlen(pargs.r.ret_str));
731             strcpy(sl->d, pargs.r.ret_str);
732             sl->next = locusr;
733             locusr = sl;
734             break;
735           case oCompress: opt.compress = pargs.r.ret_int; break;
736           case oPasswdFD: pwfd = pargs.r.ret_int; break;
737           case oCipherAlgo: def_cipher_string = m_strdup(pargs.r.ret_str); break;
738           case oDigestAlgo: def_digest_string = m_strdup(pargs.r.ret_str); break;
739           case oNoSecmemWarn: secmem_set_flags( secmem_get_flags() | 1 ); break;
740         #else
741           case oCipherAlgo:
742           case oDigestAlgo:
743           case oNoSecmemWarn:
744             break;  /* dummies */
745         #endif
746
747           default : errors++; pargs.err = configfp? 1:2; break;
748         }
749     }
750     if( configfp ) {
751         fclose( configfp );
752         configfp = NULL;
753         m_free(configname); configname = NULL;
754         goto next_pass;
755     }
756     m_free( configname ); configname = NULL;
757     if( log_get_errorcount(0) )
758         g10_exit(2);
759
760     if( greeting ) {
761         tty_printf("%s %s; %s\n", strusage(11), strusage(13), strusage(14) );
762         tty_printf("%s\n", strusage(15) );
763     }
764
765     secmem_set_flags( secmem_get_flags() & ~2 ); /* resume warnings */
766
767     set_debug();
768
769     /* must do this after dropping setuid, because string_to...
770      * may try to load an module */
771     if( def_cipher_string ) {
772         opt.def_cipher_algo = string_to_cipher_algo(def_cipher_string);
773         m_free(def_cipher_string); def_cipher_string = NULL;
774         if( check_cipher_algo(opt.def_cipher_algo) )
775             log_error(_("selected cipher algorithm is invalid\n"));
776     }
777     if( def_digest_string ) {
778         opt.def_digest_algo = string_to_digest_algo(def_digest_string);
779         m_free(def_digest_string); def_digest_string = NULL;
780         if( check_digest_algo(opt.def_digest_algo) )
781             log_error(_("selected digest algorithm is invalid\n"));
782     }
783     if( s2k_cipher_string ) {
784         opt.s2k_cipher_algo = string_to_cipher_algo(s2k_cipher_string);
785         m_free(s2k_cipher_string); s2k_cipher_string = NULL;
786         if( check_cipher_algo(opt.s2k_cipher_algo) )
787             log_error(_("selected cipher algorithm is invalid\n"));
788     }
789     if( s2k_digest_string ) {
790         opt.s2k_digest_algo = string_to_digest_algo(s2k_digest_string);
791         m_free(s2k_digest_string); s2k_digest_string = NULL;
792         if( check_digest_algo(opt.s2k_digest_algo) )
793             log_error(_("selected digest algorithm is invalid\n"));
794     }
795     if( opt.def_compress_algo < 1 || opt.def_compress_algo > 2 )
796         log_error(_("compress algorithm must be in range %d..%d\n"), 1, 2);
797     if( opt.completes_needed < 1 )
798         log_error(_("completes-needed must be greater than 0\n"));
799     if( opt.marginals_needed < 2 )
800         log_error(_("marginals-needed must be greater than 1\n"));
801     switch( opt.s2k_mode ) {
802       case 0:
803         log_info(_("note: simple S2K mode (0) is strongly discouraged\n"));
804         break;
805       case 1: case 3: break;
806       default:
807         log_error(_("invalid S2K mode; must be 0, 1 or 3\n"));
808     }
809
810     if( log_get_errorcount(0) )
811         g10_exit(2);
812
813     if( !cmd && opt.fingerprint )
814         set_cmd( &cmd, aListKeys);
815
816     if( cmd == aKMode || cmd == aKModeC ) { /* kludge to be compatible to pgp */
817         if( cmd == aKModeC ) {
818             opt.fingerprint = 1;
819             cmd = aKMode;
820         }
821         opt.list_sigs = 0;
822         if( opt.verbose > 2 )
823             opt.check_sigs++;
824         if( opt.verbose > 1 )
825             opt.list_sigs++;
826
827         opt.verbose = opt.verbose > 1;
828         g10_opt_verbose = opt.verbose;
829     }
830
831
832     /* kludge to let -sat generate a clear text signature */
833     if( opt.textmode && !detached_sig && opt.armor && cmd == aSign )
834         cmd = aClearsign;
835
836     if( opt.verbose > 1 )
837         set_packet_list_mode(1);
838
839     /* add the keyrings, but not for some special commands and
840      * not in case of "-kvv userid keyring" */
841     if( cmd != aDeArmor && cmd != aEnArmor
842         && !(cmd == aKMode && argc == 2 ) ) {
843
844         if( !sec_nrings || default_keyring )  /* add default secret rings */
845             add_keyblock_resource("secring.gpg", 0, 1);
846         for(sl = sec_nrings; sl; sl = sl->next )
847             add_keyblock_resource( sl->d, 0, 1 );
848         if( !nrings || default_keyring )  /* add default ring */
849             add_keyblock_resource("pubring.gpg", 0, 0);
850         for(sl = nrings; sl; sl = sl->next )
851             add_keyblock_resource( sl->d, 0, 0 );
852     }
853     FREE_STRLIST(nrings);
854     FREE_STRLIST(sec_nrings);
855
856
857     if( pwfd != -1 )  /* read the passphrase now. */
858         read_passphrase_from_fd( pwfd );
859
860     fname = argc? *argv : NULL;
861
862     switch( cmd ) {
863       case aPrimegen:
864       case aPrintMD:
865       case aPrintMDs:
866       case aGenRandom:
867       case aDeArmor:
868       case aEnArmor:
869       case aFixTrustDB:
870         break;
871       case aKMode:
872       case aListKeys:
873       case aListSecretKeys:
874       case aCheckKeys:
875         if( opt.with_colons ) /* need this to list the trust */
876             rc = init_trustdb(1, trustdb_name );
877         break;
878       case aExportOwnerTrust: rc = init_trustdb( 0, trustdb_name ); break;
879       case aListTrustDB: rc = init_trustdb( argc? 1:0, trustdb_name ); break;
880       default: rc = init_trustdb(1, trustdb_name ); break;
881     }
882     if( rc )
883         log_error(_("failed to initialize the TrustDB: %s\n"), g10_errstr(rc));
884
885
886     switch( cmd ) {
887       case aStore: /* only store the file */
888         if( argc > 1 )
889             wrong_args(_("--store [filename]"));
890         if( (rc = encode_store(fname)) )
891             log_error_f( print_fname_stdin(fname),
892                         "store failed: %s\n", g10_errstr(rc) );
893         break;
894     #ifdef IS_G10
895       case aSym: /* encrypt the given file only with the symmetric cipher */
896         if( argc > 1 )
897             wrong_args(_("--symmetric [filename]"));
898         if( (rc = encode_symmetric(fname)) )
899             log_error_f(print_fname_stdin(fname),
900                         "symmetric encryption failed: %s\n",g10_errstr(rc) );
901         break;
902
903       case aEncr: /* encrypt the given file */
904         if( argc > 1 )
905             wrong_args(_("--encrypt [filename]"));
906         if( (rc = encode_crypt(fname,remusr)) )
907             log_error("%s: encryption failed: %s\n", print_fname_stdin(fname), g10_errstr(rc) );
908         break;
909
910       case aSign: /* sign the given file */
911         sl = NULL;
912         if( detached_sig ) { /* sign all files */
913             for( ; argc; argc--, argv++ )
914                 add_to_strlist( &sl, *argv );
915         }
916         else {
917             if( argc > 1 )
918                 wrong_args(_("--sign [filename]"));
919             if( argc ) {
920                 sl = m_alloc_clear( sizeof *sl + strlen(fname));
921                 strcpy(sl->d, fname);
922             }
923         }
924         if( (rc = sign_file( sl, detached_sig, locusr, 0, NULL, NULL)) )
925             log_error("signing failed: %s\n", g10_errstr(rc) );
926         free_strlist(sl);
927         break;
928
929       case aSignEncr: /* sign and encrypt the given file */
930         if( argc > 1 )
931             wrong_args(_("--sign --encrypt [filename]"));
932         if( argc ) {
933             sl = m_alloc_clear( sizeof *sl + strlen(fname));
934             strcpy(sl->d, fname);
935         }
936         else
937             sl = NULL;
938         if( (rc = sign_file(sl, detached_sig, locusr, 1, remusr, NULL)) )
939             log_error("%s: sign+encrypt failed: %s\n", print_fname_stdin(fname), g10_errstr(rc) );
940         free_strlist(sl);
941         break;
942
943       case aClearsign: /* make a clearsig */
944         if( argc > 1 )
945             wrong_args(_("--clearsign [filename]"));
946         if( (rc = clearsign_file(fname, locusr, NULL)) )
947             log_error("%s: clearsign failed: %s\n", print_fname_stdin(fname), g10_errstr(rc) );
948         break;
949
950       case aVerify:
951         if( (rc = verify_signatures( argc, argv ) ))
952             log_error("verify signatures failed: %s\n", g10_errstr(rc) );
953         break;
954
955       case aDecrypt:
956         if( argc > 1 )
957             wrong_args(_("--decrypt [filename]"));
958         if( (rc = decrypt_message( fname ) ))
959             log_error("decrypt_message failed: %s\n", g10_errstr(rc) );
960         break;
961
962
963       case aSignKey: /* sign the key given as argument */
964       case aEditKey: /* Edit a key signature */
965         if( argc != 1 )
966             wrong_args(_("--edit-key username"));
967         keyedit_menu(fname, locusr );
968         break;
969
970       #endif /* IS_G10 */
971
972       case aDeleteSecretKey:
973         if( argc != 1 )
974             wrong_args(_("--delete-secret-key username"));
975       case aDeleteKey:
976         if( argc != 1 )
977             wrong_args(_("--delete-key username"));
978         /* note: fname is the user id! */
979         if( (rc = delete_key(fname, cmd==aDeleteSecretKey)) )
980             log_error("%s: delete key failed: %s\n", print_fname_stdin(fname), g10_errstr(rc) );
981         break;
982
983
984       case aCheckKeys:
985         opt.check_sigs = 1;
986       case aListSigs:
987         opt.list_sigs = 1;
988       case aListKeys:
989         public_key_list( argc, argv );
990         break;
991       case aListSecretKeys:
992         secret_key_list( argc, argv );
993         break;
994
995       case aKMode: /* list keyring */
996         if( argc < 2 )  /* -kv [userid] */
997             public_key_list( (argc && **argv)? 1:0, argv );
998         else if( argc == 2 ) { /* -kv userid keyring */
999             if( access( argv[1], R_OK ) ) {
1000                 log_error(_("can't open %s: %s\n"),
1001                                print_fname_stdin(argv[1]), strerror(errno));
1002             }
1003             else {
1004                 /* add keyring (default keyrings are not registered in this
1005                  * special case */
1006                 add_keyblock_resource( argv[1], 0, 0 );
1007                 public_key_list( **argv?1:0, argv );
1008             }
1009         }
1010         else
1011             wrong_args(_("-k[v][v][v][c] [userid] [keyring]") );
1012         break;
1013
1014     #ifdef IS_G10
1015       case aKeygen: /* generate a key (interactive) */
1016         if( argc )
1017             wrong_args("--gen-key");
1018         generate_keypair();
1019         break;
1020     #endif
1021
1022       case aImport:
1023         if( !argc  ) {
1024             rc = import_keys( NULL );
1025             if( rc )
1026                 log_error("import failed: %s\n", g10_errstr(rc) );
1027         }
1028         for( ; argc; argc--, argv++ ) {
1029             rc = import_keys( *argv );
1030             if( rc )
1031                 log_error("import from '%s' failed: %s\n",
1032                                                 *argv, g10_errstr(rc) );
1033         }
1034         break;
1035
1036       case aExport:
1037         sl = NULL;
1038         for( ; argc; argc--, argv++ )
1039             add_to_strlist( &sl, *argv );
1040         export_pubkeys( sl );
1041         free_strlist(sl);
1042         break;
1043
1044       case aExportSecret:
1045         sl = NULL;
1046         for( ; argc; argc--, argv++ )
1047             add_to_strlist( &sl, *argv );
1048         export_seckeys( sl );
1049         free_strlist(sl);
1050         break;
1051
1052     #ifdef IS_G10
1053       case aGenRevoke:
1054         if( argc != 1 )
1055             wrong_args("--gen-revoke user-id");
1056         gen_revoke( *argv );
1057         break;
1058     #endif
1059
1060     #ifdef IS_G10MAINT
1061       case aDeArmor:
1062         if( argc > 1 )
1063             wrong_args("--dearmor [file]");
1064         rc = dearmor_file( argc? *argv: NULL );
1065         if( rc )
1066             log_error(_("dearmoring failed: %s\n"), g10_errstr(rc));
1067         break;
1068
1069       case aEnArmor:
1070         if( argc > 1 )
1071             wrong_args("--enarmor [file]");
1072         rc = enarmor_file( argc? *argv: NULL );
1073         if( rc )
1074             log_error(_("enarmoring failed: %s\n"), g10_errstr(rc));
1075         break;
1076
1077
1078      #ifdef MAINTAINER_OPTIONS
1079       case aPrimegen:
1080         if( argc == 1 ) {
1081             mpi_print( stdout, generate_public_prime( atoi(argv[0]) ), 1);
1082             putchar('\n');
1083         }
1084         else if( argc == 2 ) {
1085             mpi_print( stdout, generate_elg_prime( 0, atoi(argv[0]),
1086                                                    atoi(argv[1]), NULL,NULL ), 1);
1087             putchar('\n');
1088         }
1089         else if( argc == 3 ) {
1090             MPI g = mpi_alloc(1);
1091             mpi_print( stdout, generate_elg_prime( 0, atoi(argv[0]),
1092                                                    atoi(argv[1]), g, NULL ), 1);
1093             printf("\nGenerator: ");
1094             mpi_print( stdout, g, 1 );
1095             putchar('\n');
1096             mpi_free(g);
1097         }
1098         else if( argc == 4 ) {
1099             mpi_print( stdout, generate_elg_prime( 1, atoi(argv[0]),
1100                                                    atoi(argv[1]), NULL,NULL ), 1);
1101             putchar('\n');
1102         }
1103         else
1104             usage(1);
1105         break;
1106       #endif /* MAINTAINER OPTIONS */
1107
1108       #ifdef MAINTAINER_OPTIONS
1109       case aGenRandom:
1110         if( argc < 1 || argc > 2 )
1111             wrong_args("--gen-random level [hex]");
1112         {
1113             int level = atoi(*argv);
1114             for(;;) {
1115                 byte *p = get_random_bits( 8, level, 0);
1116                 if( argc == 1 ) {
1117                     printf("%02x", *p );
1118                     fflush(stdout);
1119                 }
1120                 else
1121                     putchar(c&0xff);
1122                 m_free(p);
1123             }
1124         }
1125         break;
1126       #endif /* MAINTAINER OPTIONS */
1127
1128       case aPrintMD:
1129         if( argc < 1)
1130             wrong_args("--print-md algo [file]");
1131         else {
1132             int algo = string_to_digest_algo(*argv);
1133
1134             if( !algo )
1135                 log_error(_("invalid hash algorithm '%s'\n"), *argv );
1136             else {
1137                 argc--; argv++;
1138                 if( !argc )
1139                     print_mds(NULL, algo);
1140                 else {
1141                     for(; argc; argc--, argv++ )
1142                         print_mds(*argv, algo);
1143                 }
1144             }
1145         }
1146         break;
1147
1148       case aPrintMDs:
1149         if( !argc )
1150             print_mds(NULL,0);
1151         else {
1152             for(; argc; argc--, argv++ )
1153                 print_mds(*argv,0);
1154         }
1155         break;
1156
1157      #ifdef MAINTAINER_OPTIONS
1158       case aTest: do_test( argc? atoi(*argv): 1 ); break;
1159       #endif /* MAINTAINER OPTIONS */
1160
1161       case aListTrustDB:
1162         if( !argc )
1163             list_trustdb(NULL);
1164         else {
1165             for( ; argc; argc--, argv++ )
1166                 list_trustdb( *argv );
1167         }
1168         break;
1169
1170       case aUpdateTrustDB:
1171         if( argc )
1172             wrong_args("--update-trustdb");
1173         update_trustdb();
1174         break;
1175
1176       case aCheckTrustDB:
1177         if( !argc )
1178             check_trustdb(NULL);
1179         else {
1180             for( ; argc; argc--, argv++ )
1181                 check_trustdb( *argv );
1182         }
1183         break;
1184
1185       case aFixTrustDB:
1186         log_error("this command ist not yet implemented.\"\n");
1187         log_error("A workaround is to use \"--export-ownertrust\", remove\n");
1188         log_error("the trustdb file and do an \"--import-ownertrust\".\n" );
1189         break;
1190
1191       case aListTrustPath:
1192         if( argc != 2 )
1193             wrong_args("--list-trust-path [-- -]<maxdepth> <username>");
1194         list_trust_path( atoi(*argv), argv[1] );
1195         break;
1196
1197       case aExportOwnerTrust:
1198         if( argc )
1199             wrong_args("--export-ownertrust");
1200         export_ownertrust();
1201         break;
1202
1203       case aImportOwnerTrust:
1204         if( argc > 1 )
1205             wrong_args("--import-ownertrust [file]");
1206         import_ownertrust( argc? *argv:NULL );
1207         break;
1208
1209      #endif /* IS_G10MAINT */
1210
1211
1212       case aListPackets:
1213         opt.list_packets=1;
1214       default:
1215         /* fixme: g10maint should do regular maintenace tasks here */
1216         if( argc > 1 )
1217             wrong_args(_("[filename]"));
1218         if( !(a = iobuf_open(fname)) )
1219             log_error(_("can't open '%s'\n"), print_fname_stdin(fname));
1220         else {
1221             if( !opt.no_armor ) {
1222                 if( use_armor_filter( a ) ) {
1223                     memset( &afx, 0, sizeof afx);
1224                     iobuf_push_filter( a, armor_filter, &afx );
1225                 }
1226             }
1227             if( cmd == aListPackets ) {
1228                 set_packet_list_mode(1);
1229                 opt.list_packets=1;
1230             }
1231             proc_packets( a );
1232             iobuf_close(a);
1233         }
1234         break;
1235     }
1236
1237     /* cleanup */
1238     FREE_STRLIST(remusr);
1239     FREE_STRLIST(locusr);
1240     g10_exit(0);
1241     return 8; /*NEVER REACHED*/
1242 }
1243
1244
1245 void
1246 g10_exit( int rc )
1247 {
1248     if( opt.debug & DBG_MEMSTAT_VALUE )
1249         m_print_stats("on exit");
1250     if( opt.debug )
1251         secmem_dump_stats();
1252     secmem_term();
1253     rc = rc? rc : log_get_errorcount(0)? 2:0;
1254     /*write_status( STATUS_LEAVE );*/
1255     exit(rc );
1256 }
1257
1258
1259 void
1260 do_not_use_RSA()
1261 {
1262     static int did_rsa_note = 0;
1263
1264     if( !did_rsa_note ) {
1265         did_rsa_note = 1;
1266         log_info(_("RSA keys are deprecated; please consider "
1267                    "creating a new key and use this key in the future\n"));
1268     }
1269 }
1270
1271
1272 #ifdef IS_G10MAINT
1273 static void
1274 print_hex( byte *p, size_t n )
1275 {
1276     int i;
1277
1278     if( n == 20 ) {
1279         for(i=0; i < n ; i++, i++, p += 2 ) {
1280             if( i )
1281                 putchar(' ');
1282             if( i == 10 )
1283                 putchar(' ');
1284             printf("%02X%02X", *p, p[1] );
1285         }
1286     }
1287     else if( n == 24 ) {
1288         for(i=0; i < n ; i += 4, p += 4 ) {
1289             if( i )
1290                 putchar(' ');
1291             if( i == 12 )
1292                 putchar(' ');
1293             printf("%02X%02X%02X%02X", *p, p[1], p[2], p[3] );
1294         }
1295     }
1296     else {
1297         for(i=0; i < n ; i++, p++ ) {
1298             if( i )
1299                 putchar(' ');
1300             if( i && !(i%8) )
1301                 putchar(' ');
1302             printf("%02X", *p );
1303         }
1304     }
1305 }
1306
1307 static void
1308 print_mds( const char *fname, int algo )
1309 {
1310     FILE *fp;
1311     char buf[1024];
1312     size_t n;
1313     MD_HANDLE md;
1314     char *pname;
1315
1316     if( !fname ) {
1317         fp = stdin;
1318         pname = m_strdup("[stdin]: ");
1319     }
1320     else {
1321         pname = m_alloc(strlen(fname)+3);
1322         strcpy(stpcpy(pname,fname),": ");
1323         fp = fopen( fname, "rb" );
1324     }
1325     if( !fp ) {
1326         log_error("%s%s\n", pname, strerror(errno) );
1327         m_free(pname);
1328         return;
1329     }
1330
1331     md = md_open( 0, 0 );
1332     if( algo )
1333         md_enable( md, algo );
1334     else {
1335         md_enable( md, DIGEST_ALGO_MD5 );
1336         md_enable( md, DIGEST_ALGO_SHA1 );
1337         md_enable( md, DIGEST_ALGO_RMD160 );
1338         if( !check_digest_algo(DIGEST_ALGO_TIGER) )
1339             md_enable( md, DIGEST_ALGO_TIGER );
1340     }
1341
1342     while( (n=fread( buf, 1, DIM(buf), fp )) )
1343         md_write( md, buf, n );
1344     if( ferror(fp) )
1345         log_error("%s%s\n", pname, strerror(errno) );
1346     else {
1347         md_final(md);
1348         if( algo ) {
1349             if( fname )
1350                 fputs( pname, stdout );
1351             print_hex(md_read(md, algo), md_digest_length(algo) );
1352         }
1353         else {
1354             printf(  "%s   MD5 = ", fname?pname:"" );
1355                             print_hex(md_read(md, DIGEST_ALGO_MD5), 16 );
1356             printf("\n%s  SHA1 = ", fname?pname:""  );
1357                             print_hex(md_read(md, DIGEST_ALGO_SHA1), 20 );
1358             printf("\n%sRMD160 = ", fname?pname:""  );
1359                             print_hex(md_read(md, DIGEST_ALGO_RMD160), 20 );
1360             if( !check_digest_algo(DIGEST_ALGO_TIGER) ) {
1361                 printf("\n%s TIGER = ", fname?pname:""  );
1362                             print_hex(md_read(md, DIGEST_ALGO_TIGER), 24 );
1363             }
1364         }
1365         putchar('\n');
1366     }
1367     md_close(md);
1368
1369     if( fp != stdin )
1370         fclose(fp);
1371 }
1372
1373
1374
1375 #ifdef MAINTAINER_OPTIONS
1376 static void
1377 do_test(int times)
1378 {
1379     m_check(NULL);
1380 }
1381 #endif /* MAINTAINER OPTIONS */
1382 #endif /* IS_G10MAINT */
1383