1
0
mirror of git://git.gnupg.org/gnupg.git synced 2024-12-22 10:19:57 +01:00

added option export

This commit is contained in:
Werner Koch 1998-02-13 20:58:50 +00:00
parent b9fccd69e4
commit f477447d9a
43 changed files with 734 additions and 284 deletions

View File

@ -1,5 +1,5 @@
Tue Feb 10 11:57:23 1998 Werner Koch (wk@frodo) Fri Feb 13 19:43:41 1998 Werner Koch (wk@isil.d.shuttle.de)
* ddd/hhhh:
* configure.in : Fixed zlib stuff
* Makefile.am: Likewise

47
INSTALL
View File

@ -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/<cpu> 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 Basic Installation
================== ==================

View File

@ -1,10 +1,9 @@
## Process this file with automake to produce Makefile.in ## 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 EXTRA_DIST = VERSION
tar: clean tar: clean
cd ..; tar czvf ~/bkup/g10-`date +%d%m`.tar.gz src cd ..; tar czvf ~/bkup/g10-`date +%d%m`.tar.gz src

View File

@ -85,9 +85,8 @@ POSUB = @POSUB@
RANLIB = @RANLIB@ RANLIB = @RANLIB@
VERSION = @VERSION@ VERSION = @VERSION@
ZLIBS = @ZLIBS@ 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 EXTRA_DIST = VERSION
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
mkinstalldirs = $(SHELL) $(top_srcdir)/scripts/mkinstalldirs mkinstalldirs = $(SHELL) $(top_srcdir)/scripts/mkinstalldirs

6
NEWS
View File

@ -1,3 +1,9 @@
Noteworthy changes in version 0.2.6
-----------------------------------
* Option "--export" works.
Noteworthy changes in version 0.2.5 Noteworthy changes in version 0.2.5
----------------------------------- -----------------------------------

53
README
View File

@ -2,13 +2,24 @@
G10 - The GNU Encryption and Signing Tool 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 On a Linux box (version 2.x.x, alpha or x86 CPU) it should
USE IT FOR OTHER PURPOSES THAN EVALUATING THE CURRENT CODE. 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 <wk@isil.d.shuttle.de>"
"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 Please subscribe to g10@net.lut.ac.uk by sending a mail with
@ -42,19 +53,20 @@
Installation Installation
------------ ------------
See the file INSTALL. Here is a quick summary:
1) "./configure" 1) "./configure"
to enable the integrated malloc debugging stuff, use:
"./configure --enable-m-debug"
2) "make" 2) "make"
3) "make install" 3) "make install"
4) You end up with a binary "g10" in /usr/local/bin 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 you are asked for the passphrase, so that G10 is able to look at the
inner structure of a encrypted packet. 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 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. 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 the contents of the trustdb in a human readable format
--list-trustdb <usernames> g10maint --list-trustdb <usernames>
List the tree of certificates for the given usernames 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 List the possible trust paths for the given username, up to the specified
depth. If depth is negative, duplicate introducers are not listed, 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 using a negative number). This option may create new entries in the
trustdb. trustdb.
--print-mds filenames g10maint --print-mds filenames
List all available message digest values for the fiven 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 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 Generate a prime number suitable for ElGamal signatures of size n with
a q as largest primefactor of n-1. 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. 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 Debug Flags
@ -311,7 +323,10 @@
but for now I stick to my own formatting rules. but for now I stick to my own formatting rules.
The primary FTP site is "ftp://ftp.guug.de/pub/gcrypt/" 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 <g10-keys@isil.d.shuttle.de>; use
"g10 --export --armor | mail g10-keys@isil.d.shuttle.de" to do this.
Please direct bug reports to <g10-bugs@isil.d.shuttle.de> or better Please direct bug reports to <g10-bugs@isil.d.shuttle.de> or better
post them to the mailing list <g10@net.lut.ac.uk>. post them to the mailing list <g10@net.lut.ac.uk>.

3
THANKS
View File

@ -9,7 +9,10 @@ Daniel Eisenbud eisenbud@cs.swarthmore.edu
Detlef Lannert lannert@lannert.rz.uni-duesseldorf.de Detlef Lannert lannert@lannert.rz.uni-duesseldorf.de
Ernst Molitor ernst.molitor@uni-bonn.de Ernst Molitor ernst.molitor@uni-bonn.de
Hendrik Buschkamp buschkamp@rheumanet.org Hendrik Buschkamp buschkamp@rheumanet.org
Jean-loup Gailly gzip@prep.ai.mit.edu
Jens Bachem bachem@rrz.uni-koeln.de 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 Peter Gutmann pgut001@cs.auckland.ac.nz
Ralph Gillen gillen@theochem.uni-duesseldorf.de Ralph Gillen gillen@theochem.uni-duesseldorf.de
Thomas Roessler roessler@guug.de Thomas Roessler roessler@guug.de

11
TODO
View File

@ -23,4 +23,15 @@
we have a self-signature -> put this stuff into a kind of directory we have a self-signature -> put this stuff into a kind of directory
record, as it does not belong to the pubkey record? 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.

View File

@ -1 +1 @@
0.2.5 0.2.6

View File

