From f477447d9af4097e8c5d4c15a3dd381237e93ee2 Mon Sep 17 00:00:00 2001 From: Werner Koch Date: Fri, 13 Feb 1998 20:58:50 +0000 Subject: [PATCH] added option export --- ChangeLog | 6 +- INSTALL | 47 +++++++++ Makefile.am | 3 +- Makefile.in | 3 +- NEWS | 6 ++ README | 53 +++++++---- THANKS | 3 + TODO | 11 +++ VERSION | 2 +- checks/checkit | 71 +++++++------- cipher/ChangeLog | 0 cipher/Makefile.in | 1 - configure.in | 14 +-- g10/ChangeLog | 27 ++++++ g10/Makefile.in | 1 - g10/encode.c | 2 +- g10/export.c | 100 ++++++++++++++++++- g10/g10.c | 232 ++++++++++++++++++++++++++------------------- g10/import.c | 35 +++++-- g10/kbnode.c | 9 +- g10/keydb.h | 3 + g10/keygen.c | 14 ++- g10/parse-packet.c | 2 + g10/pubkey-enc.c | 68 +++++++------ g10/ringedit.c | 141 ++++++++++++++++++++++++++- g10/sign.c | 4 +- include/ChangeLog | 0 include/distfiles | 1 + include/util.h | 5 +- mpi/ChangeLog | 0 mpi/Makefile.in | 1 - mpi/mpicoder.c | 2 +- mpi/mpiutil.c | 7 ++ po/ChangeLog | 5 - scripts/mkdiff | 13 ++- tools/ChangeLog | 0 tools/Makefile.in | 1 - util/ChangeLog | 18 ++++ util/Makefile.in | 1 - util/argparse.c | 21 +++- util/iobuf.c | 9 ++ util/logger.c | 69 +++++++------- zlib/Makefile.am | 7 ++ 43 files changed, 734 insertions(+), 284 deletions(-) create mode 100644 cipher/ChangeLog create mode 100644 g10/ChangeLog create mode 100644 include/ChangeLog create mode 100644 mpi/ChangeLog create mode 100644 tools/ChangeLog create mode 100644 util/ChangeLog diff --git a/ChangeLog b/ChangeLog index 1d2526595..ad7644984 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,5 @@ -Tue Feb 10 11:57:23 1998 Werner Koch (wk@frodo) - - * ddd/hhhh: +Fri Feb 13 19:43:41 1998 Werner Koch (wk@isil.d.shuttle.de) + * configure.in : Fixed zlib stuff + * Makefile.am: Likewise diff --git a/INSTALL b/INSTALL index c5242221e..13ab8a523 100644 --- a/INSTALL +++ b/INSTALL @@ -1,3 +1,50 @@ + +Please read the Basic Installation section somewhere below. + +Configure options for G10 +========================= + +--with-zlib Forces usage of the local zlib sources. Default is + to use the (sahred) library of the system. + +--without-nls Disable NLS support + +--enable-m-debug Compile with the integrated malloc debugging stuff. + This makes the program slower but is checks every + free operation and can be used to create statistics + of memory usage. If this option is used the program + option "--debug 32" displays every call to a a malloc + function (this makes the program *really* slow), the + option "--debug 128" displays a memory statistic after + the program run. + +Problems +======== + +If you have compile problems, use the configure options "--with-zlib" and +"--without-nls". + +I cant check alls assembles files; so if you have problems assembling them +(or the program crashes), simply delete the files in the mpi/ directory. +The configure scripts may consider several subdirectories to get all +available assembler files; be sure to delete the correct ones. The +assembler replacements are in C and in mpi/generic; never delete udiv-qrnnd.S +in any CPU directory, because there maybe no C substitute. +Don't forget to delete "config.cache" and run "./config.status --recheck". + + + + +Installation +============ +G10 is not installed as suid:root; if you want to use it, do it manually +(only g10, not g10maint). + +You have to create the ~/.g10 directory manually. Your first action after +this should be to create a key pair: "g10 --gen-key". + + + Basic Installation ================== diff --git a/Makefile.am b/Makefile.am index c138df3c9..9c07b7656 100644 --- a/Makefile.am +++ b/Makefile.am @@ -1,10 +1,9 @@ ## Process this file with automake to produce Makefile.in -SUBDIRS = intl po util mpi cipher @ZLIB_SUBDIR@ tools g10 +SUBDIRS = intl po zlib util mpi cipher tools g10 EXTRA_DIST = VERSION - tar: clean cd ..; tar czvf ~/bkup/g10-`date +%d%m`.tar.gz src diff --git a/Makefile.in b/Makefile.in index 04bcc5374..d5dd00b69 100644 --- a/Makefile.in +++ b/Makefile.in @@ -85,9 +85,8 @@ POSUB = @POSUB@ RANLIB = @RANLIB@ VERSION = @VERSION@ ZLIBS = @ZLIBS@ -ZLIB_SUBDIR = @ZLIB_SUBDIR@ -SUBDIRS = intl po util mpi cipher @ZLIB_SUBDIR@ tools g10 +SUBDIRS = intl po zlib util mpi cipher tools g10 EXTRA_DIST = VERSION ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 mkinstalldirs = $(SHELL) $(top_srcdir)/scripts/mkinstalldirs diff --git a/NEWS b/NEWS index 748d693f8..a82c08af3 100644 --- a/NEWS +++ b/NEWS @@ -1,3 +1,9 @@ +Noteworthy changes in version 0.2.6 +----------------------------------- + + * Option "--export" works. + + Noteworthy changes in version 0.2.5 ----------------------------------- diff --git a/README b/README index 91d3ac983..f5dc7a82e 100644 --- a/README +++ b/README @@ -2,13 +2,24 @@ G10 - The GNU Encryption and Signing Tool ------------------------------------------ + THIS IS ALPHA SOFTWARE, EXPECT BUGS AND UNIMPLEMENTED STUFF. + IT MAY HAPPEN THAT SOME DATA FORMATS OR PROGRAMM OPTIONS + CHANGE WITH THE NEXT VERSION. - THIS IS VERSION IS ONLY A TEST VERSION ! YOU SHOULD NOT - USE IT FOR OTHER PURPOSES THAN EVALUATING THE CURRENT CODE. + On a Linux box (version 2.x.x, alpha or x86 CPU) it should + work reliable. You may create your key on such a machine and + use it. Please verify the tar file; there is a PGP and a G10 + signature available. My PGP key is well known and published in + the "Global Trust Register for 1998", ISBN 0-9532397-0-5. - * The data format may change in the next version! + I have included my pubring as "g10/pubring.10", which contains + the key used to make G10 signatures: + "pub 1312G/FF3EAA0B 1998-02-09 Werner Koch " + "Key fingerprint = 8489 6CD0 1851 0E33 45DA CD67 036F 11B8 FF3E AA0B" - * Some features are not yet implemented + You may add it to your G10 pubring and use it in the future to + verify new releases. Because you verified the tar file containing + this file here, you can be sure that the above fingerprint is correct. Please subscribe to g10@net.lut.ac.uk by sending a mail with @@ -42,19 +53,20 @@ Installation ------------ + See the file INSTALL. Here is a quick summary: + 1) "./configure" - to enable the integrated malloc debugging stuff, use: - - "./configure --enable-m-debug" - 2) "make" 3) "make install" 4) You end up with a binary "g10" in /usr/local/bin - 5) create a directory ".g10" under your hoem directory ("mkdir ~/.g10") + 5) Optional, but suggested: install the program "g10" as suid root. + + 6) Create a directory ".g10" under your home directory ("mkdir ~/.g10") + @@ -241,20 +253,20 @@ you are asked for the passphrase, so that G10 is able to look at the inner structure of a encrypted packet. - --quick-random + g10maint --quick-random Do not use the stroing random generator but a faster one. This can be used to generate keys for tests; those are marked as insecure. - --list-trustdb + g10maint --list-trustdb List the contents of the trustdb in a human readable format - --list-trustdb + g10maint --list-trustdb List the tree of certificates for the given usernames - --list-trust-path depth username + g10maint --list-trust-path depth username List the possible trust paths for the given username, up to the specified depth. If depth is negative, duplicate introducers are not listed, @@ -263,25 +275,25 @@ using a negative number). This option may create new entries in the trustdb. - --print-mds filenames + g10maint --print-mds filenames List all available message digest values for the fiven filenames - --gen-prime n + g10maint --gen-prime n Generate and print a simple prime number of size n - --gen-prime n q + g10maint --gen-prime n q Generate a prime number suitable for ElGamal signatures of size n with a q as largest primefactor of n-1. - --gen-prime n q 1 + g10maint --gen-prime n q 1 Ditto, but calculate a generator too. - For more options/commands see the file g10/OPTIONS. + For more options/commands see the file g10/OPTIONS, or use "g10 --help" Debug Flags @@ -311,7 +323,10 @@ but for now I stick to my own formatting rules. The primary FTP site is "ftp://ftp.guug.de/pub/gcrypt/" - The primary WWW page is "http://www.d.shuttle.de/isil/g10.html" + The primary WWW page is "http://www.d.shuttle.de/isil/crypt/g10.html" + + If you like, send your keys to ; use + "g10 --export --armor | mail g10-keys@isil.d.shuttle.de" to do this. Please direct bug reports to or better post them to the mailing list . diff --git a/THANKS b/THANKS index 4f53c92fb..315b7c18b 100644 --- a/THANKS +++ b/THANKS @@ -9,7 +9,10 @@ Daniel Eisenbud eisenbud@cs.swarthmore.edu Detlef Lannert lannert@lannert.rz.uni-duesseldorf.de Ernst Molitor ernst.molitor@uni-bonn.de Hendrik Buschkamp buschkamp@rheumanet.org +Jean-loup Gailly gzip@prep.ai.mit.edu Jens Bachem bachem@rrz.uni-koeln.de +Mark Adler madler@alumni.caltech.edu +Martin Schulte schulte@thp.uni-koeln.de Peter Gutmann pgut001@cs.auckland.ac.nz Ralph Gillen gillen@theochem.uni-duesseldorf.de Thomas Roessler roessler@guug.de diff --git a/TODO b/TODO index baaa1412f..7b193c6b1 100644 --- a/TODO +++ b/TODO @@ -23,4 +23,15 @@ we have a self-signature -> put this stuff into a kind of directory record, as it does not belong to the pubkey record? + * add an option to create a new user id and to reorder the sequence of + them, so that the preferred emal address comes first. We need to + add some logic, which guarantees, that only one user-id can be signed by + others. This prevents extensive growing of the public key certificate + due to the bad usage of signing every user id. You get no extra + security by key signatures for every user id. I consider this + behaviour of PGP a bug, introduced, becaus PGP does't require a + self-signature. New user ids will only have your self signature to bind + them to your key and because the user id which is signed by others has + also be signed by you, all user-ids are bound together. + diff --git a/VERSION b/VERSION index 3a4036fb4..53a75d673 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -0.2.5 +0.2.6 diff --git a/checks/checkit b/checks/checkit index 09cf7ac8d..4c221ce56 100755 --- a/checks/checkit +++ b/checks/checkit @@ -44,11 +44,9 @@ cleanup () { run_g10 () { - eval HOME=. ../g10/g10 $* - if [ $? != 0 ] ; then - g10_err=$? + if ! eval HOME=. ../g10/g10 $* ; then echo "(HOME=. ../g10/g10 $*) failed" >&2 - error "g10 failed: $g10_err" >&2 + exit 1 fi } @@ -58,7 +56,7 @@ run_g10 () { set -e pgmname=$(basename $0) -#trap cleanup EXIT SIGHUP SIGINT SIGQUIT +trap cleanup SIGHUP SIGINT SIGQUIT # some checks @@ -79,7 +77,7 @@ EOF # print the G10 version run_g10 --version -# intialize the trustdb + info Checking decryption for i in $plain_files ; do @@ -87,21 +85,21 @@ for i in $plain_files ; do cmp $i y || error "$i: mismatch" done -#info Checking cleartext signatures -## There is a minor glitch, which appends a lf to the cleartext. -## I do not consider that a bug, but I have to use the head .. mimic. -## It is not clear what should happen to leading LFs, we must -## change the defintion of cleartext, so that only 1 empty line -## must follow the headers, but some specs say: any number of empty lines .. -## clean-sat removes leading LFs -## I know that this does not work for random data files (due to large lines -## or what ever) - I hope we can live with it. -#for i in $plain_files; do -# echo "$usrpass1" | run_g10 --passphrase-fd 0 -sat -o x --yes $i -# run_g10 -o y --yes x -# ../tools/clean-sat < $i > z -# head -c $[ $(cat y | wc -c) - 1 ] y | diff - z || error "$i: mismatch" -#done +info Checking cleartext signatures +# There is a minor glitch, which appends a lf to the cleartext. +# I do not consider that a bug, but I have to use the head .. mimic. +# It is not clear what should happen to leading LFs, we must +# change the defintion of cleartext, so that only 1 empty line +# must follow the headers, but some specs say: any number of empty lines .. +# clean-sat removes leading LFs +# I know that this does not work for random data files (due to large lines +# or what ever) - I hope we can live with it. +for i in $plain_files; do + echo "$usrpass1" | run_g10 --passphrase-fd 0 -sat -o x --yes $i + run_g10 -o y --yes x + ../tools/clean-sat < $i > z + head -c $[ $(cat y | wc -c) - 1 ] y | diff - z || error "$i: mismatch" +done info Creating some random data files for i in 500 9000 32000 80000; do @@ -109,26 +107,25 @@ for i in 500 9000 32000 80000; do data_files="$data_files data-$i" done -#info Checking armored signatures -#for i in $plain_files $data_files ; do -# echo "$usrpass1" | run_g10 --passphrase-fd 0 -sa -o x --yes $i -# run_g10 -o y --yes x -# cmp $i y || error "$i: mismatch" -#done -# -#info Checking signatures -#for i in $plain_files $data_files; do -# echo "$usrpass1" | run_g10 --passphrase-fd 0 -s -o x --yes $i -# run_g10 -o y --yes x -# cmp $i y || error "$i: mismatch" -#done +info Checking armored signatures +for i in $plain_files $data_files ; do + echo "$usrpass1" | run_g10 --passphrase-fd 0 -sa -o x --yes $i + run_g10 -o y --yes x + cmp $i y || error "$i: mismatch" +done + +info Checking signatures +for i in $plain_files $data_files; do + echo "$usrpass1" | run_g10 --passphrase-fd 0 -s -o x --yes $i + run_g10 -o y --yes x + cmp $i y || error "$i: mismatch" +done info Checking armored encryption for i in $plain_files $data_files ; do - info "file $i" - run_g10 -v -ea -o x --yes -r "$usrname2" $i - run_g10 -v -o y --yes x + run_g10 -ea -o x --yes -r "$usrname2" $i + run_g10 -o y --yes x cmp $i y || error "$i: mismatch" done diff --git a/cipher/ChangeLog b/cipher/ChangeLog new file mode 100644 index 000000000..e69de29bb diff --git a/cipher/Makefile.in b/cipher/Makefile.in index aba727a92..b8fe2a1bb 100644 --- a/cipher/Makefile.in +++ b/cipher/Makefile.in @@ -85,7 +85,6 @@ POSUB = @POSUB@ RANLIB = @RANLIB@ VERSION = @VERSION@ ZLIBS = @ZLIBS@ -ZLIB_SUBDIR = @ZLIB_SUBDIR@ INCLUDES = -I$(top_srcdir)/include EXTRA_DIST = @CIPHER_EXTRA_DIST@ diff --git a/configure.in b/configure.in index 33e1f2f17..1a29bf7a2 100644 --- a/configure.in +++ b/configure.in @@ -162,26 +162,26 @@ AC_SUBST(MPI_EXTRA_ASM_OBJS) dnl Do we have zlib? Must do it here because Solaris failed dnl when compiling a conftest (due to the "-lz" from LIBS). -ZLIBS= -ZLIB_SUBDIR= if test "$g10_force_zlib" = "yes"; then - ZLIBS="\${top_srcdir}/zlib/libzlib.a" - ZLIB_SUBDIR=zlib + ZLIBS="-L\${top_srcdir}/zlib -lzlib" + AM_CONDITIONAL(ENABLE_LOCAL_ZLIB, true) WK_LINK_FILES(zlib/zlib.h, zlib.h ) WK_LINK_FILES(zlib/zconf.h, zconf.h ) else AC_CHECK_HEADERS(zlib.h) if test "$ac_cv_header_zlib_h" = yes ; then LIBS="$LIBS -lz" + ZLIBS= + AM_CONDITIONAL(ENABLE_LOCAL_ZLIB, false) else - ZLIBS="\${top_srcdir}/zlib/libzlib.a" - ZLIB_SUBDIR=zlib + ZLIBS="-L\${top_srcdir}/zlib -lzlib" + AM_CONDITIONAL(ENABLE_LOCAL_ZLIB, true) WK_LINK_FILES(zlib/zlib.h, zlib.h ) WK_LINK_FILES(zlib/zconf.h, zconf.h ) fi fi AC_SUBST(ZLIBS) -AC_SUBST(ZLIB_SUBDIR) + dnl checking whether we have other cipher source files CIPHER_EXTRA_OBJS="" diff --git a/g10/ChangeLog b/g10/ChangeLog new file mode 100644 index 000000000..2bfa48b74 --- /dev/null +++ b/g10/ChangeLog @@ -0,0 +1,27 @@ +Fri Feb 13 20:18:14 1998 Werner Koch (wk@isil.d.shuttle.de) + + * ringedit.c (enum_keyblocks, keyring_enum): New. + +Fri Feb 13 19:33:40 1998 Werner Koch (wk@isil.d.shuttle.de) + + * export.c: Add functionality. + + * keygen.c (generate_keypair): Moved the leading comment behind the + key packet. + * kbnode.c (walk_kbnode): Fixed. + + * g10.c (main): listing armored keys now work. + +Fri Feb 13 16:17:43 1998 Werner Koch (wk@isil.d.shuttle.de) + + * parse-packet.c (parse_publickey, parse_signature): Fixed calls + to mpi_read used for ELG b. + +Fri Feb 13 15:13:23 1998 Werner Koch (wk@isil.d.shuttle.de) + + * g10.c (main): changed formatting of help output. + +Thu Feb 12 22:24:42 1998 Werner Koch (wk@frodo) + + * pubkey-enc.c (get_session_key): rewritten + diff --git a/g10/Makefile.in b/g10/Makefile.in index 63ffc3e6b..afbeebf8f 100644 --- a/g10/Makefile.in +++ b/g10/Makefile.in @@ -85,7 +85,6 @@ POSUB = @POSUB@ RANLIB = @RANLIB@ VERSION = @VERSION@ ZLIBS = @ZLIBS@ -ZLIB_SUBDIR = @ZLIB_SUBDIR@ INCLUDES = -I$(top_srcdir)/include EXTRA_DIST = OPTIONS pubring.g10 diff --git a/g10/encode.c b/g10/encode.c index 04aebefdb..eea7345fa 100644 --- a/g10/encode.c +++ b/g10/encode.c @@ -182,7 +182,7 @@ encode_crypt( const char *filename, STRLIST remusr ) goto leave; } else if( opt.verbose ) - log_error("reading from '%s'\n", filename? filename: "[stdin]"); + log_info("reading from '%s'\n", filename? filename: "[stdin]"); if( !(out = open_outfile( filename, opt.armor? 1:0 )) ) { rc = G10ERR_CREATE_FILE; /* or user said: do not overwrite */ diff --git a/g10/export.c b/g10/export.c index d45c1285f..619d69958 100644 --- a/g10/export.c +++ b/g10/export.c @@ -31,17 +31,109 @@ #include "keydb.h" #include "memory.h" #include "util.h" +#include "main.h" /**************** - * Make a new keyring from all internal keyrings (if no user is given) - * or for all selected users. + * Export the public keys (to standard out or --outout). + * Depending on opt.armor the output is armored. + * If USERS is NULL, the complete ring wil. be exported. */ int export_pubkeys( STRLIST users ) { - log_fatal("Not yet implemented"); - return 0; + int rc = 0; + armor_filter_context_t afx; + compress_filter_context_t zfx; + IOBUF out = NULL; + PACKET pkt; + KBNODE keyblock = NULL; + KBNODE kbctx, node; + KBPOS kbpos; + STRLIST sl; + int all = !users; + int any=0; + + memset( &afx, 0, sizeof afx); + memset( &zfx, 0, sizeof zfx); + init_packet( &pkt ); + + if( !(out = open_outfile( NULL, 0 )) ) { + rc = G10ERR_CREATE_FILE; + goto leave; + } + + if( opt.armor ) { + afx.what = 1; + iobuf_push_filter( out, armor_filter, &afx ); + } + if( opt.compress ) + iobuf_push_filter( out, compress_filter, &zfx ); + + if( all ) { + rc = enum_keyblocks( 0, &kbpos, &keyblock ); + if( rc ) { + if( rc != -1 ) + log_error("enum_keyblocks(open) failed: %s\n", g10_errstr(rc) ); + goto leave; + } + all = 2; + } + + /* use the correct sequence. strlist_last,prev do work correct with + * NULL pointers :-) */ + for( sl=strlist_last(users); sl || all ; sl=strlist_prev( users, sl )) { + if( all ) { /* get the next user */ + rc = enum_keyblocks( 1, &kbpos, &keyblock ); + if( rc == -1 ) /* EOF */ + break; + if( rc ) { + log_error("enum_keyblocks(read) failed: %s\n", g10_errstr(rc)); + break; + } + } + else { + /* search the userid */ + rc = find_keyblock_byname( &kbpos, sl->d ); + if( rc ) { + log_error("%s: user not found: %s\n", sl->d, g10_errstr(rc) ); + rc = 0; + continue; + } + /* read the keyblock */ + rc = read_keyblock( &kbpos, &keyblock ); + } + + if( rc ) { + log_error("certificate read problem: %s\n", g10_errstr(rc)); + goto leave; + } + + /* and write it */ + for( kbctx=NULL; (node = walk_kbnode( keyblock, &kbctx, 0 )); ) { + if( (rc = build_packet( out, node->pkt )) ) { + log_error("build_packet(%d) failed: %s\n", + node->pkt->pkttype, g10_errstr(rc) ); + rc = G10ERR_WRITE_FILE; + goto leave; + } + } + any++; + } + if( rc == -1 ) + rc = 0; + + leave: + if( all == 2 ) + enum_keyblocks( 2, &kbpos, &keyblock ); /* close */ + release_kbnode( keyblock ); + if( rc || !any ) + iobuf_cancel(out); + else + iobuf_close(out); + if( !any ) + log_info("warning: nothing exported\n"); + return rc; } diff --git a/g10/g10.c b/g10/g10.c index b5ce5f7f0..4fbc0f7ab 100644 --- a/g10/g10.c +++ b/g10/g10.c @@ -41,11 +41,85 @@ #include "status.h" +static ARGPARSE_OPTS opts[] = { + + { 300, NULL, 0, N_("\vCommands:\n ") }, + + { '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")}, + { 'e', "encrypt", 0, N_("encrypt data")}, + { 'c', "symmetric", 0, N_("encryption only with symmetric cipher")}, + { 507, "store", 0, N_("store only")}, + { 'd', "decrypt", 0, N_("decrypt data (default)")}, + { '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")}, + { 525, "change-passphrase", 0, N_("change the passphrase of your secret keyring")}, + { 537, "export" , 0, N_("export keys") }, + { 530, "import", 0 , N_("import/merge keys")}, + + { 301, NULL, 0, N_("\v\nOptions:\n ") }, + + { '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")}, + { '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")}, + { 502, "no", 0, N_("assume no on most questions")}, + { 509, "keyring" ,2, N_("add this keyring to the list of keyrings")}, + { 517, "secret-keyring" ,2, N_("add this secret keyring to the list")}, + { 518, "options" , 2, N_("read options from file")}, + + { 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") }, + { 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)")}, + { 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")}, + + { 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" ) }, + + /* hidden options */ + { 532, "quick-random", 0, "\r"}, + { 526, "no-verbose", 0, "\r"}, + { 538, "trustdb-name", 2, "\r" }, + { 540, "no-secmem-warning", 0, "\r" }, /* used only by regression tests */ + { 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 */ + + +{0} }; + + + + enum cmd_values { aNull = 0, aSym, aStore, aEncr, aKeygen, aSign, aSignEncr, aSignKey, aClearsign, aListPackets, aEditSig, aKMode, aKModeC, aChangePass, aImport, - aExport, + aExport, aCheckKeys, aNOP }; @@ -59,7 +133,7 @@ strusage( int level ) switch( level ) { case 10: case 0: p = "g10 - v" VERSION "; " - "Copyright 1997 Werner Koch (dd9jn)\n" ; break; + "Copyright 1998 Werner Koch (dd9jn)\n" ; break; case 13: p = "g10"; break; case 14: p = VERSION; break; case 1: @@ -105,7 +179,7 @@ i18n_init(void) static void wrong_args( const char *text) { - fputs(_("Usage: g10 [options] "),stderr); + fputs(_("usage: g10 [options] "),stderr); fputs(text,stderr); putc('\n',stderr); g10_exit(2); @@ -152,63 +226,28 @@ set_cmd( enum cmd_values *ret_cmd, enum cmd_values new_cmd ) } + +static void +check_opts(void) +{ + if( !opt.def_cipher_algo || check_cipher_algo(opt.def_cipher_algo) ) + log_error(_("selected cipher algorithm is invalid\n")); + if( !opt.def_pubkey_algo || check_pubkey_algo(opt.def_pubkey_algo) ) + log_error(_("selected pubkey algorithm is invalid\n")); + if( !opt.def_digest_algo || check_digest_algo(opt.def_digest_algo) ) + log_error(_("selected digest algorithm is invalid\n")); + if( opt.completes_needed < 1 ) + log_error(_("completes-needed must be greater than 0\n")); + if( opt.marginals_needed < 2 ) + log_error(_("marginals-needed must be greater than 1\n")); +} + + + + void main( int argc, char **argv ) { - static ARGPARSE_OPTS opts[] = { - { 'a', "armor", 0, N_("create ascii armored output")}, - { 'v', "verbose", 0, N_("verbose") }, - { 'z', NULL, 1, N_("set compress level (0 disables)") }, - { 'n', "dry-run", 0, N_("don't make any changes") }, - { 'c', "symmetric", 0, N_("do only a symmetric encryption")}, - { 'o', "output", 2, N_("use as output file")}, - { 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")}, - { 503, "gen-key", 0, N_("generate a new key pair")}, - { 504, "add-key", 0, N_("add key to the public keyring")}, - { 505, "delete-key",0, N_("remove key from public keyring")}, - { 506, "sign-key" ,0, N_("make a signature on a key in the keyring")}, - { 507, "store", 0, N_("store only")}, - { 508, "check-key" ,0, N_("check signatures on a key in the keyring")}, - { 509, "keyring" ,2, N_("add this keyring to the list of keyrings")}, - { 's', "sign", 0, N_("make a signature")}, - { 't', "textmode", 0, N_("use canonical text mode")}, - { 'b', "detach-sign", 0, N_("make a detached signature")}, - { 'e', "encrypt", 0, N_("encrypt data")}, - { 'd', "decrypt", 0, N_("decrypt data (default)")}, - { 'u', "local-user",2, N_("use this user-id to sign or decrypt")}, - { 'r', "remote-user", 2, N_("use this user-id for encryption")}, - { '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") }, - { 515, "fingerprint", 0, N_("show the fingerprints")}, - { 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" }, - { 523, "passphrase-fd",1, "\r" }, - { 524, "edit-sig" ,0, N_("edit a key signature")}, - { 525, "change-passphrase", 0, N_("change the passphrase of your secret keyring")}, - { 526, "no-verbose", 0, "\r"}, - { 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")}, - { 530, "import", 0 , N_("put public keys into the trustdb")}, - { 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)")}, - { 537, "export", 0, N_("export all or the given keys") }, - { 538, "trustdb-name", 2, "\r" }, - { 539, "clearsign", 0, N_("make a clear text signature") }, - { 540, "no-secmem-warning", 0, "\r" }, /* used only by regression tests */ - { 541, "no-operation", 0, "\r" }, /* used by regression tests */ - - {0} }; ARGPARSE_ARGS pargs; IOBUF a; int rc=0; @@ -236,6 +275,7 @@ main( int argc, char **argv ) * secmem_init() somewhere after the option parsing */ + log_set_name("g10"); i18n_init(); opt.compress = -1; /* defaults to standard compress level */ opt.def_cipher_algo = CIPHER_ALGO_BLOWFISH; @@ -278,9 +318,11 @@ main( int argc, char **argv ) if( parse_debug ) log_info(_("note: no default option file '%s'\n"), configname ); } - else - log_fatal(_("option file '%s': %s\n"), + else { + log_error(_("option file '%s': %s\n"), configname, strerror(errno) ); + g10_exit(1); + } m_free(configname); configname = NULL; } if( parse_debug && configname ) @@ -291,9 +333,7 @@ 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 'v': opt.verbose++; opt.list_sigs=1; break; case 'z': opt.compress = pargs.r.ret_int; break; case 'a': opt.armor = 1; opt.no_armor=0; break; case 'd': break; /* it is default */ @@ -322,7 +362,8 @@ main( int argc, char **argv ) case 503: set_cmd( &cmd, aKeygen); break; case 506: set_cmd( &cmd, aSignKey); break; case 507: set_cmd( &cmd, aStore); break; - case 508: opt.check_sigs = 1; opt.list_sigs = 1; break; + case 508: set_cmd( &cmd, aCheckKeys); + 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; @@ -374,27 +415,8 @@ main( int argc, char **argv ) 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 ) + check_opts(); + if( log_get_errorcount(0) ) g10_exit(2); if( greeting ) { @@ -541,6 +563,7 @@ main( int argc, char **argv ) g10_errstr(rc) ); break; + case aCheckKeys: case aKMode: /* list keyring */ if( !argc ) { /* list the default public keyrings */ int i, seq=0; @@ -563,14 +586,23 @@ main( int argc, char **argv ) } } + else if( cmd == aCheckKeys ) { + log_error("will be soon: --check-keys user-ids\n"); + } 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); + log_error(_("can't open '%s'\n"), fname_print); + else { + if( !opt.no_armor ) { + memset( &afx, 0, sizeof afx); + iobuf_push_filter( a, armor_filter, &afx ); + } + proc_packets( a ); + iobuf_close(a); + } } else - wrong_args(_("-k[v][v][v][c] [keyring]")); + wrong_args(_("-k[v][v][v][c] [keyring]") ); break; case aKeygen: /* generate a key (interactive) */ @@ -607,18 +639,20 @@ main( int argc, char **argv ) if( argc > 1 ) wrong_args(_("[filename]")); 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 ); + log_error(_("can't open '%s'\n"), fname_print); + else { + 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); } - if( cmd == aListPackets ) { - set_packet_list_mode(1); - opt.list_packets=1; - } - proc_packets( a ); - iobuf_close(a); break; } diff --git a/g10/import.c b/g10/import.c index 2cba74a5b..0474152d7 100644 --- a/g10/import.c +++ b/g10/import.c @@ -35,15 +35,34 @@ /**************** - * Import the public keys from the given filename. - * Import is a somewhat misleading name, as we (only) add informations - * about the public keys into aout trustdb. + * Import the public keys from the given filename. Input may be armored. + * This function rejects alls keys which are not valid self signed on at + * least one userid. Only user ids which are self signed will be imported. + * Other signatures are not not checked. + * + * Actually this functtion does a merge, it works like this: + * FIXME: add handling for revocation certs + * + * - get the keyblock + * - check self-signatures and remove all userids and their isgnatures + * without/invalid self-signatures. + * - reject the keyblock, if we have no valid userid. + * - See wether we have this key already in one of our pubrings. + * If not, simply add it to the default keyring. + * - Compare the key and the self-signatures of the new and the one in + * our keyring. If they are differen something weird is going on; + * ask what to do. + * - See wether we have only non-self-signature on one user id; if not + * ask the user what to do. + * - compare the signatures: If we already have this signature, check + * that they compare okay, if not issue a warning and ask the user. + * (consider to look at the timestamp and use the newest?) + * - Simply add the signature. Can't verify here because we may not have + * the signatures public key yet; verification is done when putting it + * into the trustdb, which is done automagically as soon as this pubkey + * is used. + * - Proceed with next signature. * - * NOTE: this function is not really needed and will be changed to - * a function which reads a plain textfile, describing a public - * key and its associated ownertrust. This can be used (together - * with the export function) to make a backup of the assigned - * ownertrusts. */ int import_pubkeys( const char *filename ) diff --git a/g10/kbnode.c b/g10/kbnode.c index dd4f0ce24..83ec50742 100644 --- a/g10/kbnode.c +++ b/g10/kbnode.c @@ -177,11 +177,12 @@ walk_kbnode( KBNODE root, KBNODE *context, int all ) do { if( !*context ) { *context = root; - return root; + n = root; + } + else { + n = (*context)->next; + *context = n; } - - n = (*context)->next; - *context = n; } while( !all && n && (n->private_flag & 1) ); return n; diff --git a/g10/keydb.h b/g10/keydb.h index ff0ecb528..ca54020cd 100644 --- a/g10/keydb.h +++ b/g10/keydb.h @@ -51,6 +51,8 @@ struct keyblock_pos_struct { int resno; /* resource number */ ulong offset; /* position information */ unsigned count; /* length of the keyblock in packets */ + IOBUF fp; /* used by enum_keyblocks */ + PACKET *pkt; /* ditto */ }; typedef struct keyblock_pos_struct KBPOS; @@ -144,6 +146,7 @@ int find_secret_keyblock_byname( KBPOS *kbpos, const char *username ); int lock_keyblock( KBPOS *kbpos ); void unlock_keyblock( KBPOS *kbpos ); int read_keyblock( KBPOS *kbpos, KBNODE *ret_root ); +int enum_keyblocks( int mode, KBPOS *kbpos, KBNODE *ret_root ); int insert_keyblock( KBPOS *kbpos, KBNODE root ); int delete_keyblock( KBPOS *kbpos ); int update_keyblock( KBPOS *kbpos, KBNODE root ); diff --git a/g10/keygen.c b/g10/keygen.c index f9e68a083..1c9a2efbe 100644 --- a/g10/keygen.c +++ b/g10/keygen.c @@ -535,11 +535,11 @@ generate_keypair() /* we create the packets as a tree of kbnodes. Because the structure * we create is known in advance we simply generate a linked list - * The first packet is a comment packet, followed by the userid and - * the self signature. + * The first packet is a dummy comment packet which we flag + * as deleted. The very first packet must always be a CERT packet. */ - pub_root = make_comment_node("#created by G10 pre-release " VERSION ); - sec_root = make_comment_node("#created by G10 pre-release " VERSION ); + pub_root = make_comment_node("#"); delete_kbnode(pub_root, pub_root); + sec_root = make_comment_node("#"); delete_kbnode(sec_root, sec_root); tty_printf(_( "We need to generate a lot of random bytes. It is a good idea to perform\n" @@ -557,6 +557,12 @@ generate_keypair() rc = gen_dsa(nbits, pub_root, sec_root, dek, &skc ); else BUG(); + if( !rc ) { + add_kbnode( pub_root, + make_comment_node("#created by G10 release " VERSION )); + add_kbnode( sec_root, + make_comment_node("#created by G10 release " VERSION )); + } if( !rc ) write_uid(pub_root, uid ); if( !rc ) diff --git a/g10/parse-packet.c b/g10/parse-packet.c index 2e3cf21be..0e13f6d18 100644 --- a/g10/parse-packet.c +++ b/g10/parse-packet.c @@ -437,6 +437,7 @@ parse_publickey( IOBUF inp, int pkttype, unsigned long pktlen, PACKET *packet ) if( k->pubkey_algo == PUBKEY_ALGO_ELGAMAL ) { n = pktlen; k->d.elg.a = mpi_read(inp, &n, 0); pktlen -=n; + n = pktlen; k->d.elg.b = mpi_read(inp, &n, 0 ); pktlen -=n; if( list_mode ) { printf("\telg a: "); @@ -502,6 +503,7 @@ parse_signature( IOBUF inp, int pkttype, unsigned long pktlen, sig->d.elg.digest_start[1] = iobuf_get_noeof(inp); pktlen--; n = pktlen; sig->d.elg.a = mpi_read(inp, &n, 0 ); pktlen -=n; + n = pktlen; sig->d.elg.b = mpi_read(inp, &n, 0 ); pktlen -=n; if( list_mode ) { printf("\tdigest algo %d, begin of digest %02x %02x\n", diff --git a/g10/pubkey-enc.c b/g10/pubkey-enc.c index 2f8fb45f4..0fcd9c21c 100644 --- a/g10/pubkey-enc.c +++ b/g10/pubkey-enc.c @@ -38,8 +38,10 @@ int get_session_key( PKT_pubkey_enc *k, DEK *dek ) { - int i, j, c, rc = 0; - MPI dek_frame = mpi_alloc_secure(40); + int rc = 0; + MPI plain_dek = NULL; + byte *frame = NULL; + unsigned n, nframe; u16 csum, csum2; PKT_secret_cert *skc = m_alloc_clear( sizeof *skc ); @@ -58,7 +60,8 @@ get_session_key( PKT_pubkey_enc *k, DEK *dek ) skey.g = skc->d.elg.g; skey.y = skc->d.elg.y; skey.x = skc->d.elg.x; - elg_decrypt( dek_frame, k->d.elg.a, k->d.elg.b, &skey ); + plain_dek = mpi_alloc_secure( mpi_get_nlimbs(skey.p) ); + elg_decrypt( plain_dek, k->d.elg.a, k->d.elg.b, &skey ); memset( &skey, 0, sizeof skey ); } #ifdef HAVE_RSA_CIPHER @@ -74,7 +77,8 @@ get_session_key( PKT_pubkey_enc *k, DEK *dek ) skey.q = skc->d.rsa.rsa_q; skey.d = skc->d.rsa.rsa_d; skey.u = skc->d.rsa.rsa_u; - rsa_secret( dek_frame, k->d.rsa.rsa_integer, &skey ); + plain_dek = mpi_alloc_secure( mpi_get_nlimbs(skey.n) ); + rsa_secret( plain_dek, k->d.rsa.rsa_integer, &skey ); memset( &skey, 0, sizeof skey ); } #endif/*HAVE_RSA_CIPHER*/ @@ -83,9 +87,10 @@ get_session_key( PKT_pubkey_enc *k, DEK *dek ) goto leave; } free_secret_cert( skc ); skc = NULL; + frame = mpi_get_buffer( plain_dek, &nframe, NULL ); + mpi_free( plain_dek ); plain_dek = NULL; - - /* Now get the DEK (data encryption key) from the dek_frame + /* Now get the DEK (data encryption key) from the frame * * Old versions encode the DEK in in this format (msb is left): * @@ -101,51 +106,53 @@ get_session_key( PKT_pubkey_enc *k, DEK *dek ) * CSUM */ if( DBG_CIPHER ) - log_mpidump("DEK frame:", dek_frame ); - for(i=0; mpi_getbyte(dek_frame, i) != -1; i++ ) + log_hexdump("DEK frame:", frame, nframe ); + for(n=0; n < nframe && !frame[n]; n++ ) /* skip leading zeroes */ ; - for(i--; i >= 0 && !(c=mpi_getbyte(dek_frame, i)); i--) - ; /* Skip leading zeroes */ - if( i < 16 ) + if( n + 7 > nframe ) { rc = G10ERR_WRONG_SECKEY; goto leave; } - if( c == 1 && mpi_getbyte(dek_frame,0) == 2 ) { + if( frame[n] == 1 && frame[nframe-1] == 2 ) { log_error("old encoding of DEK is not supported\n"); rc = G10ERR_CIPHER_ALGO; goto leave; } - if( c != 2 ) /* somethink is wrong */ + if( frame[n] != 2 ) /* somethink is wrong */ { rc = G10ERR_WRONG_SECKEY; goto leave; } - /* look for the zero byte */ - for(i--; i > 4 ; i-- ) - if( !mpi_getbyte(dek_frame,i) ) - break; - if( i <= 4 ) /* zero byte not found */ + for(n++; n < nframe && frame[n]; n++ ) /* skip the random bytes */ + ; + n++; /* and the zero byte */ + if( n + 4 > nframe ) { rc = G10ERR_WRONG_SECKEY; goto leave; } - /* next byte indicates the used cipher */ - switch( mpi_getbyte(dek_frame, --i ) ) { + + dek->keylen = nframe - (n+1) - 2; + dek->algo = frame[n++]; + switch( dek->algo ) { case CIPHER_ALGO_IDEA: rc = G10ERR_NI_CIPHER; goto leave; case CIPHER_ALGO_BLOWFISH: - if( i != 22 ) /* length of blowfish is 20 (+2 bytes checksum) */ + if( dek->keylen != 20 ) { rc = G10ERR_WRONG_SECKEY; goto leave; } - dek->algo = CIPHER_ALGO_BLOWFISH; break; case CIPHER_ALGO_BLOWFISH128: - if( i != 18 ) /* length of blowfish-128 is 16 (+2 bytes checksum) */ + if( dek->keylen != 16 ) + { rc = G10ERR_WRONG_SECKEY; goto leave; } + break; + case CIPHER_ALGO_CAST: + if( dek->keylen < 5 || dek->keylen > 16 ) { rc = G10ERR_WRONG_SECKEY; goto leave; } - dek->algo = CIPHER_ALGO_BLOWFISH128; break; default: + dek->algo = 0; rc = G10ERR_CIPHER_ALGO; goto leave; } /* copy the key to DEK and compare the checksum */ - csum = mpi_getbyte(dek_frame, 1) << 8; - csum |= mpi_getbyte(dek_frame, 0); - dek->keylen = i - 2; - for( i--, csum2=0, j=0; i > 1; i-- ) - csum2 += dek->key[j++] = mpi_getbyte(dek_frame, i); + csum = frame[nframe-2] << 8; + csum |= frame[nframe-1]; + memcpy( dek->key, frame+n, dek->keylen ); + for( csum2=0, n=0; n < dek->keylen; n++ ) + csum2 += dek->key[n]; if( csum != csum2 ) { rc = G10ERR_WRONG_SECKEY; goto leave; @@ -154,7 +161,8 @@ get_session_key( PKT_pubkey_enc *k, DEK *dek ) log_hexdump("DEK is:", dek->key, dek->keylen ); leave: - mpi_free(dek_frame); + mpi_free(plain_dek); + m_free(frame); if( skc ) free_secret_cert( skc ); return rc; diff --git a/g10/ringedit.c b/g10/ringedit.c index 141d8cf7f..adba3db0b 100644 --- a/g10/ringedit.c +++ b/g10/ringedit.c @@ -77,6 +77,7 @@ static int keyring_search( PACKET *pkt, KBPOS *kbpos, IOBUF iobuf ); static int keyring_search2( PUBKEY_FIND_INFO info, KBPOS *kbpos, const char *fname); static int keyring_read( KBPOS *kbpos, KBNODE *ret_root ); +static int keyring_enum( KBPOS *kbpos, KBNODE *ret_root ); static int keyring_copy( KBPOS *kbpos, int mode, KBNODE root ); @@ -297,6 +298,78 @@ read_keyblock( KBPOS *kbpos, KBNODE *ret_root ) return keyring_read( kbpos, ret_root ); } + +/**************** + * This functions can be used to read trough a complete keyring. + * Mode is: 0 = open + * 1 = read + * 2 = close + * all others are reserved! + * Note that you do not need a search prior to call this function, + * only handle is needed. + * NOTE: It is not alloed to do an insert/update/delte with this + * keyblock, if you want to do this, user search/read! + */ +int +enum_keyblocks( int mode, KBPOS *kbpos, KBNODE *ret_root ) +{ + int rc = 0; + RESTBL *rentry; + + if( !mode || mode == 100 ) { + int i; + kbpos->fp = NULL; + if( !mode ) + i = 0; + else + i = kbpos->resno+1; + for(; i < MAX_RESOURCES; i++ ) + if( resource_table[i].used && !resource_table[i].secret ) + break; + if( i == MAX_RESOURCES ) + return -1; /* no resources */ + kbpos->resno = i; + rentry = check_pos( kbpos ); + kbpos->fp = iobuf_open( rentry->fname ); + if( !kbpos->fp ) { + log_error("can't open '%s'\n", rentry->fname ); + return G10ERR_OPEN_FILE; + } + kbpos->pkt = NULL; + } + else if( mode == 1 ) { + int cont; + do { + cont = 0; + if( !kbpos->fp ) + return G10ERR_GENERAL; + rc = keyring_enum( kbpos, ret_root ); + if( rc == -1 ) { + assert( !kbpos->pkt ); + rentry = check_pos( kbpos ); + assert(rentry); + /* close */ + enum_keyblocks(2, kbpos, ret_root ); + /* and open the next one */ + rc = enum_keyblocks(100, kbpos, ret_root ); + if( !rc ) + cont = 1; + } + } while(cont); + } + else if( kbpos->fp ) { + iobuf_close( kbpos->fp ); + kbpos->fp = NULL; + /* release pending packet */ + free_packet( kbpos->pkt ); + m_free( kbpos->pkt ); + } + return rc; +} + + + + /**************** * Insert the keyblock described by ROOT into the keyring described * by KBPOS. This actually appends the data to the keyfile. @@ -551,9 +624,8 @@ keyring_read( KBPOS *kbpos, KBNODE *ret_root ) if( rc ) release_kbnode( root ); - else { + else *ret_root = root; - } free_packet( pkt ); m_free( pkt ); iobuf_close(a); @@ -561,6 +633,69 @@ keyring_read( KBPOS *kbpos, KBNODE *ret_root ) } +static int +keyring_enum( KBPOS *kbpos, KBNODE *ret_root ) +{ + PACKET *pkt; + int rc; + RESTBL *rentry; + KBNODE root = NULL; + int in_cert = 0; + + if( !(rentry=check_pos(kbpos)) ) + return G10ERR_GENERAL; + + if( kbpos->pkt ) { + root = new_kbnode( kbpos->pkt ); + kbpos->pkt = NULL; + } + + pkt = m_alloc( sizeof *pkt ); + init_packet(pkt); + while( (rc=parse_packet(kbpos->fp, pkt)) != -1 ) { + if( rc ) { /* ignore errors */ + if( rc != G10ERR_UNKNOWN_PACKET ) { + log_error("read_keyblock: read error: %s\n", g10_errstr(rc) ); + rc = G10ERR_INV_KEYRING; + goto ready; + } + free_packet( pkt ); + continue; + } + /* make a linked list of all packets */ + switch( pkt->pkttype ) { + case PKT_PUBLIC_CERT: + case PKT_SECRET_CERT: + if( in_cert ) { /* store this packet */ + kbpos->pkt = pkt; + pkt = NULL; + goto ready; + } + in_cert = 1; + default: + if( !root ) + root = new_kbnode( pkt ); + else + add_kbnode( root, new_kbnode( pkt ) ); + pkt = m_alloc( sizeof *pkt ); + init_packet(pkt); + break; + } + } + ready: + if( rc == -1 && root ) + rc = 0; + + if( rc ) + release_kbnode( root ); + else + *ret_root = root; + free_packet( pkt ); + m_free( pkt ); + return rc; +} + + /**************** * Peromf insert/delete/update operation. @@ -579,6 +714,8 @@ keyring_copy( KBPOS *kbpos, int mode, KBNODE root ) if( !(rentry = check_pos( kbpos )) ) return G10ERR_GENERAL; + if( kbpos->fp ) + BUG(); /* not allowed with such a handle */ /* open the source file */ fp = iobuf_open( rentry->fname ); diff --git a/g10/sign.c b/g10/sign.c index 52718b390..d6777442a 100644 --- a/g10/sign.c +++ b/g10/sign.c @@ -796,14 +796,14 @@ edit_keysigs( const char *username ) /* search the userid */ rc = find_keyblock_byname( &kbpos, username ); if( rc ) { - log_error("user '%s' not found\n", username ); + log_error("%s: user not found\n", username ); goto leave; } /* read the keyblock */ rc = read_keyblock( &kbpos, &keyblock ); if( rc ) { - log_error("error reading the certificate: %s\n", g10_errstr(rc) ); + log_error("%s: certificate read problem: %s\n", username, g10_errstr(rc) ); goto leave; } diff --git a/include/ChangeLog b/include/ChangeLog new file mode 100644 index 000000000..e69de29bb diff --git a/include/distfiles b/include/distfiles index d847316f2..35ca3220b 100644 --- a/include/distfiles +++ b/include/distfiles @@ -8,3 +8,4 @@ types.h util.h i18n.h +ChangeLog diff --git a/include/util.h b/include/util.h index 1eca49ac4..e083c53c9 100644 --- a/include/util.h +++ b/include/util.h @@ -56,14 +56,14 @@ typedef struct { } ARGPARSE_OPTS; /*-- logger.c --*/ +void log_set_name( const char *name ); +const char *log_get_name(void); void log_set_pid( int pid ); int log_get_errorcount( int clear ); void log_hexdump( const char *text, char *buf, size_t len ); void log_mpidump( const char *text, MPI a ); #if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 5 ) - void printstr( int level, const char *fmt, ... ) - __attribute__ ((format (printf,2,3))); void log_bug( const char *fmt, ... ) __attribute__ ((noreturn, format (printf,1,2))); void log_bug0( const char *, int, const char * ) __attribute__ ((noreturn)); @@ -74,7 +74,6 @@ void log_mpidump( const char *text, MPI a ); void log_debug( const char *fmt, ... ) __attribute__ ((format (printf,1,2))); #define BUG() log_bug0( __FILE__ , __LINE__, __FUNCTION__ ) #else - void printstr( int level, const char *fmt, ... ); void log_bug( const char *fmt, ... ); void log_bug0( const char *, int ); void log_fatal( const char *fmt, ... ); diff --git a/mpi/ChangeLog b/mpi/ChangeLog new file mode 100644 index 000000000..e69de29bb diff --git a/mpi/Makefile.in b/mpi/Makefile.in index 3b34edee0..87976eebe 100644 --- a/mpi/Makefile.in +++ b/mpi/Makefile.in @@ -85,7 +85,6 @@ POSUB = @POSUB@ RANLIB = @RANLIB@ VERSION = @VERSION@ ZLIBS = @ZLIBS@ -ZLIB_SUBDIR = @ZLIB_SUBDIR@ INCLUDES = -I$(top_srcdir)/include diff --git a/mpi/mpicoder.c b/mpi/mpicoder.c index bccb51ff5..3daea767f 100644 --- a/mpi/mpicoder.c +++ b/mpi/mpicoder.c @@ -118,7 +118,7 @@ mpi_read(IOBUF inp, unsigned *ret_nread, int secure) leave: if( nread > *ret_nread ) - log_error("Ooops: mpi crosses packet border"); + log_bug("mpi crosses packet border"); else *ret_nread = nread; return val; diff --git a/mpi/mpiutil.c b/mpi/mpiutil.c index 09be317f2..3eb09f0cd 100644 --- a/mpi/mpiutil.c +++ b/mpi/mpiutil.c @@ -35,6 +35,13 @@ #undef mpi_free #endif +/**************** + * fixme: It was a bad idea to use the number of limbs to allocate + * because on a alpha the limbs are large but we normally need + * integers of n bits - So we should chnage this to bits (or bytes). + * + * But mpi_alloc is used in a lot of places :-) + */ MPI #ifdef M_DEBUG mpi_debug_alloc( unsigned nlimbs, const char *info ) diff --git a/po/ChangeLog b/po/ChangeLog index 1d2526595..e69de29bb 100644 --- a/po/ChangeLog +++ b/po/ChangeLog @@ -1,5 +0,0 @@ -Tue Feb 10 11:57:23 1998 Werner Koch (wk@frodo) - - * ddd/hhhh: - - diff --git a/scripts/mkdiff b/scripts/mkdiff index 9db701916..ae7435369 100755 --- a/scripts/mkdiff +++ b/scripts/mkdiff @@ -3,9 +3,9 @@ set -e curr_ver=$(ls g10-*.tar.gz | sort -r -t '.' -n +0.4 -1 +1 -2 +2 \ - | head -1 | sed -e 's/g10-\(.*\).tar.gz/\1/' ) + | head -1 | sed -e 's/g10-\(.*\).tar.gz/\1/' ) prev_ver=$(ls g10-*.tar.gz | sort -r -t '.' -n +0.4 -1 +1 -2 +2 \ - | head -2 | tail -1 | sed -e 's/g10-\(.*\).tar.gz/\1/' ) + | head -2 | tail -1 | sed -e 's/g10-\(.*\).tar.gz/\1/' ) echo "Current is: $curr_ver" echo "Previous is: $prev_ver" @@ -13,11 +13,13 @@ echo "Previous is: $prev_ver" echo "Removing old directories" [ -d "g10-$curr_ver" ] && rm -rf "g10-$curr_ver" [ -d "g10-$prev_ver" ] && rm -rf "g10-$prev_ver" - -echo "Unpacking previous and current tar" + +echo "Unpacking previous and current tar" tar xzf "g10-$curr_ver.tar.gz" tar xzf "g10-$prev_ver.tar.gz" +read + echo "Diffing" tmp_name="g10-$curr_ver.diff.tmp" diff_name="g10-$curr_ver.diff" @@ -44,6 +46,7 @@ Prereq: $prev_ver EOF sed -ne '/^diff.*VERSION/,/^+[0-9][0-9]*/ p' $tmp_name >> $diff_name +echo >> $diff_name sed -e '/^diff.*VERSION/,/^+[0-9][0-9]*/ d' $tmp_name >> $diff_name rm $tmp_name @@ -53,7 +56,7 @@ gzip -9 $diff_name echo "Checking patch file" cd g10-$prev_ver -zcat ../$diff_name.gz | patch -s -p1 +zcat ../$diff_name.gz | patch -s -p1 rm $(find . -name "*.orig") cd .. diff --git a/tools/ChangeLog b/tools/ChangeLog new file mode 100644 index 000000000..e69de29bb diff --git a/tools/Makefile.in b/tools/Makefile.in index 21af3c4a4..d9fa5ce70 100644 --- a/tools/Makefile.in +++ b/tools/Makefile.in @@ -85,7 +85,6 @@ POSUB = @POSUB@ RANLIB = @RANLIB@ VERSION = @VERSION@ ZLIBS = @ZLIBS@ -ZLIB_SUBDIR = @ZLIB_SUBDIR@ INCLUDES = -I$(top_srcdir)/include needed_libs = ../cipher/libcipher.a ../util/libutil.a ../mpi/libmpi.a ../util/libutil.a diff --git a/util/ChangeLog b/util/ChangeLog new file mode 100644 index 000000000..c72c6b80f --- /dev/null +++ b/util/ChangeLog @@ -0,0 +1,18 @@ +Fri Feb 13 19:34:59 1998 Werner Koch (wk@isil.d.shuttle.de) + + * iobuf.c (iobuf_seek): Set counters to new offset. + +Fri Feb 13 17:13:04 1998 Werner Koch (wk@isil.d.shuttle.de) + + * logger.c (log_set_name, log_get_name): New. + (print_prefix, pgm_name): New, changed all function to make use it. + (log_mpidump): Removed the "DBG" prefix. + (log_hexdump): Ditto. + + * logger.c (printstr): Removed. + +Fri Feb 13 15:14:13 1998 Werner Koch (wk@isil.d.shuttle.de) + + * argparse.c (show_help): New '\v' kludge. + + diff --git a/util/Makefile.in b/util/Makefile.in index 4da66400a..1a7cc11a9 100644 --- a/util/Makefile.in +++ b/util/Makefile.in @@ -85,7 +85,6 @@ POSUB = @POSUB@ RANLIB = @RANLIB@ VERSION = @VERSION@ ZLIBS = @ZLIBS@ -ZLIB_SUBDIR = @ZLIB_SUBDIR@ INCLUDES = -I$(top_srcdir)/include diff --git a/util/argparse.c b/util/argparse.c index 0c8ad8f0b..620211e31 100644 --- a/util/argparse.c +++ b/util/argparse.c @@ -538,16 +538,31 @@ show_help( ARGPARSE_OPTS *opts, unsigned flags ) /* get max. length of long options */ for(i=indent=0; opts[i].short_opt; i++ ) { if( opts[i].long_opt ) - if( (j=strlen(opts[i].long_opt)) > indent && j < 35 ) - indent = j; + if( !opts[i].description || *opts[i].description != '\v' ) + if( (j=strlen(opts[i].long_opt)) > indent && j < 35 ) + indent = j; } /* example: " -v, --verbose Viele Sachen ausgeben" */ indent += 10; - puts("Options:"); + if( *opts[0].description != '\v' ) + puts("Options:"); for(i=0; opts[i].short_opt; i++ ) { s = _( opts[i].description ); if( s && *s== '\r' ) /* hide this line */ continue; + if( s && *s == '\v' ) { /* unindented comment only line */ + for(s++; *s; s++ ) { + if( *s == '\n' ) { + if( s[1] ) + putchar('\n'); + } + else + putchar(*s); + } + putchar('\n'); + continue; + } + if( opts[i].short_opt < 256 ) printf(" -%c", opts[i].short_opt ); else diff --git a/util/iobuf.c b/util/iobuf.c index 65efc0ef5..cc3288d7e 100644 --- a/util/iobuf.c +++ b/util/iobuf.c @@ -867,6 +867,11 @@ iobuf_tell( IOBUF a ) } + +/**************** + * This is a very limited implementation. It simply discards all internal + * buffering and remove all filters but the first one. + */ int iobuf_seek( IOBUF a, ulong newpos ) { @@ -885,6 +890,10 @@ iobuf_seek( IOBUF a, ulong newpos ) log_error("can't seek to %lu: %s\n", newpos, strerror(errno) ); return -1; } + a->d.len = 0; /* discard buffer */ + a->d.start = 0; + a->nbytes = 0; + a->nlimit = 0; a->ntotal = newpos; /* remove filters, but the last */ while( a->chain ) diff --git a/util/logger.c b/util/logger.c index 7d101c29a..8b53a7b8d 100644 --- a/util/logger.c +++ b/util/logger.c @@ -26,8 +26,26 @@ #include "util.h" static char pidstring[15]; +static char *pgm_name; static int errorcount; +void +log_set_name( const char *name ) +{ + m_free(pgm_name); + if( name ) + pgm_name = m_strdup(name); + else + pgm_name = NULL; +} + +const char * +log_get_name(void) +{ + return pgm_name? pgm_name : ""; +} + + void log_set_pid( int pid ) { @@ -46,45 +64,21 @@ log_get_errorcount( int clear) return n; } - -/**************** - * General interface for printing a line - * level 0 := print to /dev/null - * 1 := print to stdout - * 2 := print as info to stderr - * 3 := ditto but as error - */ -void -printstr( int level, const char *fmt, ... ) +static void +print_prefix(const char *text) { - va_list arg_ptr ; - - if( !level ) - return; - - if( !fmt ) { - putc('\n', level? stderr: stdout); - return; - } - - va_start( arg_ptr, fmt ) ; - if( level < 2 ) { - vfprintf(stdout,fmt,arg_ptr) ; - } - else { - fprintf(stderr, level==2? "%s: ": "%s: error: ", strusage(13) ) ; - vfprintf(stderr,fmt,arg_ptr) ; - } - va_end(arg_ptr); + if( pgm_name ) + fprintf(stderr, "%s%s: %s", pgm_name, pidstring, text ); + else + fprintf(stderr, "?%s: %s", pidstring, text ); } - void log_info( const char *fmt, ... ) { va_list arg_ptr ; - fprintf(stderr, "info%s: ", pidstring ) ; + print_prefix(""); va_start( arg_ptr, fmt ) ; vfprintf(stderr,fmt,arg_ptr) ; va_end(arg_ptr); @@ -95,7 +89,7 @@ log_error( const char *fmt, ... ) { va_list arg_ptr ; - fprintf(stderr, "error%s: ", pidstring ) ; + print_prefix(""); va_start( arg_ptr, fmt ) ; vfprintf(stderr,fmt,arg_ptr) ; va_end(arg_ptr); @@ -107,7 +101,7 @@ log_fatal( const char *fmt, ... ) { va_list arg_ptr ; - fprintf(stderr, "Fatal%s: ", pidstring ) ; + print_prefix("fatal: "); va_start( arg_ptr, fmt ) ; vfprintf(stderr,fmt,arg_ptr) ; va_end(arg_ptr); @@ -120,7 +114,8 @@ log_bug( const char *fmt, ... ) { va_list arg_ptr ; - fprintf(stderr, "\nInternal Error%s: ", pidstring ) ; + putc('\n', stderr ); + print_prefix("Ooops: "); va_start( arg_ptr, fmt ) ; vfprintf(stderr,fmt,arg_ptr) ; va_end(arg_ptr); @@ -148,7 +143,7 @@ log_debug( const char *fmt, ... ) { va_list arg_ptr ; - fprintf(stderr, "DBG%s: ", pidstring ) ; + print_prefix("DBG: "); va_start( arg_ptr, fmt ) ; vfprintf(stderr,fmt,arg_ptr) ; va_end(arg_ptr); @@ -161,7 +156,7 @@ log_hexdump( const char *text, char *buf, size_t len ) { int i; - fprintf(stderr, "DBG%s: %s", pidstring, text ); + print_prefix(text); for(i=0; i < len; i++ ) fprintf(stderr, " %02X", ((byte*)buf)[i] ); fputc('\n', stderr); @@ -171,7 +166,7 @@ log_hexdump( const char *text, char *buf, size_t len ) void log_mpidump( const char *text, MPI a ) { - fprintf(stderr, "DBG%s: %s", pidstring, text ); + print_prefix(text); mpi_print(stderr, a, 1 ); fputc('\n', stderr); } diff --git a/zlib/Makefile.am b/zlib/Makefile.am index e75e2e5b9..2d2d749df 100644 --- a/zlib/Makefile.am +++ b/zlib/Makefile.am @@ -6,7 +6,13 @@ CFLAGS = -O -Wall EXTRA_DIST = README algorithm.doc ChangeLog example.c + +# I found no other easy way to use this only if zlib is neede +# doing this with SUBDIR = @xxx@ in the top Makefile.am does not +# work because automake doesn't scan this Makefile.am here. +if ENABLE_LOCAL_ZLIB noinst_LIBRARIES = libzlib.a +endif libzlib_a_SOURCES = adler32.c compress.c crc32.c gzio.c \ @@ -20,3 +26,4 @@ libzlib_a_SOURCES = adler32.c compress.c crc32.c gzio.c \ CLEANFILES = example foo.gz +