1 /* g10.c - The G10 utility
2 * Copyright (c) 1997 by Werner Koch (dd9jn)
4 * This file is part of G10.
6 * G10 is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
11 * G10 is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
41 enum cmd_values { aNull = 0,
42 aSym, aStore, aEncr, aPrimegen, aKeygen, aSign, aSignEncr,
43 aPrintMDs, aSignKey, aClearsig, aListPackets, aEditSig,
44 aKMode, aKModeC, aChangePass, aImport, aListTrustDB,
49 static void set_cmd( enum cmd_values *ret_cmd,
50 enum cmd_values new_cmd );
51 static void print_hex( byte *p, size_t n );
52 static void print_mds( const char *fname );
53 static void do_test(int);
61 case 0: p = "g10 - v" VERSION "; "
62 "Copyright 1997 Werner Koch (dd9jn)\n" ; break;
63 case 13: p = "g10"; break;
64 case 14: p = VERSION; break;
66 case 11: p = "Usage: g10 [options] [files] (-h for help)";
70 "Syntax: g10 [options] [files]\n"
71 "sign, check, encrypt or decrypt\n"
72 "default operation depends on the input data\n"; break;
75 p = "Please report bugs to <g10-bugs@isil.d.shuttle.de>.\n";
80 " NOTE: This version is compiled without ZLIB support;\n"
81 " you are not able to process compresssed data!\n"
83 #ifdef HAVE_RSA_CIPHER
84 "WARNING: This version has RSA support! Your are not allowed to\n"
85 " use it inside the Unites States before Sep 30, 2000!\n"
89 default: p = default_strusage(level);
95 wrong_args( const char *text)
97 fputs("Usage: g10 [options] ",stderr);
106 if( opt.debug & DBG_MEMORY_VALUE )
107 memory_debug_mode = 1;
108 if( opt.debug & DBG_MEMSTAT_VALUE )
109 memory_stat_debug_mode = 1;
110 if( opt.debug & DBG_MPI_VALUE )
112 if( opt.debug & DBG_CIPHER_VALUE )
113 cipher_debug_mode = 1;
114 if( opt.debug & DBG_IOBUF_VALUE )
115 iobuf_debug_mode = 1;
120 set_cmd( enum cmd_values *ret_cmd, enum cmd_values new_cmd )
122 enum cmd_values cmd = *ret_cmd;
124 if( !cmd || cmd == new_cmd )
126 else if( cmd == aSign && new_cmd == aEncr )
128 else if( cmd == aEncr && new_cmd == aSign )
130 else if( cmd == aKMode && new_cmd == aSym )
133 log_error("conflicting commands\n");
142 main( int argc, char **argv )
144 static ARGPARSE_OPTS opts[] = {
145 { 'a', "armor", 0, "create ascii armored output"},
146 { 'v', "verbose", 0, "verbose" },
147 { 'z', NULL, 1, "set compress level (0 disables)" },
148 { 'n', "dry-run", 0, "don't make any changes" },
149 { 'c', "symmetric", 0, "do only a symmetric encryption" },
150 { 'o', "output", 2, "use as output file" },
151 { 500, "batch", 0, "batch mode: never ask" },
152 { 501, "yes", 0, "assume yes on most questions"},
153 { 502, "no", 0, "assume no on most questions"},
154 { 503, "gen-key", 0, "generate a new key pair" },
155 { 504, "add-key", 0, "add key to the public keyring" },
156 { 505, "delete-key",0, "remove key from public keyring" },
157 { 506, "sign-key" ,0, "make a signature on a key in the keyring" },
158 { 507, "store", 0, "store only" },
159 { 508, "check-key" ,0, "check signatures on a key in the keyring" },
160 { 509, "keyring" ,2, "add this keyring to the list of keyrings" },
161 { 's', "sign", 0, "make a signature"},
162 { 't', "textmode", 0, "use canonical text mode"},
163 { 'b', "detach-sign", 0, "make a detached signature"},
164 { 'e', "encrypt", 0, "encrypt data" },
165 { 'd', "decrypt", 0, "decrypt data (default)" },
166 { 'u', "local-user",2, "use this user-id to sign or decrypt" },
167 { 'r', "remote-user", 2, "use this user-id for encryption" },
168 { 'k', NULL , 0, "list keys" },
169 { 510, "debug" ,4|16, "set debugging flags" },
170 { 511, "debug-all" ,0, "enable full debugging"},
171 { 512, "cache-all" ,0, "hold everything in memory"},
172 { 513, "gen-prime" , 0, "\r" },
173 { 514, "test" , 0, "\r" },
174 { 515, "fingerprint", 0, "show the fingerprints"},
175 { 516, "print-mds" , 0, "print all message digests"},
176 { 517, "secret-keyring" ,2, "add this secret keyring to the list" },
177 { 518, "options" , 2, "read options from file" },
178 { 519, "no-armor", 0, "\r"},
179 { 520, "no-default-keyring", 0, "\r" },
180 { 521, "list-packets",0,"list only the sequence of packets"},
181 { 522, "no-greeting", 0, "\r" },
182 { 523, "passphrase-fd",1, "\r" },
183 { 524, "edit-sig" ,0, "edit a key signature" },
184 { 525, "change-passphrase", 0, "change the passphrase of your secret keyring"},
185 { 526, "no-verbose", 0, "\r"},
186 { 527, "cipher-algo", 2 , "select default cipher algorithm" },
187 { 528, "pubkey-algo", 2 , "select default puplic key algorithm" },
188 { 529, "digest-algo", 2 , "select default message digest algorithm" },
189 { 530, "import", 0 , "put public keys into the trustdb" },
190 { 531, "list-trustdb",0 , "\r"},
191 { 532, "quick-random", 0, "\r"},
192 { 533, "list-trust-path",0, "\r"},
193 { 534, "no-comment", 0, "do not write comment packets"},
194 { 535, "completes_needed", 1, "(default is 1)"},
195 { 536, "marginals_needed", 1, "(default is 3)"},
203 const char *fname, *fname_print;
204 STRLIST sl, remusr= NULL, locusr=NULL;
205 int nrings=0, sec_nrings=0;
206 armor_filter_context_t afx;
208 int detached_sig = 0;
209 FILE *configfp = NULL;
210 char *configname = NULL;
211 unsigned configlineno;
212 int parse_verbose = 0;
213 int default_config =1;
215 int default_keyring = 1;
217 enum cmd_values cmd = 0;
220 opt.compress = -1; /* defaults to standard compress level */
221 opt.def_cipher_algo = CIPHER_ALGO_BLOWFISH;
222 opt.def_pubkey_algo = PUBKEY_ALGO_ELGAMAL;
223 opt.def_digest_algo = DIGEST_ALGO_RMD160;
224 opt.completes_needed = 1;
225 opt.marginals_needed = 3;
227 /* check wether we have a config file on the commandline */
232 pargs.flags= 1; /* do not remove the args */
233 while( arg_parse( &pargs, opts) ) {
234 if( pargs.r_opt == 'v' )
236 else if( pargs.r_opt == 518 ) {
237 /* yes there is one, so we do not try the default one, but
238 * read the option file when it is encountered at the commandline
245 configname = make_filename("~/.g10", "options", NULL );
251 pargs.flags= 1; /* do not remove the args */
255 configfp = fopen( configname, "r" );
257 if( default_config ) {
258 if( parse_verbose > 1 )
259 log_info("note: no default option file '%s'\n", configname );
262 log_fatal("option file '%s': %s\n",
263 configname, strerror(errno) );
264 m_free(configname); configname = NULL;
266 if( parse_verbose > 1 )
267 log_info("reading options from '%s'\n", configname );
271 while( optfile_parse( configfp, configname, &configlineno,
273 switch( pargs.r_opt ) {
274 case 'v': opt.verbose++;
277 case 'z': opt.compress = pargs.r.ret_int; break;
278 case 'a': opt.armor = 1; opt.no_armor=0; break;
279 case 'c': set_cmd( &cmd , aSym); break;
280 case 'o': opt.outfile = pargs.r.ret_str; break;
281 case 'e': set_cmd( &cmd, aEncr); break;
282 case 'b': detached_sig = 1;
284 case 's': set_cmd( &cmd, aSign ); break;
285 case 't': set_cmd( &cmd , aClearsig); break;
286 case 'u': /* store the local users */
287 sl = m_alloc( sizeof *sl + strlen(pargs.r.ret_str));
288 strcpy(sl->d, pargs.r.ret_str);
292 case 'r': /* store the remote users */
293 sl = m_alloc( sizeof *sl + strlen(pargs.r.ret_str));
294 strcpy(sl->d, pargs.r.ret_str);
298 case 'k': set_cmd( &cmd, aKMode ); break;
299 case 500: opt.batch = 1; greeting = 0; break;
300 case 501: opt.answer_yes = 1; break;
301 case 502: opt.answer_no = 1; break;
302 case 503: set_cmd( &cmd, aKeygen); break;
303 case 506: set_cmd( &cmd, aSignKey); break;
304 case 507: set_cmd( &cmd, aStore); break;
305 case 508: opt.check_sigs = 1; opt.list_sigs = 1; break;
306 case 509: add_keyring(pargs.r.ret_str); nrings++; break;
307 case 510: opt.debug |= pargs.r.ret_ulong; break;
308 case 511: opt.debug = ~0; break;
309 case 512: opt.cache_all = 1; break;
310 case 513: set_cmd( &cmd, aPrimegen); break;
311 case 514: set_cmd( &cmd, aTest); break;
312 case 515: opt.fingerprint = 1; break;
313 case 516: set_cmd( &cmd, aPrintMDs); break;
314 case 517: add_secret_keyring(pargs.r.ret_str); sec_nrings++; break;
316 /* config files may not be nested (silently ignore them) */
319 configname = m_strdup(pargs.r.ret_str);
323 case 519: opt.no_armor=1; opt.armor=0; break;
324 case 520: default_keyring = 0; break;
325 case 521: set_cmd( &cmd, aListPackets); break;
326 case 522: greeting = 0; break;
327 case 523: set_passphrase_fd( pargs.r.ret_int ); break;
328 case 524: set_cmd( &cmd, aEditSig); break;
329 case 525: set_cmd( &cmd, aChangePass); break;
330 case 526: opt.verbose = 0; opt.list_sigs=0; break;
332 opt.def_cipher_algo = string_to_cipher_algo(pargs.r.ret_str);
335 opt.def_pubkey_algo = string_to_pubkey_algo(pargs.r.ret_str);
338 opt.def_digest_algo = string_to_digest_algo(pargs.r.ret_str);
340 case 530: set_cmd( &cmd, aImport); break;
341 case 531: set_cmd( &cmd, aListTrustDB); break;
342 case 532: quick_random_gen(1); break;
343 case 533: set_cmd( &cmd, aListTrustPath); break;
344 case 534: opt.no_comment=1; break;
345 case 535: opt.completes_needed = pargs.r.ret_int; break;
346 case 536: opt.marginals_needed = pargs.r.ret_int; break;
347 default : errors++; pargs.err = configfp? 1:2; break;
353 m_free(configname); configname = NULL;
356 m_free( configname ); configname = NULL;
357 if( !opt.def_cipher_algo || check_cipher_algo(opt.def_cipher_algo) ) {
358 log_error("selected cipher algorithm is invalid\n");
361 if( !opt.def_pubkey_algo || check_pubkey_algo(opt.def_pubkey_algo) ) {
362 log_error("selected pubkey algorithm is invalid\n");
365 if( !opt.def_digest_algo || check_digest_algo(opt.def_digest_algo) ) {
366 log_error("selected digest algorithm is invalid\n");
369 if( opt.completes_needed < 1 ) {
370 log_error("completes_needed must be greater than 0\n");
373 if( opt.marginals_needed < 2 ) {
374 log_error("marginals_needed must be greater than 1\n");
382 if( cmd == aKMode || cmd == aKModeC ) { /* kludge to be compatible to pgp */
383 if( cmd == aKModeC ) {
388 if( opt.verbose > 2 )
390 if( opt.verbose > 1 )
393 opt.verbose = opt.verbose > 1;
395 if( opt.verbose > 1 )
396 set_packet_list_mode(1);
398 if( *(s=strusage(10)) )
400 if( *(s=strusage(30)) )
404 if( !sec_nrings || default_keyring ) { /* add default secret rings */
405 char *p = make_filename("~/.g10", "secring.g10", NULL );
406 add_secret_keyring(p);
409 if( !nrings || default_keyring ) { /* add default ring */
410 char *p = make_filename("~/.g10", "pubring.g10", NULL );
416 fname_print = fname = *argv;
419 fname_print = "[stdin]";
421 if( get_passphrase_fd() == 0 ) {
422 /* reading data and passphrase form stdin:
423 * we assume the first line is the passphrase, so
434 case aListTrustDB: rc = init_trustdb( argc? 1:0 ); break;
435 default: rc = init_trustdb(1); break;
438 log_error("failed to initialize the TrustDB: %s\n", g10_errstr(rc));
442 case aStore: /* only store the file */
445 if( (rc = encode_store(fname)) )
446 log_error("encode_store('%s'): %s\n",
447 fname_print, g10_errstr(rc) );
450 case aSym: /* encrypt the given file only with the symmetric cipher */
453 if( (rc = encode_symmetric(fname)) )
454 log_error("encode_symmetric('%s'): %s\n", fname_print, g10_errstr(rc) );
457 case aEncr: /* encrypt the given file */
460 if( (rc = encode_crypt(fname,remusr)) )
461 log_error("encode_crypt('%s'): %s\n", fname_print, g10_errstr(rc) );
464 case aSign: /* sign the given file */
466 if( detached_sig ) { /* sign all files */
467 for( ; argc; argc--, argv++ )
468 add_to_strlist( &sl, *argv );
474 sl = m_alloc_clear( sizeof *sl + strlen(fname));
475 strcpy(sl->d, fname);
478 if( (rc = sign_file( sl, detached_sig, locusr, 0, NULL, NULL)) )
479 log_error("sign_file: %s\n", g10_errstr(rc) );
483 case aSignEncr: /* sign and encrypt the given file */
487 sl = m_alloc_clear( sizeof *sl + strlen(fname));
488 strcpy(sl->d, fname);
492 if( (rc = sign_file(sl, detached_sig, locusr, 1, remusr, NULL)) )
493 log_error("sign_file('%s'): %s\n", fname_print, g10_errstr(rc) );
498 case aSignKey: /* sign the key given as argument */
501 /* note: fname is the user id! */
502 if( (rc = sign_key(fname, locusr)) )
503 log_error("sign_key('%s'): %s\n", fname_print, g10_errstr(rc) );
506 case aEditSig: /* Edit a key signature */
509 /* note: fname is the user id! */
510 if( (rc = edit_keysigs(fname)) )
511 log_error("edit_keysig('%s'): %s\n", fname_print, g10_errstr(rc) );
514 case aChangePass: /* Chnage the passphrase */
515 if( argc > 1 ) /* no arg: use default, 1 arg use this one */
517 /* note: fname is the user id! */
518 if( (rc = change_passphrase(fname)) )
519 log_error("change_passphrase('%s'): %s\n", fname_print,
523 case aKMode: /* list keyring */
524 if( !argc ) { /* list the default public keyrings */
528 while( (s=get_keyring(seq++)) ) {
529 if( !(a = iobuf_open(s)) ) {
530 log_error("can't open '%s'\n", s);
536 for(i=strlen(s); i; i-- )
545 else if( argc == 1) { /* list the given keyring */
546 if( !(a = iobuf_open(fname)) )
547 log_fatal("can't open '%s'\n", fname_print);
557 mpi_print( stdout, generate_public_prime( atoi(argv[0]) ), 1);
560 else if( argc == 2 ) {
561 mpi_print( stdout, generate_elg_prime( atoi(argv[0]),
562 atoi(argv[1]), NULL ), 1);
565 else if( argc == 3 ) {
566 MPI g = mpi_alloc(1);
567 mpi_print( stdout, generate_elg_prime( atoi(argv[0]),
568 atoi(argv[1]), g ), 1);
569 printf("\nGenerator: ");
570 mpi_print( stdout, g, 1 );
582 for(; argc; argc--, argv++ )
587 case aKeygen: /* generate a key (interactive) */
593 case aTest: do_test( argc? atoi(*argv): 0 ); break;
598 for( ; argc; argc--, argv++ ) {
599 rc = import_pubkeys( *argv );
601 log_error("import from '%s' failed: %s\n",
602 *argv, g10_errstr(rc) );
610 for( ; argc; argc--, argv++ )
611 list_trustdb( *argv );
617 wrong_args("--list-trust-path <maxdepth> <username>");
618 list_trust_path( atoi(*argv), argv[1] );
626 if( !(a = iobuf_open(fname)) )
627 log_fatal("can't open '%s'\n", fname_print);
628 if( !opt.no_armor ) {
629 /* push the armor filter, so it can peek at the input data */
630 memset( &afx, 0, sizeof afx);
631 iobuf_push_filter( a, armor_filter, &afx );
633 if( cmd == aListPackets ) {
634 set_packet_list_mode(1);
643 FREE_STRLIST(remusr);
644 FREE_STRLIST(locusr);
645 return log_get_errorcount(0)? 2:0;
650 print_hex( byte *p, size_t n )
655 for(i=0; i < n ; i++, i++, p += 2 ) {
658 printf(" %02X%02X", *p, p[1] );
662 for(i=0; i < n ; i++, p++ ) {
665 printf(" %02X", *p );
671 print_mds( const char *fname )
683 fp = fopen( fname, "rb" );
685 log_error("%s: %s\n", fname, strerror(errno) );
689 md = md_open( DIGEST_ALGO_MD5, 0 );
690 md_enable( md, DIGEST_ALGO_RMD160 );
691 md_enable( md, DIGEST_ALGO_SHA1 );
693 while( (n=fread( buf, 1, DIM(buf), fp )) )
694 md_write( md, buf, n );
696 log_error("%s: %s\n", fname, strerror(errno) );
699 printf( "%s: MD5 =", fname ); print_hex(md_read(md, DIGEST_ALGO_MD5), 16 );
700 printf("\n%s: RMD160 =", fname ); print_hex(md_read(md, DIGEST_ALGO_RMD160), 20 );
701 printf("\n%s: SHA1 =", fname ); print_hex(md_read(md, DIGEST_ALGO_SHA1), 20 );
718 MPI t = mpi_alloc( 50 );
719 MPI m = mpi_alloc( 50 );
720 MPI a = mpi_alloc( 50 );
721 MPI b = mpi_alloc( 50 );
722 MPI p = mpi_alloc( 50 );
723 MPI x = mpi_alloc( 50 );
725 /* output = b/(a^x) mod p */
726 log_debug("invm %d times ", times);
727 for( ; times > 0; times -- ) {
728 mpi_fromstr(a, "0xef45678343589854354a4545545454554545455"
729 "aaaaaaaaaaaaa44444fffdecb33434343443331" );
730 mpi_fromstr(b, "0x8765765589854354a4545545454554545455"
731 "aaaaaaa466577778decb36666343443331" );
733 fputc('.', stderr); fflush(stderr);