@ -44,11 +44,9 @@ cleanup () {
run_g10 () { run_g10 () {
eval HOME=. ../g10/g10 $* if ! eval HOME=. ../g10/g10 $* ; then
if [ $? != 0 ] ; then
g10_err=$?
echo "(HOME=. ../g10/g10 $*) failed" >&2 echo "(HOME=. ../g10/g10 $*) failed" >&2
error "g10 failed: $g10_err" >&2 exit 1
fi fi
} }
@ -58,7 +56,7 @@ run_g10 () {
set -e set -e
pgmname=$(basename $0) pgmname=$(basename $0)
#trap cleanup EXIT SIGHUP SIGINT SIGQUIT trap cleanup SIGHUP SIGINT SIGQUIT
# some checks # some checks
@ -79,7 +77,7 @@ EOF
# print the G10 version # print the G10 version
run_g10 --version run_g10 --version
# intialize the trustdb
info Checking decryption info Checking decryption
for i in $plain_files ; do for i in $plain_files ; do
@ -87,21 +85,21 @@ for i in $plain_files ; do
cmp $i y || error "$i: mismatch" cmp $i y || error "$i: mismatch"
done done
#info Checking cleartext signatures info Checking cleartext signatures
## There is a minor glitch, which appends a lf to the cleartext. # 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. # 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 # It is not clear what should happen to leading LFs, we must
## change the defintion of cleartext, so that only 1 empty line # change the defintion of cleartext, so that only 1 empty line
## must follow the headers, but some specs say: any number of empty lines .. # must follow the headers, but some specs say: any number of empty lines ..
## clean-sat removes leading LFs # clean-sat removes leading LFs
## I know that this does not work for random data files (due to large lines # 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. # or what ever) - I hope we can live with it.
#for i in $plain_files; do for i in $plain_files; do
# echo "$usrpass1" | run_g10 --passphrase-fd 0 -sat -o x --yes $i echo "$usrpass1" | run_g10 --passphrase-fd 0 -sat -o x --yes $i
# run_g10 -o y --yes x run_g10 -o y --yes x
# ../tools/clean-sat < $i > z ../tools/clean-sat < $i > z
# head -c $[ $(cat y | wc -c) - 1 ] y | diff - z || error "$i: mismatch" head -c $[ $(cat y | wc -c) - 1 ] y | diff - z || error "$i: mismatch"
#done done
info Creating some random data files info Creating some random data files
for i in 500 9000 32000 80000; do 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" data_files="$data_files data-$i"
done done
#info Checking armored signatures info Checking armored signatures
#for i in $plain_files $data_files ; do for i in $plain_files $data_files ; do
# echo "$usrpass1" | run_g10 --passphrase-fd 0 -sa -o x --yes $i echo "$usrpass1" | run_g10 --passphrase-fd 0 -sa -o x --yes $i
# run_g10 -o y --yes x run_g10 -o y --yes x
# cmp $i y || error "$i: mismatch" cmp $i y || error "$i: mismatch"
#done done
#
#info Checking signatures info Checking signatures
#for i in $plain_files $data_files; do for i in $plain_files $data_files; do
# echo "$usrpass1" | run_g10 --passphrase-fd 0 -s -o x --yes $i echo "$usrpass1" | run_g10 --passphrase-fd 0 -s -o x --yes $i
# run_g10 -o y --yes x run_g10 -o y --yes x
# cmp $i y || error "$i: mismatch" cmp $i y || error "$i: mismatch"
#done done
info Checking armored encryption info Checking armored encryption
for i in $plain_files $data_files ; do for i in $plain_files $data_files ; do
info "file $i" run_g10 -ea -o x --yes -r "$usrname2" $i
run_g10 -v -ea -o x --yes -r "$usrname2" $i run_g10 -o y --yes x
run_g10 -v -o y --yes x
cmp $i y || error "$i: mismatch" cmp $i y || error "$i: mismatch"
done done

0
cipher/ChangeLog Normal file
View File

View File

@ -85,7 +85,6 @@ POSUB = @POSUB@
RANLIB = @RANLIB@ RANLIB = @RANLIB@
VERSION = @VERSION@ VERSION = @VERSION@
ZLIBS = @ZLIBS@ ZLIBS = @ZLIBS@
ZLIB_SUBDIR = @ZLIB_SUBDIR@
INCLUDES = -I$(top_srcdir)/include INCLUDES = -I$(top_srcdir)/include
EXTRA_DIST = @CIPHER_EXTRA_DIST@ EXTRA_DIST = @CIPHER_EXTRA_DIST@

View File

@ -162,26 +162,26 @@ AC_SUBST(MPI_EXTRA_ASM_OBJS)
dnl Do we have zlib? Must do it here because Solaris failed dnl Do we have zlib? Must do it here because Solaris failed
dnl when compiling a conftest (due to the "-lz" from LIBS). dnl when compiling a conftest (due to the "-lz" from LIBS).
ZLIBS=
ZLIB_SUBDIR=
if test "$g10_force_zlib" = "yes"; then if test "$g10_force_zlib" = "yes"; then
ZLIBS="\${top_srcdir}/zlib/libzlib.a" ZLIBS="-L\${top_srcdir}/zlib -lzlib"
ZLIB_SUBDIR=zlib AM_CONDITIONAL(ENABLE_LOCAL_ZLIB, true)
WK_LINK_FILES(zlib/zlib.h, zlib.h ) WK_LINK_FILES(zlib/zlib.h, zlib.h )
WK_LINK_FILES(zlib/zconf.h, zconf.h ) WK_LINK_FILES(zlib/zconf.h, zconf.h )
else else
AC_CHECK_HEADERS(zlib.h) AC_CHECK_HEADERS(zlib.h)
if test "$ac_cv_header_zlib_h" = yes ; then if test "$ac_cv_header_zlib_h" = yes ; then
LIBS="$LIBS -lz" LIBS="$LIBS -lz"
ZLIBS=
AM_CONDITIONAL(ENABLE_LOCAL_ZLIB, false)
else else
ZLIBS="\${top_srcdir}/zlib/libzlib.a" ZLIBS="-L\${top_srcdir}/zlib -lzlib"
ZLIB_SUBDIR=zlib AM_CONDITIONAL(ENABLE_LOCAL_ZLIB, true)
WK_LINK_FILES(zlib/zlib.h, zlib.h ) WK_LINK_FILES(zlib/zlib.h, zlib.h )
WK_LINK_FILES(zlib/zconf.h, zconf.h ) WK_LINK_FILES(zlib/zconf.h, zconf.h )
fi fi
fi fi
AC_SUBST(ZLIBS) AC_SUBST(ZLIBS)
AC_SUBST(ZLIB_SUBDIR)
dnl checking whether we have other cipher source files dnl checking whether we have other cipher source files
CIPHER_EXTRA_OBJS="" CIPHER_EXTRA_OBJS=""

27
g10/ChangeLog Normal file
View File

@ -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

View File

@ -85,7 +85,6 @@ POSUB = @POSUB@
RANLIB = @RANLIB@ RANLIB = @RANLIB@
VERSION = @VERSION@ VERSION = @VERSION@
ZLIBS = @ZLIBS@ ZLIBS = @ZLIBS@
ZLIB_SUBDIR = @ZLIB_SUBDIR@
INCLUDES = -I$(top_srcdir)/include INCLUDES = -I$(top_srcdir)/include
EXTRA_DIST = OPTIONS pubring.g10 EXTRA_DIST = OPTIONS pubring.g10

View File

@ -182,7 +182,7 @@ encode_crypt( const char *filename, STRLIST remusr )
goto leave; goto leave;
} }
else if( opt.verbose ) 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 )) ) { if( !(out = open_outfile( filename, opt.armor? 1:0 )) ) {
rc = G10ERR_CREATE_FILE; /* or user said: do not overwrite */ rc = G10ERR_CREATE_FILE; /* or user said: do not overwrite */

View File

@ -31,17 +31,109 @@
#include "keydb.h" #include "keydb.h"
#include "memory.h" #include "memory.h"
#include "util.h" #include "util.h"
#include "main.h"
/**************** /****************
* Make a new keyring from all internal keyrings (if no user is given) * Export the public keys (to standard out or --outout).
* or for all selected users. * Depending on opt.armor the output is armored.
* If USERS is NULL, the complete ring wil. be exported.
*/ */
int int
export_pubkeys( STRLIST users ) export_pubkeys( STRLIST users )
{ {
log_fatal("Not yet implemented"); int rc = 0;
return 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;
} }

206
g10/g10.c
View File

@ -41,11 +41,85 @@
#include "status.h" #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, enum cmd_values { aNull = 0,
aSym, aStore, aEncr, aKeygen, aSign, aSignEncr, aSym, aStore, aEncr, aKeygen, aSign, aSignEncr,
aSignKey, aClearsign, aListPackets, aEditSig, aSignKey, aClearsign, aListPackets, aEditSig,
aKMode, aKModeC, aChangePass, aImport, aKMode, aKModeC, aChangePass, aImport,
aExport, aExport, aCheckKeys,
aNOP }; aNOP };
@ -59,7 +133,7 @@ strusage( int level )
switch( level ) { switch( level ) {
case 10: case 10:
case 0: p = "g10 - v" VERSION "; " 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 13: p = "g10"; break;
case 14: p = VERSION; break; case 14: p = VERSION; break;
case 1: case 1:
@ -105,7 +179,7 @@ i18n_init(void)
static void static void
wrong_args( const char *text) wrong_args( const char *text)
{ {
fputs(_("Usage: g10 [options] "),stderr); fputs(_("usage: g10 [options] "),stderr);
fputs(text,stderr); fputs(text,stderr);
putc('\n',stderr); putc('\n',stderr);
g10_exit(2); 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 void
main( int argc, char **argv ) 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; ARGPARSE_ARGS pargs;
IOBUF a; IOBUF a;
int rc=0; int rc=0;
@ -236,6 +275,7 @@ main( int argc, char **argv )
* secmem_init() somewhere after the option parsing * secmem_init() somewhere after the option parsing
*/ */
log_set_name("g10");
i18n_init(); i18n_init();
opt.compress = -1; /* defaults to standard compress level */ opt.compress = -1; /* defaults to standard compress level */
opt.def_cipher_algo = CIPHER_ALGO_BLOWFISH; opt.def_cipher_algo = CIPHER_ALGO_BLOWFISH;
@ -278,9 +318,11 @@ main( int argc, char **argv )
if( parse_debug ) if( parse_debug )
log_info(_("note: no default option file '%s'\n"), configname ); log_info(_("note: no default option file '%s'\n"), configname );
} }
else else {
log_fatal(_("option file '%s': %s\n"), log_error(_("option file '%s': %s\n"),
configname, strerror(errno) ); configname, strerror(errno) );
g10_exit(1);
}
m_free(configname); configname = NULL; m_free(configname); configname = NULL;
} }
if( parse_debug && configname ) if( parse_debug && configname )
@ -291,9 +333,7 @@ main( int argc, char **argv )
while( optfile_parse( configfp, configname, &configlineno, while( optfile_parse( configfp, configname, &configlineno,
&pargs, opts) ) { &pargs, opts) ) {
switch( pargs.r_opt ) { switch( pargs.r_opt ) {
case 'v': opt.verbose++; case 'v': opt.verbose++; opt.list_sigs=1; break;
opt.list_sigs=1;
break;
case 'z': opt.compress = pargs.r.ret_int; break; case 'z': opt.compress = pargs.r.ret_int; break;
case 'a': opt.armor = 1; opt.no_armor=0; break; case 'a': opt.armor = 1; opt.no_armor=0; break;
case 'd': break; /* it is default */ case 'd': break; /* it is default */
@ -322,7 +362,8 @@ main( int argc, char **argv )
case 503: set_cmd( &cmd, aKeygen); break; case 503: set_cmd( &cmd, aKeygen); break;
case 506: set_cmd( &cmd, aSignKey); break; case 506: set_cmd( &cmd, aSignKey); break;
case 507: set_cmd( &cmd, aStore); 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 509: add_keyring(pargs.r.ret_str); nrings++; break;
case 510: opt.debug |= pargs.r.ret_ulong; break; case 510: opt.debug |= pargs.r.ret_ulong; break;
case 511: opt.debug = ~0; break; case 511: opt.debug = ~0; break;
@ -374,27 +415,8 @@ main( int argc, char **argv )
goto next_pass; goto next_pass;
} }
m_free( configname ); configname = NULL; m_free( configname ); configname = NULL;
if( !opt.def_cipher_algo || check_cipher_algo(opt.def_cipher_algo) ) { check_opts();
log_error(_("selected cipher algorithm is invalid\n")); if( log_get_errorcount(0) )
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); g10_exit(2);
if( greeting ) { if( greeting ) {
@ -541,6 +563,7 @@ main( int argc, char **argv )
g10_errstr(rc) ); g10_errstr(rc) );
break; break;
case aCheckKeys:
case aKMode: /* list keyring */ case aKMode: /* list keyring */
if( !argc ) { /* list the default public keyrings */ if( !argc ) { /* list the default public keyrings */
int i, seq=0; int i, seq=0;
@ -563,12 +586,21 @@ 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 */ else if( argc == 1) { /* list the given keyring */
if( !(a = iobuf_open(fname)) ) if( !(a = iobuf_open(fname)) )
log_fatal(_("can't open '%s'\n"), fname_print); 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 ); proc_packets( a );
iobuf_close(a); iobuf_close(a);
} }
}
else else
wrong_args(_("-k[v][v][v][c] [keyring]") ); wrong_args(_("-k[v][v][v][c] [keyring]") );
break; break;
@ -607,7 +639,8 @@ main( int argc, char **argv )
if( argc > 1 ) if( argc > 1 )
wrong_args(_("[filename]")); wrong_args(_("[filename]"));
if( !(a = iobuf_open(fname)) ) if( !(a = iobuf_open(fname)) )
log_fatal(_("can't open '%s'\n"), fname_print); log_error(_("can't open '%s'\n"), fname_print);
else {
if( !opt.no_armor ) { if( !opt.no_armor ) {
/* push the armor filter, so it can peek at the input data */ /* push the armor filter, so it can peek at the input data */
memset( &afx, 0, sizeof afx); memset( &afx, 0, sizeof afx);
@ -619,6 +652,7 @@ main( int argc, char **argv )
} }
proc_packets( a ); proc_packets( a );
iobuf_close(a); iobuf_close(a);
}
break; break;
} }

