From 1b1a6d7e77a29ffcadd3e67b78c9ed2c978e9af7 Mon Sep 17 00:00:00 2001 From: Werner Koch Date: Thu, 5 Mar 1998 09:22:13 +0000 Subject: [PATCH] removed g10maint.c --- g10/ChangeLog | 32 +++ g10/Makefile.am | 6 +- g10/Makefile.in | 24 +- g10/g10.c | 437 ++++++++++++++++++++++++----- g10/g10maint.c | 717 ------------------------------------------------ g10/getkey.c | 29 ++ g10/keydb.h | 1 + g10/keygen.c | 6 +- g10/keylist.c | 48 ++++ g10/main.h | 5 +- g10/sign.c | 74 +++-- g10/trustdb.c | 2 +- 12 files changed, 571 insertions(+), 810 deletions(-) delete mode 100644 g10/g10maint.c create mode 100644 g10/keylist.c diff --git a/g10/ChangeLog b/g10/ChangeLog index 3e295ccc0..c1f6036c4 100644 --- a/g10/ChangeLog +++ b/g10/ChangeLog @@ -1,3 +1,35 @@ +Thu Mar 5 10:20:06 1998 Werner Koch (wk@isil.d.shuttle.de) + + * g10.c: Is nom the common source for gpg and gpgm + * g10maint.c: Removed + * Makefile.am: Add rule to build g10maint.c + +Thu Mar 5 08:43:59 1998 Werner Koch (wk@isil.d.shuttle.de) + + * g10.c (main): Changed the way clear text sigs are faked. + +Wed Mar 4 19:47:37 1998 Werner Koch (wk@isil.d.shuttle.de) + + * g10maint.c (aMuttKeyList): New + * keylist.c: New. + +Wed Mar 4 17:20:33 1998 Werner Koch (wk@isil.d.shuttle.de) + + * getkey.c (get_pubkey_byname): Kludge to allow 0x prefix. + +Tue Mar 3 13:46:55 1998 Werner Koch (wk@isil.d.shuttle.de) + + * g10maint.c (main): New option --gen-random. + +Tue Mar 3 09:50:08 1998 Werner Koch (wk@isil.d.shuttle.de) + + * g10.c (aDeleteSecretKey): New. + (aEditSig): Add option "--edit-key" as synonym for "--edit-sig". + (aDeleteSecretKey): New. + * getkey.c (seckey_available): New. + * sign.c (delete_key): Enhanced to delete secret keys, changed all + callers. + Mon Mar 2 21:23:48 1998 Werner Koch (wk@isil.d.shuttle.de) * pkc_list.c (build_pkc_list): Add interactive input of user ID. diff --git a/g10/Makefile.am b/g10/Makefile.am index bee2df285..aaed0ff23 100644 --- a/g10/Makefile.am +++ b/g10/Makefile.am @@ -3,6 +3,7 @@ INCLUDES = -I$(top_srcdir)/include EXTRA_DIST = OPTIONS pubring.asc OMIT_DEPENDENCIES = zlib.h zconf.h +BUILT_SOURCES = g10maint.c needed_libs = ../cipher/libcipher.a ../mpi/libmpi.a ../util/libutil.a bin_PROGRAMS = gpg gpgm @@ -55,11 +56,14 @@ gpg_SOURCES = g10.c \ gpgm_SOURCES = g10maint.c \ - dearmor.c \ + dearmor.c \ + keylist.c \ $(common_source) LDADD = @INTLLIBS@ $(needed_libs) @ZLIBS@ +g10maint.c : g10.c + $(CPP) $(DEFS) $(INCLUDES) -DIS_G10MAINT $< > $@ || rm $@ $(PROGRAMS): $(needed_libs) diff --git a/g10/Makefile.in b/g10/Makefile.in index 9d15d1336..caffcd7f5 100644 --- a/g10/Makefile.in +++ b/g10/Makefile.in @@ -95,6 +95,7 @@ l = @l@ INCLUDES = -I$(top_srcdir)/include EXTRA_DIST = OPTIONS pubring.asc OMIT_DEPENDENCIES = zlib.h zconf.h +BUILT_SOURCES = g10maint.c needed_libs = ../cipher/libcipher.a ../mpi/libmpi.a ../util/libutil.a bin_PROGRAMS = gpg gpgm @@ -146,7 +147,8 @@ gpg_SOURCES = g10.c \ keygen.c gpgm_SOURCES = g10maint.c \ - dearmor.c \ + dearmor.c \ + keylist.c \ $(common_source) LDADD = @INTLLIBS@ $(needed_libs) @ZLIBS@ @@ -170,7 +172,7 @@ gpg_LDADD = $(LDADD) gpg_DEPENDENCIES = ../cipher/libcipher.a ../mpi/libmpi.a \ ../util/libutil.a gpg_LDFLAGS = -gpgm_OBJECTS = g10maint.o dearmor.o build-packet.o compress.o \ +gpgm_OBJECTS = g10maint.o dearmor.o keylist.o build-packet.o compress.o \ free-packet.o getkey.o pkclist.o skclist.o ringedit.o kbnode.o \ mainproc.o armor.o mdfilter.o textfilter.o cipher.o elg.o rsa.o \ openfile.o keyid.o trustdb.o parse-packet.o passphrase.o pubkey-enc.o \ @@ -193,13 +195,14 @@ GZIP = --best DEP_FILES = .deps/armor.P .deps/build-packet.P .deps/cipher.P \ .deps/comment.P .deps/compress.P .deps/dearmor.P .deps/elg.P \ .deps/encode.P .deps/encr-data.P .deps/export.P .deps/free-packet.P \ -.deps/g10.P .deps/g10maint.P .deps/getkey.P .deps/import.P \ -.deps/kbnode.P .deps/keygen.P .deps/keyid.P .deps/mainproc.P \ -.deps/mdfilter.P .deps/openfile.P .deps/parse-packet.P \ -.deps/passphrase.P .deps/pkclist.P .deps/plaintext.P .deps/pubkey-enc.P \ -.deps/revoke.P .deps/ringedit.P .deps/rsa.P .deps/seckey-cert.P \ -.deps/seskey.P .deps/sig-check.P .deps/sign.P .deps/skclist.P \ -.deps/status.P .deps/textfilter.P .deps/trustdb.P +.deps/g10.P .deps/g10maint .deps/g10maint.P .deps/getkey.P \ +.deps/import.P .deps/kbnode.P .deps/keygen.P .deps/keyid.P \ +.deps/keylist.P .deps/mainproc.P .deps/mdfilter.P .deps/openfile.P \ +.deps/parse-packet.P .deps/passphrase.P .deps/pkclist.P \ +.deps/plaintext.P .deps/pubkey-enc.P .deps/revoke.P .deps/ringedit.P \ +.deps/rsa.P .deps/seckey-cert.P .deps/seskey.P .deps/sig-check.P \ +.deps/sign.P .deps/skclist.P .deps/status.P .deps/textfilter.P \ +.deps/trustdb.P SOURCES = $(gpg_SOURCES) $(gpgm_SOURCES) OBJECTS = $(gpg_OBJECTS) $(gpgm_OBJECTS) @@ -394,6 +397,9 @@ installdirs mostlyclean-generic distclean-generic clean-generic \ maintainer-clean-generic clean mostlyclean distclean maintainer-clean +g10maint.c : g10.c + $(CPP) $(DEFS) $(INCLUDES) -DIS_G10MAINT $< > $@ || rm $@ + $(PROGRAMS): $(needed_libs) # Tell versions [3.59,3.63) of GNU make to not export all variables. diff --git a/g10/g10.c b/g10/g10.c index 0fddeedbb..b5ee4e4e3 100644 --- a/g10/g10.c +++ b/g10/g10.c @@ -18,6 +18,12 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ +/**************** + * We use cpp to generate the source g10maint.c (IS_G10MAINT) from this + * source; the main difference is, that g10maint can only work with public + * keys and does not need to lock memory or run suid. + */ + #include #include #include @@ -40,11 +46,16 @@ #include "i18n.h" #include "status.h" +#ifndef IS_G10MAINT + #define IS_G10 1 +#endif + static ARGPARSE_OPTS opts[] = { { 300, NULL, 0, N_("\vCommands:\n ") }, + #ifdef IS_G10 { 's', "sign", 0, N_("make a signature")}, { 539, "clearsign", 0, N_("make a clear text signature") }, { 'b', "detach-sign", 0, N_("make a detached signature")}, @@ -55,25 +66,36 @@ static ARGPARSE_OPTS opts[] = { { 'k', "list-keys", 0, N_("list keys")}, { 508, "check-keys",0, N_("check signatures on a key in the keyring")}, { 515, "fingerprint", 0, N_("show the fingerprints")}, - { 521, "list-packets",0,N_("list only the sequence of packets")}, { 503, "gen-key", 0, N_("generate a new key pair")}, { 506, "sign-key" ,0, N_("make a signature on a key in the keyring")}, { 505, "delete-key",0, N_("remove key from the public keyring")}, - { 524, "edit-sig" ,0, N_("edit a key signature")}, + { 524, "edit-key" ,0, N_("edit a key signature")}, { 525, "change-passphrase", 0, N_("change the passphrase of your secret keyring")}, { 542, "gen-revoke",0, N_("generate a revocation certificate")}, + #endif { 537, "export" , 0, N_("export keys") }, { 530, "import", 0 , N_("import/merge keys")}, + { 521, "list-packets",0,N_("list only the sequence of packets")}, + #ifdef IS_G10MAINT + { 546, "dearmor", 0, N_("De-Armor a file or stdin") }, + { 547, "enarmor", 0, N_("En-Armor a file or stdin") }, + { 516, "print-mds" , 0, N_("print all message digests")}, + { 513, "gen-prime" , 0, "\r" }, + { 548, "gen-random" , 0, "\r" }, + { 549, "ext-list-keys", 0, "Print a parsable list of keys" }, + #endif { 301, NULL, 0, N_("\v\nOptions:\n ") }, + #ifdef IS_G10 { 'a', "armor", 0, N_("create ascii armored output")}, - { 'o', "output", 2, N_("use as output file")}, { 'u', "local-user",2, N_("use this user-id to sign or decrypt")}, { 'r', "remote-user", 2, N_("use this user-id for encryption")}, - { 'v', "verbose", 0, N_("verbose") }, { 'z', NULL, 1, N_("set compress level (0 disables)") }, { 't', "textmode", 0, N_("use canonical text mode")}, + #endif + { 'o', "output", 2, N_("use as output file")}, + { 'v', "verbose", 0, N_("verbose") }, { 'n', "dry-run", 0, N_("don't make any changes") }, { 500, "batch", 0, N_("batch mode: never ask")}, { 501, "yes", 0, N_("assume yes on most questions")}, @@ -88,18 +110,32 @@ static ARGPARSE_OPTS opts[] = { { 534, "no-comment", 0, N_("do not write comment packets")}, { 535, "completes-needed", 1, N_("(default is 1)")}, { 536, "marginals-needed", 1, N_("(default is 3)")}, + #ifdef IS_G10 { 527, "cipher-algo", 2 , N_("select default cipher algorithm")}, { 528, "pubkey-algo", 2 , N_("select default puplic key algorithm")}, { 529, "digest-algo", 2 , N_("select default message digest algorithm")}, + #endif + #ifdef IS_G10 { 302, NULL, 0, N_("\v\nExamples:\n\n" " -se -r Bob [file] sign and encrypt for user Bob\n" " -sat [file] make a clear text signature\n" " -sb [file] make a detached signature\n" " -k [userid] show keys\n" " -kc [userid] show fingerprint\n" ) }, + #endif /* hidden options */ + #ifdef IS_G10MAINT + { 514, "test" , 0, "\r" }, + { 531, "list-trustdb",0 , "\r"}, + { 533, "list-trust-path",0, "\r"}, + #endif + #ifdef IS_G10 + { 504, "delete-secret-key",0, "\r" }, + { 524, "edit-sig" ,0, "\r"}, /* alias for edit-key */ + { 523, "passphrase-fd",1, "\r" }, + #endif { 532, "quick-random", 0, "\r"}, { 526, "no-verbose", 0, "\r"}, { 538, "trustdb-name", 2, "\r" }, @@ -107,12 +143,12 @@ static ARGPARSE_OPTS opts[] = { { 519, "no-armor", 0, "\r"}, { 520, "no-default-keyring", 0, "\r" }, { 522, "no-greeting", 0, "\r" }, - { 523, "passphrase-fd",1, "\r" }, { 541, "no-operation", 0, "\r" }, /* used by regression tests */ { 543, "no-options", 0, "\r" }, /* shortcut for --options /dev/null */ { 544, "homedir", 2, "\r" }, /* defaults to "~/.gnupg" */ { 545, "no-batch", 0, "\r" }, + {0} }; @@ -120,9 +156,10 @@ static ARGPARSE_OPTS opts[] = { enum cmd_values { aNull = 0, aSym, aStore, aEncr, aKeygen, aSign, aSignEncr, - aSignKey, aClearsign, aListPackets, aEditSig, aDeleteKey, + aSignKey, aClearsign, aListPackets, aEditSig, aDeleteKey, aDeleteSecretKey, aKMode, aKModeC, aChangePass, aImport, - aExport, aCheckKeys, aGenRevoke, + aExport, aCheckKeys, aGenRevoke, aPrimegen, aPrintMDs, aExtKeyList, + aListTrustDB, aListTrustPath, aDeArmor, aEnArmor, aGenRandom, aTest, aNOP }; @@ -130,6 +167,11 @@ static char *build_list( const char *text, const char *(*mapf)(int), int (*chkf)(int) ); static void set_cmd( enum cmd_values *ret_cmd, enum cmd_values new_cmd ); +#ifdef IS_G10MAINT +static void print_hex( byte *p, size_t n ); +static void print_mds( const char *fname ); +static void do_test(int); +#endif const char * strusage( int level ) @@ -137,21 +179,36 @@ strusage( int level ) static char *digests, *pubkeys, *ciphers; const char *p; switch( level ) { - case 11: p = "gpg (GNUPG)"; break; + case 11: p = + #ifdef IS_G10MAINT + "gpgm (GNUPG)"; + #else + "gpg (GNUPG)"; + #endif + break; case 13: p = VERSION; break; case 17: p = PRINTABLE_OS_NAME; break; - case 19: p = _( -"Please report bugs to .\n" - ); break; + case 19: p = + _("Please report bugs to .\n"); + break; case 1: - case 40: p = _( -"Usage: gpg [options] [files] (-h for help)" - ); break; - case 41: p = _( -"Syntax: gpg [options] [files]\n" -"sign, check, encrypt or decrypt\n" -"default operation depends on the input data\n" - ); break; + case 40: p = + #ifdef IS_G10MAINT + _("Usage: gpgm [options] [files] (-h for help)"); + #else + _("Usage: gpg [options] [files] (-h for help)"); + #endif + break; + case 41: p = + #ifdef IS_G10MAINT + _("Syntax: gpgm [options] [files]\n" + "GNUPG maintenance utility\n"); + #else + _("Syntax: gpg [options] [files]\n" + "sign, check, encrypt or decrypt\n" + "default operation depends on the input data\n"); + #endif + break; case 31: p = "\n"; break; case 32: @@ -223,7 +280,11 @@ i18n_init(void) static void wrong_args( const char *text) { + #ifdef IS_G10MAINT + fputs(_("usage: gpgm [options] "),stderr); + #else fputs(_("usage: gpg [options] "),stderr); + #endif fputs(text,stderr); putc('\n',stderr); g10_exit(2); @@ -313,12 +374,17 @@ main( int argc, char **argv ) enum cmd_values cmd = 0; const char *trustdb_name = NULL; + #ifdef IS_G10MAINT + secmem_init( 0 ); /* disable use of secmem */ + log_set_name("gpgm"); + #else /* Please note that we may running SUID(ROOT), so be very CAREFUL * when adding any stuff between here and the call to * secmem_init() somewhere after the option parsing */ - log_set_name("gpg"); + secure_random_alloc(); /* put random number into secure memory */ + #endif i18n_init(); opt.compress = -1; /* defaults to standard compress level */ opt.def_cipher_algo = CIPHER_ALGO_BLOWFISH; @@ -389,43 +455,77 @@ main( int argc, char **argv ) while( optfile_parse( configfp, configname, &configlineno, &pargs, opts) ) { switch( pargs.r_opt ) { - case 'v': opt.verbose++; opt.list_sigs=1; break; - case 'z': opt.compress = pargs.r.ret_int; break; + + #ifdef IS_G10 case 'a': opt.armor = 1; opt.no_armor=0; break; - case 'd': break; /* it is default */ - case 'c': set_cmd( &cmd , aSym); break; - case 'o': opt.outfile = pargs.r.ret_str; break; - case 'e': set_cmd( &cmd, aEncr); break; case 'b': detached_sig = 1; /* fall trough */ - case 's': set_cmd( &cmd, aSign ); break; - case 't': set_cmd( &cmd , aClearsign); break; - case 'u': /* store the local users */ - sl = m_alloc( sizeof *sl + strlen(pargs.r.ret_str)); - strcpy(sl->d, pargs.r.ret_str); - sl->next = locusr; - locusr = sl; - break; + case 'c': set_cmd( &cmd , aSym); break; + case 'd': break; /* it is default */ + case 'e': set_cmd( &cmd, aEncr); break; + case 'k': set_cmd( &cmd, aKMode ); break; case 'r': /* store the remote users */ sl = m_alloc( sizeof *sl + strlen(pargs.r.ret_str)); strcpy(sl->d, pargs.r.ret_str); sl->next = remusr; remusr = sl; break; - case 'k': set_cmd( &cmd, aKMode ); break; - case 500: opt.batch = 1; greeting = 0; break; - case 501: opt.answer_yes = 1; break; - case 502: opt.answer_no = 1; break; + case 's': set_cmd( &cmd, aSign ); break; + case 't': opt.textmode=1; break; + case 'u': /* store the local users */ + sl = m_alloc( sizeof *sl + strlen(pargs.r.ret_str)); + strcpy(sl->d, pargs.r.ret_str); + sl->next = locusr; + locusr = sl; + break; + case 'z': opt.compress = pargs.r.ret_int; break; case 503: set_cmd( &cmd, aKeygen); break; + case 504: set_cmd( &cmd, aDeleteSecretKey); break; case 505: set_cmd( &cmd, aDeleteKey); break; case 506: set_cmd( &cmd, aSignKey); break; case 507: set_cmd( &cmd, aStore); break; case 508: set_cmd( &cmd, aCheckKeys); opt.check_sigs = 1; opt.list_sigs = 1; break; + case 515: opt.fingerprint = 1; break; + case 523: set_passphrase_fd( pargs.r.ret_int ); break; + case 524: set_cmd( &cmd, aEditSig); break; + case 525: set_cmd( &cmd, aChangePass); break; + case 527: + opt.def_cipher_algo = string_to_cipher_algo(pargs.r.ret_str); + break; + case 528: + opt.def_pubkey_algo = string_to_pubkey_algo(pargs.r.ret_str); + break; + case 529: + opt.def_digest_algo = string_to_digest_algo(pargs.r.ret_str); + break; + case 539: set_cmd( &cmd, aClearsign); break; + case 540: secmem_set_flags( secmem_get_flags() | 1 ); break; + case 542: set_cmd( &cmd, aGenRevoke); break; + #endif /* IS_G10 */ + + #ifdef IS_G10MAINT + case 513: set_cmd( &cmd, aPrimegen); break; + case 514: set_cmd( &cmd, aTest); break; + case 516: set_cmd( &cmd, aPrintMDs); break; + case 531: set_cmd( &cmd, aListTrustDB); break; + case 533: set_cmd( &cmd, aListTrustPath); break; + case 540: break; /* dummy */ + case 546: set_cmd( &cmd, aDeArmor); break; + case 547: set_cmd( &cmd, aEnArmor); break; + case 548: set_cmd( &cmd, aGenRandom); break; + case 549: set_cmd( &cmd, aExtKeyList); break; + #endif /* IS_G10MAINT */ + + case 'o': opt.outfile = pargs.r.ret_str; break; + case 'v': opt.verbose++; opt.list_sigs=1; break; + + case 500: opt.batch = 1; greeting = 0; break; + case 501: opt.answer_yes = 1; break; + case 502: opt.answer_no = 1; break; case 509: add_keyring(pargs.r.ret_str); nrings++; break; case 510: opt.debug |= pargs.r.ret_ulong; break; case 511: opt.debug = ~0; break; case 512: set_status_fd( pargs.r.ret_int ); break; - case 515: opt.fingerprint = 1; break; case 517: add_secret_keyring(pargs.r.ret_str); sec_nrings++; break; case 518: /* config files may not be nested (silently ignore them) */ @@ -439,19 +539,7 @@ main( int argc, char **argv ) case 520: default_keyring = 0; break; case 521: set_cmd( &cmd, aListPackets); break; case 522: greeting = 0; break; - case 523: set_passphrase_fd( pargs.r.ret_int ); break; - case 524: set_cmd( &cmd, aEditSig); break; - case 525: set_cmd( &cmd, aChangePass); break; case 526: opt.verbose = 0; opt.list_sigs=0; break; - case 527: - opt.def_cipher_algo = string_to_cipher_algo(pargs.r.ret_str); - break; - case 528: - opt.def_pubkey_algo = string_to_pubkey_algo(pargs.r.ret_str); - break; - case 529: - opt.def_digest_algo = string_to_digest_algo(pargs.r.ret_str); - break; case 530: set_cmd( &cmd, aImport); break; case 532: quick_random_gen(1); break; case 534: opt.no_comment=1; break; @@ -459,10 +547,7 @@ main( int argc, char **argv ) case 536: opt.marginals_needed = pargs.r.ret_int; break; case 537: set_cmd( &cmd, aExport); break; case 538: trustdb_name = pargs.r.ret_str; break; - case 539: set_cmd( &cmd, aClearsign); break; - case 540: secmem_set_flags( secmem_get_flags() | 1 ); break; case 541: set_cmd( &cmd, aNOP); break; - case 542: set_cmd( &cmd, aGenRevoke); break; case 543: break; /* no-options */ case 544: opt.homedir = pargs.r.ret_str; break; case 545: opt.batch = 0; break; @@ -485,9 +570,11 @@ main( int argc, char **argv ) tty_printf("%s\n", strusage(15) ); } + #ifdef IS_G10 /* initialize the secure memory. */ secmem_init( 16384 ); /* Okay, we are now working under our real uid */ + #endif write_status( STATUS_ENTER ); @@ -505,13 +592,20 @@ main( int argc, char **argv ) opt.verbose = opt.verbose > 1; } + + /* kludge to let -sat generate a clear text signature */ + if( opt.textmode && !detached_sig && opt.armor && cmd == aSign ) + cmd = aClearsign; + if( opt.verbose > 1 ) set_packet_list_mode(1); - if( !sec_nrings || default_keyring ) /* add default secret rings */ - add_secret_keyring("secring.gpg"); - if( !nrings || default_keyring ) /* add default ring */ - add_keyring("pubring.gpg"); + if( cmd != aDeArmor && cmd != aEnArmor ) { + if( !sec_nrings || default_keyring ) /* add default secret rings */ + add_secret_keyring("secring.gpg"); + if( !nrings || default_keyring ) /* add default ring */ + add_keyring("pubring.gpg"); + } if( argc ) { fname_print = fname = *argv; @@ -528,7 +622,16 @@ main( int argc, char **argv ) } } - rc = init_trustdb(1, trustdb_name ); + switch( cmd ) { + case aPrimegen: + case aPrintMDs: + case aGenRandom: + case aDeArmor: + case aEnArmor: + break; + case aListTrustDB: rc = init_trustdb( argc? 1:0, trustdb_name ); break; + default: rc = init_trustdb(1, trustdb_name ); break; + } if( rc ) log_error(_("failed to initialize the TrustDB: %s\n"), g10_errstr(rc)); @@ -541,7 +644,7 @@ main( int argc, char **argv ) log_error("%s: store failed: %s\n", fname_print, g10_errstr(rc) ); break; - + #ifdef IS_G10 case aSym: /* encrypt the given file only with the symmetric cipher */ if( argc > 1 ) wrong_args(_("--symmetric [filename]")); @@ -613,15 +716,18 @@ main( int argc, char **argv ) log_error("%s: edit signature failed: %s\n", fname_print, g10_errstr(rc) ); break; + case aDeleteSecretKey: + if( argc != 1 ) + wrong_args(_("--delete-secret-key username")); case aDeleteKey: if( argc != 1 ) wrong_args(_("--delete-key username")); /* note: fname is the user id! */ - if( (rc = delete_key(fname)) ) + if( (rc = delete_key(fname, cmd==aDeleteSecretKey)) ) log_error("%s: delete key failed: %s\n", fname_print, g10_errstr(rc) ); break; - case aChangePass: /* Chnage the passphrase */ + case aChangePass: /* Change the passphrase */ if( argc > 1 ) /* no arg: use default, 1 arg use this one */ wrong_args(_("--change-passphrase [username]")); /* note: fname is the user id! */ @@ -629,6 +735,7 @@ main( int argc, char **argv ) log_error("%s: change passphrase failed: %s\n", fname_print, g10_errstr(rc) ); break; + #endif /* IS_G10 */ case aCheckKeys: case aKMode: /* list keyring */ @@ -672,11 +779,13 @@ main( int argc, char **argv ) wrong_args(_("-k[v][v][v][c] [keyring]") ); break; + #ifdef IS_G10 case aKeygen: /* generate a key (interactive) */ if( argc ) wrong_args(_("--gen-key")); generate_keypair(); break; + #endif case aImport: if( !argc ) { @@ -700,11 +809,107 @@ main( int argc, char **argv ) free_strlist(sl); break; + #ifdef IS_G10 case aGenRevoke: if( argc != 1 ) wrong_args("--gen-revoke user-id"); gen_revoke( *argv ); break; + #endif + + #ifdef IS_G10MAINT + case aDeArmor: + if( argc > 1 ) + wrong_args("--dearmor [file]"); + rc = dearmor_file( argc? *argv: NULL ); + if( rc ) + log_error(_("dearmoring failed: %s\n"), g10_errstr(rc)); + break; + + case aEnArmor: + if( argc > 1 ) + wrong_args("--enarmor [file]"); + rc = enarmor_file( argc? *argv: NULL ); + if( rc ) + log_error(_("enarmoring failed: %s\n"), g10_errstr(rc)); + break; + + + case aPrimegen: + if( argc == 1 ) { + mpi_print( stdout, generate_public_prime( atoi(argv[0]) ), 1); + putchar('\n'); + } + else if( argc == 2 ) { + mpi_print( stdout, generate_elg_prime( atoi(argv[0]), + atoi(argv[1]), NULL,NULL ), 1); + putchar('\n'); + } + else if( argc == 3 ) { + MPI g = mpi_alloc(1); + mpi_print( stdout, generate_elg_prime( atoi(argv[0]), + atoi(argv[1]), g, NULL ), 1); + printf("\nGenerator: "); + mpi_print( stdout, g, 1 ); + putchar('\n'); + mpi_free(g); + } + else + usage(1); + break; + + case aGenRandom: + if( argc < 1 || argc > 2 ) + wrong_args("--gen-random level [hex]"); + { + int level = atoi(*argv); + for(;;) { + int c = get_random_byte(level); + if( argc == 1 ) { + printf("%02x", c ); + fflush(stdout); + } + else + putchar(c&0xff); + } + } + break; + + case aPrintMDs: + if( !argc ) + print_mds(NULL); + else { + for(; argc; argc--, argv++ ) + print_mds(*argv); + } + break; + + case aTest: do_test( argc? atoi(*argv): 1 ); break; + + case aListTrustDB: + if( !argc ) + list_trustdb(NULL); + else { + for( ; argc; argc--, argv++ ) + list_trustdb( *argv ); + } + break; + + case aListTrustPath: + if( argc != 2 ) + wrong_args("--list-trust-path [-- -] "); + list_trust_path( atoi(*argv), argv[1] ); + break; + + case aExtKeyList: + sl = NULL; + for( ; argc; argc--, argv++ ) + add_to_strlist( &sl, *argv ); + ext_key_list( sl ); + free_strlist(sl); + break; + #endif /* IS_G10MAINT */ + case aNOP: break; @@ -712,6 +917,7 @@ main( int argc, char **argv ) case aListPackets: opt.list_packets=1; default: + /* fixme: g10maint should to regular maintenace tasks here */ if( argc > 1 ) wrong_args(_("[filename]")); if( !(a = iobuf_open(fname)) ) @@ -751,4 +957,111 @@ g10_exit( int rc ) exit(rc ); } +#ifdef IS_G10MAINT +static void +print_hex( byte *p, size_t n ) +{ + int i; + + if( n == 20 ) { + for(i=0; i < n ; i++, i++, p += 2 ) { + if( i == 10 ) + putchar(' '); + printf(" %02X%02X", *p, p[1] ); + } + } + else { + for(i=0; i < n ; i++, p++ ) { + if( i && !(i%8) ) + putchar(' '); + printf(" %02X", *p ); + } + } +} + +static void +print_mds( const char *fname ) +{ + FILE *fp; + char buf[1024]; + size_t n; + MD_HANDLE md; + + if( !fname ) { + fp = stdin; + fname = "[stdin]"; + } + else + fp = fopen( fname, "rb" ); + if( !fp ) { + log_error("%s: %s\n", fname, strerror(errno) ); + return; + } + + md = md_open( DIGEST_ALGO_MD5, 0 ); + md_enable( md, DIGEST_ALGO_RMD160 ); + md_enable( md, DIGEST_ALGO_SHA1 ); + + while( (n=fread( buf, 1, DIM(buf), fp )) ) + md_write( md, buf, n ); + if( ferror(fp) ) + log_error("%s: %s\n", fname, strerror(errno) ); + else { + md_final(md); + printf( "%s: MD5 =", fname ); print_hex(md_read(md, DIGEST_ALGO_MD5), 16 ); + printf("\n%s: RMD160 =", fname ); print_hex(md_read(md, DIGEST_ALGO_RMD160), 20 ); + printf("\n%s: SHA1 =", fname ); print_hex(md_read(md, DIGEST_ALGO_SHA1), 20 ); + putchar('\n'); + } + + + md_close(md); + + if( fp != stdin ) + fclose(fp); +} + + + +static void +do_test(int times) +{ + MPI base[4]; + MPI exp[4]; + MPI t1 = mpi_alloc(50); + MPI t2 = mpi_alloc(50); + MPI t3 = mpi_alloc(50); + MPI tmp= mpi_alloc(50); + MPI m = mpi_alloc(50); + MPI res = mpi_alloc(50); + + mpi_fromstr( m, "0x10000000000000000000000000" ); + base[0] = mpi_alloc_set_ui( 3 ); + mpi_fromstr( base[0], "0x145984358945989898495ffdd13" ); + base[1] = mpi_alloc_set_ui( 5 ); + mpi_fromstr( base[1], "0x000effff9999000000001100001" ); + base[2] = mpi_alloc_set_ui( 2 ); + mpi_fromstr( base[2], "0x499eeeaaaaa0444444545466672" ); + base[3] = NULL; + exp[0] = mpi_alloc_set_ui( 30 ); + exp[1] = mpi_alloc_set_ui( 10 ); + mpi_fromstr( exp[1], "0x3457878888888888aabbbccccc1" ); + exp[2] = mpi_alloc_set_ui( 24 ); + exp[3] = NULL; + + mpi_powm( t1, base[0], exp[0], m ); + mpi_powm( t2, base[1], exp[1], m ); + mpi_powm( t3, base[2], exp[2], m ); + mpi_mulm( tmp, t1, t2, m ); + mpi_mulm( t1, tmp, t3, m ); + log_mpidump("X=", t1 ); + + + mpi_mulpowm( res, base, exp, m ); + log_mpidump("X=", res ); + + + m_check(NULL); +} +#endif /* IS_G10MAINT */ diff --git a/g10/g10maint.c b/g10/g10maint.c deleted file mode 100644 index b35106c0d..000000000 --- a/g10/g10maint.c +++ /dev/null @@ -1,717 +0,0 @@ -/* g10maint.c - The GNUPG maintenance utility - * Copyright (C) 1998 Free Software Foundation, Inc. - * - * This file is part of GNUPG. - * - * GNUPG is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * GNUPG is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA - */ - -#include -#include -#include -#include -#include -#include - -#include "packet.h" -#include "iobuf.h" -#include "memory.h" -#include "util.h" -#include "main.h" -#include "options.h" -#include "keydb.h" -#include "mpi.h" -#include "cipher.h" -#include "filter.h" -#include "trustdb.h" -#include "ttyio.h" -#include "i18n.h" -#include "status.h" - - -enum cmd_values { aNull = 0, - aPrimegen, aPrintMDs, aListPackets, aKMode, aKModeC, - aListTrustDB, aListTrustPath, aDeArmor, aEnArmor, -aTest }; - - -static char *build_list( const char *text, - const char *(*mapf)(int), int (*chkf)(int) ); -static void set_cmd( enum cmd_values *ret_cmd, - enum cmd_values new_cmd ); -static void print_hex( byte *p, size_t n ); -static void print_mds( const char *fname ); -static void do_test(int); - - -const char * -strusage( int level ) -{ - static char *digests, *pubkeys, *ciphers; - const char *p; - switch( level ) { - case 11: p = "gpgm (GNUPG)"; break; - case 13: p = VERSION; break; - case 17: p = PRINTABLE_OS_NAME; break; - case 19: p = _( -"Please report bugs to .\n" - ); break; - case 1: - case 40: p = _( -"Usage: gpgm [options] [files] (-h for help)" - ); break; - case 41: p = _( -"Syntax: gpgm [options] [files]\n" -"GNUPG maintenance utility\n" - ); break; - - case 31: p = "\n"; break; - case 32: - if( !ciphers ) - ciphers = build_list("Supported ciphers: ", cipher_algo_to_string, - check_cipher_algo ); - p = ciphers; - break; - case 33: - if( !pubkeys ) - pubkeys = build_list("Supported pubkeys: ", pubkey_algo_to_string, - check_pubkey_algo ); - p = pubkeys; - break; - case 34: - if( !digests ) - digests = build_list("Supported digests: ", digest_algo_to_string, - check_digest_algo ); - p = digests; - break; - - default: p = default_strusage(level); - } - return p; -} - - -static char * -build_list( const char *text, const char * (*mapf)(int), int (*chkf)(int) ) -{ - int i; - const char *s; - size_t n=strlen(text)+2; - char *list, *p; - - for(i=1; i < 100; i++ ) - if( !chkf(i) && (s=mapf(i)) ) - n += strlen(s) + 2; - list = m_alloc( 21 + n ); *list = 0; - for(p=NULL, i=1; i < 100; i++ ) { - if( !chkf(i) && (s=mapf(i)) ) { - if( !p ) - p = stpcpy( list, text ); - else - p = stpcpy( p, ", "); - p = stpcpy(p, s ); - } - } - if( p ) - p = stpcpy(p, "\n" ); - return list; -} - -static void -i18n_init(void) -{ - #ifdef HAVE_LIBINTL - #ifdef HAVE_LC_MESSAGES - setlocale( LC_MESSAGES, "" ); - #else - setlocale( LC_ALL, "" ); - #endif - bindtextdomain( PACKAGE, G10_LOCALEDIR ); - textdomain( PACKAGE ); - #endif -} - -static void -wrong_args( const char *text) -{ - fputs(_("Usage: gpgm [options] "),stderr); - fputs(text,stderr); - putc('\n',stderr); - g10_exit(2); -} - -static void -set_debug(void) -{ - if( opt.debug & DBG_MEMORY_VALUE ) - memory_debug_mode = 1; - if( opt.debug & DBG_MEMSTAT_VALUE ) - memory_stat_debug_mode = 1; - if( opt.debug & DBG_MPI_VALUE ) - mpi_debug_mode = 1; - if( opt.debug & DBG_CIPHER_VALUE ) - cipher_debug_mode = 1; - if( opt.debug & DBG_IOBUF_VALUE ) - iobuf_debug_mode = 1; -} - - -static void -set_cmd( enum cmd_values *ret_cmd, enum cmd_values new_cmd ) -{ - enum cmd_values cmd = *ret_cmd; - - if( !cmd || cmd == new_cmd ) - cmd = new_cmd; - else if( cmd == aKMode && new_cmd == aKModeC ) - cmd = aKModeC; - else { - log_error(_("conflicting commands\n")); - g10_exit(2); - } - - *ret_cmd = cmd; -} - - -void -main( int argc, char **argv ) -{ - static ARGPARSE_OPTS opts[] = { - { 'v', "verbose", 0, N_("verbose") }, - { 'n', "dry-run", 0, N_("don't make any changes") }, - { 'o', "output", 2, N_("use as output file")}, - { 'c', NULL , 0, N_("check signatures")}, - { 500, "batch", 0, N_("batch mode: never ask")}, - { 501, "yes", 0, N_("assume yes on most questions")}, - { 502, "no", 0, N_("assume no on most questions")}, - { 509, "keyring" ,2, N_("add this keyring to the list of keyrings")}, - { 'k', NULL , 0, N_("list keys")}, - { 510, "debug" ,4|16, N_("set debugging flags")}, - { 511, "debug-all" ,0, N_("enable full debugging")}, - { 512, "status-fd" ,1, N_("write status info to this fd") }, - { 513, "gen-prime" , 0, "\r" }, - { 514, "test" , 0, "\r" }, - { 516, "print-mds" , 0, N_("print all message digests")}, - { 517, "secret-keyring" ,2, N_("add this secret keyring to the list")}, - { 518, "options" , 2, N_("read options from file")}, - { 519, "no-armor", 0, "\r"}, - { 520, "no-default-keyring", 0, "\r" }, - { 521, "list-packets",0,N_("list only the sequence of packets")}, - { 522, "no-greeting", 0, "\r" }, - { 526, "no-verbose", 0, "\r"}, - { 531, "list-trustdb",0 , "\r"}, - { 533, "list-trust-path",0, "\r"}, - { 532, "quick-random", 0, "\r"}, - { 534, "no-comment", 0, N_("do not write comment packets")}, - { 535, "completes-needed", 1, N_("(default is 1)")}, - { 536, "marginals-needed", 1, N_("(default is 3)")}, - { 538, "trustdb-name", 2, "\r" }, - { 540, "no-secmem-warning", 0, "\r" }, /* dummy */ - { 543, "no-options", 0, "\r" }, /* shortcut for --options /dev/null */ - { 544, "homedir", 2, "\r" }, /* defaults to "~/.gpg" */ - { 545, "no-batch", 0, "\r" }, - { 546, "dearmor", 0, N_("De-Armor a file or stdin") }, - { 547, "enarmor", 0, N_("En-Armor a file or stdin") }, - - {0} }; - ARGPARSE_ARGS pargs; - IOBUF a; - int rc=0; - int orig_argc; - char **orig_argv; - const char *fname, *fname_print; - STRLIST remusr= NULL, locusr=NULL; - int nrings=0, sec_nrings=0; - armor_filter_context_t afx; - FILE *configfp = NULL; - char *configname = NULL; - unsigned configlineno; - int parse_verbose = 0; - int default_config =1; - int errors=0; - int default_keyring = 1; - int greeting = 1; - enum cmd_values cmd = 0; - const char *trustdb_name = NULL; - - - secmem_init( 0 ); /* disable use of secmem */ - - log_set_name("gpgm"); - i18n_init(); - opt.compress = -1; /* defaults to standard compress level */ - opt.def_cipher_algo = CIPHER_ALGO_BLOWFISH; - opt.def_pubkey_algo = PUBKEY_ALGO_ELGAMAL; - opt.def_digest_algo = DIGEST_ALGO_RMD160; - opt.completes_needed = 1; - opt.marginals_needed = 3; - opt.homedir = getenv("GNUPGHOME"); - if( !opt.homedir || !*opt.homedir ) { - #ifdef __MINGW32__ - opt.homedir = "c:/gnupg"; - #else - opt.homedir = "~/.gnupg"; - #endif - } - - /* check wether we have a config file on the commandline */ - orig_argc = argc; - orig_argv = argv; - pargs.argc = &argc; - pargs.argv = &argv; - pargs.flags= 1; /* do not remove the args */ - while( arg_parse( &pargs, opts) ) { - if( pargs.r_opt == 'v' ) - parse_verbose++; - else if( pargs.r_opt == 518 ) { - /* yes there is one, so we do not try the default one, but - * read the option file when it is encountered at the commandline - */ - default_config = 0; - } - else if( pargs.r_opt == 543 ) - default_config = 0; /* --no-options */ - else if( pargs.r_opt == 544 ) - opt.homedir = pargs.r.ret_str; - } - - if( default_config ) - configname = make_filename(opt.homedir, "options", NULL ); - - argc = orig_argc; - argv = orig_argv; - pargs.argc = &argc; - pargs.argv = &argv; - pargs.flags= 1; /* do not remove the args */ - next_pass: - if( configname ) { - configlineno = 0; - configfp = fopen( configname, "r" ); - if( !configfp ) { - if( default_config ) { - if( parse_verbose > 1 ) - log_info(_("note: no default option file '%s'\n"), configname ); - } - else - log_fatal(_("option file '%s': %s\n"), - configname, strerror(errno) ); - m_free(configname); configname = NULL; - } - if( parse_verbose > 1 ) - log_info(_("reading options from '%s'\n"), configname ); - default_config = 0; - } - - while( optfile_parse( configfp, configname, &configlineno, - &pargs, opts) ) { - switch( pargs.r_opt ) { - case 'v': opt.verbose++; - opt.list_sigs=1; - break; - case 'o': opt.outfile = pargs.r.ret_str; break; - case 'k': set_cmd( &cmd, aKMode ); break; - case 'c': set_cmd( &cmd, aKModeC ); break; - case 500: opt.batch = 1; greeting = 0; break; - case 501: opt.answer_yes = 1; break; - case 502: opt.answer_no = 1; break; - case 508: opt.check_sigs = 1; opt.list_sigs = 1; break; - case 509: add_keyring(pargs.r.ret_str); nrings++; break; - case 510: opt.debug |= pargs.r.ret_ulong; break; - case 511: opt.debug = ~0; break; - case 512: set_status_fd( pargs.r.ret_int ); break; - case 513: set_cmd( &cmd, aPrimegen); break; - case 514: set_cmd( &cmd, aTest); break; - case 515: opt.fingerprint = 1; break; - case 516: set_cmd( &cmd, aPrintMDs); break; - case 517: add_secret_keyring(pargs.r.ret_str); sec_nrings++; break; - case 518: - /* config files may not be nested (silently ignore them) */ - if( !configfp ) { - m_free(configname); - configname = m_strdup(pargs.r.ret_str); - goto next_pass; - } - break; - case 519: opt.no_armor=1; opt.armor=0; break; - case 520: default_keyring = 0; break; - case 521: set_cmd( &cmd, aListPackets); break; - case 522: greeting = 0; break; - case 523: set_passphrase_fd( pargs.r.ret_int ); break; - case 526: opt.verbose = 0; opt.list_sigs=0; break; - case 527: - opt.def_cipher_algo = string_to_cipher_algo(pargs.r.ret_str); - break; - case 528: - opt.def_pubkey_algo = string_to_pubkey_algo(pargs.r.ret_str); - break; - case 529: - opt.def_digest_algo = string_to_digest_algo(pargs.r.ret_str); - break; - case 531: set_cmd( &cmd, aListTrustDB); break; - case 532: quick_random_gen(1); break; - case 533: set_cmd( &cmd, aListTrustPath); break; - case 534: opt.no_comment=1; break; - case 535: opt.completes_needed = pargs.r.ret_int; break; - case 536: opt.marginals_needed = pargs.r.ret_int; break; - case 538: trustdb_name = pargs.r.ret_str; break; - case 540: break; /*dummy*/ - case 543: break; /* no-options */ - case 544: opt.homedir = pargs.r.ret_str; break; - case 545: opt.batch = 0; break; - case 546: set_cmd( &cmd, aDeArmor); break; - case 547: set_cmd( &cmd, aEnArmor); break; - default : errors++; pargs.err = configfp? 1:2; break; - } - } - if( configfp ) { - fclose( configfp ); - configfp = NULL; - m_free(configname); configname = NULL; - goto next_pass; - } - m_free( configname ); configname = NULL; - if( !opt.def_cipher_algo || check_cipher_algo(opt.def_cipher_algo) ) { - log_error(_("selected cipher algorithm is invalid\n")); - errors++; - } - if( !opt.def_pubkey_algo || check_pubkey_algo(opt.def_pubkey_algo) ) { - log_error(_("selected pubkey algorithm is invalid\n")); - errors++; - } - if( !opt.def_digest_algo || check_digest_algo(opt.def_digest_algo) ) { - log_error(_("selected digest algorithm is invalid\n")); - errors++; - } - if( opt.completes_needed < 1 ) { - log_error(_("completes-needed must be greater than 0\n")); - errors++; - } - if( opt.marginals_needed < 2 ) { - log_error(_("marginals-needed must be greater than 1\n")); - errors++; - } - if( errors ) - g10_exit(2); - - write_status( STATUS_ENTER ); - - set_debug(); - if( cmd == aKMode || cmd == aKModeC ) { /* kludge to be compatible to pgp */ - if( cmd == aKModeC ) { - opt.fingerprint = 1; - cmd = aKMode; - } - opt.list_sigs = 0; - if( opt.verbose > 2 ) - opt.check_sigs++; - if( opt.verbose > 1 ) - opt.list_sigs++; - - opt.verbose = opt.verbose > 1; - } - if( opt.verbose > 1 ) - set_packet_list_mode(1); - if( greeting ) { - tty_printf("%s %s; %s\n", strusage(11), strusage(13), strusage(14) ); - tty_printf("%s", strusage(15) ); - } - - if( cmd != aDeArmor && cmd != aEnArmor ) { - if( !sec_nrings || default_keyring ) { /* add default secret rings */ - char *p = make_filename(opt.homedir, "secring.gpg", NULL ); - add_secret_keyring(p); - m_free(p); - } - if( !nrings || default_keyring ) { /* add default ring */ - char *p = make_filename(opt.homedir, "pubring.gpg", NULL ); - add_keyring(p); - m_free(p); - } - } - - if( argc ) { - fname_print = fname = *argv; - } - else { - fname_print = "[stdin]"; - fname = NULL; - if( get_passphrase_fd() == 0 ) { - /* reading data and passphrase form stdin: - * we assume the first line is the passphrase, so - * we read it now - */ - /* FIXME: doit */ - } - } - - switch( cmd ) { - case aPrimegen: - case aPrintMDs: - case aDeArmor: - case aEnArmor: - break; - case aListTrustDB: rc = init_trustdb( argc? 1:0, trustdb_name ); break; - default: rc = init_trustdb(1, trustdb_name ); break; - } - if( rc ) - log_error(_("failed to initialize the TrustDB: %s\n"), g10_errstr(rc)); - - - switch( cmd ) { - case aKMode: /* list keyring */ - if( !argc ) { /* list the default public keyrings */ - int i, seq=0; - const char *s; - - while( (s=get_keyring(seq++)) ) { - if( !(a = iobuf_open(s)) ) { - log_error(_("can't open '%s'\n"), s); - continue; - } - if( seq > 1 ) - putchar('\n'); - printf("%s\n", s ); - for(i=strlen(s); i; i-- ) - putchar('-'); - putchar('\n'); - - proc_packets( a ); - iobuf_close(a); - } - - } - else if( argc == 1) { /* list the given keyring */ - if( !(a = iobuf_open(fname)) ) - log_fatal(_("can't open '%s'\n"), fname_print); - proc_packets( a ); - iobuf_close(a); - } - else - usage(1); - break; - - case aDeArmor: - if( argc > 1 ) - wrong_args("--dearmor [file]"); - rc = dearmor_file( argc? *argv: NULL ); - if( rc ) - log_error(_("dearmoring failed: %s\n"), g10_errstr(rc)); - break; - - case aEnArmor: - if( argc > 1 ) - wrong_args("--enarmor [file]"); - rc = enarmor_file( argc? *argv: NULL ); - if( rc ) - log_error(_("enarmoring failed: %s\n"), g10_errstr(rc)); - break; - - - case aPrimegen: - if( argc == 1 ) { - mpi_print( stdout, generate_public_prime( atoi(argv[0]) ), 1); - putchar('\n'); - } - else if( argc == 2 ) { - mpi_print( stdout, generate_elg_prime( atoi(argv[0]), - atoi(argv[1]), NULL,NULL ), 1); - putchar('\n'); - } - else if( argc == 3 ) { - MPI g = mpi_alloc(1); - mpi_print( stdout, generate_elg_prime( atoi(argv[0]), - atoi(argv[1]), g, NULL ), 1); - printf("\nGenerator: "); - mpi_print( stdout, g, 1 ); - putchar('\n'); - mpi_free(g); - } - else - usage(1); - break; - - case aPrintMDs: - if( !argc ) - print_mds(NULL); - else { - for(; argc; argc--, argv++ ) - print_mds(*argv); - } - break; - - case aTest: do_test( argc? atoi(*argv): 1 ); break; - - case aListTrustDB: - if( !argc ) - list_trustdb(NULL); - else { - for( ; argc; argc--, argv++ ) - list_trustdb( *argv ); - } - break; - - case aListTrustPath: - if( argc != 2 ) - wrong_args("--list-trust-path [-- -] "); - list_trust_path( atoi(*argv), argv[1] ); - break; - - case aListPackets: - opt.list_packets=1; - default: /* do regular maintenace tasks */ - if( argc > 1 ) - usage(1); - if( !(a = iobuf_open(fname)) ) - log_fatal(_("can't open '%s'\n"), fname_print); - if( !opt.no_armor ) { - /* push the armor filter, so it can peek at the input data */ - memset( &afx, 0, sizeof afx); - iobuf_push_filter( a, armor_filter, &afx ); - } - if( cmd == aListPackets ) { - set_packet_list_mode(1); - opt.list_packets=1; - } - proc_packets( a ); - iobuf_close(a); - break; - } - - /* cleanup */ - FREE_STRLIST(remusr); - FREE_STRLIST(locusr); - g10_exit(0); -} - - -void -g10_exit( int rc ) -{ - if( opt.verbose ) - secmem_dump_stats(); - secmem_term(); - rc = rc? rc : log_get_errorcount(0)? 2:0; - write_status( STATUS_LEAVE ); - exit(rc ); -} - - -static void -print_hex( byte *p, size_t n ) -{ - int i; - - if( n == 20 ) { - for(i=0; i < n ; i++, i++, p += 2 ) { - if( i == 10 ) - putchar(' '); - printf(" %02X%02X", *p, p[1] ); - } - } - else { - for(i=0; i < n ; i++, p++ ) { - if( i && !(i%8) ) - putchar(' '); - printf(" %02X", *p ); - } - } -} - -static void -print_mds( const char *fname ) -{ - FILE *fp; - char buf[1024]; - size_t n; - MD_HANDLE md; - - if( !fname ) { - fp = stdin; - fname = "[stdin]"; - } - else - fp = fopen( fname, "rb" ); - if( !fp ) { - log_error("%s: %s\n", fname, strerror(errno) ); - return; - } - - md = md_open( DIGEST_ALGO_MD5, 0 ); - md_enable( md, DIGEST_ALGO_RMD160 ); - md_enable( md, DIGEST_ALGO_SHA1 ); - - while( (n=fread( buf, 1, DIM(buf), fp )) ) - md_write( md, buf, n ); - if( ferror(fp) ) - log_error("%s: %s\n", fname, strerror(errno) ); - else { - md_final(md); - printf( "%s: MD5 =", fname ); print_hex(md_read(md, DIGEST_ALGO_MD5), 16 ); - printf("\n%s: RMD160 =", fname ); print_hex(md_read(md, DIGEST_ALGO_RMD160), 20 ); - printf("\n%s: SHA1 =", fname ); print_hex(md_read(md, DIGEST_ALGO_SHA1), 20 ); - putchar('\n'); - } - - - md_close(md); - - if( fp != stdin ) - fclose(fp); -} - - - -static void -do_test(int times) -{ - MPI base[4]; - MPI exp[4]; - MPI t1 = mpi_alloc(50); - MPI t2 = mpi_alloc(50); - MPI t3 = mpi_alloc(50); - MPI tmp= mpi_alloc(50); - MPI m = mpi_alloc(50); - MPI res = mpi_alloc(50); - - mpi_fromstr( m, "0x10000000000000000000000000" ); - base[0] = mpi_alloc_set_ui( 3 ); - mpi_fromstr( base[0], "0x145984358945989898495ffdd13" ); - base[1] = mpi_alloc_set_ui( 5 ); - mpi_fromstr( base[1], "0x000effff9999000000001100001" ); - base[2] = mpi_alloc_set_ui( 2 ); - mpi_fromstr( base[2], "0x499eeeaaaaa0444444545466672" ); - base[3] = NULL; - exp[0] = mpi_alloc_set_ui( 30 ); - exp[1] = mpi_alloc_set_ui( 10 ); - mpi_fromstr( exp[1], "0x3457878888888888aabbbccccc1" ); - exp[2] = mpi_alloc_set_ui( 24 ); - exp[3] = NULL; - - mpi_powm( t1, base[0], exp[0], m ); - mpi_powm( t2, base[1], exp[1], m ); - mpi_powm( t3, base[2], exp[2], m ); - mpi_mulm( tmp, t1, t2, m ); - mpi_mulm( t1, tmp, t3, m ); - log_mpidump("X=", t1 ); - - - mpi_mulpowm( res, base, exp, m ); - log_mpidump("X=", res ); - - - m_check(NULL); -} - diff --git a/g10/getkey.c b/g10/getkey.c index dd72f6df0..b528ed782 100644 --- a/g10/getkey.c +++ b/g10/getkey.c @@ -323,6 +323,8 @@ get_pubkey_byname( PKT_public_cert *pkc, const char *name ) int i; char buf[9]; + if( *s == '0' && s[1] == 'x' && isxdigit(s[2]) ) + s += 2; /*kludge to allow 0x034343434 */ for(i=0; isxdigit(s[i]); i++ ) ; if( s[i] && !isspace(s[i]) ) /* not terminated by EOS or blank*/ @@ -418,6 +420,33 @@ get_seckey( PKT_secret_cert *skc, u32 *keyid ) return rc; } +/**************** + * Check wether the secret key is available + * Returns: 0 := key is available + * G10ERR_NO_SECKEY := not availabe + */ +int +seckey_available( u32 *keyid ) +{ + PKT_secret_cert *skc; + STRLIST sl; + int rc=0; + + skc = m_alloc_clear( sizeof *skc ); + for(sl = secret_keyrings; sl; sl = sl->next ) + if( !(rc=scan_secret_keyring( skc, keyid, NULL, sl->d )) ) + goto found; + /* fixme: look at other places */ + goto leave; + + found: + leave: + free_secret_cert( skc ); + return rc; +} + + + /**************** * Get a secret key by name and store it into skc * If NAME is NULL use the default certificate diff --git a/g10/keydb.h b/g10/keydb.h index 7f49f3545..a115578da 100644 --- a/g10/keydb.h +++ b/g10/keydb.h @@ -107,6 +107,7 @@ void cache_user_id( PKT_user_id *uid, u32 *keyid ); int get_pubkey( PKT_public_cert *pkc, u32 *keyid ); int get_pubkey_byname( PKT_public_cert *pkc, const char *name ); int get_seckey( PKT_secret_cert *skc, u32 *keyid ); +int seckey_available( u32 *keyid ); int get_seckey_byname( PKT_secret_cert *skc, const char *name, int unlock ); int enum_secret_keys( void **context, PKT_secret_cert *skc ); char*get_user_id_string( u32 *keyid ); diff --git a/g10/keygen.c b/g10/keygen.c index ed16d5288..e8f9382ad 100644 --- a/g10/keygen.c +++ b/g10/keygen.c @@ -299,8 +299,10 @@ generate_keypair() char *aname, *acomment, *amail; #ifndef TEST_ALGO - if( opt.batch || opt.answer_yes || opt.answer_no ) - log_fatal(_("Key generation can only be used in interactive mode\n")); + if( opt.batch || opt.answer_yes || opt.answer_no ) { + log_error(_("Key generation can only be used in interactive mode\n")); + return; + } tty_printf(_("Please select the algorithm to use:\n" " (1) ElGamal is the suggested one.\n" diff --git a/g10/keylist.c b/g10/keylist.c new file mode 100644 index 000000000..15f3c2f19 --- /dev/null +++ b/g10/keylist.c @@ -0,0 +1,48 @@ +/* keylist.c + * Copyright (C) 1998 Free Software Foundation, Inc. + * + * This file is part of GNUPG. + * + * GNUPG is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * GNUPG is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + */ + +#include +#include +#include +#include +#include +#include + +#include "options.h" +#include "packet.h" +#include "errors.h" +#include "keydb.h" +#include "memory.h" +#include "util.h" +#include "trustdb.h" +#include "ttyio.h" +#include "i18n.h" + + +/**************** + * List the keys in a special forma which is extensible and easy to parse + * If NAMES is NULL; the complte keyring is listed + * + */ +void +ext_key_list( STRLIST names ) +{ +} + diff --git a/g10/main.h b/g10/main.h index ef8180f06..eef3d7377 100644 --- a/g10/main.h +++ b/g10/main.h @@ -53,7 +53,7 @@ int sign_file( STRLIST filenames, int detached, STRLIST locusr, int clearsign_file( const char *fname, STRLIST locusr, const char *outfile ); int sign_key( const char *username, STRLIST locusr ); int edit_keysigs( const char *username ); -int delete_key( const char *username ); +int delete_key( const char *username, int secure ); int change_passphrase( const char *username ); /*-- sig-check.c --*/ @@ -97,4 +97,7 @@ int enarmor_file( const char *fname ); /*-- revoke.c --*/ int gen_revoke( const char *uname ); +/*-- keylist.c --*/ +void ext_key_list( STRLIST names ); + #endif /*G10_MAIN_H*/ diff --git a/g10/sign.c b/g10/sign.c index 55e5fbdd7..9d8208870 100644 --- a/g10/sign.c +++ b/g10/sign.c @@ -35,6 +35,7 @@ #include "main.h" #include "filter.h" #include "ttyio.h" +#include "i18n.h" @@ -855,21 +856,23 @@ edit_keysigs( const char *username ) /**************** - * Eine public key aus dem keyring entfernen. + * Delete a public or secret key from a keyring. */ int -delete_key( const char *username ) +delete_key( const char *username, int secret ) { int rc = 0; KBNODE keyblock = NULL; KBNODE node; KBPOS kbpos; PKT_public_cert *pkc; - u32 pkc_keyid[2]; + PKT_secret_cert *skc; + u32 keyid[2]; int okay=0; /* search the userid */ - rc = find_keyblock_byname( &kbpos, username ); + rc = secret? find_secret_keyblock_byname( &kbpos, username ) + : find_keyblock_byname( &kbpos, username ); if( rc ) { log_error("%s: user not found\n", username ); goto leave; @@ -878,40 +881,77 @@ delete_key( const char *username ) /* read the keyblock */ rc = read_keyblock( &kbpos, &keyblock ); if( rc ) { - log_error("%s: certificate read problem: %s\n", username, g10_errstr(rc) ); + log_error("%s: read problem: %s\n", username, g10_errstr(rc) ); goto leave; } /* get the keyid from the keyblock */ - node = find_kbnode( keyblock, PKT_PUBLIC_CERT ); + node = find_kbnode( keyblock, secret? PKT_SECRET_CERT:PKT_PUBLIC_CERT ); if( !node ) { - log_error("Oops; public key not found anymore!\n"); + log_error("Oops; key not found anymore!\n"); rc = G10ERR_GENERAL; goto leave; } - pkc = node->pkt->pkt.public_cert; - keyid_from_pkc( pkc, pkc_keyid ); + if( secret ) { + skc = node->pkt->pkt.secret_cert; + keyid_from_skc( skc, keyid ); + } + else { + pkc = node->pkt->pkt.public_cert; + keyid_from_pkc( pkc, keyid ); + rc = seckey_available( keyid ); + if( !rc ) { + log_error(_( + "there is a secret key for this public key!\n")); + log_info(_( + "use option \"--delete-secret-key\" to delete it first.\n")); + rc = -1; + } + else if( rc != G10ERR_NO_SECKEY ) + log_error("%s: get secret key: %s\n", username, g10_errstr(rc) ); + else + rc = 0; + } - if( opt.batch && opt.answer_yes ) + if( rc ) + rc = 0; + else if( opt.batch && secret ) + log_error(_("can't do that in batch-mode\n")); + else if( opt.batch && opt.answer_yes ) okay++; else if( opt.batch ) - log_error("can't do that in batch-mode without \"--yes\"\n"); + log_error(_("can't do that in batch-mode without \"--yes\"\n")); else { char *p; size_t n; - tty_printf("pub %4u%c/%08lX %s ", - nbits_from_pkc( pkc ), - pubkey_letter( pkc->pubkey_algo ), - pkc_keyid[1], datestr_from_pkc(pkc) ); - p = get_user_id( pkc_keyid, &n ); + if( secret ) + tty_printf("sec %4u%c/%08lX %s ", + nbits_from_skc( skc ), + pubkey_letter( skc->pubkey_algo ), + keyid[1], datestr_from_skc(skc) ); + else + tty_printf("pub %4u%c/%08lX %s ", + nbits_from_pkc( pkc ), + pubkey_letter( pkc->pubkey_algo ), + keyid[1], datestr_from_pkc(pkc) ); + p = get_user_id( keyid, &n ); tty_print_string( p, n ); m_free(p); tty_printf("\n\n"); - p = tty_get("Delete this key from the keyring? "); + p = tty_get(_("Delete this key from the keyring? ")); tty_kill_prompt(); + if( secret && answer_is_yes(p)) { + /* I think it is not required to check a passphrase; if + * the user is so stupid to let others access his secret keyring + * (and has no backup) - it is up him to read some very + * basic texts about security. + */ + m_free(p); + p = tty_get(_("This is a secret key! - really delete? ")); + } if( answer_is_yes(p) ) okay++; m_free(p); diff --git a/g10/trustdb.c b/g10/trustdb.c index 9f06bca92..8c9088b91 100644 --- a/g10/trustdb.c +++ b/g10/trustdb.c @@ -836,7 +836,7 @@ verify_own_certs() while( !(rc=enum_secret_keys( &enum_context, skc) ) ) { /* fixed: to be sure that it is a secret key of our own, * we should check it, but this needs a passphrase - * for every key and this boring for the user. + * for every key and this is boring for the user. * Solution: Sign the secring and the trustring * and verify this signature during * startup