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