View File

@ -35,15 +35,34 @@
/**************** /****************
* Import the public keys from the given filename. * Import the public keys from the given filename. Input may be armored.
* Import is a somewhat misleading name, as we (only) add informations * This function rejects alls keys which are not valid self signed on at
* about the public keys into aout trustdb. * 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 int
import_pubkeys( const char *filename ) import_pubkeys( const char *filename )

View File

@ -177,11 +177,12 @@ walk_kbnode( KBNODE root, KBNODE *context, int all )
do { do {
if( !*context ) { if( !*context ) {
*context = root; *context = root;
return root; n = root;
} }
else {
n = (*context)->next; n = (*context)->next;
*context = n; *context = n;
}
} while( !all && n && (n->private_flag & 1) ); } while( !all && n && (n->private_flag & 1) );
return n; return n;

View File

@ -51,6 +51,8 @@ struct keyblock_pos_struct {
int resno; /* resource number */ int resno; /* resource number */
ulong offset; /* position information */ ulong offset; /* position information */
unsigned count; /* length of the keyblock in packets */ unsigned count; /* length of the keyblock in packets */
IOBUF fp; /* used by enum_keyblocks */
PACKET *pkt; /* ditto */
}; };
typedef struct keyblock_pos_struct KBPOS; 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 ); int lock_keyblock( KBPOS *kbpos );
void unlock_keyblock( KBPOS *kbpos ); void unlock_keyblock( KBPOS *kbpos );
int read_keyblock( KBPOS *kbpos, KBNODE *ret_root ); 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 insert_keyblock( KBPOS *kbpos, KBNODE root );
int delete_keyblock( KBPOS *kbpos ); int delete_keyblock( KBPOS *kbpos );
int update_keyblock( KBPOS *kbpos, KBNODE root ); int update_keyblock( KBPOS *kbpos, KBNODE root );

