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