partial DSA support
[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 /****************
22  * We use cpp to generate the source g10maint.c (IS_G10MAINT) from this
23  * source; the main difference is, that g10maint can only work with public
24  * keys and does not need to lock memory or run suid.
25  */
26
27 #include <config.h>
28 #include <errno.h>
29 #include <stdio.h>
30 #include <stdlib.h>
31 #include <string.h>
32 #include <unistd.h>
33
34 #include "packet.h"
35 #include "iobuf.h"
36 #include "memory.h"
37 #include "util.h"
38 #include "main.h"
39 #include "options.h"
40 #include "keydb.h"
41 #include "mpi.h"
42 #include "cipher.h"
43 #include "filter.h"
44 #include "trustdb.h"
45 #include "ttyio.h"
46 #include "i18n.h"
47 #include "status.h"
48
49 #ifndef IS_G10MAINT
50   #define IS_G10 1
51 #endif
52
53
54 static ARGPARSE_OPTS opts[] = {
55
56     { 300, NULL, 0, N_("\vCommands:\n ") },
57
58   #ifdef IS_G10
59     { 's', "sign",      0, N_("make a signature")},
60     { 539, "clearsign", 0, N_("make a clear text signature") },
61     { 'b', "detach-sign", 0, N_("make a detached signature")},
62     { 'e', "encrypt",   0, N_("encrypt data")},
63     { 'c', "symmetric", 0, N_("encryption only with symmetric cipher")},
64     { 507, "store",     0, N_("store only")},
65     { 'd', "decrypt",   0, N_("decrypt data (default)")},
66     { 550, "verify"   , 0, N_("verify a signature")},
67   #endif
68     { 551, "list-keys", 0, N_("list keys")},
69     { 552, "list-sigs", 0, N_("list keys and signatures")},
70     { 508, "check-sigs",0, N_("check key signatures")},
71     { 515, "fingerprint", 0, N_("list keys and fingerprints")},
72   #ifdef IS_G10
73     { 503, "gen-key",   0, N_("generate a new key pair")},
74     { 506, "sign-key"  ,0, N_("make a signature on a key in the keyring")},
75     { 505, "delete-key",0, N_("remove key from the public keyring")},
76     { 524, "edit-key"  ,0, N_("edit a key signature")},
77     { 525, "change-passphrase", 0, N_("change the passphrase of your secret keyring")},
78     { 542, "gen-revoke",0, N_("generate a revocation certificate")},
79   #endif
80     { 537, "export"          , 0, N_("export keys") },
81     { 530, "import",      0     , N_("import/merge keys")},
82     { 521, "list-packets",0,N_("list only the sequence of packets")},
83   #ifdef IS_G10MAINT
84     { 546, "dearmor", 0, N_("De-Armor a file or stdin") },
85     { 547, "enarmor", 0, N_("En-Armor a file or stdin") },
86     { 516, "print-mds" , 0, N_("print all message digests")},
87     { 513, "gen-prime" , 0, "\r" },
88     { 548, "gen-random" , 0, "\r" },
89   #endif
90
91     { 301, NULL, 0, N_("\v\nOptions:\n ") },
92
93   #ifdef IS_G10
94     { 'a', "armor",     0, N_("create ascii armored output")},
95     { 'u', "local-user",2, N_("use this user-id to sign or decrypt")},
96     { 'r', "remote-user", 2, N_("use this user-id for encryption")},
97     { 'z', NULL,        1, N_("set compress level (0 disables)") },
98     { 't', "textmode",  0, N_("use canonical text mode")},
99   #endif
100     { 'o', "output",    2, N_("use as output file")},
101     { 'v', "verbose",   0, N_("verbose") },
102     { 'n', "dry-run",   0, N_("don't make any changes") },
103     { 500, "batch",     0, N_("batch mode: never ask")},
104     { 501, "yes",       0, N_("assume yes on most questions")},
105     { 502, "no",        0, N_("assume no on most questions")},
106     { 509, "keyring"   ,2, N_("add this keyring to the list of keyrings")},
107     { 517, "secret-keyring" ,2, N_("add this secret keyring to the list")},
108     { 518, "options"   , 2, N_("read options from file")},
109
110     { 510, "debug"     ,4|16, N_("set debugging flags")},
111     { 511, "debug-all" ,0, N_("enable full debugging")},
112     { 512, "status-fd" ,1, N_("write status info to this fd") },
113     { 534, "no-comment", 0,   N_("do not write comment packets")},
114     { 535, "completes-needed", 1, N_("(default is 1)")},
115     { 536, "marginals-needed", 1, N_("(default is 3)")},
116   #ifdef IS_G10
117     { 527, "cipher-algo", 2 , N_("select default cipher algorithm")},
118     { 528, "pubkey-algo", 2 , N_("select default puplic key algorithm")},
119     { 529, "digest-algo", 2 , N_("select default message digest algorithm")},
120   #endif
121
122   #ifdef IS_G10
123     { 302, NULL, 0, N_("\v\nExamples:\n\n"
124     " -se -r Bob [file]          sign and encrypt for user Bob\n"
125     " -sat [file]                make a clear text signature\n"
126     " -sb  [file]                make a detached signature\n"
127     " -k   [userid]              show keys\n"
128     " -kc  [userid]              show fingerprint\n"  ) },
129   #endif
130
131   /* hidden options */
132   #ifdef IS_G10MAINT
133     { 514, "test"      , 0, "\r" },
134     { 531, "list-trustdb",0 , "\r"},
135     { 533, "list-trust-path",0, "\r"},
136   #endif
137   #ifdef IS_G10
138     { 'k', NULL,        0, "\r"},
139     { 504, "delete-secret-key",0, "\r" },
140     { 524, "edit-sig"  ,0, "\r"}, /* alias for edit-key */
141     { 523, "passphrase-fd",1, "\r" },
142   #endif
143     { 532, "quick-random", 0, "\r"},
144     { 526, "no-verbose", 0, "\r"},
145     { 538, "trustdb-name", 2, "\r" },
146     { 540, "no-secmem-warning", 0, "\r" }, /* used only by regression tests */
147     { 519, "no-armor",   0, "\r"},
148     { 520, "no-default-keyring", 0, "\r" },
149     { 522, "no-greeting", 0, "\r" },
150     { 541, "no-operation", 0, "\r" },      /* used by regression tests */
151     { 543, "no-options", 0, "\r" }, /* shortcut for --options /dev/null */
152     { 544, "homedir", 2, "\r" },   /* defaults to "~/.gnupg" */
153     { 545, "no-batch", 0, "\r" },
154     { 549, "with-colons", 0, "\r"},
155     { 551, "list-key", 0, "\r" }, /* alias */
156     { 552, "list-sig", 0, "\r" }, /* alias */
157     { 508, "check-sig",0, "\r" }, /* alias */
158
159
160 {0} };
161
162
163
164
165 enum cmd_values { aNull = 0,
166     aSym, aStore, aEncr, aKeygen, aSign, aSignEncr,
167     aSignKey, aClearsign, aListPackets, aEditSig, aDeleteKey, aDeleteSecretKey,
168     aKMode, aKModeC, aChangePass, aImport, aVerify, aDecrypt, aListKeys,
169     aListSigs,
170     aExport, aCheckKeys, aGenRevoke, aPrimegen, aPrintMDs,
171     aListTrustDB, aListTrustPath, aDeArmor, aEnArmor, aGenRandom, aTest,
172 aNOP };
173
174
175 static char *build_list( const char *text,
176                          const char *(*mapf)(int), int (*chkf)(int) );
177 static void set_cmd( enum cmd_values *ret_cmd,
178                         enum cmd_values new_cmd );
179 #ifdef IS_G10MAINT
180 static void print_hex( byte *p, size_t n );
181 static void print_mds( const char *fname );
182 static void do_test(int);
183 #endif
184
185 const char *
186 strusage( int level )
187 {
188   static char *digests, *pubkeys, *ciphers;
189     const char *p;
190     switch( level ) {
191       case 11: p =
192           #ifdef IS_G10MAINT
193             "gpgm (GNUPG)";
194           #else
195             "gpg (GNUPG)";
196           #endif
197         break;
198       case 13: p = VERSION; break;
199       case 17: p = PRINTABLE_OS_NAME; break;
200       case 19: p =
201             _("Please report bugs to <gnupg-bugs@isil.d.shuttle.de>.\n");
202         break;
203       case 1:
204       case 40:  p =
205           #ifdef IS_G10MAINT
206             _("Usage: gpgm [options] [files] (-h for help)");
207           #else
208             _("Usage: gpg [options] [files] (-h for help)");
209           #endif
210         break;
211       case 41:  p =
212           #ifdef IS_G10MAINT
213             _("Syntax: gpgm [options] [files]\n"
214               "GNUPG maintenance utility\n");
215           #else
216             _("Syntax: gpg [options] [files]\n"
217               "sign, check, encrypt or decrypt\n"
218               "default operation depends on the input data\n");
219           #endif
220         break;
221
222       case 31: p = "\n"; break;
223       case 32:
224         if( !ciphers )
225             ciphers = build_list("Supported ciphers: ", cipher_algo_to_string,
226                                                         check_cipher_algo );
227         p = ciphers;
228         break;
229       case 33:
230         if( !pubkeys )
231             pubkeys = build_list("Supported pubkeys: ", pubkey_algo_to_string,
232                                                         check_pubkey_algo );
233         p = pubkeys;
234         break;
235       case 34:
236         if( !digests )
237             digests = build_list("Supported digests: ", digest_algo_to_string,
238                                                         check_digest_algo );
239         p = digests;
240         break;
241
242       default:  p = default_strusage(level);
243     }
244     return p;
245 }
246
247
248 static char *
249 build_list( const char *text, const char * (*mapf)(int), int (*chkf)(int) )
250 {
251     int i;
252     const char *s;
253     size_t n=strlen(text)+2;
254     char *list, *p;
255
256     for(i=1; i < 100; i++ )
257         if( !chkf(i) && (s=mapf(i)) )
258             n += strlen(s) + 2;
259     list = m_alloc( 21 + n ); *list = 0;
260     for(p=NULL, i=1; i < 100; i++ ) {
261         if( !chkf(i) && (s=mapf(i)) ) {
262             if( !p )
263                 p = stpcpy( list, text );
264             else
265                 p = stpcpy( p, ", ");
266             p = stpcpy(p, s );
267         }
268     }
269     if( p )
270         p = stpcpy(p, "\n" );
271     return list;
272 }
273
274
275 static void
276 i18n_init(void)
277 {
278   #ifdef HAVE_LIBINTL
279     #ifdef HAVE_LC_MESSAGES
280        setlocale( LC_MESSAGES, "" );
281     #else
282        setlocale( LC_ALL, "" );
283     #endif
284     bindtextdomain( PACKAGE, G10_LOCALEDIR );
285     textdomain( PACKAGE );
286   #endif
287 }
288
289 static void
290 wrong_args( const char *text)
291 {
292   #ifdef IS_G10MAINT
293     fputs(_("usage: gpgm [options] "),stderr);
294   #else
295     fputs(_("usage: gpg [options] "),stderr);
296   #endif
297     fputs(text,stderr);
298     putc('\n',stderr);
299     g10_exit(2);
300 }
301
302 static void
303 set_debug(void)
304 {
305     if( opt.debug & DBG_MEMORY_VALUE )
306         memory_debug_mode = 1;
307     if( opt.debug & DBG_MEMSTAT_VALUE )
308         memory_stat_debug_mode = 1;
309     if( opt.debug & DBG_MPI_VALUE )
310         mpi_debug_mode = 1;
311     if( opt.debug & DBG_CIPHER_VALUE )
312         cipher_debug_mode = 1;
313     if( opt.debug & DBG_IOBUF_VALUE )
314         iobuf_debug_mode = 1;
315 }
316
317
318 static void
319 set_cmd( enum cmd_values *ret_cmd, enum cmd_values new_cmd )
320 {
321     enum cmd_values cmd = *ret_cmd;
322
323     if( !cmd || cmd == new_cmd )
324         cmd = new_cmd;
325     else if( cmd == aSign && new_cmd == aEncr )
326         cmd = aSignEncr;
327     else if( cmd == aEncr && new_cmd == aSign )
328         cmd = aSignEncr;
329     else if( cmd == aKMode && new_cmd == aSym )
330         cmd = aKModeC;
331     else if(    ( cmd == aSign     && new_cmd == aClearsign )
332              || ( cmd == aClearsign && new_cmd == aSign )  )
333         cmd = aClearsign;
334     else {
335         log_error(_("conflicting commands\n"));
336         g10_exit(2);
337     }
338
339     *ret_cmd = cmd;
340 }
341
342
343
344 static void
345 check_opts(void)
346 {
347     if( !opt.def_cipher_algo || check_cipher_algo(opt.def_cipher_algo) )
348         log_error(_("selected cipher algorithm is invalid\n"));
349     if( !opt.def_pubkey_algo || check_pubkey_algo(opt.def_pubkey_algo) )
350         log_error(_("selected pubkey algorithm is invalid\n"));
351     if( !opt.def_digest_algo || check_digest_algo(opt.def_digest_algo) )
352         log_error(_("selected digest algorithm is invalid\n"));
353     if( opt.completes_needed < 1 )
354         log_error(_("completes-needed must be greater than 0\n"));
355     if( opt.marginals_needed < 2 )
356         log_error(_("marginals-needed must be greater than 1\n"));
357 }
358
359
360
361
362 void
363 main( int argc, char **argv )
364 {
365     ARGPARSE_ARGS pargs;
366     IOBUF a;
367     int rc=0;
368     int orig_argc;
369     char **orig_argv;
370     const char *fname;
371     STRLIST sl, remusr= NULL, locusr=NULL;
372     int nrings=0, sec_nrings=0;
373     armor_filter_context_t afx;
374     int detached_sig = 0;
375     FILE *configfp = NULL;
376     char *configname = NULL;
377     unsigned configlineno;
378     int parse_debug = 0;
379     int default_config =1;
380     int errors=0;
381     int default_keyring = 1;
382     int greeting = 1;
383     enum cmd_values cmd = 0;
384     const char *trustdb_name = NULL;
385
386   #ifdef IS_G10MAINT
387     secmem_init( 0 );      /* disable use of secmem */
388     log_set_name("gpgm");
389   #else
390     /* Please note that we may running SUID(ROOT), so be very CAREFUL
391      * when adding any stuff between here and the call to
392      * secmem_init()  somewhere after the option parsing
393      */
394     log_set_name("gpg");
395     secure_random_alloc(); /* put random number into secure memory */
396   #endif
397     i18n_init();
398     opt.compress = -1; /* defaults to standard compress level */
399     opt.def_cipher_algo = CIPHER_ALGO_BLOWFISH;
400     opt.def_pubkey_algo = PUBKEY_ALGO_ELGAMAL;
401     opt.def_digest_algo = DIGEST_ALGO_RMD160;
402     opt.completes_needed = 1;
403     opt.marginals_needed = 3;
404     opt.homedir = getenv("GNUPGHOME");
405     if( !opt.homedir || !*opt.homedir ) {
406       #ifdef __MINGW32__
407         opt.homedir = "c:/gnupg";
408       #else
409         opt.homedir = "~/.gnupg";
410       #endif
411     }
412
413     /* check wether we have a config file on the commandline */
414     orig_argc = argc;
415     orig_argv = argv;
416     pargs.argc = &argc;
417     pargs.argv = &argv;
418     pargs.flags=  1;  /* do not remove the args */
419     while( arg_parse( &pargs, opts) ) {
420         if( pargs.r_opt == 510 || pargs.r_opt == 511 )
421             parse_debug++;
422         else if( pargs.r_opt == 518 ) {
423             /* yes there is one, so we do not try the default one, but
424              * read the option file when it is encountered at the commandline
425              */
426             default_config = 0;
427         }
428         else if( pargs.r_opt == 543 )
429             default_config = 0; /* --no-options */
430         else if( pargs.r_opt == 544 )
431             opt.homedir = pargs.r.ret_str;
432     }
433
434     if( default_config )
435         configname = make_filename(opt.homedir, "options", NULL );
436
437     argc = orig_argc;
438     argv = orig_argv;
439     pargs.argc = &argc;
440     pargs.argv = &argv;
441     pargs.flags=  1;  /* do not remove the args */
442   next_pass:
443     if( configname ) {
444         configlineno = 0;
445         configfp = fopen( configname, "r" );
446         if( !configfp ) {
447             if( default_config ) {
448                 if( parse_debug )
449                     log_info(_("note: no default option file '%s'\n"),
450                                                             configname );
451             }
452             else {
453                 log_error(_("option file '%s': %s\n"),
454                                     configname, strerror(errno) );
455                 g10_exit(1);
456             }
457             m_free(configname); configname = NULL;
458         }
459         if( parse_debug && configname )
460             log_info(_("reading options from '%s'\n"), configname );
461         default_config = 0;
462     }
463
464     while( optfile_parse( configfp, configname, &configlineno,
465                                                 &pargs, opts) ) {
466         switch( pargs.r_opt ) {
467
468         #ifdef IS_G10
469           case 'a': opt.armor = 1; opt.no_armor=0; break;
470           case 'b': detached_sig = 1; set_cmd( &cmd, aSign ); break;
471           case 'c': set_cmd( &cmd, aSym); break;
472           case 'd': set_cmd( &cmd, aDecrypt); break;
473           case 'e': set_cmd( &cmd, aEncr); break;
474           case 'r': /* store the remote users */
475             sl = m_alloc( sizeof *sl + strlen(pargs.r.ret_str));
476             strcpy(sl->d, pargs.r.ret_str);
477             sl->next = remusr;
478             remusr = sl;
479             break;
480           case 's': set_cmd( &cmd, aSign );  break;
481           case 't': opt.textmode=1;  break;
482           case 'u': /* store the local users */
483             sl = m_alloc( sizeof *sl + strlen(pargs.r.ret_str));
484             strcpy(sl->d, pargs.r.ret_str);
485             sl->next = locusr;
486             locusr = sl;
487             break;
488           case 'z': opt.compress = pargs.r.ret_int; break;
489           case 503: set_cmd( &cmd, aKeygen); break;
490           case 504: set_cmd( &cmd, aDeleteSecretKey); break;
491           case 505: set_cmd( &cmd, aDeleteKey); break;
492           case 506: set_cmd( &cmd, aSignKey); break;
493           case 507: set_cmd( &cmd, aStore); break;
494           case 523: set_passphrase_fd( pargs.r.ret_int ); break;
495           case 524: set_cmd( &cmd, aEditSig); break;
496           case 525: set_cmd( &cmd, aChangePass); break;
497           case 527:
498             opt.def_cipher_algo = string_to_cipher_algo(pargs.r.ret_str);
499             break;
500           case 528:
501             opt.def_pubkey_algo = string_to_pubkey_algo(pargs.r.ret_str);
502             break;
503           case 529:
504             opt.def_digest_algo = string_to_digest_algo(pargs.r.ret_str);
505             break;
506           case 539: set_cmd( &cmd, aClearsign); break;
507           case 540: secmem_set_flags( secmem_get_flags() | 1 ); break;
508           case 542: set_cmd( &cmd, aGenRevoke); break;
509           case 550: set_cmd( &cmd, aVerify); break;
510         #endif /* IS_G10 */
511
512         #ifdef IS_G10MAINT
513           case 513: set_cmd( &cmd, aPrimegen); break;
514           case 514: set_cmd( &cmd, aTest); break;
515           case 516: set_cmd( &cmd, aPrintMDs); break;
516           case 531: set_cmd( &cmd, aListTrustDB); break;
517           case 533: set_cmd( &cmd, aListTrustPath); break;
518           case 540: break; /* dummy */
519           case 546: set_cmd( &cmd, aDeArmor); break;
520           case 547: set_cmd( &cmd, aEnArmor); break;
521           case 548: set_cmd( &cmd, aGenRandom); break;
522         #endif /* IS_G10MAINT */
523
524           case 'o': opt.outfile = pargs.r.ret_str; break;
525           case 'v': opt.verbose++; opt.list_sigs=1; break;
526           case 'k': set_cmd( &cmd, aKMode ); break;
527
528           case 500: opt.batch = 1; greeting = 0; break;
529           case 501: opt.answer_yes = 1; break;
530           case 502: opt.answer_no = 1; break;
531           case 508: set_cmd( &cmd, aCheckKeys); break;
532           case 509: add_keyring(pargs.r.ret_str); nrings++; break;
533           case 510: opt.debug |= pargs.r.ret_ulong; break;
534           case 511: opt.debug = ~0; break;
535           case 512: set_status_fd( pargs.r.ret_int ); break;
536           case 515: opt.fingerprint = 1; break;
537           case 517: add_secret_keyring(pargs.r.ret_str); sec_nrings++; break;
538           case 518:
539             /* config files may not be nested (silently ignore them) */
540             if( !configfp ) {
541                 m_free(configname);
542                 configname = m_strdup(pargs.r.ret_str);
543                 goto next_pass;
544             }
545             break;
546           case 519: opt.no_armor=1; opt.armor=0; break;
547           case 520: default_keyring = 0; break;
548           case 521: set_cmd( &cmd, aListPackets); break;
549           case 522: greeting = 0; break;
550           case 526: opt.verbose = 0; opt.list_sigs=0; break;
551           case 530: set_cmd( &cmd, aImport); break;
552           case 532: quick_random_gen(1); break;
553           case 534: opt.no_comment=1; break;
554           case 535: opt.completes_needed = pargs.r.ret_int; break;
555           case 536: opt.marginals_needed = pargs.r.ret_int; break;
556           case 537: set_cmd( &cmd, aExport); break;
557           case 538: trustdb_name = pargs.r.ret_str; break;
558           case 541: set_cmd( &cmd, aNOP); break;
559           case 543: break; /* no-options */
560           case 544: opt.homedir = pargs.r.ret_str; break;
561           case 545: opt.batch = 0; break;
562           case 549: opt.with_colons=':'; break;
563           case 551: set_cmd( &cmd, aListKeys); break;
564           case 552: set_cmd( &cmd, aListSigs); break;
565           default : errors++; pargs.err = configfp? 1:2; break;
566         }
567     }
568     if( configfp ) {
569         fclose( configfp );
570         configfp = NULL;
571         m_free(configname); configname = NULL;
572         goto next_pass;
573     }
574     m_free( configname ); configname = NULL;
575     check_opts();
576     if( log_get_errorcount(0) )
577         g10_exit(2);
578
579     if( greeting ) {
580         tty_printf("%s %s; %s\n", strusage(11), strusage(13), strusage(14) );
581         tty_printf("%s\n", strusage(15) );
582     }
583
584   #ifdef IS_G10
585     /* initialize the secure memory. */
586     secmem_init( 16384 );
587     /* Okay, we are now working under our real uid */
588   #endif
589
590     /*write_status( STATUS_ENTER );*/
591
592     set_debug();
593     if( !cmd && opt.fingerprint )
594         set_cmd( &cmd, aListKeys);
595
596     if( cmd == aKMode || cmd == aKModeC ) { /* kludge to be compatible to pgp */
597         if( cmd == aKModeC ) {
598             opt.fingerprint = 1;
599             cmd = aKMode;
600         }
601         opt.list_sigs = 0;
602         if( opt.verbose > 2 )
603             opt.check_sigs++;
604         if( opt.verbose > 1 )
605             opt.list_sigs++;
606
607         opt.verbose = opt.verbose > 1;
608     }
609
610
611     /* kludge to let -sat generate a clear text signature */
612     if( opt.textmode && !detached_sig && opt.armor && cmd == aSign )
613         cmd = aClearsign;
614
615     if( opt.verbose > 1 )
616         set_packet_list_mode(1);
617
618     /* add the keyrings, but not for some special commands and
619      * not in case of "-kvv userid keyring" */
620     if( cmd != aDeArmor && cmd != aEnArmor
621         && !(cmd == aKMode && argc == 2 ) ) {
622         if( !sec_nrings || default_keyring )  /* add default secret rings */
623             add_secret_keyring("secring.gpg");
624         if( !nrings || default_keyring )  /* add default ring */
625             add_keyring("pubring.gpg");
626     }
627
628     if( argc )
629         fname = *argv;
630     else {
631         fname = NULL;
632         if( get_passphrase_fd() == 0 ) {
633             /* reading data and passphrase form stdin:
634              * we assume the first line is the passphrase, so
635              * we better should read it now.
636              */
637             /* FIXME: doit */
638         }
639     }
640
641     switch( cmd ) {
642       case aPrimegen:
643       case aPrintMDs:
644       case aGenRandom:
645       case aDeArmor:
646       case aEnArmor:
647         break;
648       case aKMode:
649       case aListKeys:
650       case aCheckKeys:
651         break;
652       case aListTrustDB: rc = init_trustdb( argc? 1:0, trustdb_name ); break;
653       default: rc = init_trustdb(1, trustdb_name ); break;
654     }
655     if( rc )
656         log_error(_("failed to initialize the TrustDB: %s\n"), g10_errstr(rc));
657
658
659     switch( cmd ) {
660       case aStore: /* only store the file */
661         if( argc > 1 )
662             wrong_args(_("--store [filename]"));
663         if( (rc = encode_store(fname)) )
664             log_error("%s: store failed: %s\n",
665                                  print_fname_stdin(fname), g10_errstr(rc) );
666         break;
667     #ifdef IS_G10
668       case aSym: /* encrypt the given file only with the symmetric cipher */
669         if( argc > 1 )
670             wrong_args(_("--symmetric [filename]"));
671         if( (rc = encode_symmetric(fname)) )
672             log_error("%s: symmetric encryption failed: %s\n",
673                             print_fname_stdin(fname), g10_errstr(rc) );
674         break;
675
676       case aEncr: /* encrypt the given file */
677         if( argc > 1 )
678             wrong_args(_("--encrypt [filename]"));
679         if( (rc = encode_crypt(fname,remusr)) )
680             log_error("%s: encryption failed: %s\n", print_fname_stdin(fname), g10_errstr(rc) );
681         break;
682
683       case aSign: /* sign the given file */
684         sl = NULL;
685         if( detached_sig ) { /* sign all files */
686             for( ; argc; argc--, argv++ )
687                 add_to_strlist( &sl, *argv );
688         }
689         else {
690             if( argc > 1 )
691                 wrong_args(_("--sign [filename]"));
692             if( argc ) {
693                 sl = m_alloc_clear( sizeof *sl + strlen(fname));
694                 strcpy(sl->d, fname);
695             }
696         }
697         if( (rc = sign_file( sl, detached_sig, locusr, 0, NULL, NULL)) )
698             log_error("signing failed: %s\n", g10_errstr(rc) );
699         free_strlist(sl);
700         break;
701
702       case aSignEncr: /* sign and encrypt the given file */
703         if( argc > 1 )
704             wrong_args(_("--sign --encrypt [filename]"));
705         if( argc ) {
706             sl = m_alloc_clear( sizeof *sl + strlen(fname));
707             strcpy(sl->d, fname);
708         }
709         else
710             sl = NULL;
711         if( (rc = sign_file(sl, detached_sig, locusr, 1, remusr, NULL)) )
712             log_error("%s: sign+encrypt failed: %s\n", print_fname_stdin(fname), g10_errstr(rc) );
713         free_strlist(sl);
714         break;
715
716       case aClearsign: /* make a clearsig */
717         if( argc > 1 )
718             wrong_args(_("--clearsign [filename]"));
719         if( (rc = clearsign_file(fname, locusr, NULL)) )
720             log_error("%s: clearsign failed: %s\n", print_fname_stdin(fname), g10_errstr(rc) );
721         break;
722
723       case aVerify:
724         if( (rc = verify_signatures( argc, argv ) ))
725             log_error("verify signatures failed: %s\n", g10_errstr(rc) );
726         break;
727
728       case aDecrypt:
729         if( argc > 1 )
730             wrong_args(_("--decrypt [filename]"));
731         if( (rc = decrypt_message( fname ) ))
732             log_error("decrypt_message failed: %s\n", g10_errstr(rc) );
733         break;
734
735
736       case aSignKey: /* sign the key given as argument */
737         if( argc != 1 )
738             wrong_args(_("--sign-key username"));
739         /* note: fname is the user id! */
740         if( (rc = sign_key(fname, locusr)) )
741             log_error("%s: sign key failed: %s\n", print_fname_stdin(fname), g10_errstr(rc) );
742         break;
743
744       case aEditSig: /* Edit a key signature */
745         if( argc != 1 )
746             wrong_args(_("--edit-sig username"));
747         /* note: fname is the user id! */
748         if( (rc = edit_keysigs(fname)) )
749             log_error("%s: edit signature failed: %s\n", print_fname_stdin(fname), g10_errstr(rc) );
750         break;
751
752       case aDeleteSecretKey:
753         if( argc != 1 )
754             wrong_args(_("--delete-secret-key username"));
755       case aDeleteKey:
756         if( argc != 1 )
757             wrong_args(_("--delete-key username"));
758         /* note: fname is the user id! */
759         if( (rc = delete_key(fname, cmd==aDeleteSecretKey)) )
760             log_error("%s: delete key failed: %s\n", print_fname_stdin(fname), g10_errstr(rc) );
761         break;
762
763       case aChangePass: /* Change the passphrase */
764         if( argc > 1 ) /* no arg: use default, 1 arg use this one */
765             wrong_args(_("--change-passphrase [username]"));
766         /* note: fname is the user id! */
767         if( (rc = change_passphrase(fname)) )
768             log_error("%s: change passphrase failed: %s\n", print_fname_stdin(fname),
769                                                        g10_errstr(rc) );
770         break;
771       #endif /* IS_G10 */
772
773       case aCheckKeys:
774         opt.check_sigs = 1;
775       case aListSigs:
776         opt.list_sigs = 1;
777       case aListKeys:
778         std_key_list( argc, argv );
779         break;
780
781       case aKMode: /* list keyring */
782         if( argc < 2 )  /* -kv [userid] */
783             std_key_list( (argc && **argv)? 1:0, argv );
784         else if( argc == 2 ) { /* -kv userid keyring */
785             if( access( argv[1], R_OK ) ) {
786                 log_error(_("can't open %s: %s\n"),
787                                print_fname_stdin(argv[1]), strerror(errno));
788             }
789             else {
790                 /* add keyring (default keyrings are not registered in this
791                  * special case */
792                 add_keyring( argv[1] );
793                 std_key_list( **argv?1:0, argv );
794             }
795         }
796         else
797             wrong_args(_("-k[v][v][v][c] [userid] [keyring]") );
798         break;
799
800     #ifdef IS_G10
801       case aKeygen: /* generate a key (interactive) */
802         if( argc )
803             wrong_args(_("--gen-key"));
804         generate_keypair();
805         break;
806     #endif
807
808       case aImport:
809         if( !argc  ) {
810             rc = import_pubkeys( NULL );
811             if( rc )
812                 log_error("import failed: %s\n", g10_errstr(rc) );
813         }
814         for( ; argc; argc--, argv++ ) {
815             rc = import_pubkeys( *argv );
816             if( rc )
817                 log_error("import from '%s' failed: %s\n",
818                                                 *argv, g10_errstr(rc) );
819         }
820         break;
821
822       case aExport:
823         sl = NULL;
824         for( ; argc; argc--, argv++ )
825             add_to_strlist( &sl, *argv );
826         export_pubkeys( sl );
827         free_strlist(sl);
828         break;
829
830     #ifdef IS_G10
831       case aGenRevoke:
832         if( argc != 1 )
833             wrong_args("--gen-revoke user-id");
834         gen_revoke( *argv );
835         break;
836     #endif
837
838     #ifdef IS_G10MAINT
839       case aDeArmor:
840         if( argc > 1 )
841             wrong_args("--dearmor [file]");
842         rc = dearmor_file( argc? *argv: NULL );
843         if( rc )
844             log_error(_("dearmoring failed: %s\n"), g10_errstr(rc));
845         break;
846
847       case aEnArmor:
848         if( argc > 1 )
849             wrong_args("--enarmor [file]");
850         rc = enarmor_file( argc? *argv: NULL );
851         if( rc )
852             log_error(_("enarmoring failed: %s\n"), g10_errstr(rc));
853         break;
854
855
856       case aPrimegen:
857         if( argc == 1 ) {
858             mpi_print( stdout, generate_public_prime( atoi(argv[0]) ), 1);
859             putchar('\n');
860         }
861         else if( argc == 2 ) {
862             mpi_print( stdout, generate_elg_prime( atoi(argv[0]),
863                                                    atoi(argv[1]), NULL,NULL ), 1);
864             putchar('\n');
865         }
866         else if( argc == 3 ) {
867             MPI g = mpi_alloc(1);
868             mpi_print( stdout, generate_elg_prime( atoi(argv[0]),
869                                                    atoi(argv[1]), g, NULL ), 1);
870             printf("\nGenerator: ");
871             mpi_print( stdout, g, 1 );
872             putchar('\n');
873             mpi_free(g);
874         }
875         else
876             usage(1);
877         break;
878
879       case aGenRandom:
880         if( argc < 1 || argc > 2 )
881             wrong_args("--gen-random level [hex]");
882         {
883             int level = atoi(*argv);
884             for(;;) {
885                 int c = get_random_byte(level);
886                 if( argc == 1 ) {
887                     printf("%02x", c );
888                     fflush(stdout);
889                 }
890                 else
891                     putchar(c&0xff);
892             }
893         }
894         break;
895
896       case aPrintMDs:
897         if( !argc )
898             print_mds(NULL);
899         else {
900             for(; argc; argc--, argv++ )
901                 print_mds(*argv);
902         }
903         break;
904
905       case aTest: do_test( argc? atoi(*argv): 1 ); break;
906
907       case aListTrustDB:
908         if( !argc )
909             list_trustdb(NULL);
910         else {
911             for( ; argc; argc--, argv++ )
912                 list_trustdb( *argv );
913         }
914         break;
915
916       case aListTrustPath:
917         if( argc != 2 )
918             wrong_args("--list-trust-path [-- -]<maxdepth> <username>");
919         list_trust_path( atoi(*argv), argv[1] );
920         break;
921
922      #endif /* IS_G10MAINT */
923
924
925       case aNOP:
926         break;
927
928       case aListPackets:
929         opt.list_packets=1;
930       default:
931         /* fixme: g10maint should to regular maintenace tasks here */
932         if( argc > 1 )
933             wrong_args(_("[filename]"));
934         if( !(a = iobuf_open(fname)) )
935             log_error(_("can't open '%s'\n"), print_fname_stdin(fname));
936         else {
937             if( !opt.no_armor ) {
938                 if( use_armor_filter( a ) ) {
939                     memset( &afx, 0, sizeof afx);
940                     iobuf_push_filter( a, armor_filter, &afx );
941                 }
942             }
943             if( cmd == aListPackets ) {
944                 set_packet_list_mode(1);
945                 opt.list_packets=1;
946             }
947             proc_packets( a );
948             iobuf_close(a);
949         }
950         break;
951     }
952
953     /* cleanup */
954     FREE_STRLIST(remusr);
955     FREE_STRLIST(locusr);
956     g10_exit(0);
957 }
958
959
960 void
961 g10_exit( int rc )
962 {
963     if( opt.debug )
964         secmem_dump_stats();
965     secmem_term();
966     rc = rc? rc : log_get_errorcount(0)? 2:0;
967     /*write_status( STATUS_LEAVE );*/
968     exit(rc );
969 }
970
971 #ifdef IS_G10MAINT
972 static void
973 print_hex( byte *p, size_t n )
974 {
975     int i;
976
977     if( n == 20 ) {
978         for(i=0; i < n ; i++, i++, p += 2 ) {
979             if( i == 10 )
980                 putchar(' ');
981             printf(" %02X%02X", *p, p[1] );
982         }
983     }
984     else {
985         for(i=0; i < n ; i++, p++ ) {
986             if( i && !(i%8) )
987                 putchar(' ');
988             printf(" %02X", *p );
989         }
990     }
991 }
992
993 static void
994 print_mds( const char *fname )
995 {
996     FILE *fp;
997     char buf[1024];
998     size_t n;
999     MD_HANDLE md;
1000
1001     if( !fname ) {
1002         fp = stdin;
1003         fname = "[stdin]";
1004     }
1005     else
1006         fp = fopen( fname, "rb" );
1007     if( !fp ) {
1008         log_error("%s: %s\n", fname, strerror(errno) );
1009         return;
1010     }
1011
1012     md = md_open( DIGEST_ALGO_MD5, 0 );
1013     md_enable( md, DIGEST_ALGO_RMD160 );
1014     md_enable( md, DIGEST_ALGO_SHA1 );
1015
1016     while( (n=fread( buf, 1, DIM(buf), fp )) )
1017         md_write( md, buf, n );
1018     if( ferror(fp) )
1019         log_error("%s: %s\n", fname, strerror(errno) );
1020     else {
1021         md_final(md);
1022         printf(  "%s:    MD5 =", fname ); print_hex(md_read(md, DIGEST_ALGO_MD5), 16 );
1023         printf("\n%s: RMD160 =", fname ); print_hex(md_read(md, DIGEST_ALGO_RMD160), 20 );
1024         printf("\n%s:   SHA1 =", fname ); print_hex(md_read(md, DIGEST_ALGO_SHA1), 20 );
1025         putchar('\n');
1026     }
1027
1028
1029     md_close(md);
1030
1031     if( fp != stdin )
1032         fclose(fp);
1033 }
1034
1035
1036
1037 static void
1038 do_test(int times)
1039 {
1040     MPI base[4];
1041     MPI exp[4];
1042     MPI t1 = mpi_alloc(50);
1043     MPI t2 = mpi_alloc(50);
1044     MPI t3 = mpi_alloc(50);
1045     MPI tmp= mpi_alloc(50);
1046     MPI m =   mpi_alloc(50);
1047     MPI res = mpi_alloc(50);
1048
1049     mpi_fromstr( m, "0x10000000000000000000000000" );
1050     base[0] = mpi_alloc_set_ui( 3 );
1051     mpi_fromstr( base[0], "0x145984358945989898495ffdd13" );
1052     base[1] = mpi_alloc_set_ui( 5 );
1053     mpi_fromstr( base[1], "0x000effff9999000000001100001" );
1054     base[2] = mpi_alloc_set_ui( 2 );
1055     mpi_fromstr( base[2], "0x499eeeaaaaa0444444545466672" );
1056     base[3] = NULL;
1057     exp[0]  = mpi_alloc_set_ui( 30 );
1058     exp[1]  = mpi_alloc_set_ui( 10 );
1059     mpi_fromstr( exp[1], "0x3457878888888888aabbbccccc1" );
1060     exp[2]  = mpi_alloc_set_ui( 24 );
1061     exp[3] = NULL;
1062
1063     mpi_powm( t1, base[0], exp[0], m );
1064     mpi_powm( t2, base[1], exp[1], m );
1065     mpi_powm( t3, base[2], exp[2], m );
1066     mpi_mulm( tmp, t1, t2, m );
1067     mpi_mulm( t1, tmp, t3, m );
1068     log_mpidump("X=", t1 );
1069
1070
1071     mpi_mulpowm( res, base, exp, m );
1072     log_mpidump("X=", res );
1073
1074
1075     m_check(NULL);
1076 }
1077 #endif /* IS_G10MAINT */
1078