View File

@ -535,11 +535,11 @@ generate_keypair()
/* we create the packets as a tree of kbnodes. Because the structure /* we create the packets as a tree of kbnodes. Because the structure
* we create is known in advance we simply generate a linked list * 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 first packet is a dummy comment packet which we flag
* the self signature. * as deleted. The very first packet must always be a CERT packet.
*/ */
pub_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("#created by G10 pre-release " VERSION ); sec_root = make_comment_node("#"); delete_kbnode(sec_root, sec_root);
tty_printf(_( tty_printf(_(
"We need to generate a lot of random bytes. It is a good idea to perform\n" "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 ); rc = gen_dsa(nbits, pub_root, sec_root, dek, &skc );
else else
BUG(); 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 ) if( !rc )
write_uid(pub_root, uid ); write_uid(pub_root, uid );
if( !rc ) if( !rc )

View File

@ -437,6 +437,7 @@ parse_publickey( IOBUF inp, int pkttype, unsigned long pktlen, PACKET *packet )
if( k->pubkey_algo == PUBKEY_ALGO_ELGAMAL ) { if( k->pubkey_algo == PUBKEY_ALGO_ELGAMAL ) {
n = pktlen; n = pktlen;
k->d.elg.a = mpi_read(inp, &n, 0); pktlen -=n; k->d.elg.a = mpi_read(inp, &n, 0); pktlen -=n;
n = pktlen;
k->d.elg.b = mpi_read(inp, &n, 0 ); pktlen -=n; k->d.elg.b = mpi_read(inp, &n, 0 ); pktlen -=n;
if( list_mode ) { if( list_mode ) {
printf("\telg a: "); 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--; sig->d.elg.digest_start[1] = iobuf_get_noeof(inp); pktlen--;
n = pktlen; n = pktlen;
sig->d.elg.a = mpi_read(inp, &n, 0 ); pktlen -=n; sig->d.elg.a = mpi_read(inp, &n, 0 ); pktlen -=n;
n = pktlen;
sig->d.elg.b = mpi_read(inp, &n, 0 ); pktlen -=n; sig->d.elg.b = mpi_read(inp, &n, 0 ); pktlen -=n;
if( list_mode ) { if( list_mode ) {
printf("\tdigest algo %d, begin of digest %02x %02x\n", printf("\tdigest algo %d, begin of digest %02x %02x\n",

View File

@ -38,8 +38,10 @@
int int
get_session_key( PKT_pubkey_enc *k, DEK *dek ) get_session_key( PKT_pubkey_enc *k, DEK *dek )
{ {
int i, j, c, rc = 0; int rc = 0;
MPI dek_frame = mpi_alloc_secure(40); MPI plain_dek = NULL;
byte *frame = NULL;
unsigned n, nframe;
u16 csum, csum2; u16 csum, csum2;
PKT_secret_cert *skc = m_alloc_clear( sizeof *skc ); 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.g = skc->d.elg.g;
skey.y = skc->d.elg.y; skey.y = skc->d.elg.y;
skey.x = skc->d.elg.x; 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 ); memset( &skey, 0, sizeof skey );
} }
#ifdef HAVE_RSA_CIPHER #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.q = skc->d.rsa.rsa_q;
skey.d = skc->d.rsa.rsa_d; skey.d = skc->d.rsa.rsa_d;
skey.u = skc->d.rsa.rsa_u; 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 ); memset( &skey, 0, sizeof skey );
} }
#endif/*HAVE_RSA_CIPHER*/ #endif/*HAVE_RSA_CIPHER*/
@ -83,9 +87,10 @@ get_session_key( PKT_pubkey_enc *k, DEK *dek )
goto leave; goto leave;
} }
free_secret_cert( skc ); skc = NULL; 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 frame
/* Now get the DEK (data encryption key) from the dek_frame
* *
* Old versions encode the DEK in in this format (msb is left): * 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 * CSUM
*/ */
if( DBG_CIPHER ) if( DBG_CIPHER )
log_mpidump("DEK frame:", dek_frame ); log_hexdump("DEK frame:", frame, nframe );
for(i=0; mpi_getbyte(dek_frame, i) != -1; i++ ) for(n=0; n < nframe && !frame[n]; n++ ) /* skip leading zeroes */
; ;
for(i--; i >= 0 && !(c=mpi_getbyte(dek_frame, i)); i--) if( n + 7 > nframe )
; /* Skip leading zeroes */
if( i < 16 )
{ rc = G10ERR_WRONG_SECKEY; goto leave; } { 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"); log_error("old encoding of DEK is not supported\n");
rc = G10ERR_CIPHER_ALGO; rc = G10ERR_CIPHER_ALGO;
goto leave; goto leave;
} }
if( c != 2 ) /* somethink is wrong */ if( frame[n] != 2 ) /* somethink is wrong */
{ rc = G10ERR_WRONG_SECKEY; goto leave; } { rc = G10ERR_WRONG_SECKEY; goto leave; }
/* look for the zero byte */ for(n++; n < nframe && frame[n]; n++ ) /* skip the random bytes */
for(i--; i > 4 ; i-- ) ;
if( !mpi_getbyte(dek_frame,i) ) n++; /* and the zero byte */
break; if( n + 4 > nframe )
if( i <= 4 ) /* zero byte not found */
{ rc = G10ERR_WRONG_SECKEY; goto leave; } { 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: case CIPHER_ALGO_IDEA:
rc = G10ERR_NI_CIPHER; rc = G10ERR_NI_CIPHER;
goto leave; goto leave;
case CIPHER_ALGO_BLOWFISH: 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; } { rc = G10ERR_WRONG_SECKEY; goto leave; }
dek->algo = CIPHER_ALGO_BLOWFISH;
break; break;
case CIPHER_ALGO_BLOWFISH128: 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; } { rc = G10ERR_WRONG_SECKEY; goto leave; }
dek->algo = CIPHER_ALGO_BLOWFISH128;
break; break;
default: default:
dek->algo = 0;
rc = G10ERR_CIPHER_ALGO; rc = G10ERR_CIPHER_ALGO;
goto leave; goto leave;
} }
/* copy the key to DEK and compare the checksum */ /* copy the key to DEK and compare the checksum */
csum = mpi_getbyte(dek_frame, 1) << 8; csum = frame[nframe-2] << 8;
csum |= mpi_getbyte(dek_frame, 0); csum |= frame[nframe-1];
dek->keylen = i - 2; memcpy( dek->key, frame+n, dek->keylen );
for( i--, csum2=0, j=0; i > 1; i-- ) for( csum2=0, n=0; n < dek->keylen; n++ )
csum2 += dek->key[j++] = mpi_getbyte(dek_frame, i); csum2 += dek->key[n];
if( csum != csum2 ) { if( csum != csum2 ) {
rc = G10ERR_WRONG_SECKEY; rc = G10ERR_WRONG_SECKEY;
goto leave; goto leave;
@ -154,7 +161,8 @@ get_session_key( PKT_pubkey_enc *k, DEK *dek )
log_hexdump("DEK is:", dek->key, dek->keylen ); log_hexdump("DEK is:", dek->key, dek->keylen );
leave: leave:
mpi_free(dek_frame); mpi_free(plain_dek);
m_free(frame);
if( skc ) if( skc )
free_secret_cert( skc ); free_secret_cert( skc );
return rc; return rc;

View File

@ -77,6 +77,7 @@ static int keyring_search( PACKET *pkt, KBPOS *kbpos, IOBUF iobuf );
static int keyring_search2( PUBKEY_FIND_INFO info, KBPOS *kbpos, static int keyring_search2( PUBKEY_FIND_INFO info, KBPOS *kbpos,
const char *fname); const char *fname);
static int keyring_read( KBPOS *kbpos, KBNODE *ret_root ); 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 ); 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 ); 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 * Insert the keyblock described by ROOT into the keyring described
* by KBPOS. This actually appends the data to the keyfile. * by KBPOS. This actually appends the data to the keyfile.
@ -551,9 +624,8 @@ keyring_read( KBPOS *kbpos, KBNODE *ret_root )
if( rc ) if( rc )
release_kbnode( root ); release_kbnode( root );
else { else
*ret_root = root; *ret_root = root;
}
free_packet( pkt ); free_packet( pkt );
m_free( pkt ); m_free( pkt );
iobuf_close(a); 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. * Peromf insert/delete/update operation.
@ -579,6 +714,8 @@ keyring_copy( KBPOS *kbpos, int mode, KBNODE root )
if( !(rentry = check_pos( kbpos )) ) if( !(rentry = check_pos( kbpos )) )
return G10ERR_GENERAL; return G10ERR_GENERAL;
if( kbpos->fp )
BUG(); /* not allowed with such a handle */
/* open the source file */ /* open the source file */
fp = iobuf_open( rentry->fname ); fp = iobuf_open( rentry->fname );

View File

@ -796,14 +796,14 @@ edit_keysigs( const char *username )
/* search the userid */ /* search the userid */
rc = find_keyblock_byname( &kbpos, username ); rc = find_keyblock_byname( &kbpos, username );
if( rc ) { if( rc ) {
log_error("user '%s' not found\n", username ); log_error("%s: user not found\n", username );
goto leave; goto leave;
} }
/* read the keyblock */ /* read the keyblock */
rc = read_keyblock( &kbpos, &keyblock ); rc = read_keyblock( &kbpos, &keyblock );
if( rc ) { 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; goto leave;
} }

0
include/ChangeLog Normal file
View File

View File

@ -8,3 +8,4 @@ types.h
util.h util.h
i18n.h i18n.h
ChangeLog

View File

@ -56,14 +56,14 @@ typedef struct {
} ARGPARSE_OPTS; } ARGPARSE_OPTS;
/*-- logger.c --*/ /*-- logger.c --*/
void log_set_name( const char *name );
const char *log_get_name(void);
void log_set_pid( int pid ); void log_set_pid( int pid );
int log_get_errorcount( int clear ); int log_get_errorcount( int clear );
void log_hexdump( const char *text, char *buf, size_t len ); void log_hexdump( const char *text, char *buf, size_t len );
void log_mpidump( const char *text, MPI a ); void log_mpidump( const char *text, MPI a );
#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 5 ) #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, ... ) void log_bug( const char *fmt, ... )
__attribute__ ((noreturn, format (printf,1,2))); __attribute__ ((noreturn, format (printf,1,2)));
void log_bug0( const char *, int, const char * ) __attribute__ ((noreturn)); 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))); void log_debug( const char *fmt, ... ) __attribute__ ((format (printf,1,2)));
#define BUG() log_bug0( __FILE__ , __LINE__, __FUNCTION__ ) #define BUG() log_bug0( __FILE__ , __LINE__, __FUNCTION__ )
#else #else
void printstr( int level, const char *fmt, ... );
void log_bug( const char *fmt, ... ); void log_bug( const char *fmt, ... );
void log_bug0( const char *, int ); void log_bug0( const char *, int );
void log_fatal( const char *fmt, ... ); void log_fatal( const char *fmt, ... );

0
mpi/ChangeLog Normal file
View File

View File

@ -85,7 +85,6 @@ POSUB = @POSUB@
RANLIB = @RANLIB@ RANLIB = @RANLIB@
VERSION = @VERSION@ VERSION = @VERSION@
ZLIBS = @ZLIBS@ ZLIBS = @ZLIBS@
ZLIB_SUBDIR = @ZLIB_SUBDIR@
INCLUDES = -I$(top_srcdir)/include INCLUDES = -I$(top_srcdir)/include

View File

@ -118,7 +118,7 @@ mpi_read(IOBUF inp, unsigned *ret_nread, int secure)
leave: leave:
if( nread > *ret_nread ) if( nread > *ret_nread )
log_error("Ooops: mpi crosses packet border"); log_bug("mpi crosses packet border");
else else
*ret_nread = nread; *ret_nread = nread;
return val; return val;

View File

@ -35,6 +35,13 @@
#undef mpi_free #undef mpi_free
#endif #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 MPI
#ifdef M_DEBUG #ifdef M_DEBUG
mpi_debug_alloc( unsigned nlimbs, const char *info ) mpi_debug_alloc( unsigned nlimbs, const char *info )

View File

@ -1,5 +0,0 @@
Tue Feb 10 11:57:23 1998 Werner Koch (wk@frodo)
* ddd/hhhh:

View File

@ -18,6 +18,8 @@ echo "Unpacking previous and current tar"
tar xzf "g10-$curr_ver.tar.gz" tar xzf "g10-$curr_ver.tar.gz"
tar xzf "g10-$prev_ver.tar.gz" tar xzf "g10-$prev_ver.tar.gz"
read
echo "Diffing" echo "Diffing"
tmp_name="g10-$curr_ver.diff.tmp" tmp_name="g10-$curr_ver.diff.tmp"
diff_name="g10-$curr_ver.diff" diff_name="g10-$curr_ver.diff"
@ -44,6 +46,7 @@ Prereq: $prev_ver
EOF EOF
sed -ne '/^diff.*VERSION/,/^+[0-9][0-9]*/ p' $tmp_name >> $diff_name 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 sed -e '/^diff.*VERSION/,/^+[0-9][0-9]*/ d' $tmp_name >> $diff_name
rm $tmp_name rm $tmp_name

0
tools/ChangeLog Normal file
View File

View File

@ -85,7 +85,6 @@ POSUB = @POSUB@
RANLIB = @RANLIB@ RANLIB = @RANLIB@
VERSION = @VERSION@ VERSION = @VERSION@
ZLIBS = @ZLIBS@ ZLIBS = @ZLIBS@
ZLIB_SUBDIR = @ZLIB_SUBDIR@
INCLUDES = -I$(top_srcdir)/include INCLUDES = -I$(top_srcdir)/include
needed_libs = ../cipher/libcipher.a ../util/libutil.a ../mpi/libmpi.a ../util/libutil.a needed_libs = ../cipher/libcipher.a ../util/libutil.a ../mpi/libmpi.a ../util/libutil.a

18
util/ChangeLog Normal file
View File

@ -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.

View File

@ -85,7 +85,6 @@ POSUB = @POSUB@
RANLIB = @RANLIB@ RANLIB = @RANLIB@
VERSION = @VERSION@ VERSION = @VERSION@
ZLIBS = @ZLIBS@ ZLIBS = @ZLIBS@
ZLIB_SUBDIR = @ZLIB_SUBDIR@
INCLUDES = -I$(top_srcdir)/include INCLUDES = -I$(top_srcdir)/include

View File

@ -538,16 +538,31 @@ show_help( ARGPARSE_OPTS *opts, unsigned flags )
/* get max. length of long options */ /* get max. length of long options */
for(i=indent=0; opts[i].short_opt; i++ ) { for(i=indent=0; opts[i].short_opt; i++ ) {
if( opts[i].long_opt ) if( opts[i].long_opt )
if( !opts[i].description || *opts[i].description != '\v' )
if( (j=strlen(opts[i].long_opt)) > indent && j < 35 ) if( (j=strlen(opts[i].long_opt)) > indent && j < 35 )
indent = j; indent = j;
} }
/* example: " -v, --verbose Viele Sachen ausgeben" */ /* example: " -v, --verbose Viele Sachen ausgeben" */
indent += 10; indent += 10;
if( *opts[0].description != '\v' )
puts("Options:"); puts("Options:");
for(i=0; opts[i].short_opt; i++ ) { for(i=0; opts[i].short_opt; i++ ) {
s = _( opts[i].description ); s = _( opts[i].description );
if( s && *s== '\r' ) /* hide this line */ if( s && *s== '\r' ) /* hide this line */
continue; 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 ) if( opts[i].short_opt < 256 )
printf(" -%c", opts[i].short_opt ); printf(" -%c", opts[i].short_opt );
else else

View File

@ -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 int
iobuf_seek( IOBUF a, ulong newpos ) 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) ); log_error("can't seek to %lu: %s\n", newpos, strerror(errno) );
return -1; return -1;
} }
a->d.len = 0; /* discard buffer */
a->d.start = 0;
a->nbytes = 0;
a->nlimit = 0;
a->ntotal = newpos; a->ntotal = newpos;
/* remove filters, but the last */ /* remove filters, but the last */
while( a->chain ) while( a->chain )

View File

@ -26,8 +26,26 @@
#include "util.h" #include "util.h"
static char pidstring[15]; static char pidstring[15];
static char *pgm_name;
static int errorcount; 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 void
log_set_pid( int pid ) log_set_pid( int pid )
{ {
@ -46,45 +64,21 @@ log_get_errorcount( int clear)
return n; return n;
} }
static void
/**************** print_prefix(const char *text)
* 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, ... )
{ {
va_list arg_ptr ; if( pgm_name )
fprintf(stderr, "%s%s: %s", pgm_name, pidstring, text );
if( !level ) else
return; fprintf(stderr, "?%s: %s", pidstring, text );
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);
}
void void
log_info( const char *fmt, ... ) log_info( const char *fmt, ... )
{ {
va_list arg_ptr ; va_list arg_ptr ;
fprintf(stderr, "info%s: ", pidstring ) ; print_prefix("");
va_start( arg_ptr, fmt ) ; va_start( arg_ptr, fmt ) ;
vfprintf(stderr,fmt,arg_ptr) ; vfprintf(stderr,fmt,arg_ptr) ;
va_end(arg_ptr); va_end(arg_ptr);
@ -95,7 +89,7 @@ log_error( const char *fmt, ... )
{ {
va_list arg_ptr ; va_list arg_ptr ;
fprintf(stderr, "error%s: ", pidstring ) ; print_prefix("");
va_start( arg_ptr, fmt ) ; va_start( arg_ptr, fmt ) ;
vfprintf(stderr,fmt,arg_ptr) ; vfprintf(stderr,fmt,arg_ptr) ;
va_end(arg_ptr); va_end(arg_ptr);
@ -107,7 +101,7 @@ log_fatal( const char *fmt, ... )
{ {
va_list arg_ptr ; va_list arg_ptr ;
fprintf(stderr, "Fatal%s: ", pidstring ) ; print_prefix("fatal: ");
va_start( arg_ptr, fmt ) ; va_start( arg_ptr, fmt ) ;
vfprintf(stderr,fmt,arg_ptr) ; vfprintf(stderr,fmt,arg_ptr) ;
va_end(arg_ptr); va_end(arg_ptr);
@ -120,7 +114,8 @@ log_bug( const char *fmt, ... )
{ {
va_list arg_ptr ; va_list arg_ptr ;
fprintf(stderr, "\nInternal Error%s: ", pidstring ) ; putc('\n', stderr );
print_prefix("Ooops: ");
va_start( arg_ptr, fmt ) ; va_start( arg_ptr, fmt ) ;
vfprintf(stderr,fmt,arg_ptr) ; vfprintf(stderr,fmt,arg_ptr) ;
va_end(arg_ptr); va_end(arg_ptr);
@ -148,7 +143,7 @@ log_debug( const char *fmt, ... )
{ {
va_list arg_ptr ; va_list arg_ptr ;
fprintf(stderr, "DBG%s: ", pidstring ) ; print_prefix("DBG: ");
va_start( arg_ptr, fmt ) ; va_start( arg_ptr, fmt ) ;
vfprintf(stderr,fmt,arg_ptr) ; vfprintf(stderr,fmt,arg_ptr) ;
va_end(arg_ptr); va_end(arg_ptr);
@ -161,7 +156,7 @@ log_hexdump( const char *text, char *buf, size_t len )
{ {
int i; int i;
fprintf(stderr, "DBG%s: %s", pidstring, text ); print_prefix(text);
for(i=0; i < len; i++ ) for(i=0; i < len; i++ )
fprintf(stderr, " %02X", ((byte*)buf)[i] ); fprintf(stderr, " %02X", ((byte*)buf)[i] );
fputc('\n', stderr); fputc('\n', stderr);
@ -171,7 +166,7 @@ log_hexdump( const char *text, char *buf, size_t len )
void void
log_mpidump( const char *text, MPI a ) log_mpidump( const char *text, MPI a )
{ {
fprintf(stderr, "DBG%s: %s", pidstring, text ); print_prefix(text);
mpi_print(stderr, a, 1 ); mpi_print(stderr, a, 1 );
fputc('\n', stderr); fputc('\n', stderr);
} }

View File

@ -6,7 +6,13 @@
CFLAGS = -O -Wall CFLAGS = -O -Wall
EXTRA_DIST = README algorithm.doc ChangeLog example.c 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 noinst_LIBRARIES = libzlib.a
endif
libzlib_a_SOURCES = adler32.c compress.c crc32.c gzio.c \ 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 CLEANFILES = example foo.gz