1
0
mirror of git://git.gnupg.org/gnupg.git synced 2024-06-06 23:17:47 +02:00

This commit was manufactured by cvs2svn to create branch 'ePit-1-0'.

This commit is contained in:
Repo Admin 2000-05-30 15:31:45 +00:00
parent dcaaa9223e
commit ea887464b1
173 changed files with 34607 additions and 8116 deletions

96
AUTHORS
View File

@ -1,84 +1,59 @@
Authors of GNU Privacy Guard (GnuPG)
====================================
Program: GnuPG
Maintainer: Werner Koch <wk@gnupg.org>
GNUPG Werner Koch 1998-02-23
Assigns GNU Privacy Guard and future changes.
werner.koch@guug.de
Designed and implemented GnuPG.
Authors
=======
Daniel Resare <daniel@resare.com> xxxx [sv]
GNUPG Matthew Skala 1998-08-10
Disclaims changes.
mskala@ansuz.sooke.bc.ca
Wrote cipher/twofish.c.
Gael Queri <gqueri@mail.dotcom.fr> Translations [fr]
(fixed a lot of typos)
GNUPG Natural Resources Canada 1998-08-11
Disclaims changes by Matthew Skala.
Gregory Steuck <steuck@iname.com> Translations [ru]
Edmund GRIMLEY EVANS <edmundo@rano.org> Translations [eo]
GNUPG Michael Roth Germany 1998-09-17
Assigns changes.
mroth@nessie.de
Wrote cipher/des.c.
Changes and bug fixes all over the place.
Ivo Timmermans <itimmermans@bigfoot.com> Translations [nl]
Janusz Aleksander Urbanowicz <alex@bofh.torun.pl> Translations [po]
GNUPG Niklas Hernaeus 1998-09-18
Disclaims changes.
nh@df.lth.se
Weak key patches.
Michael Roth <mroth@nessie.de> Assignment
(wrote cipher/des.c., changes and bug fixes all over the place)
Marco d'Itri <md@linux.it> Translations [it]
GNUPG Rémi Guyomarch 1999-05-25
Assigns past and future changes. (g10/compress.c, g10/encr-data.c,
g10/free-packet.c, g10/mdfilter.c, g10/plaintext.c, util/iobuf.c)
rguyom@mail.dotcom.fr
Matthew Skala <mskala@ansuz.sooke.bc.ca> Disclaimer
(wrote cipher/twofish.c)
Niklas Hernaeus <nh@df.lth.se> Disclaimer
(weak key patches)
TRANSLATIONS Marco d'Itri 1997-02-22
Disclaimer. [it]
md@linux.it
Pedro Morais <morais@poli.org> Translations [pt_BR]
Rémi Guyomarch <rguyom@mail.dotcom.fr> Assignment
(g10/compress.c, g10/encr-data.c,
g10/free-packet.c, g10/mdfilter.c, g10/plaintext.c, util/iobuf.c)
TRANSLATIONS Gael Queri 1998-09-08
Disclaimer. [fr]
gqueri@mail.dotcom.fr
Fixed a lot of typos.
Tedi Heriyanto <tedi-h@usa.net> Translations [id]
Thiago Jung Bauermann <jungmann@cwb.matrix.com.br> Translations [pt_BR]
TRANSLATIONS Walter Koch 1998-09-08
Disclaimer. [de]
koch@hsp.de
Urko Lusa <ulusa@euskalnet.net> Translations [es_ES]
Walter Koch <koch@hsp.de> Translations [de]
TRANSLATIONS Gregory Steuck 1998-10-20
Disclaimer. [ru]
steuck@iname.com
Werner Koch <wk@gnupg.org> Assignment
(started the whole thing)
TRANSLATIONS Urko Lusa
Disclaimer. [es_ES]
ulusa@lacueva.ddns.org
TRANSLATIONS Thiago Jung Bauermann
Disclaimer. [pt_BR]
jungmann@cwb.matrix.com.br
TRANSLATIONS Pedro Morais
??????????. [pt_PT]
morais@poli.org
TRANSLATIONS Janusz Aleksander Urbanowicz 1999-01-09
Disclaimer. [po]
alex@bofh.torun.pl
Yosiaki IIDA <iida@secom.ne.jp> Translations [ja]
More credits
============
Other legal information
=======================
Natural Resources Canada disclaims changes by Matthew Skala.
This program uses the zlib compression library written by
Jean-loup Gailly and Mark Adler.
@ -87,7 +62,8 @@ Torbjorn Granlund <tege@noisy.tmg.se>.
The keybox implementation is based on GDBM 1.7.3 by Philip A. Nelson.
The file cipher/rndunix.c is based on rndunix.c from cryptlib.
The files cipher/rndunix.c and cipher/rndw32.c are based on rndunix.c
and rndwin32.c from cryptlib.
Copyright Peter Gutmann, Paul Kendall, and Chris Wedgwood 1996-1999.
The files in debian/ are by James Troup who is the Debian maintainer

60
BUGS
View File

@ -1,58 +1,8 @@
List of some known bugs
-------------------------
Please see
This following list contains those bugs which we are aware of. Please
make sure that bugs you report are not listed here. If you can fix one
of these bugs/limitations we will certainly be glad to receive a patch.
(Please note that we need a disclaimer if a patch is longer than about
10 lines; but it may help anyway to show us where we have to fix it. Do
an "info standards" to find out why a disclaimer is needed for GNU.)
http://www.gnupg.org/buglist.html
Format: severity: [ *] to [***], no, first reported, by, version.
Bugs which are marked with "FIX: yyyy-mm-dd" are fixed in the CVS
and after about half a day in the rsync snapshots.
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
for a list know bugs in GnuPG. We don't distribute this list anymore
with the package because a more current one with notes in which version
the bug is fixed can be found online.
[ *] #3
--list-packets should continue even w/o a passphrase (or in batch
mode). Maybe we have to move it to a separate program??
[ *] #4 1999-01-13 <ralf.stephan@fitug.de> 0.9.1
v3 key 'expiration date' problem:
1. generate a key, set expiration date
2. <do other things, deleting etc.>
3. edit a v3 secret key, try to set expiration date
- output: "You can't change...
4. save
5. key has expiration date from 1. and gpg reports that pubkey
and seckey differ.
The for loop the exp.date is set before v3 detection?
[is this bug still alive? - can someone please check it]
[ **] #6 1999-02-22 <backes@rhrk.uni-kl.de> 0.9.3
Bus error on IRIX 6.4: Crash while doing a keygen. I think while creating
the prime. Other bus errors are reported when doing a "gpg README"
on sparc-solaris2.6.
--> Solaris fixed.
--> IRIX bug still there but someone should test this again!
[ *] #18 1999-05-27 <Steffen.Zahn@icn.siemens.de> 0.9.7
rndunix hangs on hp/ux. The problem is related to my_plcose which is
not always called. (I suggest to use EGD instead of rndunix.)
[ *] #22 1999-07-22
Solaris make has problems with the generated POTFILES - seems to be a
gettext bug. Use GNU gmake as a workaround.
[ *] #23 1999-09-03 <todd.brooks@yale.edu> 0.9.11
Only the first signature of a cleartext sig seems to be verified.
Can't fix it in 1.0 because the code is semi-frozen.
HMMM: Can't reprodude the bug here - it just works. Check wehther
[ *] #24 1999-09-05 <marcus@yoyo.cc.monash.edu.au> 0.9.11
Does not link libc and libz expect when removing all "-lc -lz" except
for the last one. This happens on some systems when not using the
GNU ld. This need to be fixed in libtool.
Next #25

128
ChangeLog
View File

@ -1,5 +1,128 @@
Wed Sep 15 16:22:17 CEST 1999 Werner Koch <wk@isil.d.shuttle.de>
Tue May 30 16:37:55 CEST 2000 Werner Koch <wk@openit.de>
Version 1.0.1-ePit-1
Sun May 28 13:55:17 CEST 2000 Werner Koch <wk@openit.de>
* acinclude.m4 (GNUPG_SYS_NM_PARSE): Added BSDI support.
(GNUPG_CHECK_RDYNAMIC): Ditto.
Wed Apr 19 10:57:26 CEST 2000 Werner Koch <wk@openit.de>
* acconfig.h (HAVE_MLOCK): Added
Wed Mar 22 13:50:24 CET 2000 Werner Koch <wk@openit.de>
* acinclude.m4 (GNUPG_CHECK_MLOCK): Changed the way to test for
librt. Test suggested by Jeff Long.
Fri Mar 17 17:50:25 CET 2000 Werner Koch <wk@openit.de>
* acinclude.m4 (GNUPG_CHECK_MLOCK): Do librt check only when
we can't link a test program. This way GNU systems don't need
to link against linrt.
(GNUPG_CHECK_IPC): Fixed use of TRY_COMPILE macro. From Tim Mooney.
2000-03-14 12:07:54 Werner Koch (wk@habibti.openit.de)
* acinclude.m4 (GNUPG_SYS_SYMBOL_UNDERSCORE): Add support for
DJGPP.
(GNUPG_CHECK_MLOCK): Check whether mlock sits in librt.
* configure.in: Add a test for unisgned long long.
Tue Mar 7 18:45:31 CET 2000 Werner Koch <wk@gnupg.de>
* acinclude.m4 (GNUPG_CHECK_RDYNAMIC): Add NetBSD. By Thomas Klausner.
* configure.in (DYNLINK_MOD_CFLAGS): Set different for NetBSD.
Thu Mar 2 15:37:46 CET 2000 Werner Koch <wk@gnupg.de>
* configure.in: Add check for clock_gettime
Wed Feb 23 10:07:57 CET 2000 Werner Koch <wk@gnupg.de>
* configure.in (ALL_LINGUAS): Add nl.
Wed Feb 16 16:25:09 CET 2000 Werner Koch <wk@gnupg.de>
* configure.in (ALL_LINGUAS): Add Esperanto.
Wed Feb 16 14:09:00 CET 2000 Werner Koch <wk@gnupg.de>
* configure.in (ALL_LINGUAS): Add sv and ja.
* AUTHORS: Converted to a more compact format.
* INSTALL: Wrote a note about a Solaris problem.
Thu Feb 10 17:39:44 CET 2000 Werner Koch <wk@gnupg.de>
* configure.in: Use /usr/local for CFLAGS and LDFLAGS when
target is freebsd. By Rémi.
Thu Jan 13 19:31:58 CET 2000 Werner Koch <wk@gnupg.de>
* configure.in: Do not set development version when the version has
a dash in it. Suggested by Dave Dykstra.
Thu Dec 16 10:07:58 CET 1999 Werner Koch <wk@gnupg.de>
* VERSION: Set to 1.0.1.
* configure.in: Removed substitution for doc/gph/Makefile.
Do all the gcc warning only in maintainer mode.
Thu Dec 9 10:31:05 CET 1999 Werner Koch <wk@gnupg.de>
* INSTALL: Add a hint for AIX. By Jos Backus.
Sat Dec 4 12:30:28 CET 1999 Werner Koch <wk@gnupg.de>
* configure.in (dlopen): Use CHECK_FUNC for a test of dlopen in libc.
Suggested by Alexandre Oliva.
(-Wall): Moved the settting of gcc warning options near to the end
so that tests don't get confused. Suggested by Paul D. Smith.
Mon Nov 22 11:14:53 CET 1999 Werner Koch <wk@gnupg.de>
* BUGS: Replaced content with a link to the online list.
Fri Nov 12 20:33:19 CET 1999 Werner Koch <wk@gnupg.de>
* README: Fixed a type and add a note about the gnupg-i18n ML.
Thu Oct 28 16:08:20 CEST 1999 Werner Koch <wk@gnupg.de>
* acinclude.m4, configure.in (GNUPG_CHECK_GNUMAKE): New.
Sat Oct 9 20:34:41 CEST 1999 Werner Koch <wk@gnupg.de>
* configure.in: Tweaked handling of random modules and removed
dummy support for libgcrypt.
* Makefile.am: Removed libgcrypt support.
* cgrypt/ : Removed.
* Makefile.am: Removed libtool.
Fri Oct 8 20:32:01 CEST 1999 Werner Koch <wk@gnupg.de>
* configure.in: Fixed quoting in test for development version.
* THANKS: Add entries for Michael, Brenno and J Horacio who did
very nice Howto documents - I apoligize for forgetting to mention them
earlier.
Tue Sep 28 20:54:37 CEST 1999 Werner Koch <wk@gnupg.de>
* textfilter.c (copy_clearsig_text) [__MINGW32__): Use CR,LF.
Fri Sep 17 12:56:42 CEST 1999 Werner Koch <wk@isil.d.shuttle.de>
* configure.in: Add "-lcap" when capabilities are requested.
Add the conditional CROSS_COMPILING.
* Makefile.am: Don't use checks when CROSS_COMPILING.
Wed Sep 15 16:22:17 CEST 1999 Werner Koch <wk@isil.d.shuttle.de>
* configure.in (ALL_LINGUAS): Add pt_PT.
@ -8,12 +131,10 @@ Wed Sep 15 16:22:17 CEST 1999 Werner Koch <wk@isil.d.shuttle.de>
Tue Sep 7 17:08:10 CEST 1999 Werner Koch <wk@isil.d.shuttle.de>
* VERSION: Set to 1.0.0.
Mon Sep 6 19:59:08 CEST 1999 Werner Koch <wk@isil.d.shuttle.de>
* configure.in: Create makefile in doc/gph
* acinclude.m4 (GNUPG_FUNC_MKDIR_TAKES_ONE_ARG): New
@ -21,7 +142,6 @@ Mon Sep 6 19:59:08 CEST 1999 Werner Koch <wk@isil.d.shuttle.de>
Thu Sep 2 16:40:55 CEST 1999 Werner Koch <wk@isil.d.shuttle.de>
* VERSION: Set to 0.9.11.
Tue Aug 31 17:20:44 CEST 1999 Werner Koch <wk@isil.d.shuttle.de>

18
INSTALL
View File

@ -70,6 +70,24 @@ This doesn't matter and we know about it (actually it is due to the some
warning options which we have enabled for gcc)
Specific problems on some machines
==================================
* IBM RS/6000 running AIX:
Due to a change in gcc (since version 2.8) the MPI stuff may
not build. In this case try to run configure using:
CFLAGS="-g -O2 -mcpu=powerpc" ./configure
* Solaris
There are reports that the function gethrtime() as used in
cipher/random.c raised a SIGILL. It seems that is due to
a header/lib miscmatch. Solution is to fix the Solaris
installation or comment the call to gethrtime().
The Random Device
=================
Random devices are available in Linux, FreeBSD and OpenBSD.

View File

@ -1,19 +1,16 @@
## Process this file with automake to produce Makefile.in
if COMPILE_LIBGCRYPT
gcrypt = gcrypt
my_clean_gcrypt =
if CROSS_COMPILING
checks =
else
gcrypt =
my_clean_gcrypt = gcrypt/Makefile
checks = checks
endif
SUBDIRS = intl zlib util mpi cipher tools g10 po doc checks ${gcrypt}
SUBDIRS = intl zlib util mpi cipher tools g10 po doc ${checks}
EXTRA_DIST = VERSION PROJECTS BUGS
# gettext never gets it right, so we take here care of deleting the
# symlink. my_clean_gcrypt is just a kludge until we can include
# libgcrypt.
DISTCLEANFILES = g10defs.h intl/libintl.h ${my_clean_gcrypt}
# symlink.
DISTCLEANFILES = g10defs.h intl/libintl.h
dist-hook:
@set -e; \
@ -28,23 +25,6 @@ dist-hook:
sed -e 's/@pkg_version@/$(VERSION)/g' \
$(top_srcdir)/scripts/gnupg.spec.in \
> $(distdir)/scripts/gnupg.spec
-rm $(distdir)/gcrypt/*.[ch]
if MAINTAINER_MODE
# This is only useful within my local environment (wk)
cvs-get:
rsync -Cavuzb --exclude scratch --exclude .deps \
wkoch@sigtrap.guug.de:work/gnupg .
cvs-put:
rsync -Cavuzb --exclude .deps --exclude scratch \
. wkoch@sigtrap.guug.de:work/gnupg
cvs-sync: cvs-get cvs-put
endif
.PHONY: cvs-get cvs-put cvs-sync

79
NEWS
View File

@ -1,3 +1,82 @@
Noteworthy changes in version 1.0.1-ePit-1
------------------------------------------
* Fixed expiration handling of encryption keys.
* Add an experimental feature to do unattended key generation.
* The user is now asked for the reason of revocation as required
by the new OpenPGP draft.
* There is a ~/.gnupg/random_seed file now which saves the
state of the internal RNG and increases system performance
somewhat. This way the full entropy source is only used in
cases were it is really required.
Use the option --no-random-seed-file to disable this feature.
* New options --ignore-time-conflict and --lock-never.
* Some fixes for the W32 version.
* The entropy.dll is not anymore used by the W32 version but replaced
by code derived from Cryptlib.
* Encryption is now much faster: About 2 times for 1k bit keys
and 8 times for 4k keys.
* New encryption keys are generated in a way which allows a much
faster decryption.
* New command --export-secret-subkeys which outputs the
the _primary_ key with is's secret parts deleted. This is
useful for automated decryption/signature creation as it
allows to keep the real secret primary key offline and
thereby protecting the key certificates and allowing to
create revocations for the subkeys. See the FAQ for a
procedure to install such secret keys.
* Keygeneration now writes to the first writeable keyring or
as default to the one in the homedirectory. Prior versions
ignored all --keyring options.
* New option --command-fd to take user input from a file descriptor;
to be used with --status-fd by software which uses GnuPG as a backend.
* There is a new status PROGRESS which is used to show progress during
key generation.
Noteworthy changes in version 1.0.1 (1999-12-16)
-----------------------------------
* New command --verify-files. New option --fast-list-mode.
* $http_proxy is now used when --honor-http-proxy is set.
* Fixed some minor bugs and the problem with conventional encrypted
packets which did use the gpg v3 partial length headers.
* Add Indonesian and Portugese translations.
* Fixed a bug with symmetric-only encryption using the non-default 3DES.
The option --emulate-3des-s2k-bug may be used to decrypt documents
which have been encrypted this way; this should be done immediately
as this workaround will be remove in 1.1
* Can now handle (but not display) PGP's photo IDs. I don't know the
format of that packet but after stripping a few bytes from the start
it looks like a JPEG (at least my test data). Handling of this
package is required because otherwise it would mix up the
self signatures and you can't import those keys.
* Passing non-ascii user IDs on the commandline should now work in all
cases.
* New keys are now generated with an additional preference to Blowfish.
* Removed the GNU Privacy Handbook from the distribution as it will go
into a separate one.
Noteworthy changes in version 1.0.0 (1999-09-07)
-----------------------------------

19
NOTES
View File

@ -10,4 +10,23 @@ Some other reported cpu-vendor-os strings:
sparc-sun-solaris5.4
sparc-sun-sunos4.1.2
i386-pc-sysv4.2 (USL Unixware v1.1.2)
powerpc-ibm-aix4.3.2.0 John Payne <jcapayne@att.com>
gpg 1.0.1 okay with MP-RAS 3.02.01 Edition 5 using gcc 2.95.2 and EGD
By <CSpeicher@eisi.com>
gpg 1.0.1 okay with 4.0.1 BSDI BSD/OS 4.0 i386
rndw32 tested on:
Windows 98 4.10.1998 mit einem AMD-K6-2-450
Michael Engels <angel@dalrin.de>)
Windows 95 4.00.950a
Windows NT 4.00.1381

25
README
View File

@ -121,7 +121,7 @@
c) If you don't have any of the above programs, you have to verify
the MD5 checksum:
$ md5sum gnupg-x.y.z.tar.gz.sig
$ md5sum gnupg-x.y.z.tar.gz
This should yield an output similar_to this:
@ -135,10 +135,11 @@
Documentation
-------------
A draft version of the manual is included in the subdirectory doc/gph.
The supplied version is rendered in HTML and you may access it with any
browser (e.g.: lynx doc/gpg/index.html). The GnuPG webpages have a link
to the latest development version and you may want to read those instead.
The manual will be distributed separate under the name "gnupgdoc".
An online version of the latest manual draft is available at the
GnuPG web pages:
http://www.gnupg.org/gph/
A couple of HOWTO documents are available online; for a listing see:
@ -473,7 +474,7 @@
The primary WWW page is "http://www.gnupg.org"
The primary FTP site is "ftp://ftp.gnupg.org/pub/gcrypt/"
See http://www.gnupg.org/mirrors.html for a list of FTP mirrors
See http://www.gnupg.org/mirrors.html for a list of mirrors
and use them if possible. You may also find GnuPG mirrored on
some of the regular GNU mirrors.
@ -485,6 +486,8 @@
very low traffic.
gnupg-users@gnupg.org For general user discussion and
help.
gnupg-i18n@gnupg.org Discussion about internationalization
issues.
gnupg-devel@gnupg.org GnuPG developers main forum.
You subscribe to one of the list by sending mail with a subject
@ -508,11 +511,9 @@
the GNU service directory or search other resources.
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v0.9.11 (GNU/Linux)
Comment: For info see http://www.gnupg.org
iQB1AwUBN9QAwB0Z9MEMmFelAQG0XwMAqyH3UR0Jk+dm2ZkVoTqckGqmMMt5IdBN
MlG4g3dau5De8XXHvbQ45cUpU4CC0MOlEuKDp+CKOc+xbzczdH35qYt/5XKmVWS8
JwTvuKKCZ/95JRMk0ZMRueQduH7tSijZ
=MefQ
iQB1AwUBOEkX0B0Z9MEMmFelAQE2aQL/bo8po/atFACnG7eZBodfV0ikE+PFynOf
uzQjirp00hSFwP8jMmv+ccnlyZkHRwrhl/Xc8GCmmeATwtb1fuAWvCO51T1YIv3i
+K8Y6ThnQxG6TS0A/DBcoxwKpT7jEEPG
=WYfE
-----END PGP SIGNATURE-----

228
THANKS
View File

@ -3,109 +3,143 @@ reporting problems, suggesting various improvements or submitting actual
code. Here is a list of those people. Help me keep it complete and free of
errors.
Allan Clark allanc@sco.com
Anand Kumria wildfire@progsoc.uts.edu.au
Ariel T Glenn ariel@columbia.edu
Bodo Moeller Bodo_Moeller@public.uni-hamburg.de
Bryan Fullerton bryanf@samurai.com
Brian Moore bem@cmc.net
Brian Warner warner@lothar.com
Caskey L. Dickson caskey@technocage.com
Cees van de Griend cees-list@griend.xs4all.nl
Charles Levert charles@comm.polymtl.ca
Christian von Roques roques@pond.sub.org
Christopher Oliver oliver@fritz.traverse.net
Christian Recktenwald chris@citecs.de
Daniel Eisenbud eisenbud@cs.swarthmore.edu
Daniel Koening dan@mail.isis.de
David Ellement ellement@sdd.hp.com
Detlef Lannert lannert@lannert.rz.uni-duesseldorf.de
Dirk Lattermann dlatt@t-online.de
Ed Boraas ecxjo@esperanto.org
Enzo Michelangeli em@MailAndNews.com
Ernst Molitor ernst.molitor@uni-bonn.de
Fabio Coatti cova@felix.unife.it
Felix von Leitner leitner@amdiv.de
Frank Heckenbach heckenb@mi.uni-erlangen.de
Frank Stajano frank.stajano@cl.cam.ac.uk
Gaël Quéri gqueri@mail.dotcom.fr
Greg Louis glouis@dynamicro.on.ca
Greg Troxel gdt@ir.bbn.com
Gregory Steuck steuck@iname.com
Geoff Keating geoffk@ozemail.com.au
Harald Denker harry@hal.westfalen.de
Hendrik Buschkamp buschkamp@rheumanet.org
Holger Schurig holger@d.om.org
Hugh Daniel hugh@toad.com
Ian McKellar imckellar@harvestroad.com.au
Janusz A. Urbanowicz alex@bofh.torun.pl
James Troup james@nocrew.org
Jean-loup Gailly gzip@prep.ai.mit.edu
Jens Bachem bachem@rrz.uni-koeln.de
Joachim Backes backes@rhrk.uni-kl.de
John A. Martin jam@jamux.com
Johnny Teveßen j.tevessen@gmx.de
Jörg Schilling schilling@fokus.gmd.de
Jun Kuriyama kuriyama@sky.rim.or.jp
Karl Fogel kfogel@guanabana.onshore.com
Karsten Thygesen karthy@kom.auc.dk
Katsuhiro Kondou kondou@nec.co.jp
Kazu Yamamoto kazu@iijlab.net
Lars Kellogg-Stedman lars@bu.edu
Marco d'Itri md@linux.it
Mark Adler madler@alumni.caltech.edu
Mark Elbrecht snowball3@bigfoot.com
Markus Friedl Markus.Friedl@informatik.uni-erlangen.de
Martin Kahlert martin.kahlert@provi.de
Adam Mitchell adam@cafe21.org
Alec Habig habig@budoe2.bu.edu
Allan Clark allanc@sco.com
Anand Kumria wildfire@progsoc.uts.edu.au
Ariel T Glenn ariel@columbia.edu
Bodo Moeller Bodo_Moeller@public.uni-hamburg.de
Brenno de Winter brenno@dewinter.com
Brian Moore bem@cmc.net
Brian Warner warner@lothar.com
Bryan Fullerton bryanf@samurai.com
Caskey L. Dickson caskey@technocage.com
Cees van de Griend cees-list@griend.xs4all.nl
Charles Levert charles@comm.polymtl.ca
Chip Salzenberg chip@valinux.com
Christian Kurz shorty@debian.org
Christian von Roques roques@pond.sub.org
Christopher Oliver oliver@fritz.traverse.net
Christian Recktenwald chris@citecs.de
Daniel Eisenbud eisenbud@cs.swarthmore.edu
Daniel Koening dan@mail.isis.de
Daniel Resare daniel@resare.com
Detlef Lannert lannert@lannert.rz.uni-duesseldorf.de
Dave Dykstra dwd@bell-labs.com
David Ellement ellement@sdd.hp.com
David Hallinan hallinan@rtd.com
Dirk Lattermann dlatt@t-online.de
Ed Boraas ecxjo@esperanto.org
Edmund GRIMLEY EVANS edmundo@rano.org
Enzo Michelangeli em@MailAndNews.com
Ernst Molitor ernst.molitor@uni-bonn.de
Fabio Coatti cova@felix.unife.it
Felix von Leitner leitner@amdiv.de
Frank Donahoe fdonahoe@wilkes1.wilkes.edu
Frank Heckenbach heckenb@mi.uni-erlangen.de
Frank Stajano frank.stajano@cl.cam.ac.uk
Frank Tobin ftobin@uiuc.edu
Gaël Quéri gqueri@mail.dotcom.fr
Greg Louis glouis@dynamicro.on.ca
Greg Troxel gdt@ir.bbn.com
Gregory Steuck steuck@iname.com
Geoff Keating geoffk@ozemail.com.au
Harald Denker harry@hal.westfalen.de
Hendrik Buschkamp buschkamp@rheumanet.org
Holger Schurig holger@d.om.org
Holger Smolinski smolinsk@de.ibm.com
Holger Trapp Holger.Trapp@informatik.tu-chemnitz.de
Hugh Daniel hugh@toad.com
Huy Le huyle@ugcs.caltech.edu
Ian McKellar imckellar@harvestroad.com.au
Ivo Timmermans itimmermans@bigfoot.com
Jan Krueger max@physics.otago.ac.nz
Janusz A. Urbanowicz alex@bofh.torun.pl
James Troup james@nocrew.org
Jean-loup Gailly gzip@prep.ai.mit.edu
Jeff Long long@kestrel.cc.ukans.edu
Jens Bachem bachem@rrz.uni-koeln.de
J Horacio MG homega@ciberia.es
Joachim Backes backes@rhrk.uni-kl.de
John A. Martin jam@jamux.com
Johnny Teveßen j.tevessen@gmx.de
Jörg Schilling schilling@fokus.gmd.de
Jos Backus Jos.Backus@nl.origin-it.com
Jun Kuriyama kuriyama@sky.rim.or.jp
Karl Fogel kfogel@guanabana.onshore.com
Karsten Thygesen karthy@kom.auc.dk
Katsuhiro Kondou kondou@nec.co.jp
Kazu Yamamoto kazu@iijlab.net
Lars Kellogg-Stedman lars@bu.edu
L. Sassaman rabbi@quickie.net
Marco d'Itri md@linux.it
Mark Adler madler@alumni.caltech.edu
Mark Elbrecht snowball3@bigfoot.com
Markus Friedl Markus.Friedl@informatik.uni-erlangen.de
Martin Kahlert martin.kahlert@provi.de
Martin Hamilton
Martin Schulte schulte@thp.uni-koeln.de
Matthew Skala mskala@ansuz.sooke.bc.ca
Max Valianskiy maxcom@maxcom.ml.org
Michael Roth mroth@nessie.de
Michael Sobolev mss@despair.transas.com
Nicolas Graner Nicolas.Graner@cri.u-psud.fr
NIIBE Yutaka gniibe@chroot.org
Martin Schulte schulte@thp.uni-koeln.de
Matthew Skala mskala@ansuz.sooke.bc.ca
Max Valianskiy maxcom@maxcom.ml.org
Michael Fischer v. Mollard mfvm@gmx.de
Michael Roth mroth@nessie.de
Michael Sobolev mss@despair.transas.com
Nicolas Graner Nicolas.Graner@cri.u-psud.fr
Mike McEwan mike@lotusland.demon.co.uk
NIIBE Yutaka gniibe@chroot.org
Niklas Hernaeus
Nimrod Zimerman zimerman@forfree.at
N J Doye nic@niss.ac.uk
Oliver Haakert haakert@hsp.de
Oskari Jääskeläinen f33003a@cc.hut.fi
Paul D. Smith psmith@baynetworks.com
Philippe Laliberte arsphl@oeil.qc.ca
Peter Gutmann pgut001@cs.auckland.ac.nz
QingLong qinglong@bolizm.ihep.su
Ralph Gillen gillen@theochem.uni-duesseldorf.de
Rat ratinox@peorth.gweep.net
Reinhard Wobst R.Wobst@ifw-dresden.de
Rémi Guyomarch rguyom@mail.dotcom.fr
Reuben Sumner rasumner@wisdom.weizmann.ac.il
Roddy Strachan roddy@satlink.com.au
Roland Rosenfeld roland@spinnaker.rhein.de
Ross Golder rossigee@bigfoot.com
Serge Munhoven munhoven@mema.ucl.ac.be
SL Baur steve@xemacs.org
Stefan Karrmann S.Karrmann@gmx.net
Stefan Keller dres@cs.tu-berlin.de
Steffen Ullrich ccrlphr@xensei.com
Steffen Zahn zahn@berlin.snafu.de
Steven Bakker steven@icoe.att.com
Susanne Schultz schultz@hsp.de
Thiago Jung Bauermann jungmann@cwb.matrix.com.br
Thomas Roessler roessler@guug.de
Tom Spindler dogcow@home.merit.edu
Tom Zerucha tzeruch@ceddec.com
Tomas Fasth tomas.fasth@twinspot.net
Thomas Mikkelsen tbm@image.dk
Ulf Möller 3umoelle@informatik.uni-hamburg.de
Urko Lusa ulusa@lacueva.ddns.org
Walter Koch koch@hsp.de
Werner Koch werner.koch@guug.de
Wim Vandeputte bunbun@reptile.rug.ac.be
nbecker@hns.com
Nimrod Zimerman zimerman@forfree.at
N J Doye nic@niss.ac.uk
Oliver Haakert haakert@hsp.de
Oskari Jääskeläinen f33003a@cc.hut.fi
Paul D. Smith psmith@baynetworks.com
Philippe Laliberte arsphl@oeil.qc.ca
Peter Gutmann pgut001@cs.auckland.ac.nz
QingLong qinglong@bolizm.ihep.su
Ralph Gillen gillen@theochem.uni-duesseldorf.de
Rat ratinox@peorth.gweep.net
Reinhard Wobst R.Wobst@ifw-dresden.de
Rémi Guyomarch rguyom@mail.dotcom.fr
Reuben Sumner rasumner@wisdom.weizmann.ac.il
Richard Outerbridge outer@interlog.com
Roddy Strachan roddy@satlink.com.au
Roland Rosenfeld roland@spinnaker.rhein.de
Ross Golder rossigee@bigfoot.com
Sam Roberts sam@cogent.ca
Sean MacLennan seanm@netwinder.org
Serge Munhoven munhoven@mema.ucl.ac.be
SL Baur steve@xemacs.org
Stefan Karrmann S.Karrmann@gmx.net
Stefan Keller dres@cs.tu-berlin.de
Steffen Ullrich ccrlphr@xensei.com
Steffen Zahn zahn@berlin.snafu.de
Steven Bakker steven@icoe.att.com
Susanne Schultz schultz@hsp.de
Thiago Jung Bauermann jungmann@cwb.matrix.com.br
Thomas Roessler roessler@guug.de
Tim Mooney mooney@dogbert.cc.ndsu.nodak.edu
Tom Spindler dogcow@home.merit.edu
Tom Zerucha tzeruch@ceddec.com
Tomas Fasth tomas.fasth@twinspot.net
Thomas Klausner wiz@danbala.ifoer.tuwien.ac.at
Thomas Mikkelsen tbm@image.dk
Ulf Möller 3umoelle@informatik.uni-hamburg.de
Urko Lusa ulusa@euskalnet.net
Walter Hofmann Walter.Hofmann@physik.stud.uni-erlangen.de
Walter Koch koch@hsp.de
Wayne Chapeskie waynec@spinnaker.com
Werner Koch wk@gnupg.org
Wim Vandeputte bunbun@reptile.rug.ac.be
Yosiaki IIDA iida@secom.ne.jp
Yoshihiro Kajiki kajiki@ylug.org
nbecker@hns.com
Thanks to the German Unix User Group for providing FTP space,
Martin Hamilton for hosting the mailing list and HSP for
hosting gnupg.org.
The development of this software has partly been funded by the German
Ministry for Economics and Technology under grant VIB3-68553.168-001/1999.
Many thanks to my wife Gerlinde for having so much patience with
me while hacking late in the evening.

23
TODO
View File

@ -1,6 +1,25 @@
* g10/trustdb.c (make_sig_records): fix the fixme.
* at least an option to prefer DSA keys over RSA when selecting the key to
use. Depending on creation time would be nice too. I think this is
already done for the subkeys - check it.
* Fix localtime() in W32.
* export sollte exit(1) machen bei einem Fehler - testen! Es wird ein
leerer File erzeugt. Nur unter Windows?
* No TCP support yet for W32? arggg - should go into a separate program
anyway.
Scheduled for 1.1
-----------------
* Rework the whole key selection stuff: Compile a list of valid
candidates for a keyblock first and the select one from it.
The current code is too ugly (getkey.c).
* With option -i prompt before adding a key to the keyring and show some
info what we are about to add.
@ -22,6 +41,9 @@ Scheduled for 1.1
* Check the beginning of file to detect already compressed files (gzip,
bzip2, xdelta and some picture formats)
* Delay the read of the passphrase-fd after a NEED_PASSPHRASE. But this
may break some scripts.
Nice to have
------------
@ -51,5 +73,4 @@ Nice to have
trustdb.
* Evaluate whether it make sense to replace the namehashs either by
using the user ID directly or by using pointers into the trustdb.
* --gen-prime may trigger a log_bug; should be a log_fatal.

View File

@ -1 +1 @@
1.0.0a
1.0.1-ePit-1

View File

@ -53,6 +53,7 @@
#undef HAVE_STPCPY
#undef HAVE_MLOCK
#undef BIG_ENDIAN_HOST
#undef LITTLE_ENDIAN_HOST

View File

@ -27,6 +27,24 @@ AC_DEFUN(GNUPG_CHECK_TYPEDEF,
])
dnl GNUPG_CHECK_GNUMAKE
dnl
AC_DEFUN(GNUPG_CHECK_GNUMAKE,
[
if ${MAKE-make} --version 2>/dev/null | grep '^GNU ' >/dev/null 2>&1; then
:
else
AC_MSG_WARN([[
***
*** It seems that you are not using GNU make. Some make tools have serious
*** flaws and you may not be able to build this software at all. Before you
*** complain, please try GNU make: GNU make is easy to build and available
*** at all GNU archives. It is always available from ftp.gnu.org:/gnu/make.
***]])
fi
])
dnl GNUPG_LINK_FILES( SRC, DEST )
dnl same as AC_LINK_FILES, but collect the files to link in
@ -208,7 +226,7 @@ define(GNUPG_CHECK_RDYNAMIC,
CFLAGS_RDYNAMIC="-Wl,-E"
;;
openbsd* | freebsd2* | osf4* | irix* )
openbsd* | freebsd2* | osf4* | irix* | netbsd* | bsdi* )
CFLAGS_RDYNAMIC=""
;;
@ -275,7 +293,8 @@ define(GNUPG_CHECK_IPC,
AC_TRY_COMPILE([#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/shm.h>],[
int foo( int shm_id ) { shmctl(shm_id, SHM_LOCK, 0); }
int shm_id;
shmctl(shm_id, SHM_LOCK, 0);
],
gnupg_cv_ipc_have_shm_lock="yes",
gnupg_cv_ipc_have_shm_lock="no"
@ -294,11 +313,46 @@ define(GNUPG_CHECK_IPC,
######################################################################
# Check whether mlock is broken (hpux 10.20 raises a SIGBUS if mlock
# is not called from uid 0 (not tested whether uid 0 works)
# For DECs Tru64 we have also to check whether mlock is in librt
# mlock is there a macro using memlk()
######################################################################
dnl GNUPG_CHECK_MLOCK
dnl
define(GNUPG_CHECK_MLOCK,
[ AC_CHECK_FUNCS(mlock)
if test "$ac_cv_func_mlock" = "no"; then
AC_CHECK_HEADERS(sys/mman.h)
if test "$ac_cv_header_sys_mman_h" = "yes"; then
# Add librt to LIBS:
AC_CHECK_LIB(rt, memlk)
AC_CACHE_CHECK([whether mlock is in sys/mman.h],
gnupg_cv_mlock_is_in_sys_mman,
[AC_TRY_LINK([
#include <assert.h>
#ifdef HAVE_SYS_MMAN_H
#include <sys/mman.h>
#endif
], [
mkdir ("foo", 0);
int i;
/* glibc defines this for functions which it implements
* to always fail with ENOSYS. Some functions are actually
* named something starting with __ and the normal name
* is an alias. */
#if defined (__stub_mlock) || defined (__stub___mlock)
choke me
#else
mlock(&i, 4);
#endif
; return 0;
],
gnupg_cv_mlock_is_in_sys_mman=yes,
gnupg_cv_mlock_is_in_sys_mman=no)])
if test "$gnupg_cv_mlock_is_in_sys_mman" = "yes"; then
AC_DEFINE(HAVE_MLOCK)
fi
fi
fi
if test "$ac_cv_func_mlock" = "yes"; then
AC_MSG_CHECKING(whether mlock is broken)
AC_CACHE_VAL(gnupg_cv_have_broken_mlock,
@ -409,7 +463,7 @@ case "$host_os" in
aix*)
ac_symcode='[BCDTU]'
;;
freebsd* | netbsd* | openbsd* | sunos* | cygwin32* | mingw32*)
freebsd* | netbsd* | openbsd* | bsdi* | sunos* | cygwin32* | mingw32*)
ac_sympat='_\([_A-Za-z][_A-Za-z0-9]*\)'
ac_symxfrm='_\1 \1'
;;
@ -562,7 +616,7 @@ AC_CHECK_TOOL(AS, as, false)
AC_DEFUN(GNUPG_SYS_SYMBOL_UNDERSCORE,
[tmp_do_check="no"
case "${target}" in
i386-emx-os2 | i[3456]86-pc-os2*emx )
i386-emx-os2 | i[3456]86-pc-os2*emx | i386-pc-msdosdjgpp)
ac_cv_sys_symbol_underscore=yes
;;
*)
@ -633,7 +687,7 @@ AC_DEFUN(GNUPG_FUNC_MKDIR_TAKES_ONE_ARG,
#ifdef HAVE_DIRECT_H
# include <direct.h>
#endif], [mkdir ("foo", 0);],
gnupg_cv_mkdir_takes_one_arg=no, gnupg_cv_mkdir_takes_one_arg=yes)])
gnupg_cv_mkdir_takes_one_arg=no, gnupg_cv_mkdir_takes_one_arg=yes)])
if test $gnupg_cv_mkdir_takes_one_arg = yes ; then
AC_DEFINE(MKDIR_TAKES_ONE_ARG)
fi

View File

@ -1,11 +1,22 @@
Tue Aug 31 17:20:44 CEST 1999 Werner Koch <wk@isil.d.shuttle.de>
Thu Feb 10 17:39:44 CET 2000 Werner Koch <wk@gnupg.de>
* mkdemodirs: Fixed the --clean loop.
Thu Jan 13 19:31:58 CET 2000 Werner Koch <wk@gnupg.de>
* defs.inc (chdir): Removed becuase it is unsused an plain old sh
does not like this name. Reported by Alec Habig.
Tue Oct 26 20:02:23 1999 Werner Koch (wk@gnupg.org)
* Makefile.am (GPG_DEARMOR): New and use --no-options.
Tue Aug 31 17:20:44 CEST 1999 Werner Koch <wk@isil.d.shuttle.de>
* defs.inc: set LC_ALL empty
Wed Aug 4 10:34:18 CEST 1999 Werner Koch <wk@isil.d.shuttle.de>
* defs.inc (echo_n): New and used instead of /bin/echo "\c"
Sun Apr 18 10:11:28 CEST 1999 Werner Koch <wk@isil.d.shuttle.de>

View File

@ -1,5 +1,7 @@
## Process this file with automake to create Makefile.in
GPG_DEARMOR = ../g10/gpg --no-options --quiet --yes --dearmor
TESTS = version.test mds.test \
decrypt.test decrypt-dsa.test \
sigs.test sigs-dsa.test \
@ -37,25 +39,25 @@ prepared.stamp: ./pubring.gpg ./secring.gpg ./plain-1 ./plain-2 ./plain-3 \
./pubring.gpg: $(srcdir)/pubring.asc
../g10/gpg --yes --dearmor -o ./pubring.gpg $(srcdir)/pubring.asc
$(GPG_DEARMOR) -o ./pubring.gpg $(srcdir)/pubring.asc
./secring.gpg: $(srcdir)/secring.asc
../g10/gpg --yes --dearmor -o ./secring.gpg $(srcdir)/secring.asc
$(GPG_DEARMOR) -o ./secring.gpg $(srcdir)/secring.asc
./pubring.pkr: $(srcdir)/pubring.pkr.asc
../g10/gpg --yes --dearmor -o ./pubring.pkr $(srcdir)/pubring.pkr.asc
$(GPG_DEARMOR) -o ./pubring.pkr $(srcdir)/pubring.pkr.asc
./secring.skr: $(srcdir)/secring.skr.asc
../g10/gpg --yes --dearmor -o ./secring.skr $(srcdir)/secring.skr.asc
$(GPG_DEARMOR) -o ./secring.skr $(srcdir)/secring.skr.asc
./plain-1: $(srcdir)/plain-1o.asc
../g10/gpg --yes --dearmor -o ./plain-1 $(srcdir)/plain-1o.asc
$(GPG_DEARMOR) -o ./plain-1 $(srcdir)/plain-1o.asc
./plain-2: $(srcdir)/plain-2o.asc
../g10/gpg --yes --dearmor -o ./plain-2 $(srcdir)/plain-2o.asc
$(GPG_DEARMOR) -o ./plain-2 $(srcdir)/plain-2o.asc
./plain-3: $(srcdir)/plain-3o.asc
../g10/gpg --yes --dearmor -o ./plain-3 $(srcdir)/plain-3o.asc
$(GPG_DEARMOR) -o ./plain-3 $(srcdir)/plain-3o.asc

View File

@ -48,9 +48,6 @@ info () {
echo "$pgmname:" $* >&2
}
chdir () {
cd $1 || fatal "cannot cd to $1"
}
echo_n_init=no
echo_n () {

View File

@ -8,9 +8,9 @@ NAMES='Alpha Bravo Charlie Delta Echo Foxtrot Golf Hotel India
Sierra Tango Uniform Victor Whisky XRay Yankee Zulu'
if [ "$1" = "--clean" ]; then
for i in $NAMES; do
(for i in $NAMES; do
[ -d $i ] && rm -r $i
done
done) || true
exit 0
fi
@ -24,10 +24,10 @@ for name in $NAMES; do
/bin/echo " $name\c"
[ -d $name ] && rm -r $name
mkdir $name
$GPGDEMO --export-secret-key -o - $name | tee $name/Secret.gpg | \
$GPG --homedir $name --import
$GPGDEMO --export -o - $name | tee $name/Public.gpg | \
$GPG --homedir $name --import
$GPGDEMO --export-secret-key -o - $name > $name/Secret.gpg
$GPG --homedir $name --import $name/Secret.gpg
$GPGDEMO --export -o - $name > $name/Public.gpg
$GPG --homedir $name --import $name/Public.gpg
[ -f $name/pubring.gpg~ ] && rm $name/pubring.gpg~
done
echo "."

View File

@ -1,5 +1,137 @@
Wed Sep 15 16:22:17 CEST 1999 Werner Koch <wk@isil.d.shuttle.de>
Sun May 28 13:55:17 CEST 2000 Werner Koch <wk@openit.de>
* random.c (read_seed_file): Binary open for DOSish system
(update_random_seed_file): Ditto.
* rndw32.c: Add some debuging code enabled by an environment variable.
Tue May 23 09:19:00 CEST 2000 Werner Koch <wk@openit.de>
* rndw32.c: Started with alternative code to replace entropy.dll
Thu May 18 11:38:54 CEST 2000 Werner Koch <wk@openit.de>
* primegen.c (register_primegen_progress): New.
* dsa.c (register_pk_dsa_progress): New.
* elgamal.c (register_pk_elg_progress): New.
Fri Apr 14 19:37:08 CEST 2000 Werner Koch <wk@openit.de>
* twofish.c (twofish_get_info): Fixed warning about cast.
Tue Mar 28 14:26:58 CEST 2000 Werner Koch <wk@openit.de>
* random.c [MINGW32]: Include process.h for getpid.
Thu Mar 2 15:37:46 CET 2000 Werner Koch <wk@gnupg.de>
* random.c (fast_random_poll): Add clock_gettime() as fallback for
system which support this POSIX.4 fucntion. By Sam Roberts.
* rndunix.c: Add some more headers for QNX. By Sam Roberts.
* random.c (read_seed_file): Removed the S_ISLNK test becuase it
is already covered by !S_ISREG and is not defined in Unixware.
Reported by Dave Dykstra.
* sha1.c (sha1_get_info): Removed those stupid double lines. Dave
is really a good lint.
Wed Feb 23 10:07:57 CET 2000 Werner Koch <wk@gnupg.de>
* twofish.c (twofish_get_info): Add some const to the casts. By Martin
Kahlert.
Mon Feb 14 14:30:20 CET 2000 Werner Koch <wk@gnupg.de>
(update_random_seed_file): Silently ignore update request when pool
is not filled.
Fri Feb 11 17:44:40 CET 2000 Werner Koch <wk@gnupg.de>
* random.c (read_seed_file): New.
(set_random_seed_file): New.
(read_pool): Try to read the seeding file.
(update_random_seed_file): New.
(read_pool): Do an initial extra seeding when level 2 quality random
is requested the first time. This requestes at least POOLSIZE/2 bytes
of entropy. Compined with the seeding file this should make normal
random bytes cheaper and increase the quality of the random bytes
used for key generation.
* rndegd.c (gather_random): Shortcut level 0.
* rndunix.c (gather_random): Ditto.
* rndw32.c (gather_random): Ditto.
Fri Jan 14 18:32:01 CET 2000 Werner Koch <wk@gnupg.de>
* rmd160.c (rmd160_get_info): Moved casting to the left side due to a
problem with UTS4.3. Suggested by Dave Dykstra.
* sha1.c (sha1_get_info): Ditto.
* tiger.c (tiger_get_info): Ditto.
* md5.c (md5_get_info): Ditto
* des.c (des_get_info): Ditto.
* blowfish.c (blowfish_get_info): Ditto.
* cast5.c (cast5_get_info): Ditto.
* twofish.c (twofish_get_info): Ditto.
Thu Jan 13 19:31:58 CET 2000 Werner Koch <wk@gnupg.de>
* elgamal.c (wiener_map): New.
(gen_k): Use a much smaller k.
(generate): Calculate the qbits using the wiener map and
choose an x at a size comparable to the one choosen in gen_k
* random.c (read_pool): Print a more friendly error message in
cases when too much random is requested in one call.
* Makefile.am (tiger): Replaced -O1 by -O. Suggested by Alec Habig.
Sat Dec 4 12:30:28 CET 1999 Werner Koch <wk@gnupg.de>
* primegen.c (generate_elg_prime): All primes are now generated with
the lowest random quality level. Becuase they are public anyway we
don't need stronger random and by this we do not drain the systems
entropy so much.
Thu Oct 28 16:08:20 CEST 1999 Werner Koch <wk@gnupg.de>
* random.c (fast_random_poll): Check whether RUSAGE_SELF is defined;
this is not the case for some ESIX and Unixware, although they have
getrusage().
* elgamal.c (sign): Hugh found strange code here. Replaced by BUG().
Mon Oct 11 09:24:12 CEST 1999 Werner Koch <wk@gnupg.de>
* rndw32.c (gather_random): Handle PCP_SEEDER_TOO_SMALL.
Sat Oct 9 20:34:41 CEST 1999 Werner Koch <wk@gnupg.de>
* Makefile.am: Tweaked module build and removed libtool
Fri Oct 8 20:32:01 CEST 1999 Werner Koch <wk@gnupg.de>
* rndw32.c (load_and_init_winseed): Use the Registry to locate the DLL
Mon Oct 4 21:23:04 CEST 1999 Werner Koch <wk@gnupg.de>
* md.c (md_reset): Clear finalized; thanks to Ulf Moeller for
fixing this bug.
Sat Sep 18 12:51:51 CEST 1999 Werner Koch <wk@isil.d.shuttle.de>
* Makefile.am: Never compile mingw32 as module
Wed Sep 15 14:39:59 CEST 1999 Michael Roth <mroth@nessie.de>
* des.c: Various speed improvements: One bit pre rotation
trick after initial permutation (Richard Outerbridge).
Finished test of SSLeay Tripple-DES patterns.
Wed Sep 15 16:22:17 CEST 1999 Werner Koch <wk@isil.d.shuttle.de>
* rndw32.c: New.

View File

@ -3,17 +3,10 @@
INCLUDES = -I$(top_srcdir)/include -I$(top_srcdir)/intl
noinst_LTLIBRARIES = libcipher.la
noinst_LIBRARIES = libcipher.a
# The configure script greps the module names from the following lines.
# You must also add all these names to EXTRA_PROGRAMS some lines below
# and EXTRA_foo_SOURCES entries.
# Hmmm is there a more easy way to do this? (EXTRA_PROGRAMS
# might also list programs which are not modules)
# MODULES: rndunix rndlinux rndegd rndw32
# MODULES: sha1 rmd160 md5 tiger
EXTRA_PROGRAMS = rndunix rndlinux rndegd rndw32 \
sha1 rmd160 md5 tiger
# The configure script greps the module names from the EXTRA_PROGRAMS line
EXTRA_PROGRAMS = rndlinux rndunix rndegd rndw32 sha1 rmd160 md5 tiger
EXTRA_rndlinux_SOURCES = rndlinux.c
EXTRA_rndunix_SOURCES = rndunix.c
@ -34,8 +27,8 @@ endif
DYNLINK_MOD_CFLAGS = -DIS_MODULE @DYNLINK_MOD_CFLAGS@
libcipher_la_LDFLAGS =
libcipher_la_SOURCES = cipher.c \
#libcipher_a_LDFLAGS =
libcipher_a_SOURCES = cipher.c \
pubkey.c \
md.c \
dynload.c \
@ -65,8 +58,8 @@ libcipher_la_SOURCES = cipher.c \
BUILT_SOURCES = construct.c
libcipher_la_DEPENDENCIES = @STATIC_CIPHER_OBJS@
libcipher_la_LIBADD = @STATIC_CIPHER_OBJS@
libcipher_a_DEPENDENCIES = @STATIC_CIPHER_OBJS@
libcipher_a_LIBADD = @STATIC_CIPHER_OBJS@
# If I remember it correct, automake 1.4 has a feature to set
@ -74,7 +67,7 @@ libcipher_la_LIBADD = @STATIC_CIPHER_OBJS@
tiger: $(srcdir)/tiger.c
`echo $(COMPILE) $(DYNLINK_MOD_CFLAGS) -o tiger $(srcdir)/tiger.c | \
sed -e 's/-O[2-9s]*/-O1/g' `
sed -e 's/-O[2-9s]*/-O/g' `
tiger.o: $(srcdir)/tiger.c
`echo $(COMPILE) -c $(srcdir)/tiger.c | sed -e 's/-O[2-9s]*/-O1/g' `
@ -99,4 +92,3 @@ rndlinux: $(srcdir)/rndlinux.c
rndegd: $(srcdir)/rndegd.c
$(COMPILE) $(DYNLINK_MOD_CFLAGS) -o rndegd $(srcdir)/rndegd.c

View File

@ -43,9 +43,6 @@
#define CIPHER_ALGO_BLOWFISH 4 /* blowfish 128 bit key */
#define FNCCAST_SETKEY(f) (int(*)(void*, byte*, unsigned))(f)
#define FNCCAST_CRYPT(f) (void(*)(void*, byte*, byte*))(f)
#define BLOWFISH_BLOCKSIZE 8
#define BLOWFISH_ROUNDS 16
@ -584,9 +581,12 @@ blowfish_get_info( int algo, size_t *keylen,
*keylen = 128;
*blocksize = BLOWFISH_BLOCKSIZE;
*contextsize = sizeof(BLOWFISH_context);
*r_setkey = FNCCAST_SETKEY(bf_setkey);
*r_encrypt= FNCCAST_CRYPT(encrypt_block);
*r_decrypt= FNCCAST_CRYPT(decrypt_block);
*(int (**)(BLOWFISH_context*, byte*, unsigned))r_setkey
= bf_setkey;
*(void (**)(BLOWFISH_context*, byte*, byte*))r_encrypt
= encrypt_block;
*(void (**)(BLOWFISH_context*, byte*, byte*))r_decrypt
= decrypt_block;
if( algo == CIPHER_ALGO_BLOWFISH )
return "BLOWFISH";

View File

@ -46,9 +46,6 @@
#define CIPHER_ALGO_CAST5 3
#define FNCCAST_SETKEY(f) (int(*)(void*, byte*, unsigned))(f)
#define FNCCAST_CRYPT(f) (void(*)(void*, byte*, byte*))(f)
#define CAST5_BLOCKSIZE 8
typedef struct {
@ -610,9 +607,13 @@ cast5_get_info( int algo, size_t *keylen,
*keylen = 128;
*blocksize = CAST5_BLOCKSIZE;
*contextsize = sizeof(CAST5_context);
*r_setkey = FNCCAST_SETKEY(cast_setkey);
*r_encrypt= FNCCAST_CRYPT(encrypt_block);
*r_decrypt= FNCCAST_CRYPT(decrypt_block);
*(int (**)(CAST5_context*, byte*, unsigned))r_setkey
= cast_setkey;
*(void (**)(CAST5_context*, byte*, byte*))r_encrypt
= encrypt_block;
*(void (**)(CAST5_context*, byte*, byte*))r_decrypt
= decrypt_block;
if( algo == CIPHER_ALGO_CAST5 )
return "CAST5";

View File

@ -1,5 +1,5 @@
/* des.c - DES and Triple-DES encryption/decryption Algorithm
* Copyright (C) 1998 Free Software Foundation, Inc.
* Copyright (C) 1998, 1999 Free Software Foundation, Inc.
*
* Please see below for more legal information!
*
@ -147,9 +147,6 @@ working_memcmp( const char *a, const char *b, size_t n )
#endif
/* Macros used by the info function. */
#define FNCCAST_SETKEY(f) ((int(*)(void*, byte*, unsigned))(f))
#define FNCCAST_CRYPT(f) ((void(*)(void*, byte*, byte*))(f))
/*
@ -190,105 +187,105 @@ static const char *selftest (void);
/*
* The s-box values are permuted according to the 'primitive function P'
* and are rotated one bit to the left.
*/
static u32 sbox1[64] =
{
0x00808200, 0x00000000, 0x00008000, 0x00808202, 0x00808002, 0x00008202, 0x00000002, 0x00008000,
0x00000200, 0x00808200, 0x00808202, 0x00000200, 0x00800202, 0x00808002, 0x00800000, 0x00000002,
0x00000202, 0x00800200, 0x00800200, 0x00008200, 0x00008200, 0x00808000, 0x00808000, 0x00800202,
0x00008002, 0x00800002, 0x00800002, 0x00008002, 0x00000000, 0x00000202, 0x00008202, 0x00800000,
0x00008000, 0x00808202, 0x00000002, 0x00808000, 0x00808200, 0x00800000, 0x00800000, 0x00000200,
0x00808002, 0x00008000, 0x00008200, 0x00800002, 0x00000200, 0x00000002, 0x00800202, 0x00008202,
0x00808202, 0x00008002, 0x00808000, 0x00800202, 0x00800002, 0x00000202, 0x00008202, 0x00808200,
0x00000202, 0x00800200, 0x00800200, 0x00000000, 0x00008002, 0x00008200, 0x00000000, 0x00808002
0x01010400, 0x00000000, 0x00010000, 0x01010404, 0x01010004, 0x00010404, 0x00000004, 0x00010000,
0x00000400, 0x01010400, 0x01010404, 0x00000400, 0x01000404, 0x01010004, 0x01000000, 0x00000004,
0x00000404, 0x01000400, 0x01000400, 0x00010400, 0x00010400, 0x01010000, 0x01010000, 0x01000404,
0x00010004, 0x01000004, 0x01000004, 0x00010004, 0x00000000, 0x00000404, 0x00010404, 0x01000000,
0x00010000, 0x01010404, 0x00000004, 0x01010000, 0x01010400, 0x01000000, 0x01000000, 0x00000400,
0x01010004, 0x00010000, 0x00010400, 0x01000004, 0x00000400, 0x00000004, 0x01000404, 0x00010404,
0x01010404, 0x00010004, 0x01010000, 0x01000404, 0x01000004, 0x00000404, 0x00010404, 0x01010400,
0x00000404, 0x01000400, 0x01000400, 0x00000000, 0x00010004, 0x00010400, 0x00000000, 0x01010004
};
static u32 sbox2[64] =
{
0x40084010, 0x40004000, 0x00004000, 0x00084010, 0x00080000, 0x00000010, 0x40080010, 0x40004010,
0x40000010, 0x40084010, 0x40084000, 0x40000000, 0x40004000, 0x00080000, 0x00000010, 0x40080010,
0x00084000, 0x00080010, 0x40004010, 0x00000000, 0x40000000, 0x00004000, 0x00084010, 0x40080000,
0x00080010, 0x40000010, 0x00000000, 0x00084000, 0x00004010, 0x40084000, 0x40080000, 0x00004010,
0x00000000, 0x00084010, 0x40080010, 0x00080000, 0x40004010, 0x40080000, 0x40084000, 0x00004000,
0x40080000, 0x40004000, 0x00000010, 0x40084010, 0x00084010, 0x00000010, 0x00004000, 0x40000000,
0x00004010, 0x40084000, 0x00080000, 0x40000010, 0x00080010, 0x40004010, 0x40000010, 0x00080010,
0x00084000, 0x00000000, 0x40004000, 0x00004010, 0x40000000, 0x40080010, 0x40084010, 0x00084000
0x80108020, 0x80008000, 0x00008000, 0x00108020, 0x00100000, 0x00000020, 0x80100020, 0x80008020,
0x80000020, 0x80108020, 0x80108000, 0x80000000, 0x80008000, 0x00100000, 0x00000020, 0x80100020,
0x00108000, 0x00100020, 0x80008020, 0x00000000, 0x80000000, 0x00008000, 0x00108020, 0x80100000,
0x00100020, 0x80000020, 0x00000000, 0x00108000, 0x00008020, 0x80108000, 0x80100000, 0x00008020,
0x00000000, 0x00108020, 0x80100020, 0x00100000, 0x80008020, 0x80100000, 0x80108000, 0x00008000,
0x80100000, 0x80008000, 0x00000020, 0x80108020, 0x00108020, 0x00000020, 0x00008000, 0x80000000,
0x00008020, 0x80108000, 0x00100000, 0x80000020, 0x00100020, 0x80008020, 0x80000020, 0x00100020,
0x00108000, 0x00000000, 0x80008000, 0x00008020, 0x80000000, 0x80100020, 0x80108020, 0x00108000
};
static u32 sbox3[64] =
{
0x00000104, 0x04010100, 0x00000000, 0x04010004, 0x04000100, 0x00000000, 0x00010104, 0x04000100,
0x00010004, 0x04000004, 0x04000004, 0x00010000, 0x04010104, 0x00010004, 0x04010000, 0x00000104,
0x04000000, 0x00000004, 0x04010100, 0x00000100, 0x00010100, 0x04010000, 0x04010004, 0x00010104,
0x04000104, 0x00010100, 0x00010000, 0x04000104, 0x00000004, 0x04010104, 0x00000100, 0x04000000,
0x04010100, 0x04000000, 0x00010004, 0x00000104, 0x00010000, 0x04010100, 0x04000100, 0x00000000,
0x00000100, 0x00010004, 0x04010104, 0x04000100, 0x04000004, 0x00000100, 0x00000000, 0x04010004,
0x04000104, 0x00010000, 0x04000000, 0x04010104, 0x00000004, 0x00010104, 0x00010100, 0x04000004,
0x04010000, 0x04000104, 0x00000104, 0x04010000, 0x00010104, 0x00000004, 0x04010004, 0x00010100
0x00000208, 0x08020200, 0x00000000, 0x08020008, 0x08000200, 0x00000000, 0x00020208, 0x08000200,
0x00020008, 0x08000008, 0x08000008, 0x00020000, 0x08020208, 0x00020008, 0x08020000, 0x00000208,
0x08000000, 0x00000008, 0x08020200, 0x00000200, 0x00020200, 0x08020000, 0x08020008, 0x00020208,
0x08000208, 0x00020200, 0x00020000, 0x08000208, 0x00000008, 0x08020208, 0x00000200, 0x08000000,
0x08020200, 0x08000000, 0x00020008, 0x00000208, 0x00020000, 0x08020200, 0x08000200, 0x00000000,
0x00000200, 0x00020008, 0x08020208, 0x08000200, 0x08000008, 0x00000200, 0x00000000, 0x08020008,
0x08000208, 0x00020000, 0x08000000, 0x08020208, 0x00000008, 0x00020208, 0x00020200, 0x08000008,
0x08020000, 0x08000208, 0x00000208, 0x08020000, 0x00020208, 0x00000008, 0x08020008, 0x00020200
};
static u32 sbox4[64] =
{
0x80401000, 0x80001040, 0x80001040, 0x00000040, 0x00401040, 0x80400040, 0x80400000, 0x80001000,
0x00000000, 0x00401000, 0x00401000, 0x80401040, 0x80000040, 0x00000000, 0x00400040, 0x80400000,
0x80000000, 0x00001000, 0x00400000, 0x80401000, 0x00000040, 0x00400000, 0x80001000, 0x00001040,
0x80400040, 0x80000000, 0x00001040, 0x00400040, 0x00001000, 0x00401040, 0x80401040, 0x80000040,
0x00400040, 0x80400000, 0x00401000, 0x80401040, 0x80000040, 0x00000000, 0x00000000, 0x00401000,
0x00001040, 0x00400040, 0x80400040, 0x80000000, 0x80401000, 0x80001040, 0x80001040, 0x00000040,
0x80401040, 0x80000040, 0x80000000, 0x00001000, 0x80400000, 0x80001000, 0x00401040, 0x80400040,
0x80001000, 0x00001040, 0x00400000, 0x80401000, 0x00000040, 0x00400000, 0x00001000, 0x00401040
0x00802001, 0x00002081, 0x00002081, 0x00000080, 0x00802080, 0x00800081, 0x00800001, 0x00002001,
0x00000000, 0x00802000, 0x00802000, 0x00802081, 0x00000081, 0x00000000, 0x00800080, 0x00800001,
0x00000001, 0x00002000, 0x00800000, 0x00802001, 0x00000080, 0x00800000, 0x00002001, 0x00002080,
0x00800081, 0x00000001, 0x00002080, 0x00800080, 0x00002000, 0x00802080, 0x00802081, 0x00000081,
0x00800080, 0x00800001, 0x00802000, 0x00802081, 0x00000081, 0x00000000, 0x00000000, 0x00802000,
0x00002080, 0x00800080, 0x00800081, 0x00000001, 0x00802001, 0x00002081, 0x00002081, 0x00000080,
0x00802081, 0x00000081, 0x00000001, 0x00002000, 0x00800001, 0x00002001, 0x00802080, 0x00800081,
0x00002001, 0x00002080, 0x00800000, 0x00802001, 0x00000080, 0x00800000, 0x00002000, 0x00802080
};
static u32 sbox5[64] =
{
0x00000080, 0x01040080, 0x01040000, 0x21000080, 0x00040000, 0x00000080, 0x20000000, 0x01040000,
0x20040080, 0x00040000, 0x01000080, 0x20040080, 0x21000080, 0x21040000, 0x00040080, 0x20000000,
0x01000000, 0x20040000, 0x20040000, 0x00000000, 0x20000080, 0x21040080, 0x21040080, 0x01000080,
0x21040000, 0x20000080, 0x00000000, 0x21000000, 0x01040080, 0x01000000, 0x21000000, 0x00040080,
0x00040000, 0x21000080, 0x00000080, 0x01000000, 0x20000000, 0x01040000, 0x21000080, 0x20040080,
0x01000080, 0x20000000, 0x21040000, 0x01040080, 0x20040080, 0x00000080, 0x01000000, 0x21040000,
0x21040080, 0x00040080, 0x21000000, 0x21040080, 0x01040000, 0x00000000, 0x20040000, 0x21000000,
0x00040080, 0x01000080, 0x20000080, 0x00040000, 0x00000000, 0x20040000, 0x01040080, 0x20000080
0x00000100, 0x02080100, 0x02080000, 0x42000100, 0x00080000, 0x00000100, 0x40000000, 0x02080000,
0x40080100, 0x00080000, 0x02000100, 0x40080100, 0x42000100, 0x42080000, 0x00080100, 0x40000000,
0x02000000, 0x40080000, 0x40080000, 0x00000000, 0x40000100, 0x42080100, 0x42080100, 0x02000100,
0x42080000, 0x40000100, 0x00000000, 0x42000000, 0x02080100, 0x02000000, 0x42000000, 0x00080100,
0x00080000, 0x42000100, 0x00000100, 0x02000000, 0x40000000, 0x02080000, 0x42000100, 0x40080100,
0x02000100, 0x40000000, 0x42080000, 0x02080100, 0x40080100, 0x00000100, 0x02000000, 0x42080000,
0x42080100, 0x00080100, 0x42000000, 0x42080100, 0x02080000, 0x00000000, 0x40080000, 0x42000000,
0x00080100, 0x02000100, 0x40000100, 0x00080000, 0x00000000, 0x40080000, 0x02080100, 0x40000100
};
static u32 sbox6[64] =
{
0x10000008, 0x10200000, 0x00002000, 0x10202008, 0x10200000, 0x00000008, 0x10202008, 0x00200000,
0x10002000, 0x00202008, 0x00200000, 0x10000008, 0x00200008, 0x10002000, 0x10000000, 0x00002008,
0x00000000, 0x00200008, 0x10002008, 0x00002000, 0x00202000, 0x10002008, 0x00000008, 0x10200008,
0x10200008, 0x00000000, 0x00202008, 0x10202000, 0x00002008, 0x00202000, 0x10202000, 0x10000000,
0x10002000, 0x00000008, 0x10200008, 0x00202000, 0x10202008, 0x00200000, 0x00002008, 0x10000008,
0x00200000, 0x10002000, 0x10000000, 0x00002008, 0x10000008, 0x10202008, 0x00202000, 0x10200000,
0x00202008, 0x10202000, 0x00000000, 0x10200008, 0x00000008, 0x00002000, 0x10200000, 0x00202008,
0x00002000, 0x00200008, 0x10002008, 0x00000000, 0x10202000, 0x10000000, 0x00200008, 0x10002008
0x20000010, 0x20400000, 0x00004000, 0x20404010, 0x20400000, 0x00000010, 0x20404010, 0x00400000,
0x20004000, 0x00404010, 0x00400000, 0x20000010, 0x00400010, 0x20004000, 0x20000000, 0x00004010,
0x00000000, 0x00400010, 0x20004010, 0x00004000, 0x00404000, 0x20004010, 0x00000010, 0x20400010,
0x20400010, 0x00000000, 0x00404010, 0x20404000, 0x00004010, 0x00404000, 0x20404000, 0x20000000,
0x20004000, 0x00000010, 0x20400010, 0x00404000, 0x20404010, 0x00400000, 0x00004010, 0x20000010,
0x00400000, 0x20004000, 0x20000000, 0x00004010, 0x20000010, 0x20404010, 0x00404000, 0x20400000,
0x00404010, 0x20404000, 0x00000000, 0x20400010, 0x00000010, 0x00004000, 0x20400000, 0x00404010,
0x00004000, 0x00400010, 0x20004010, 0x00000000, 0x20404000, 0x20000000, 0x00400010, 0x20004010
};
static u32 sbox7[64] =
{
0x00100000, 0x02100001, 0x02000401, 0x00000000, 0x00000400, 0x02000401, 0x00100401, 0x02100400,
0x02100401, 0x00100000, 0x00000000, 0x02000001, 0x00000001, 0x02000000, 0x02100001, 0x00000401,
0x02000400, 0x00100401, 0x00100001, 0x02000400, 0x02000001, 0x02100000, 0x02100400, 0x00100001,
0x02100000, 0x00000400, 0x00000401, 0x02100401, 0x00100400, 0x00000001, 0x02000000, 0x00100400,
0x02000000, 0x00100400, 0x00100000, 0x02000401, 0x02000401, 0x02100001, 0x02100001, 0x00000001,
0x00100001, 0x02000000, 0x02000400, 0x00100000, 0x02100400, 0x00000401, 0x00100401, 0x02100400,
0x00000401, 0x02000001, 0x02100401, 0x02100000, 0x00100400, 0x00000000, 0x00000001, 0x02100401,
0x00000000, 0x00100401, 0x02100000, 0x00000400, 0x02000001, 0x02000400, 0x00000400, 0x00100001
0x00200000, 0x04200002, 0x04000802, 0x00000000, 0x00000800, 0x04000802, 0x00200802, 0x04200800,
0x04200802, 0x00200000, 0x00000000, 0x04000002, 0x00000002, 0x04000000, 0x04200002, 0x00000802,
0x04000800, 0x00200802, 0x00200002, 0x04000800, 0x04000002, 0x04200000, 0x04200800, 0x00200002,
0x04200000, 0x00000800, 0x00000802, 0x04200802, 0x00200800, 0x00000002, 0x04000000, 0x00200800,
0x04000000, 0x00200800, 0x00200000, 0x04000802, 0x04000802, 0x04200002, 0x04200002, 0x00000002,
0x00200002, 0x04000000, 0x04000800, 0x00200000, 0x04200800, 0x00000802, 0x00200802, 0x04200800,
0x00000802, 0x04000002, 0x04200802, 0x04200000, 0x00200800, 0x00000000, 0x00000002, 0x04200802,
0x00000000, 0x00200802, 0x04200000, 0x00000800, 0x04000002, 0x04000800, 0x00000800, 0x00200002
};
static u32 sbox8[64] =
{
0x08000820, 0x00000800, 0x00020000, 0x08020820, 0x08000000, 0x08000820, 0x00000020, 0x08000000,
0x00020020, 0x08020000, 0x08020820, 0x00020800, 0x08020800, 0x00020820, 0x00000800, 0x00000020,
0x08020000, 0x08000020, 0x08000800, 0x00000820, 0x00020800, 0x00020020, 0x08020020, 0x08020800,
0x00000820, 0x00000000, 0x00000000, 0x08020020, 0x08000020, 0x08000800, 0x00020820, 0x00020000,
0x00020820, 0x00020000, 0x08020800, 0x00000800, 0x00000020, 0x08020020, 0x00000800, 0x00020820,
0x08000800, 0x00000020, 0x08000020, 0x08020000, 0x08020020, 0x08000000, 0x00020000, 0x08000820,
0x00000000, 0x08020820, 0x00020020, 0x08000020, 0x08020000, 0x08000800, 0x08000820, 0x00000000,
0x08020820, 0x00020800, 0x00020800, 0x00000820, 0x00000820, 0x00020020, 0x08000000, 0x08020800
0x10001040, 0x00001000, 0x00040000, 0x10041040, 0x10000000, 0x10001040, 0x00000040, 0x10000000,
0x00040040, 0x10040000, 0x10041040, 0x00041000, 0x10041000, 0x00041040, 0x00001000, 0x00000040,
0x10040000, 0x10000040, 0x10001000, 0x00001040, 0x00041000, 0x00040040, 0x10040040, 0x10041000,
0x00001040, 0x00000000, 0x00000000, 0x10040040, 0x10000040, 0x10001000, 0x00041040, 0x00040000,
0x00041040, 0x00040000, 0x10041000, 0x00001000, 0x00000040, 0x10040040, 0x00001000, 0x00041040,
0x10001000, 0x00000040, 0x10000040, 0x10040000, 0x10040040, 0x10000000, 0x00040000, 0x10001040,
0x00000000, 0x10041040, 0x00040040, 0x10000040, 0x10040000, 0x10001000, 0x10001040, 0x00000000,
0x10041040, 0x00041000, 0x00041000, 0x00001040, 0x00001040, 0x00040040, 0x10000000, 0x10041000
};
/*
* These two tables are part of the 'permuted choice 1' function.
* In this implementation several speed improvements are done.
@ -312,10 +309,10 @@ u32 rightkey_swap[16] =
/*
* Numbers of left shifts per round for encryption subkey schedule
* To calculate the decryption key scheduling we just reverse the
* ordering of the subkeys so we can omit the table for decryption
* subkey schedule.
* Numbers of left shifts per round for encryption subkeys.
* To calculate the decryption subkeys we just reverse the
* ordering of the calculated encryption subkeys. So their
* is no need for a decryption rotate tab.
*/
static byte encrypt_rotate_tab[16] =
{
@ -373,7 +370,7 @@ static byte weak_keys[64][8] =
/*
* Macro to swap bits across two words
* Macro to swap bits across two words.
*/
#define DO_PERMUTATION(a, temp, b, offset, mask) \
temp = ((a>>offset) ^ b) & mask; \
@ -382,21 +379,30 @@ static byte weak_keys[64][8] =
/*
* This performs the 'initial permutation' for the data to be encrypted or decrypted
* This performs the 'initial permutation' of the data to be encrypted
* or decrypted. Additionally the resulting two words are rotated one bit
* to the left.
*/
#define INITIAL_PERMUTATION(left, temp, right) \
DO_PERMUTATION(left, temp, right, 4, 0x0f0f0f0f) \
DO_PERMUTATION(left, temp, right, 16, 0x0000ffff) \
DO_PERMUTATION(right, temp, left, 2, 0x33333333) \
DO_PERMUTATION(right, temp, left, 8, 0x00ff00ff) \
DO_PERMUTATION(left, temp, right, 1, 0x55555555)
right = (right << 1) | (right >> 31); \
temp = (left ^ right) & 0xaaaaaaaa; \
right ^= temp; \
left ^= temp; \
left = (left << 1) | (left >> 31);
/*
* The 'inverse initial permutation'
* The 'inverse initial permutation'.
*/
#define FINAL_PERMUTATION(left, temp, right) \
DO_PERMUTATION(left, temp, right, 1, 0x55555555) \
left = (left << 31) | (left >> 1); \
temp = (left ^ right) & 0xaaaaaaaa; \
left ^= temp; \
right ^= temp; \
right = (right << 31) | (right >> 1); \
DO_PERMUTATION(right, temp, left, 8, 0x00ff00ff) \
DO_PERMUTATION(right, temp, left, 2, 0x33333333) \
DO_PERMUTATION(left, temp, right, 16, 0x0000ffff) \
@ -406,22 +412,23 @@ static byte weak_keys[64][8] =
/*
* A full DES round including 'expansion function', 'sbox substitution'
* and 'primitive function P' but without swapping the left and right word.
* Please note: The data in 'from' and 'to' is already rotated one bit to
* the left, done in the initial permutation.
*/
#define DES_ROUND(from, to, work, subkey) \
work = ((from<<1) | (from>>31)) ^ *subkey++; \
work = from ^ *subkey++; \
to ^= sbox8[ work & 0x3f ]; \
to ^= sbox6[ (work>>8) & 0x3f ]; \
to ^= sbox4[ (work>>16) & 0x3f ]; \
to ^= sbox2[ (work>>24) & 0x3f ]; \
work = ((from>>3) | (from<<29)) ^ *subkey++; \
work = ((from << 28) | (from >> 4)) ^ *subkey++; \
to ^= sbox7[ work & 0x3f ]; \
to ^= sbox5[ (work>>8) & 0x3f ]; \
to ^= sbox3[ (work>>16) & 0x3f ]; \
to ^= sbox1[ (work>>24) & 0x3f ];
/*
* Macros to convert 8 bytes from/to 32bit words
* Macros to convert 8 bytes from/to 32bit words.
*/
#define READ_64BIT_DATA(data, left, right) \
left = (data[0] << 24) | (data[1] << 16) | (data[2] << 8) | data[3]; \
@ -433,7 +440,6 @@ static byte weak_keys[64][8] =
data[4] = (right >> 24) &0xff; data[5] = (right >> 16) &0xff; \
data[6] = (right >> 8) &0xff; data[7] = right &0xff;
/*
* Handy macros for encryption and decryption of data
*/
@ -797,9 +803,7 @@ selftest (void)
/*
* Triple-DES test (Do somebody known on official test?)
*
* Note: This test doesn't use tripledes_set3keys() !
* Self made Triple-DES test (Does somebody known an official test?)
*/
{
int i;
@ -823,10 +827,9 @@ selftest (void)
tripledes_ecb_encrypt (des3, input, input);
}
if (memcmp (input, result, 8))
return "TRIPLE-DES test failed.";
return "Triple-DES test failed.";
}
#if 0
/*
* More Triple-DES test. These are testvectors as used by SSLeay,
* thanks to Jeroen C. van Gelderen.
@ -894,13 +897,32 @@ selftest (void)
{ 0xe1,0xef,0x62,0xc3,0x32,0xfe,0x82,0x5b }
}
};
/* fixme: do the test */
byte result[8];
int i;
static char error[80];
tripledes_ctx des3;
for (i=0; i<sizeof(testdata)/sizeof(*testdata); ++i) {
tripledes_set3keys (des3, testdata[i].key, testdata[i].key + 8, testdata[i].key + 16);
tripledes_ecb_encrypt (des3, testdata[i].plain, result);
if (memcmp (testdata[i].cipher, result, 8)) {
sprintf (error, "Triple-DES SSLeay test pattern no. %d failend on encryption.", i+1);
return error;
}
tripledes_ecb_decrypt (des3, testdata[i].cipher, result);
if (memcmp (testdata[i].plain, result, 8)) {
sprintf (error, "Triple-DES SSLeay test pattern no. %d failend on decryption.", i+1);
return error;
}
}
}
#endif
/*
* Check the weak key detection. We simply assume the table with
* weak keys is ok and check every key in the table if it is
* Check the weak key detection. We simply assume that the table
* with weak keys is ok and check every key in the table if it is
* detected... (This test is a little bit stupid)
*/
{
@ -971,14 +993,16 @@ des_get_info( int algo, size_t *keylen,
}
}
if( algo == CIPHER_ALGO_3DES ) {
*keylen = 192;
*blocksize = 8;
*contextsize = sizeof(struct _tripledes_ctx);
*r_setkey = FNCCAST_SETKEY(do_tripledes_setkey);
*r_encrypt= FNCCAST_CRYPT(do_tripledes_encrypt);
*r_decrypt= FNCCAST_CRYPT(do_tripledes_decrypt);
*(int (**)(struct _tripledes_ctx*, byte*, unsigned))r_setkey
= do_tripledes_setkey;
*(void (**)(struct _tripledes_ctx*, byte*, byte*))r_encrypt
= do_tripledes_encrypt;
*(void (**)(struct _tripledes_ctx*, byte*, byte*))r_decrypt
= do_tripledes_decrypt;
return "3DES";
}
return NULL;

View File

@ -52,13 +52,29 @@ static void generate( DSA_secret_key *sk, unsigned nbits, MPI **ret_factors );
static void sign(MPI r, MPI s, MPI input, DSA_secret_key *skey);
static int verify(MPI r, MPI s, MPI input, DSA_public_key *pkey);
static void (*progress_cb) ( void *, int );
static void *progress_cb_data;
void
register_pk_dsa_progress ( void (*cb)( void *, int), void *cb_data )
{
progress_cb = cb;
progress_cb_data = cb_data;
}
static void
progress( int c )
{
fputc( c, stderr );
if ( progress_cb )
progress_cb ( progress_cb_data, c );
else
fputc( c, stderr );
}
/****************
* Generate a random secret exponent k less than q
*/

View File

@ -1,5 +1,5 @@
/* elgamal.c - ElGamal Public Key encryption
* Copyright (C) 1998 Free Software Foundation, Inc.
* Copyright (C) 1998, 2000 Free Software Foundation, Inc.
*
* For a description of the algorithm, see:
* Bruce Schneier: Applied Cryptography. John Wiley & Sons, 1996.
@ -56,13 +56,67 @@ static void sign(MPI a, MPI b, MPI input, ELG_secret_key *skey);
static int verify(MPI a, MPI b, MPI input, ELG_public_key *pkey);
static void (*progress_cb) ( void *, int );
static void *progress_cb_data;
void
register_pk_elg_progress ( void (*cb)( void *, int), void *cb_data )
{
progress_cb = cb;
progress_cb_data = cb_data;
}
static void
progress( int c )
{
fputc( c, stderr );
if ( progress_cb )
progress_cb ( progress_cb_data, c );
else
fputc( c, stderr );
}
/****************
* Michael Wiener's table about subgroup sizes to match field sizes
* (floating around somewhere - Fixme: need a reference)
*/
static unsigned int
wiener_map( unsigned int n )
{
static struct { unsigned int p_n, q_n; } t[] =
{ /* p q attack cost */
{ 512, 119 }, /* 9 x 10^17 */
{ 768, 145 }, /* 6 x 10^21 */
{ 1024, 165 }, /* 7 x 10^24 */
{ 1280, 183 }, /* 3 x 10^27 */
{ 1536, 198 }, /* 7 x 10^29 */
{ 1792, 212 }, /* 9 x 10^31 */
{ 2048, 225 }, /* 8 x 10^33 */
{ 2304, 237 }, /* 5 x 10^35 */
{ 2560, 249 }, /* 3 x 10^37 */
{ 2816, 259 }, /* 1 x 10^39 */
{ 3072, 269 }, /* 3 x 10^40 */
{ 3328, 279 }, /* 8 x 10^41 */
{ 3584, 288 }, /* 2 x 10^43 */
{ 3840, 296 }, /* 4 x 10^44 */
{ 4096, 305 }, /* 7 x 10^45 */
{ 4352, 313 }, /* 1 x 10^47 */
{ 4608, 320 }, /* 2 x 10^48 */
{ 4864, 328 }, /* 2 x 10^49 */
{ 5120, 335 }, /* 3 x 10^50 */
{ 0, 0 }
};
int i;
for(i=0; t[i].p_n; i++ ) {
if( n <= t[i].p_n )
return t[i].q_n;
}
/* not in table - use some arbitrary high number ;-) */
return n / 8 + 200;
}
static void
test_keys( ELG_secret_key *sk, unsigned nbits )
{
@ -108,38 +162,45 @@ gen_k( MPI p )
MPI k = mpi_alloc_secure( 0 );
MPI temp = mpi_alloc( mpi_get_nlimbs(p) );
MPI p_1 = mpi_copy(p);
unsigned int nbits = mpi_get_nbits(p);
unsigned int nbytes = (nbits+7)/8;
unsigned int orig_nbits = mpi_get_nbits(p);
unsigned int nbits;
unsigned int nbytes;
char *rndbuf = NULL;
/* IMO using a k much lesser than p is sufficient and it greatly
* improves the encryption performance. We use Wiener's table
* and add a large safety margin.
*/
nbits = wiener_map( orig_nbits ) * 3 / 2;
if( nbits >= orig_nbits )
BUG();
nbytes = (nbits+7)/8;
if( DBG_CIPHER )
log_debug("choosing a random k ");
log_debug("choosing a random k of %u bits", nbits);
mpi_sub_ui( p_1, p, 1);
for(;;) {
if( DBG_CIPHER )
progress('.');
if( !rndbuf || nbits < 32 ) {
m_free(rndbuf);
rndbuf = get_random_bits( nbits, 1, 1 );
}
else { /* change only some of the higher bits */
/* we could imporove this by directly requesting more memory
/* we could impprove this by directly requesting more memory
* at the first call to get_random_bits() and use this the here
* maybe it is easier to do this directly in random.c */
* maybe it is easier to do this directly in random.c
* Anyway, it is highly inlikely that we will ever reach this code
*/
char *pp = get_random_bits( 32, 1, 1 );
memcpy( rndbuf,pp, 4 );
m_free(pp);
log_debug("gen_k: tsss, never expected to reach this\n");
}
mpi_set_buffer( k, rndbuf, nbytes, 0 );
for(;;) {
/* make sure that the number is of the exact lenght */
if( mpi_test_bit( k, nbits-1 ) )
mpi_set_highbit( k, nbits-1 );
else {
mpi_set_highbit( k, nbits-1 );
mpi_clear_bit( k, nbits-1 );
}
/* Hmm, actually we don't need this step here
* because we use k much smaller than p - we do it anyway
* just in case the keep on adding a one to k ;) */
if( !(mpi_cmp( k, p_1 ) < 0) ) { /* check: k < (p-1) */
if( DBG_CIPHER )
progress('+');
@ -153,6 +214,8 @@ gen_k( MPI p )
if( mpi_gcd( temp, k, p_1 ) )
goto found; /* okay, k is relatively prime to (p-1) */
mpi_add_ui( k, k, 1 );
if( DBG_CIPHER )
progress('.');
}
}
found:
@ -171,7 +234,7 @@ gen_k( MPI p )
* and an array with n-1 factors of (p-1)
*/
static void
generate( ELG_secret_key *sk, unsigned nbits, MPI **ret_factors )
generate( ELG_secret_key *sk, unsigned int nbits, MPI **ret_factors )
{
MPI p; /* the prime */
MPI p_min1;
@ -179,19 +242,15 @@ generate( ELG_secret_key *sk, unsigned nbits, MPI **ret_factors )
MPI x; /* the secret exponent */
MPI y;
MPI temp;
unsigned qbits;
unsigned int qbits;
unsigned int xbits;
byte *rndbuf;
p_min1 = mpi_alloc( (nbits+BITS_PER_MPI_LIMB-1)/BITS_PER_MPI_LIMB );
temp = mpi_alloc( (nbits+BITS_PER_MPI_LIMB-1)/BITS_PER_MPI_LIMB );
if( nbits < 512 )
qbits = 120;
else if( nbits <= 1024 )
qbits = 160;
else if( nbits <= 2048 )
qbits = 200;
else
qbits = 240;
qbits = wiener_map( nbits );
if( qbits & 1 ) /* better have a even one */
qbits++;
g = mpi_alloc(1);
p = generate_elg_prime( 0, nbits, qbits, g, ret_factors );
mpi_sub_ui(p_min1, p, 1);
@ -202,18 +261,26 @@ generate( ELG_secret_key *sk, unsigned nbits, MPI **ret_factors )
* This must be a very good random number because this is the
* secret part. The prime is public and may be shared anyway,
* so a random generator level of 1 is used for the prime.
*
* I don't see a reason to have a x of about the same size
* as the p. It should be sufficient to have one about the size
* of q or the later used k plus a large safety margin. Decryption
* will be much faster with such an x.
*/
x = mpi_alloc_secure( nbits/BITS_PER_MPI_LIMB );
xbits = qbits * 3 / 2;
if( xbits >= nbits )
BUG();
x = mpi_alloc_secure( xbits/BITS_PER_MPI_LIMB );
if( DBG_CIPHER )
log_debug("choosing a random x ");
log_debug("choosing a random x of size %u", xbits );
rndbuf = NULL;
do {
if( DBG_CIPHER )
progress('.');
if( rndbuf ) { /* change only some of the higher bits */
if( nbits < 16 ) {/* should never happen ... */
if( xbits < 16 ) {/* should never happen ... */
m_free(rndbuf);
rndbuf = get_random_bits( nbits, 2, 1 );
rndbuf = get_random_bits( xbits, 2, 1 );
}
else {
char *r = get_random_bits( 16, 2, 1 );
@ -222,9 +289,9 @@ generate( ELG_secret_key *sk, unsigned nbits, MPI **ret_factors )
}
}
else
rndbuf = get_random_bits( nbits, 2, 1 );
mpi_set_buffer( x, rndbuf, (nbits+7)/8, 0 );
mpi_clear_highbit( x, nbits+1 );
rndbuf = get_random_bits( xbits, 2, 1 );
mpi_set_buffer( x, rndbuf, (xbits+7)/8, 0 );
mpi_clear_highbit( x, xbits+1 );
} while( !( mpi_cmp_ui( x, 0 )>0 && mpi_cmp( x, p_min1 )<0 ) );
m_free(rndbuf);
@ -311,7 +378,6 @@ decrypt(MPI output, MPI a, MPI b, ELG_secret_key *skey )
MPI t1 = mpi_alloc_secure( mpi_get_nlimbs( skey->p ) );
/* output = b/(a^x) mod p */
mpi_powm( t1, a, skey->x, skey->p );
mpi_invm( t1, t1, skey->p );
mpi_mulm( output, b, t1, skey->p );
@ -351,8 +417,10 @@ sign(MPI a, MPI b, MPI input, ELG_secret_key *skey )
mpi_powm( a, skey->g, k, skey->p );
mpi_mul(t, skey->x, a );
mpi_subm(t, input, t, p_1 );
while( mpi_is_neg(t) )
while( mpi_is_neg(t) ) {
BUG(); /* That is nonsense code - left over from a very early test?*/
mpi_add(t, t, p_1);
}
mpi_invm(inv, k, p_1 );
mpi_mulm(b, t, inv, p_1 );

View File

@ -291,7 +291,7 @@ md_reset( MD_HANDLE a )
{
struct md_digest_list_s *r;
a->bufcount = 0;
a->bufcount = a->finalized = 0;
for( r=a->list; r; r = r->next ) {
memset( r->context.c, 0, r->contextsize );
(*r->init)( &r->context.c );

View File

@ -344,10 +344,10 @@ md5_get_info( int algo, size_t *contextsize,
*r_asnoid = asn;
*r_asnlen = DIM(asn);
*r_mdlen = 16;
*r_init = (void (*)(void *))md5_init;
*r_write = (void (*)(void *, byte*, size_t))md5_write;
*r_final = (void (*)(void *))md5_final;
*r_read = (byte *(*)(void *))md5_read;
*(void (**)(MD5_CONTEXT *))r_init = md5_init;
*(void (**)(MD5_CONTEXT *, byte*, size_t))r_write = md5_write;
*(void (**)(MD5_CONTEXT *))r_final = md5_final;
*(byte *(**)(MD5_CONTEXT *))r_read = md5_read;
return "MD5";
}

View File

@ -38,11 +38,24 @@ static int check_prime( MPI prime, MPI val_2 );
static int is_prime( MPI n, int steps, int *count );
static void m_out_of_n( char *array, int m, int n );
static void (*progress_cb) ( void *, int );
static void *progress_cb_data;
void
register_primegen_progress ( void (*cb)( void *, int), void *cb_data )
{
progress_cb = cb;
progress_cb_data = cb_data;
}
static void
progress( int c )
{
fputc( c, stderr );
if ( progress_cb )
progress_cb ( progress_cb_data, c );
else
fputc( c, stderr );
}
@ -117,8 +130,8 @@ generate_elg_prime( int mode, unsigned pbits, unsigned qbits,
log_debug("gen prime: pbits=%u qbits=%u fbits=%u/%u n=%d\n",
pbits, req_qbits, qbits, fbits, n );
prime = mpi_alloc( (pbits + BITS_PER_MPI_LIMB - 1) / BITS_PER_MPI_LIMB );
q = gen_prime( qbits, 0, 1 );
q_factor = mode==1? gen_prime( req_qbits, 0, 1 ) : NULL;
q = gen_prime( qbits, 0, 0 );
q_factor = mode==1? gen_prime( req_qbits, 0, 0 ) : NULL;
/* allocate an array to hold the factors + 2 for later usage */
factors = m_alloc_clear( (n+2) * sizeof *factors );
@ -145,7 +158,7 @@ generate_elg_prime( int mode, unsigned pbits, unsigned qbits,
perms = m_alloc_clear( m );
for(i=0; i < n; i++ ) {
perms[i] = 1;
pool[i] = gen_prime( fbits, 0, 1 );
pool[i] = gen_prime( fbits, 0, 0 );
factors[i] = pool[i];
}
}
@ -154,7 +167,7 @@ generate_elg_prime( int mode, unsigned pbits, unsigned qbits,
for(i=j=0; i < m && j < n ; i++ )
if( perms[i] ) {
if( !pool[i] )
pool[i] = gen_prime( fbits, 0, 1 );
pool[i] = gen_prime( fbits, 0, 0 );
factors[j++] = pool[i];
}
if( i == n ) {
@ -177,7 +190,7 @@ generate_elg_prime( int mode, unsigned pbits, unsigned qbits,
count1 = 0;
qbits++;
progress('>');
q = gen_prime( qbits, 0, 1 );
q = gen_prime( qbits, 0, 0 );
goto next_try;
}
}
@ -188,7 +201,7 @@ generate_elg_prime( int mode, unsigned pbits, unsigned qbits,
count2 = 0;
qbits--;
progress('<');
q = gen_prime( qbits, 0, 1 );
q = gen_prime( qbits, 0, 0 );
goto next_try;
}
}

View File

@ -36,15 +36,22 @@
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <fcntl.h>
#ifdef HAVE_GETHRTIME
#include <sys/times.h>
#endif
#ifdef HAVE_GETTIMEOFDAY
#include <sys/times.h>
#endif
#ifdef HAVE_CLOCK_GETTIME
#include <time.h>
#endif
#ifdef HAVE_GETRUSAGE
#include <sys/resource.h>
#endif
#ifdef __MINGW32__
#include <process.h>
#endif
#include "util.h"
#include "rmd.h"
#include "ttyio.h"
@ -91,6 +98,9 @@ static size_t pool_writepos;
static int pool_filled;
static int pool_balance;
static int just_mixed;
static int did_initial_extra_seeding;
static char *seed_file_name;
static int allow_seed_file_update;
static int secure_alloc;
static int quick_test;
@ -264,14 +274,171 @@ mix_pool(byte *pool)
}
void
set_random_seed_file( const char *name )
{
if( seed_file_name )
BUG();
seed_file_name = m_strdup( name );
}
/****************
* Read in a seed form the random_seed file
* and return true if this was successful
*/
static int
read_seed_file()
{
int fd;
struct stat sb;
unsigned char buffer[POOLSIZE];
int n;
if( !seed_file_name )
return 0;
#ifdef HAVE_DOSISH_SYSTEM
fd = open( seed_file_name, O_RDONLY | O_BINARY );
#else
fd = open( seed_file_name, O_RDONLY );
#endif
if( fd == -1 && errno == ENOENT) {
allow_seed_file_update = 1;
return 0;
}
if( fd == -1 ) {
log_info(_("can't open `%s': %s\n"), seed_file_name, strerror(errno) );
return 0;
}
if( fstat( fd, &sb ) ) {
log_info(_("can't stat `%s': %s\n"), seed_file_name, strerror(errno) );
close(fd);
return 0;
}
if( !S_ISREG(sb.st_mode) ) {
log_info(_("`%s' is not a regular file - ignored\n"), seed_file_name );
close(fd);
return 0;
}
if( !sb.st_size ) {
log_info(_("note: random_seed file is empty\n") );
close(fd);
allow_seed_file_update = 1;
return 0;
}
if( sb.st_size != POOLSIZE ) {
log_info(_("warning: invalid size of random_seed file - not used\n") );
close(fd);
return 0;
}
do {
n = read( fd, buffer, POOLSIZE );
} while( n == -1 && errno == EINTR );
if( n != POOLSIZE ) {
log_fatal(_("can't read `%s': %s\n"), seed_file_name,strerror(errno) );
close(fd);
return 0;
}
close(fd);
add_randomness( buffer, POOLSIZE, 0 );
/* add some minor entropy to the pool now (this will also force a mixing) */
{ pid_t x = getpid();
add_randomness( &x, sizeof(x), 0 );
}
{ time_t x = time(NULL);
add_randomness( &x, sizeof(x), 0 );
}
{ clock_t x = clock();
add_randomness( &x, sizeof(x), 0 );
}
/* And read a few bytes from our entropy source. By using
* a level of 0 this will not block and might not return anything
* with some entropy drivers, however the rndlinux driver will use
* /dev/urandom and return some stuff - Do not read to much as we
* want to be friendly to the scare system entropy resource. */
read_random_source( 0, 16, 0 );
allow_seed_file_update = 1;
return 1;
}
void
update_random_seed_file()
{
ulong *sp, *dp;
int fd, i;
if( !seed_file_name || !is_initialized || !pool_filled )
return;
if( !allow_seed_file_update ) {
log_info(_("note: random_seed file not updated\n"));
return;
}
/* copy the entropy pool to a scratch pool and mix both of them */
for(i=0,dp=(ulong*)keypool, sp=(ulong*)rndpool;
i < POOLWORDS; i++, dp++, sp++ ) {
*dp = *sp + ADD_VALUE;
}
mix_pool(rndpool); rndstats.mixrnd++;
mix_pool(keypool); rndstats.mixkey++;
#ifdef HAVE_DOSISH_SYSTEM
fd = open( seed_file_name, O_WRONLY|O_CREAT|O_TRUNC|O_BINARY,
S_IRUSR|S_IWUSR );
#else
fd = open( seed_file_name, O_WRONLY|O_CREAT|O_TRUNC, S_IRUSR|S_IWUSR );
#endif
if( fd == -1 ) {
log_info(_("can't create `%s': %s\n"), seed_file_name, strerror(errno) );
return;
}
do {
i = write( fd, keypool, POOLSIZE );
} while( i == -1 && errno == EINTR );
if( i != POOLSIZE ) {
log_info(_("can't write `%s': %s\n"), seed_file_name, strerror(errno) );
}
if( close(fd) )
log_info(_("can't close `%s': %s\n"), seed_file_name, strerror(errno) );
}
static void
read_pool( byte *buffer, size_t length, int level )
{
int i;
ulong *sp, *dp;
if( length >= POOLSIZE )
BUG(); /* not allowed */
if( length >= POOLSIZE ) {
log_fatal(_("too many random bits requested; the limit is %d\n"),
POOLSIZE*8-1 );
}
if( !pool_filled ) {
if( read_seed_file() )
pool_filled = 1;
}
/* For level 2 quality (key generation) we alwas make
* sure that the pool has been seeded enough initially */
if( level == 2 && !did_initial_extra_seeding ) {
size_t needed;
pool_balance = 0;
needed = length - pool_balance;
if( needed < POOLSIZE/2 )
needed = POOLSIZE/2;
else if( needed > POOLSIZE )
BUG();
read_random_source( 3, needed, 2 );
pool_balance += needed;
did_initial_extra_seeding=1;
}
/* for level 2 make sure that there is enough random in the pool */
if( level == 2 && pool_balance < length ) {
@ -336,6 +503,12 @@ read_pool( byte *buffer, size_t length, int level )
/****************
* Add LENGTH bytes of randomness from buffer to the pool.
* source may be used to specify the randomness source.
* Source is:
* 0 - used ony for initialization
* 1 - fast random poll function
* 2 - normal poll function
* 3 - used when level 2 random quality has been requested
* to do an extra pool seed.
*/
static void
add_randomness( const void *buffer, size_t length, int source )
@ -399,6 +572,13 @@ fast_random_poll()
add_randomness( &tv.tv_sec, sizeof(tv.tv_sec), 1 );
add_randomness( &tv.tv_usec, sizeof(tv.tv_usec), 1 );
}
#elif HAVE_CLOCK_GETTIME
{ struct timespec tv;
if( clock_gettime( CLOCK_REALTIME, &tv ) == -1 )
BUG();
add_randomness( &tv.tv_sec, sizeof(tv.tv_sec), 1 );
add_randomness( &tv.tv_nsec, sizeof(tv.tv_nsec), 1 );
}
#else /* use times */
#ifndef HAVE_DOSISH_SYSTEM
{ struct tms buf;
@ -408,13 +588,28 @@ fast_random_poll()
#endif
#endif
#ifdef HAVE_GETRUSAGE
#ifndef RUSAGE_SELF
#ifdef __GCC__
#warning There is no RUSAGE_SELF on this system
#endif
#else
{ struct rusage buf;
if( getrusage( RUSAGE_SELF, &buf ) )
BUG();
add_randomness( &buf, sizeof buf, 1 );
memset( &buf, 0, sizeof buf );
}
#endif
#endif
/* time and clock are availabe on all systems - so
* we better do it just in case one of the above functions
* didn't work */
{ time_t x = time(NULL);
add_randomness( &x, sizeof(x), 1 );
}
{ clock_t x = clock();
add_randomness( &x, sizeof(x), 1 );
}
}

View File

@ -25,6 +25,8 @@
/*-- random.c --*/
void random_dump_stats(void);
void secure_random_alloc(void);
void set_random_seed_file(const char *);
void update_random_seed_file(void);
int quick_random_gen( int onoff );
int random_is_faked(void);
void randomize_buffer( byte *buffer, size_t length, int level );

View File

@ -562,10 +562,10 @@ rmd160_get_info( int algo, size_t *contextsize,
*r_asnoid = asn;
*r_asnlen = DIM(asn);
*r_mdlen = 20;
*r_init = (void (*)(void *))rmd160_init;
*r_write = (void (*)(void *, byte*, size_t))rmd160_write;
*r_final = (void (*)(void *))rmd160_final;
*r_read = (byte *(*)(void *))rmd160_read;
*(void (**)(RMD160_CONTEXT *))r_init = rmd160_init;
*(void (**)(RMD160_CONTEXT *, byte*, size_t))r_write = rmd160_write;
*(void (**)(RMD160_CONTEXT *))r_final = rmd160_final;
*(byte *(**)(RMD160_CONTEXT *))r_read = rmd160_read;
return "RIPEMD160";
}

View File

@ -83,9 +83,13 @@ do_read( int fd, void *buf, size_t nbytes )
/* Note: we always use the highest level.
/****************
* Note: we always use the highest level.
* TO boost the performance we may want to add some
* additional code for level 1
*
* Using a level of 0 should never block and better add nothing
* to the pool. So this is just a dummy for EGD.
*/
static int
gather_random( void (*add)(const void*, size_t, int), int requester,
@ -99,7 +103,8 @@ gather_random( void (*add)(const void*, size_t, int), int requester,
if( !length )
return 0;
if( !level )
return 0;
restart:
if( do_restart ) {

View File

@ -89,6 +89,10 @@ open_device( const char *name, int minor )
}
/****************
* Note: Using a level of 0 should never block and better add nothing
* to the pool. This is easy to accomplish with /dev/urandom.
*/
static int
gather_random( void (*add)(const void*, size_t, int), int requester,
size_t length, int level )
@ -106,6 +110,8 @@ gather_random( void (*add)(const void*, size_t, int), int requester,
fd = fd_random;
}
else {
/* this will also be used for elve 0 but by using /dev/urandom
* we can be sure that oit will never block. */
if( fd_urandom == -1 )
fd_urandom = open_device( NAME_OF_DEV_URANDOM, 9 );
fd = fd_urandom;

View File

@ -75,9 +75,9 @@
#ifndef __QNX__
#include <sys/resource.h>
#endif /* __QNX__ */
#ifdef _AIX
#if defined( _AIX ) || defined( __QNX__ )
#include <sys/select.h>
#endif /* _AIX */
#endif /* _AIX || __QNX__ */
#ifndef __QNX__
#include <sys/shm.h>
#include <sys/signal.h>
@ -89,6 +89,10 @@
#endif /* __hpux 9.x, after that it's in unistd.h */
#include <sys/wait.h>
/* #include <kitchensink.h> */
#ifdef __QNX__
#include <signal.h>
#include <process.h>
#endif /* __QNX__ */
#include <errno.h>
#include "types.h" /* for byte and u32 typedefs */
@ -716,6 +720,10 @@ read_a_msg( int fd, GATHER_MSG *msg )
}
/****************
* Using a level of 0 should never block and better add nothing
* to the pool. So this is just a dummy for this gatherer.
*/
static int
gather_random( void (*add)(const void*, size_t, int), int requester,
size_t length, int level )
@ -725,6 +733,9 @@ gather_random( void (*add)(const void*, size_t, int), int requester,
GATHER_MSG msg;
size_t n;
if( !level )
return 0;
if( !gatherer_pid ) {
/* make sure we are not setuid */
if( getuid() != geteuid() )

958
cipher/rndw32.c Normal file
View File

@ -0,0 +1,958 @@
/* rndw32.c - W32 entropy gatherer
* Copyright (C) 1999, 2000 Free Software Foundation, Inc.
* Copyright Peter Gutmann, Matt Thomlinson and Blake Coverett 1996-1999
*
* This file is part of GnuPG.
*
* GnuPG is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* GnuPG is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*
*************************************************************************
* The code here is based on code from Cryptlib 3.0 beta by Peter Gutmann.
* Source file misc/rndwin32.c "Win32 Randomness-Gathering Code" with this
* copyright notice:
*
* This module is part of the cryptlib continuously seeded pseudorandom
* number generator. For usage conditions, see lib_rand.c
*
* [Here is the notice from lib_rand.c, which is now called dev_sys.c]
*
* This module and the misc/rnd*.c modules represent the cryptlib
* continuously seeded pseudorandom number generator (CSPRNG) as described in
* my 1998 Usenix Security Symposium paper "The generation of random numbers
* for cryptographic purposes".
*
* The CSPRNG code is copyright Peter Gutmann (and various others) 1996,
* 1997, 1998, 1999, all rights reserved. Redistribution of the CSPRNG
* modules and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice
* and this permission notice in its entirety.
*
* 2. Redistributions in binary form must reproduce the copyright notice in
* the documentation and/or other materials provided with the distribution.
*
* 3. A copy of any bugfixes or enhancements made must be provided to the
* author, <pgut001@cs.auckland.ac.nz> to allow them to be added to the
* baseline version of the code.
*
* ALTERNATIVELY, the code may be distributed under the terms of the GNU
* General Public License, version 2 or any later version published by the
* Free Software Foundation, in which case the provisions of the GNU GPL are
* required INSTEAD OF the above restrictions.
*
* Although not required under the terms of the GPL, it would still be nice if
* you could make any changes available to the author to allow a consistent
* code base to be maintained
*************************************************************************
*/
#include <config.h>
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#include <errno.h>
#include <string.h>
#include <windows.h>
#include "types.h"
#include "util.h"
#include "dynload.h"
/* We do not use the netropy DLL anymore because a standalone program is
* easier to maintain and */
/*#define USE_ENTROPY_DLL*/
#ifdef IS_MODULE
#define _(a) (a)
#else
#include "i18n.h"
#endif
static int debug_me;
#ifdef USE_ENTROPY_DLL
#define WIN32_SLOW_SEEDER 0
#define WIN32_FAST_SEEDER 1
#define PCP_SUCCESS 0
#define PCP_NULL_POINTER 1
#define PCP_SEEDER_FAILED 2
#define PCP_SEEDER_NO_MEM 3
#define PCP_SEEDER_TOO_SMALL 4
#define PCP_DLL_LOAD_FAILED 5
#define PCP_UNKNOWN_PLATFORM 6
#define PCP_ERROR_VERSION 7
#define PCP_DLL_FUNC 8
#define PCP_UNKNOWN_SEEDER_TYPE 9
/****************
* We sometimes get a SEEDER_TOO_SMALL error, in which case we increment
* the internal buffer by SEEDER_INC_CHUNK until we reach MAX_SEEDER_SIZE
* MAX_SEEDER_SIZE is used as an arbitrary limit to protect against
* bugs in Winseed.
*/
#define MAX_SEEDER_SIZE 500000
#define SEEDER_INC_CHUNK 50000
typedef void *WIN32_SEEDER;
static WIN32_SEEDER (WINAPI *create_instance)( byte type, unsigned int *reason);
static void (WINAPI *delete_instance)( WIN32_SEEDER that );
static unsigned int (WINAPI *get_internal_seed_size)( WIN32_SEEDER that );
static void (WINAPI *set_internal_seed_size)( WIN32_SEEDER that,
unsigned int new_size);
static unsigned int (WINAPI *get_expected_seed_size)( WIN32_SEEDER that);
static unsigned int (WINAPI *get_seed)( WIN32_SEEDER that, byte *buffer,
unsigned int *desired_length);
static WIN32_SEEDER slow_seeder, fast_seeder;
static byte *entropy_buffer;
static size_t entropy_buffer_size;
/****************
* Load and initialize the winseed DLL
* NOTE: winseed is not part of the GnuPG distribution. It should be available
* at the GNU crypto FTP server site.
* We do not load the DLL on demand to have a better control over the
* location of the library.
*/
static void
load_and_init_winseed( void )
{
HANDLE hInstance;
void *addr;
unsigned int reason = 0;
unsigned int n1, n2;
const char *dllname;
dllname = read_w32_registry_string( "HKEY_LOCAL_MACHINE",
"Software\\GNU\\GnuPG",
"EntropyDLL" );
if( !dllname )
dllname = "c:/gnupg/entropy.dll";
hInstance = LoadLibrary( dllname );
if( !hInstance )
goto failure;
if( !(addr = GetProcAddress( hInstance, "WS_create_instance" )) )
goto failure;
create_instance = addr;
if( !(addr = GetProcAddress( hInstance, "WS_delete_instance" )) )
goto failure;
delete_instance = addr;
if( !(addr = GetProcAddress( hInstance, "WS_get_internal_seed_size" )) )
goto failure;
get_internal_seed_size = addr;
if( !(addr = GetProcAddress( hInstance, "WS_set_internal_seed_size" )) )
goto failure;
set_internal_seed_size = addr;
if( !(addr = GetProcAddress( hInstance, "WS_get_expected_seed_size" )) )
goto failure;
get_expected_seed_size = addr;
if( !(addr = GetProcAddress( hInstance, "WS_get_seed" )) )
goto failure;
get_seed = addr;
/* we have all the functions - init the system */
slow_seeder = create_instance( WIN32_SLOW_SEEDER, &reason);
if( !slow_seeder ) {
g10_log_fatal("error creating winseed slow seeder: rc=%u\n", reason );
goto failure;
}
fast_seeder = create_instance( WIN32_FAST_SEEDER, &reason);
if( !fast_seeder ) {
g10_log_fatal("error creating winseed fast seeder: rc=%u\n", reason );
goto failure;
}
n1 = get_internal_seed_size( slow_seeder );
/*g10_log_info("slow buffer size=%u\n", n1);*/
n2 = get_internal_seed_size( fast_seeder );
/*g10_log_info("fast buffer size=%u\n", n2);*/
entropy_buffer_size = n1 > n2? n1: n2;
entropy_buffer = m_alloc( entropy_buffer_size );
/*g10_log_info("using a buffer of size=%u\n", entropy_buffer_size );*/
return;
failure:
g10_log_fatal("error loading winseed DLL `%s'\n", dllname );
}
/* Note: we always use the highest level.
* TO boost the performance we may want to add some
* additional code for level 1
*/
static int
gather_random( void (*add)(const void*, size_t, int), int requester,
size_t length, int level )
{
unsigned int result;
unsigned int nbytes;
if( !level )
return 0;
if( !slow_seeder )
load_and_init_winseed();
/* Our estimation on how much entropy we should use is very vague.
* Winseed delivers some amount of entropy on each slow poll and
* we add it to our random pool. Depending on the required quality
* level we adjust the requested length so that for higher quality
* we make sure to add more entropy to our pool. However, as we don't
* like to waste any entropy collected by winseed, we always add
* at least everything we got from winseed.
*/
if( level > 1 )
length *= 100;
else if( level > 0 )
length *= 10;
for(;;) {
nbytes = entropy_buffer_size;
result = get_seed( slow_seeder, entropy_buffer, &nbytes);
if( result == PCP_SEEDER_TOO_SMALL ) {
unsigned int n1 = get_internal_seed_size( slow_seeder );
if( n1 > MAX_SEEDER_SIZE ) {
g10_log_fatal("rndw32: internal seeder problem (size=%u)\n",
n1);
return -1; /* actually never reached */
}
n1 += SEEDER_INC_CHUNK;
set_internal_seed_size( slow_seeder, n1 );
if( n1 > entropy_buffer_size ) {
entropy_buffer_size = n1;
entropy_buffer = m_realloc( entropy_buffer,
entropy_buffer_size );
}
continue;
}
if( result ) {
g10_log_fatal("rndw32: get_seed(slow) failed: rc=%u\n", result);
return -1; /* actually never reached */
}
/*g10_log_info("rndw32: slow poll level %d, need %u, got %u\n",
level, (unsigned int)length, (unsigned int)nbytes );*/
(*add)( entropy_buffer, nbytes, requester );
if( length <= nbytes )
return 0; /* okay */
length -= nbytes;
}
}
static int
gather_random_fast( void (*add)(const void*, size_t, int), int requester )
{
unsigned int result;
unsigned int nbytes;
if( !fast_seeder )
load_and_init_winseed();
/* winseed delivers a constant ammount of entropy for a fast
* poll. We can simply use this and add it to the pool; no need
* a loop like it is used in the slow poll */
nbytes = entropy_buffer_size;
result = get_seed( fast_seeder, entropy_buffer, &nbytes);
if( result ) {
g10_log_fatal("rndw32: get_seed(fast) failed: rc=%u\n", result);
return -1; /* actually never reached */
}
/*g10_log_info("rndw32: fast poll got %u\n", (unsigned int)nbytes );*/
(*add)( entropy_buffer, nbytes, requester );
return 0;
}
#else /* !USE_ENTROPY_DLL */
/* This is the new code which does not require the entropy.dll */
/*
* Definitions which are missing from the current GNU Windows32Api
*/
#define TH32CS_SNAPHEAPLIST 1
#define TH32CS_SNAPPROCESS 2
#define TH32CS_SNAPTHREAD 4
#define TH32CS_SNAPMODULE 8
#define TH32CS_SNAPALL (1|2|4|8)
#define TH32CS_INHERIT 0x80000000
#define IOCTL_DISK_PERFORMANCE 0x00070020
#define VER_PLATFORM_WIN32_WINDOWS 1
typedef struct {
DWORD dwSize;
DWORD th32ProcessID;
DWORD th32HeapID;
DWORD dwFlags;
} HEAPLIST32;
typedef struct {
DWORD dwSize;
HANDLE hHandle;
DWORD dwAddress;
DWORD dwBlockSize;
DWORD dwFlags;
DWORD dwLockCount;
DWORD dwResvd;
DWORD th32ProcessID;
DWORD th32HeapID;
} HEAPENTRY32;
typedef struct {
DWORD dwSize;
DWORD cntUsage;
DWORD th32ProcessID;
DWORD th32DefaultHeapID;
DWORD th32ModuleID;
DWORD cntThreads;
DWORD th32ParentProcessID;
LONG pcPriClassBase;
DWORD dwFlags;
char szExeFile[260];
} PROCESSENTRY32;
typedef struct {
DWORD dwSize;
DWORD cntUsage;
DWORD th32ThreadID;
DWORD th32OwnerProcessID;
LONG tpBasePri;
LONG tpDeltaPri;
DWORD dwFlags;
} THREADENTRY32;
typedef struct {
DWORD dwSize;
DWORD th32ModuleID;
DWORD th32ProcessID;
DWORD GlblcntUsage;
DWORD ProccntUsage;
BYTE *modBaseAddr;
DWORD modBaseSize;
HMODULE hModule;
char szModule[256];
char szExePath[260];
} MODULEENTRY32;
/* Type definitions for function pointers to call Toolhelp32 functions
* used with the windows95 gatherer */
typedef BOOL (WINAPI * MODULEWALK) (HANDLE hSnapshot, MODULEENTRY32 *lpme);
typedef BOOL (WINAPI * THREADWALK) (HANDLE hSnapshot, THREADENTRY32 *lpte);
typedef BOOL (WINAPI * PROCESSWALK) (HANDLE hSnapshot, PROCESSENTRY32 *lppe);
typedef BOOL (WINAPI * HEAPLISTWALK) (HANDLE hSnapshot, HEAPLIST32 *lphl);
typedef BOOL (WINAPI * HEAPFIRST) (HEAPENTRY32 *lphe, DWORD th32ProcessID,
DWORD th32HeapID);
typedef BOOL (WINAPI * HEAPNEXT) (HEAPENTRY32 *lphe);
typedef HANDLE (WINAPI * CREATESNAPSHOT) (DWORD dwFlags, DWORD th32ProcessID);
/* Type definitions for function pointers to call NetAPI32 functions */
typedef DWORD (WINAPI * NETSTATISTICSGET) (LPWSTR szServer, LPWSTR szService,
DWORD dwLevel, DWORD dwOptions,
LPBYTE * lpBuffer);
typedef DWORD (WINAPI * NETAPIBUFFERSIZE) (LPVOID lpBuffer, LPDWORD cbBuffer);
typedef DWORD (WINAPI * NETAPIBUFFERFREE) (LPVOID lpBuffer);
/* When we query the performance counters, we allocate an initial buffer and
* then reallocate it as required until RegQueryValueEx() stops returning
* ERROR_MORE_DATA. The following values define the initial buffer size and
* step size by which the buffer is increased
*/
#define PERFORMANCE_BUFFER_SIZE 65536 /* Start at 64K */
#define PERFORMANCE_BUFFER_STEP 16384 /* Step by 16K */
static void
slow_gatherer_windows95( void (*add)(const void*, size_t, int), int requester )
{
static CREATESNAPSHOT pCreateToolhelp32Snapshot = NULL;
static MODULEWALK pModule32First = NULL;
static MODULEWALK pModule32Next = NULL;
static PROCESSWALK pProcess32First = NULL;
static PROCESSWALK pProcess32Next = NULL;
static THREADWALK pThread32First = NULL;
static THREADWALK pThread32Next = NULL;
static HEAPLISTWALK pHeap32ListFirst = NULL;
static HEAPLISTWALK pHeap32ListNext = NULL;
static HEAPFIRST pHeap32First = NULL;
static HEAPNEXT pHeap32Next = NULL;
HANDLE hSnapshot;
/* initialize the Toolhelp32 function pointers */
if ( !pCreateToolhelp32Snapshot ) {
HANDLE hKernel;
if ( debug_me )
log_debug ("rndw32#slow_gatherer_95: init toolkit\n" );
/* Obtain the module handle of the kernel to retrieve the addresses
* of the Toolhelp32 functions */
if ( ( !(hKernel = GetModuleHandle ("KERNEL32.DLL"))) ) {
g10_log_fatal ( "rndw32: can't get module handle\n" );
}
/* Now get pointers to the functions */
pCreateToolhelp32Snapshot = (CREATESNAPSHOT) GetProcAddress (hKernel,
"CreateToolhelp32Snapshot");
pModule32First = (MODULEWALK) GetProcAddress (hKernel, "Module32First");
pModule32Next = (MODULEWALK) GetProcAddress (hKernel, "Module32Next");
pProcess32First = (PROCESSWALK) GetProcAddress (hKernel,
"Process32First");
pProcess32Next = (PROCESSWALK) GetProcAddress (hKernel,
"Process32Next");
pThread32First = (THREADWALK) GetProcAddress (hKernel, "Thread32First");
pThread32Next = (THREADWALK) GetProcAddress (hKernel, "Thread32Next");
pHeap32ListFirst = (HEAPLISTWALK) GetProcAddress (hKernel,
"Heap32ListFirst");
pHeap32ListNext = (HEAPLISTWALK) GetProcAddress (hKernel,
"Heap32ListNext");
pHeap32First = (HEAPFIRST) GetProcAddress (hKernel, "Heap32First");
pHeap32Next = (HEAPNEXT) GetProcAddress (hKernel, "Heap32Next");
if ( !pCreateToolhelp32Snapshot
|| !pModule32First || !pModule32Next
|| !pProcess32First || !pProcess32Next
|| !pThread32First || !pThread32Next
|| !pHeap32ListFirst || !pHeap32ListNext
|| !pHeap32First || !pHeap32Next ) {
g10_log_fatal ( "rndw32: failed to get a toolhep function\n" );
}
}
/* Take a snapshot of everything we can get to which is currently
* in the system */
if ( !(hSnapshot = pCreateToolhelp32Snapshot (TH32CS_SNAPALL, 0)) ) {
g10_log_fatal ( "rndw32: failed to take a toolhelp snapshot\n" );
}
/* Walk through the local heap */
{ HEAPLIST32 hl32;
hl32.dwSize = sizeof (HEAPLIST32);
if (pHeap32ListFirst (hSnapshot, &hl32)) {
if ( debug_me )
log_debug ("rndw32#slow_gatherer_95: walk heap\n" );
do {
HEAPENTRY32 he32;
/* First add the information from the basic Heaplist32 struct */
(*add) ( &hl32, sizeof (hl32), requester );
/* Now walk through the heap blocks getting information
* on each of them */
he32.dwSize = sizeof (HEAPENTRY32);
if (pHeap32First (&he32, hl32.th32ProcessID, hl32.th32HeapID)){
do {
(*add) ( &he32, sizeof (he32), requester );
} while (pHeap32Next (&he32));
}
} while (pHeap32ListNext (hSnapshot, &hl32));
}
}
/* Walk through all processes */
{ PROCESSENTRY32 pe32;
pe32.dwSize = sizeof (PROCESSENTRY32);
if (pProcess32First (hSnapshot, &pe32)) {
if ( debug_me )
log_debug ("rndw32#slow_gatherer_95: walk processes\n" );
do {
(*add) ( &pe32, sizeof (pe32), requester );
} while (pProcess32Next (hSnapshot, &pe32));
}
}
/* Walk through all threads */
{ THREADENTRY32 te32;
te32.dwSize = sizeof (THREADENTRY32);
if (pThread32First (hSnapshot, &te32)) {
if ( debug_me )
log_debug ("rndw32#slow_gatherer_95: walk threads\n" );
do {
(*add) ( &te32, sizeof (te32), requester );
} while (pThread32Next (hSnapshot, &te32));
}
}
/* Walk through all modules associated with the process */
{ MODULEENTRY32 me32;
me32.dwSize = sizeof (MODULEENTRY32);
if (pModule32First (hSnapshot, &me32)) {
if ( debug_me )
log_debug ("rndw32#slow_gatherer_95: walk modules\n" );
do {
(*add) ( &me32, sizeof (me32), requester );
} while (pModule32Next (hSnapshot, &me32));
}
}
CloseHandle (hSnapshot);
}
static void
slow_gatherer_windowsNT( void (*add)(const void*, size_t, int), int requester )
{
static int is_initialized = 0;
static NETSTATISTICSGET pNetStatisticsGet = NULL;
static NETAPIBUFFERSIZE pNetApiBufferSize = NULL;
static NETAPIBUFFERFREE pNetApiBufferFree = NULL;
static int is_workstation = 1;
static int cbPerfData = PERFORMANCE_BUFFER_SIZE;
PERF_DATA_BLOCK *pPerfData;
HANDLE hDevice, hNetAPI32 = NULL;
DWORD dwSize, status;
int nDrive;
if ( !is_initialized ) {
HKEY hKey;
if ( debug_me )
log_debug ("rndw32#slow_gatherer_nt: init toolkit\n" );
/* Find out whether this is an NT server or workstation if necessary */
if (RegOpenKeyEx (HKEY_LOCAL_MACHINE,
"SYSTEM\\CurrentControlSet\\Control\\ProductOptions",
0, KEY_READ, &hKey) == ERROR_SUCCESS) {
BYTE szValue[32];
dwSize = sizeof (szValue);
if ( debug_me )
log_debug ("rndw32#slow_gatherer_nt: check product options\n" );
status = RegQueryValueEx (hKey, "ProductType", 0, NULL,
szValue, &dwSize);
if (status == ERROR_SUCCESS && stricmp (szValue, "WinNT")) {
/* Note: There are (at least) three cases for ProductType:
* WinNT = NT Workstation, ServerNT = NT Server, LanmanNT =
* NT Server acting as a Domain Controller */
is_workstation = 0;
if ( debug_me )
log_debug ("rndw32: this is a NT server\n");
}
RegCloseKey (hKey);
}
/* Initialize the NetAPI32 function pointers if necessary */
if ( (hNetAPI32 = LoadLibrary ("NETAPI32.DLL")) ) {
if ( debug_me )
log_debug ("rndw32#slow_gatherer_nt: netapi32 loaded\n" );
pNetStatisticsGet = (NETSTATISTICSGET) GetProcAddress (hNetAPI32,
"NetStatisticsGet");
pNetApiBufferSize = (NETAPIBUFFERSIZE) GetProcAddress (hNetAPI32,
"NetApiBufferSize");
pNetApiBufferFree = (NETAPIBUFFERFREE) GetProcAddress (hNetAPI32,
"NetApiBufferFree");
if ( !pNetStatisticsGet
|| !pNetApiBufferSize || !pNetApiBufferFree ) {
FreeLibrary (hNetAPI32);
hNetAPI32 = NULL;
g10_log_debug ("rndw32: No NETAPI found\n" );
}
}
is_initialized = 1;
}
/* Get network statistics. Note: Both NT Workstation and NT Server by
* default will be running both the workstation and server services. The
* heuristic below is probably useful though on the assumption that the
* majority of the network traffic will be via the appropriate service.
* In any case the network statistics return almost no randomness */
{ LPBYTE lpBuffer;
if (hNetAPI32 && !pNetStatisticsGet (NULL,
is_workstation ? L"LanmanWorkstation" :
L"LanmanServer", 0, 0, &lpBuffer) ) {
if ( debug_me )
log_debug ("rndw32#slow_gatherer_nt: get netstats\n" );
pNetApiBufferSize (lpBuffer, &dwSize);
(*add) ( lpBuffer, dwSize,requester );
pNetApiBufferFree (lpBuffer);
}
}
/* Get disk I/O statistics for all the hard drives */
for (nDrive = 0;; nDrive++) {
DISK_PERFORMANCE diskPerformance;
char szDevice[50];
/* Check whether we can access this device */
sprintf (szDevice, "\\\\.\\PhysicalDrive%d", nDrive);
hDevice = CreateFile (szDevice, 0, FILE_SHARE_READ | FILE_SHARE_WRITE,
NULL, OPEN_EXISTING, 0, NULL);
if (hDevice == INVALID_HANDLE_VALUE)
break;
/* Note: This only works if you have turned on the disk performance
* counters with 'diskperf -y'. These counters are off by default */
if (DeviceIoControl (hDevice, IOCTL_DISK_PERFORMANCE, NULL, 0,
&diskPerformance, sizeof (DISK_PERFORMANCE),
&dwSize, NULL))
{
if ( debug_me )
log_debug ("rndw32#slow_gatherer_nt: iostats drive %d\n",
nDrive );
(*add) ( &diskPerformance, dwSize, requester );
}
else {
log_info ("NOTE: you should run 'diskperf -y' "
"to enable the disk statistics\n");
}
CloseHandle (hDevice);
}
#if 0 /* we don't need this in GnuPG */
/* Wait for any async keyset driver binding to complete. You may be
* wondering what this call is doing here... the reason it's necessary is
* because RegQueryValueEx() will hang indefinitely if the async driver
* bind is in progress. The problem occurs in the dynamic loading and
* linking of driver DLL's, which work as follows:
*
* hDriver = LoadLibrary( DRIVERNAME );
* pFunction1 = ( TYPE_FUNC1 ) GetProcAddress( hDriver, NAME_FUNC1 );
* pFunction2 = ( TYPE_FUNC1 ) GetProcAddress( hDriver, NAME_FUNC2 );
*
* If RegQueryValueEx() is called while the GetProcAddress()'s are in
* progress, it will hang indefinitely. This is probably due to some
* synchronisation problem in the NT kernel where the GetProcAddress()
* calls affect something like a module reference count or function
* reference count while RegQueryValueEx() is trying to take a snapshot
* of the statistics, which include the reference counts. Because of
* this, we have to wait until any async driver bind has completed
* before we can call RegQueryValueEx() */
waitSemaphore (SEMAPHORE_DRIVERBIND);
#endif
/* Get information from the system performance counters. This can take
* a few seconds to do. In some environments the call to
* RegQueryValueEx() can produce an access violation at some random time
* in the future, adding a short delay after the following code block
* makes the problem go away. This problem is extremely difficult to
* reproduce, I haven't been able to get it to occur despite running it
* on a number of machines. The best explanation for the problem is that
* on the machine where it did occur, it was caused by an external driver
* or other program which adds its own values under the
* HKEY_PERFORMANCE_DATA key. The NT kernel calls the required external
* modules to map in the data, if there's a synchronisation problem the
* external module would write its data at an inappropriate moment,
* causing the access violation. A low-level memory checker indicated
* that ExpandEnvironmentStrings() in KERNEL32.DLL, called an
* interminable number of calls down inside RegQueryValueEx(), was
* overwriting memory (it wrote twice the allocated size of a buffer to a
* buffer allocated by the NT kernel). This may be what's causing the
* problem, but since it's in the kernel there isn't much which can be
* done.
*
* In addition to these problems the code in RegQueryValueEx() which
* estimates the amount of memory required to return the performance
* counter information isn't very accurate, since it always returns a
* worst-case estimate which is usually nowhere near the actual amount
* required. For example it may report that 128K of memory is required,
* but only return 64K of data */
{ pPerfData = m_alloc (cbPerfData);
for (;;) {
dwSize = cbPerfData;
if ( debug_me )
log_debug ("rndw32#slow_gatherer_nt: get perf data\n" );
status = RegQueryValueEx (HKEY_PERFORMANCE_DATA, "Global", NULL,
NULL, (LPBYTE) pPerfData, &dwSize);
if (status == ERROR_SUCCESS) {
if (!memcmp (pPerfData->Signature, L"PERF", 8)) {
(*add) ( pPerfData, dwSize, requester );
}
else
g10_log_debug ( "rndw32: no PERF signature\n");
break;
}
else if (status == ERROR_MORE_DATA) {
cbPerfData += PERFORMANCE_BUFFER_STEP;
pPerfData = m_realloc (pPerfData, cbPerfData);
}
else {
g10_log_debug ( "rndw32: get performance data problem\n");
break;
}
}
m_free (pPerfData);
}
/* Although this isn't documented in the Win32 API docs, it's necessary
to explicitly close the HKEY_PERFORMANCE_DATA key after use (it's
implicitly opened on the first call to RegQueryValueEx()). If this
isn't done then any system components which provide performance data
can't be removed or changed while the handle remains active */
RegCloseKey (HKEY_PERFORMANCE_DATA);
}
static int
gather_random( void (*add)(const void*, size_t, int), int requester,
size_t length, int level )
{
static int is_initialized;
static int is_windows95;
if( !level )
return 0;
/* We don't differentiate between level 1 and 2 here because
* there is no nternal entropy pool as a scary resource. It may
* all work slower, but because our entropy source will never
* block but deliver some not easy to measure entropy, we assume level 2
*/
if ( !is_initialized ) {
OSVERSIONINFO osvi = { sizeof( osvi ) };
DWORD platform;
GetVersionEx( &osvi );
platform = osvi.dwPlatformId;
is_windows95 = platform == VER_PLATFORM_WIN32_WINDOWS;
if ( platform == VER_PLATFORM_WIN32s ) {
g10_log_fatal("can't run on a W32s platform\n" );
}
is_initialized = 1;
if ( debug_me )
log_debug ("rndw32#gather_random: platform=%d\n", (int)platform );
}
if ( debug_me )
log_debug ("rndw32#gather_random: req=%d len=%u lvl=%d\n",
requester, (unsigned int)length, level );
if (is_windows95 ) {
slow_gatherer_windows95( add, requester );
}
else {
slow_gatherer_windowsNT( add, requester );
}
return 0;
}
static int
gather_random_fast( void (*add)(const void*, size_t, int), int requester )
{
static int addedFixedItems = 0;
if ( debug_me )
log_debug ("rndw32#gather_random_fast: req=%d\n", requester );
/* Get various basic pieces of system information: Handle of active
* window, handle of window with mouse capture, handle of clipboard owner
* handle of start of clpboard viewer list, pseudohandle of current
* process, current process ID, pseudohandle of current thread, current
* thread ID, handle of desktop window, handle of window with keyboard
* focus, whether system queue has any events, cursor position for last
* message, 1 ms time for last message, handle of window with clipboard
* open, handle of process heap, handle of procs window station, types of
* events in input queue, and milliseconds since Windows was started */
{ byte buffer[20*sizeof(ulong)], *bufptr;
bufptr = buffer;
#define ADD(f) do { ulong along = (ulong)(f); \
memcpy (bufptr, &along, sizeof (along) ); \
bufptr += sizeof (along); } while (0)
ADD ( GetActiveWindow ());
ADD ( GetCapture ());
ADD ( GetClipboardOwner ());
ADD ( GetClipboardViewer ());
ADD ( GetCurrentProcess ());
ADD ( GetCurrentProcessId ());
ADD ( GetCurrentThread ());
ADD ( GetCurrentThreadId ());
ADD ( GetDesktopWindow ());
ADD ( GetFocus ());
ADD ( GetInputState ());
ADD ( GetMessagePos ());
ADD ( GetMessageTime ());
ADD ( GetOpenClipboardWindow ());
ADD ( GetProcessHeap ());
ADD ( GetProcessWindowStation ());
ADD ( GetQueueStatus (QS_ALLEVENTS));
ADD ( GetTickCount ());
assert ( bufptr-buffer < sizeof (buffer) );
(*add) ( buffer, bufptr-buffer, requester );
#undef ADD
}
/* Get multiword system information: Current caret position, current
* mouse cursor position */
{ POINT point;
GetCaretPos (&point);
(*add) ( &point, sizeof (point), requester );
GetCursorPos (&point);
(*add) ( &point, sizeof (point), requester );
}
/* Get percent of memory in use, bytes of physical memory, bytes of free
* physical memory, bytes in paging file, free bytes in paging file, user
* bytes of address space, and free user bytes */
{ MEMORYSTATUS memoryStatus;
memoryStatus.dwLength = sizeof (MEMORYSTATUS);
GlobalMemoryStatus (&memoryStatus);
(*add) ( &memoryStatus, sizeof (memoryStatus), requester );
}
/* Get thread and process creation time, exit time, time in kernel mode,
and time in user mode in 100ns intervals */
{ HANDLE handle;
FILETIME creationTime, exitTime, kernelTime, userTime;
DWORD minimumWorkingSetSize, maximumWorkingSetSize;
handle = GetCurrentThread ();
GetThreadTimes (handle, &creationTime, &exitTime,
&kernelTime, &userTime);
(*add) ( &creationTime, sizeof (creationTime), requester );
(*add) ( &exitTime, sizeof (exitTime), requester );
(*add) ( &kernelTime, sizeof (kernelTime), requester );
(*add) ( &userTime, sizeof (userTime), requester );
handle = GetCurrentProcess ();
GetProcessTimes (handle, &creationTime, &exitTime,
&kernelTime, &userTime);
(*add) ( &creationTime, sizeof (creationTime), requester );
(*add) ( &exitTime, sizeof (exitTime), requester );
(*add) ( &kernelTime, sizeof (kernelTime), requester );
(*add) ( &userTime, sizeof (userTime), requester );
/* Get the minimum and maximum working set size for the current process */
GetProcessWorkingSetSize (handle, &minimumWorkingSetSize,
&maximumWorkingSetSize);
(*add) ( &minimumWorkingSetSize,
sizeof (&minimumWorkingSetSize), requester );
(*add) ( &maximumWorkingSetSize,
sizeof (&maximumWorkingSetSize), requester );
}
/* The following are fixed for the lifetime of the process so we only
* add them once */
if (!addedFixedItems) {
STARTUPINFO startupInfo;
/* Get name of desktop, console window title, new window position and
* size, window flags, and handles for stdin, stdout, and stderr */
startupInfo.cb = sizeof (STARTUPINFO);
GetStartupInfo (&startupInfo);
(*add) ( &startupInfo, sizeof (STARTUPINFO), requester );
addedFixedItems = 1;
}
/* The performance of QPC varies depending on the architecture it's
* running on and on the OS. Under NT it reads the CPU's 64-bit timestamp
* counter (at least on a Pentium and newer '486's, it hasn't been tested
* on anything without a TSC), under Win95 it reads the 1.193180 MHz PIC
* timer. There are vague mumblings in the docs that it may fail if the
* appropriate hardware isn't available (possibly '386's or MIPS machines
* running NT), but who's going to run NT on a '386? */
{ LARGE_INTEGER performanceCount;
if (QueryPerformanceCounter (&performanceCount)) {
if ( debug_me )
log_debug ("rndw32#gather_random_fast: perf data\n");
(*add) (&performanceCount, sizeof (&performanceCount), requester);
}
else { /* Millisecond accuracy at best... */
DWORD aword = GetTickCount ();
(*add) (&aword, sizeof (aword), requester );
}
}
return 0;
}
#endif /* !USE_ENTROPY_DLL */
#ifndef IS_MODULE
static
#endif
const char * const gnupgext_version = "RNDW32 ($Revision$)";
static struct {
int class;
int version;
void *func;
} func_table[] = {
{ 40, 1, gather_random },
{ 41, 1, gather_random_fast },
};
#ifndef IS_MODULE
static
#endif
void *
gnupgext_enum_func( int what, int *sequence, int *class, int *vers )
{
void *ret;
int i = *sequence;
debug_me = !!getenv("DEBUG_RNDW32");
do {
if ( i >= DIM(func_table) || i < 0 ) {
return NULL;
}
*class = func_table[i].class;
*vers = func_table[i].version;
ret = func_table[i].func;
i++;
} while ( what && what != *class );
*sequence = i;
return ret;
}
#ifndef IS_MODULE
void
rndw32_constructor(void)
{
register_internal_cipher_extension( gnupgext_version,
gnupgext_enum_func );
}
#endif

View File

@ -337,10 +337,10 @@ sha1_get_info( int algo, size_t *contextsize,
*r_asnoid = asn;
*r_asnlen = DIM(asn);
*r_mdlen = 20;
*r_init = (void (*)(void *))sha1_init;
*r_write = (void (*)(void *, byte*, size_t))sha1_write;
*r_final = (void (*)(void *))sha1_final;
*r_read = (byte *(*)(void *))sha1_read;
*(void (**)(SHA1_CONTEXT *))r_init = sha1_init;
*(void (**)(SHA1_CONTEXT *, byte*, size_t))r_write = sha1_write;
*(void (**)(SHA1_CONTEXT *))r_final = sha1_final;
*(byte *(**)(SHA1_CONTEXT *))r_read = sha1_read;
return "SHA1";
}

View File

@ -899,10 +899,10 @@ tiger_get_info( int algo, size_t *contextsize,
*r_asnoid = asn;
*r_asnlen = DIM(asn);
*r_mdlen = 24;
*r_init = (void (*)(void *))tiger_init;
*r_write = (void (*)(void *, byte*, size_t))tiger_write;
*r_final = (void (*)(void *))tiger_final;
*r_read = (byte *(*)(void *))tiger_read;
*(void (**)(TIGER_CONTEXT *))r_init = tiger_init;
*(void (**)(TIGER_CONTEXT *, byte*, size_t))r_write = tiger_write;
*(void (**)(TIGER_CONTEXT *))r_final = tiger_final;
*(byte *(**)(TIGER_CONTEXT *))r_read = tiger_read;
return "TIGER";
}

View File

@ -35,10 +35,6 @@
/* Prototype for the self-test function. */
static const char *selftest(void);
/* Macros used by the info function. */
#define FNCCAST_SETKEY(f) ((int(*)(void*, byte*, unsigned))(f))
#define FNCCAST_CRYPT(f) ((void(*)(void*, byte*, byte*))(f))
/* Structure for an expanded Twofish key. s contains the key-dependent
* S-boxes composed with the MDS matrix; w contains the eight "whitening"
* subkeys, K[0] through K[7]. k holds the remaining, "round" subkeys. Note
@ -991,16 +987,20 @@ twofish_get_info (int algo, size_t *keylen,
*keylen = algo==10? 256 : 128;
*blocksize = 16;
*contextsize = sizeof (TWOFISH_context);
*r_setkey = FNCCAST_SETKEY (twofish_setkey);
*r_encrypt= FNCCAST_CRYPT (twofish_encrypt);
*r_decrypt= FNCCAST_CRYPT (twofish_decrypt);
if( algo == 10 )
return "TWOFISH";
if (algo == 102) /* This algorithm number is assigned for
* experiments, so we can use it */
return "TWOFISH128";
return NULL;
*(int (**)(TWOFISH_context*, const byte*, const unsigned))r_setkey
= twofish_setkey;
*(void (**)(const TWOFISH_context*, byte*, const byte*))r_encrypt
= twofish_encrypt;
*(void (**)(const TWOFISH_context*, byte*, const byte*))r_decrypt
= twofish_decrypt;
if( algo == 10 )
return "TWOFISH";
if (algo == 102) /* This algorithm number is assigned for
* experiments, so we can use it */
return "TWOFISH128";
return NULL;
}

View File

@ -15,15 +15,16 @@ AM_CONFIG_HEADER(config.h)
VERSION=`cat $srcdir/VERSION`
PACKAGE=gnupg
ALL_LINGUAS="de es_ES fr it pl pt_BR pt_PT ru"
ALL_LINGUAS="de eo es_ES fr id it ja nl pl pt_BR pt_PT ru sv"
static_modules="sha1 md5 rmd160"
static_random_module=""
AC_SUBST(VERSION)
AC_SUBST(PACKAGE)
AC_DEFINE_UNQUOTED(VERSION, "$VERSION")
AC_DEFINE_UNQUOTED(PACKAGE, "$PACKAGE")
MODULES_IN_CIPHER=`awk '/# MODULES: / { for(i=3;i<=NF;i++) print $i}' \
$srcdir/cipher/Makefile.am`
MODULES_IN_CIPHER=`awk '/^EXTRA_PROGRAMS/ { for(i=3;i<=NF;i++) print $i}' \
$srcdir/cipher/Makefile.am`
dnl
dnl Check for random module options
@ -104,29 +105,6 @@ AC_ARG_WITH(included-zlib,
[g10_force_zlib=yes], [g10_force_zlib=no] )
AC_MSG_RESULT($g10_force_zlib)
dnl
dnl Check wether we want to compile libgcrypt
dnl
AC_MSG_CHECKING([whether compilation of libgcrypt is requested])
AC_ARG_ENABLE(libgcrypt,
[ --enable-libgcrypt compile the libgcrypt [default=no]],
[compile_libgcrypt="$enableval"],[compile_libgcrypt=no])
AC_MSG_RESULT($compile_libgcrypt)
if test x$compile_libgcrypt = xyes ; then
if test -f $srcdir/gcrypt/gcrypt.h; then
:
else
compile_libgcrypt=no
AC_MSG_WARN([[
***
*** LIBGCRYPT is not yet ready for public testing.
*** Maybe you have more luck with the next release of GnuPG
*** Watch the gnupg-announce mailing list or the webpage.
***]])
fi
fi
AM_CONDITIONAL(COMPILE_LIBGCRYPT, test x$compile_libgcrypt = xyes)
dnl
dnl Check whether we want to use Linux capabilities
@ -154,12 +132,13 @@ case "${target}" in
# special stuff for Windoze NT
# Do we need to set cross_compiling here or is it sufficient
# to rely on AC_PROG_CC which is called later?
cross_compiling=yes
CC="${target}-gcc"
CPP="${target}-gcc -E"
RANLIB="${target}-ranlib"
disallowed_modules="rndunix rndlinux rndegd"
;;
*)
disallowed_modules="rndw32"
;;
esac
@ -181,19 +160,7 @@ AC_CHECK_PROG(DOCBOOK_TO_MAN, docbook-to-man, yes, no)
AM_CONDITIONAL(HAVE_DOCBOOK_TO_MAN, test "$ac_cv_prog_DOCBOOK_TO_MAN" = yes)
dnl
dnl Build shared libraries only when compilation of libgcrypt
dnl has been requested
dnl
AM_DISABLE_SHARED
enable_shared="$compile_libgcrypt"
AM_PROG_LIBTOOL
MPI_OPT_FLAGS=""
if test "$GCC" = yes; then
CFLAGS="$CFLAGS -Wall -Wcast-align -Wshadow -Wstrict-prototypes"
fi
try_gettext=yes
@ -227,6 +194,12 @@ case "${target}" in
try_gdbm="no"
;;
*-*-freebsd*)
# FreeBSD
CPPFLAGS="$CPPFLAGS -I/usr/local/include"
LDFLAGS="$LDFLAGS -L/usr/local/lib"
;;
*-*-hpux*)
if test -z "$GCC" ; then
CFLAGS="$CFLAGS -Ae -D_HPUX_SOURCE"
@ -279,13 +252,19 @@ esac
AC_DEFINE_UNQUOTED(PRINTABLE_OS_NAME, "$PRINTABLE_OS_NAME")
dnl Fixme: Are these the best flags for OpenBSD????
dnl (I have removed the -lc from * ...CFLAGS for test purposes.)
case "${target}" in
*-openbsd*)
NAME_OF_DEV_RANDOM="/dev/srandom"
NAME_OF_DEV_URANDOM="/dev/urandom"
DYNLINK_MOD_CFLAGS="-shared -rdynamic -fpic -Wl,-Bshareable -Wl,-x"
;;
*-netbsd*)
NAME_OF_DEV_RANDOM="/dev/random"
NAME_OF_DEV_URANDOM="/dev/urandom"
DYNLINK_MOD_CFLAGS="-shared -rdynamic -fpic -Wl,-Bshareable -Wl,-x"
;;
*)
NAME_OF_DEV_RANDOM="/dev/random"
NAME_OF_DEV_URANDOM="/dev/urandom"
@ -344,8 +323,8 @@ if test "$try_dynload" = yes ; then
DYNLINK_LDFLAGS="$CFLAGS_RDYNAMIC"
use_gnupg_extensions=yes
else
AC_CHECK_LIB(c,dlopen)
if test "$ac_cv_lib_c_dlopen" = "yes"; then
AC_CHECK_FUNCS(dlopen)
if test "$ac_cv_func_dlopen" = "yes"; then
AC_DEFINE(USE_DYNAMIC_LINKING)
AC_DEFINE(HAVE_DL_DLOPEN)
DYNLINK_LDFLAGS="$CFLAGS_RDYNAMIC"
@ -407,6 +386,7 @@ GNUPG_CHECK_TYPEDEF(u32, HAVE_U32_TYPEDEF)
AC_CHECK_SIZEOF(unsigned short, 2)
AC_CHECK_SIZEOF(unsigned int, 4)
AC_CHECK_SIZEOF(unsigned long, 4)
AC_CHECK_SIZEOF(unsigned long long, 0)
if test "$ac_cv_sizeof_unsigned_short" = "0" \
|| test "$ac_cv_sizeof_unsigned_int" = "0" \
@ -419,7 +399,7 @@ fi
dnl Checks for library functions.
AC_FUNC_VPRINTF
AC_CHECK_FUNCS(strerror stpcpy strlwr stricmp tcgetattr rand strtoul mmap)
AC_CHECK_FUNCS(memmove gettimeofday getrusage gethrtime setrlimit)
AC_CHECK_FUNCS(memmove gettimeofday getrusage gethrtime setrlimit clock_gettime)
AC_CHECK_FUNCS(memicmp atexit raise getpagesize strftime nl_langinfo)
GNUPG_CHECK_MLOCK
@ -435,6 +415,7 @@ if test "$ac_cv_header_sys_capability_h" = "yes" ; then
AC_CHECK_LIB(cap, cap_init, ac_need_libcap=1)
if test "$ac_cv_lib_cap_cap_init" = "yes"; then
AC_DEFINE(USE_CAPABILITIES)
LIBS="$LIBS -lcap"
use_capabilities=yes
fi
fi
@ -494,31 +475,29 @@ fi
dnl
dnl Figure out the default linkage mode for cipher modules
dnl Figure out the default linkage mode for random modules
dnl
dnl (We always need a static rmd160)
print_egd_notice=no
static_modules="$static_modules rmd160"
if test "$use_static_rnd" = default; then
if test "$ac_cv_have_dev_random" = yes; then
static_modules="$static_modules rndlinux"
static_random_module="rndlinux"
else
case "${target}" in
*-*-mingw32)
static_modules="$static_modules rndw32"
static_random_module="rndw32"
AC_DEFINE(USE_STATIC_RNDW32)
;;
i?86-emx-os2|i?86-*-os2*emx)
static_modules="$static_modules rndos2"
static_random_module="rndos2"
;;
m68k-atari-mint)
static_modules="$static_modules rndatari"
static_random_module="rndatari"
;;
i?86-*-msdosdjgpp*)
static_modules="$static_modules"
:
;;
*)
static_modules="$static_modules rndunix"
static_random_module="rndunix"
print_egd_notice=yes
;;
esac
@ -527,7 +506,7 @@ else
if test "$use_static_rnd" = none; then
:
else
static_modules="$static_modules rnd$use_static_rnd"
static_random_module="rnd$use_static_rnd"
if test "$use_static_rnd" = "unix"; then
print_egd_notice=yes
fi
@ -560,23 +539,31 @@ dnl
dnl Parse the modules list and build the list
dnl of static and dymically linked modules
dnl
dnl (We always need a static rmd160)
static_modules="$static_modules rmd160 $static_random_module"
STATIC_CIPHER_NAMES=""
STATIC_CIPHER_OBJS=""
DYNAMIC_CIPHER_MODS=""
GNUPG_MSG_PRINT([dynamically linked cipher modules:])
for name in $MODULES_IN_CIPHER; do
x="no"
for i in $static_modules; do
if test "$name" = "$i" ; then
x="yes"
fi
x="yes"
for i in $disallowed_modules; do
if test "$name" = "$i" ; then x="no" ; fi
done;
if test $x = yes; then
STATIC_CIPHER_NAMES="$STATIC_CIPHER_NAMES $name"
STATIC_CIPHER_OBJS="$STATIC_CIPHER_OBJS $name.lo"
else
DYNAMIC_CIPHER_MODS="$DYNAMIC_CIPHER_MODS $name"
GNUPG_MSG_PRINT([$name])
x="no"
for i in $static_modules; do
if test "$name" = "$i" ; then
x="yes"
fi
done;
if test $x = yes; then
STATIC_CIPHER_NAMES="$STATIC_CIPHER_NAMES $name"
STATIC_CIPHER_OBJS="$STATIC_CIPHER_OBJS $name.o"
else
DYNAMIC_CIPHER_MODS="$DYNAMIC_CIPHER_MODS $name"
GNUPG_MSG_PRINT([$name])
fi
fi
done
AC_MSG_RESULT()
@ -643,7 +630,7 @@ if test "$ac_cv_mpi_extra_asm_modules" != ""; then
GNUPG_MSG_PRINT([mpi extra asm functions:])
for i in $ac_cv_mpi_extra_asm_modules; do
GNUPG_MSG_PRINT([$i])
MPI_EXTRA_ASM_OBJS="$MPI_EXTRA_ASM_OBJS $i.lo"
MPI_EXTRA_ASM_OBJS="$MPI_EXTRA_ASM_OBJS $i.o"
done
AC_MSG_RESULT()
fi
@ -676,15 +663,29 @@ fi
AC_SUBST(ZLIBS)
# Allow users to append something to the version string without
# flagging it as development version. The user version parts is
# considered everything after a dash.
changequote(,)dnl
tmp_pat='[a-zA-Z]'
changequote([,])dnl
if echo "$VERSION" | grep $tmp_pat >/dev/null ; then
if echo "$VERSION" | sed 's/-.*//' | grep "$tmp_pat" >/dev/null ; then
AC_DEFINE(IS_DEVELOPMENT_VERSION)
fi
AM_CONDITIONAL(CROSS_COMPILING, test x$cross_compiling = xyes)
GNUPG_DO_LINK_FILES
GNUPG_CHECK_GNUMAKE
if test "$GCC" = yes; then
if test "$MAINTAINER_MODE" = "yes"; then
CFLAGS="$CFLAGS -Wall -Wcast-align -Wshadow -Wstrict-prototypes"
else
CFLAGS="$CFLAGS -Wall"
fi
fi
AC_OUTPUT_COMMANDS([
cat >g10defs.tmp <<G10EOF
@ -725,11 +726,9 @@ mpi/Makefile
cipher/Makefile
g10/Makefile
doc/Makefile
doc/gph/Makefile
tools/Makefile
zlib/Makefile
checks/Makefile
gcrypt/Makefile
])
dnl *-*wedit:notab*-* Please keep this as the last line.

69
doc/ChangeLog Normal file
View File

@ -0,0 +1,69 @@
2000-05-12 10:57:21 Werner Koch (wk@habibti.openit.de)
* gpg.sgml: Documented --no-tty.
2000-03-09 15:01:51 Werner Koch (wk@habibti.openit.de)
* DETAILS: Ad a short blurb about unattended key generation.
Wed Feb 9 15:33:44 CET 2000 Werner Koch <wk@gnupg.de>
* gpg.sgml: Describe --ignore-time-conflict.
* gpg.sgml: Fixed a few typos. Thanks to Holger Trapp.
Wed Jan 5 11:51:17 CET 2000 Werner Koch <wk@gnupg.de>
* FAQ: Enhanced answer for the 3des-s2k bug.
Sat Dec 4 12:30:28 CET 1999 Werner Koch <wk@gnupg.de>
* gpg.sgml: Add section about the user ID
Mon Nov 22 11:14:53 CET 1999 Werner Koch <wk@gnupg.de>
* gph: Removed the directory from the dist becuase it will
go into it's own package.
Thu Sep 23 09:52:58 CEST 1999 Werner Koch <wk@isil.d.shuttle.de>
* README.W32: New.
Mon Sep 6 19:59:08 CEST 1999 Werner Koch <wk@isil.d.shuttle.de>
* Makefile.am (SUBDIRS): New subdir gph for the manual.
Thu Jul 22 20:03:03 CEST 1999 Werner Koch <wk@isil.d.shuttle.de>
* gpg.sgml (--always-trust): Added.
Wed Jul 14 19:42:08 CEST 1999 Werner Koch <wk@isil.d.shuttle.de>
* Makefile.am: Create a dummy man page if docbook-to-man is missing.
Wed Jun 16 20:16:21 CEST 1999 Werner Koch <wk@isil.d.shuttle.de>
* gpg1.pod: Removed.
* gpg.sgml: New. Replaces the pod file
* Makefile.am: Add rule to make a man file from sgml
Tue Jun 15 12:21:08 CEST 1999 Werner Koch <wk@isil.d.shuttle.de>
* Makefile.in.in: Use DESTDIR.
Mon May 31 19:41:10 CEST 1999 Werner Koch <wk@isil.d.shuttle.de>
* gpg.1pod: Enhanced the Bugs section (Michael).
Wed Feb 10 17:15:39 CET 1999 Werner Koch <wk@isil.d.shuttle.de>
* gpg.1pod: Spelling and grammar corrections (John A. Martin)
* FAQ: Ditto.
* DETAILS: Ditto.

View File

@ -134,6 +134,11 @@ more arguments in future versions.
SHM_GET_BOOL
SHM_GET_HIDDEN
GET_BOOL
GET_LINE
GET_HIDDEN
GOT_IT
NEED_PASSPHRASE <long keyid> <keytype> <keylength>
Issued whenever a passphrase is needed.
keytype is the numerical value of the public key algorithm
@ -181,6 +186,36 @@ more arguments in future versions.
<n_uids> <n_subk> <n_sigs> <n_revoc> <sec_read> <sec_imported> <sec_dups>
Final statistics on import process (this is one long line)
FILE_START <what> <filename>
Start processing a file <filename>. <what> indicates the performed
operation:
1 - verify
FILE_DONE
Marks the end of a file processing which has been started
by FILE_START.
BEGIN_DECRYPTION
END_DECRYPTION
Mark the start and end of the actual decryption process. These
are also emmited when in --list-only mode.
BEGIN_ENCRYPTION
END_ENCRYPTION
Mark the start and end of the actual encryption process.
DELETE_PROBLEM reason_code
Deleting a key failed. Reason codes are:
1 - No such key
2 - Must delete secret key first
PROGRESS what char cur total
Used by the primegen and Public key functions to indicate progress.
"char" is the character displayed with no --status-fd enabled, with
the linefeed replaced by an 'X'. "cur" is the current amount
done and "total" is amount to be done; a "total" of 0 indicates that
the toatal amount is not known. 100/100 may be used to detect the
end of operation.
Key generation
@ -214,6 +249,107 @@ Key generation
Crypto '97 proceedings p. 260.
Unattended key generation
=========================
There is an experimental feature which allows for unattended
generation of keys controlled by a parameter file.
This feature is not very well tested and does only make sense for some
very special applications. Please don't complain if we decide to chnage
the behaviour of this command.
To use this feature, you use --gen-key together with --batch and feed the
parameters either form stdin or from a file given on the commandline.
The format of this file is as follows:
o Text only, line length is limited to about 1000 chars.
o You must use UTF-8 encoding to specifiy non-ascii characters.
o Empty lines are ignored
o Leading and trailing spaces are ignored
o A hash sign as the first non white space character indicates a comment line
o Control statements are indicated by a leading percent sign, the
arguments are separated by white space from the keyword.
o Parameters are specified by a keyword, followed by a colon. Arguments
are speparated by white space.
o The first parameter must be "Key-Type", control statements
may be placed anywhere.
o Key generation takes place when either the end of the parameter file
is reached, the next "Key-Type" parameter is encountered or at the
controlstatement "%commit"
o Control staements:
%echo <text>
Print <text>
%dry-run
Suppress actual key generation (useful for syntax checking)
%commit
Perform the key generation. An implicit commit is done
at the next "Key-Type" parameter.
%pubring <filename>
%secring <filename>
Do not write the key to the default or commandline given
keyring but to <filename>. This must be given before the first
commit to take place, duplicate specification of the same filename
is ignored, the last filename before a commit is used.
The filename is used until a new filename is used (at commit points)
and all keys are written to that file. If a new filename is given,
this file is created (and overwrites an existing one).
Both control statements must be given.
o The order of the parameters does not matter except for "Key-Type"
which must be the first parameter. The paramtyers are only for the
generated keyblock and paramters from previous key generations are not
used. Some syntactically checks may be performed.
The currently defined parameters are:
Key-Type: <algo-number>|<algo-string>
Starts a new parameter block by giving the type of the
primary key. The algorithm must be capable of signing.
This is a required parameter.
Key-Length: <length-in-bits>
Length of the key in bits. Default is 1024
Subkey-Type: <algo-number>|<algo-string>
This generates a secondary key. Currently only one subkey
can be handled.
Subkey-Length: <length-in-bits>
Length of the subkey in bits. Default is 1024.
Passphrase: <string>
If you want to specify a passphrase for the secret key,
enter it here. Default is not to use any passphrase.
Name-Real: <string>
Name-Comment: <string>
Name-Email: <string>
The 3 parts of a key. Remember to use UTF-8 here.
If you don't give any of them, no user ID is created.
Expire-Date: <iso-date>|(<number>[d|w|m|y])
Set the expiration date for the key (and the subkey). It
may either be entered in ISO date format (2000-08-15) or as
number of days, weeks, month or years. Without a letter days
are assumed.
Here is an example:
$ cat >foo <<EOF
%echo Generating a standard key
Key-Type: DSA
Key-Length: 1024
Subkey-Type: ELG-E
Subkey-Length: 1024
Name-Real: Joe Tester
Name-Comment: with stupid passphrase
Name-Email: joe@foo.bar
Expire-Date: 0
Passphrase: abc
%pubring foo.pub
%secring foo.sec
# Do a commit here, so that we can later print "done" :-)
%commit
%echo done
EOF
$ gpg --batch --gen-key -a foo
[...]
$ gpg --no-default-keyring --secret-keyring foo.sec \
--keyring foo.pub --list-secret-keys
/home/wk/work/gnupg-stable/scratch/foo.sec
------------------------------------------
sec 1024D/915A878D 2000-03-09 Joe Tester (with stupid passphrase) <joe@foo.bar>
ssb 1024g/8F70E2C0 2000-03-09
Layout of the TrustDB
=====================
@ -477,6 +613,15 @@ There is one enhancement used with the old style packet headers:
+ that this is the last packet.
GNU extensions to the S2K algorithm
===================================
S2K mode 101 is used to identify these extensions.
After the hash algorithm the 3 bytes "GNU" are used to make
clear that these are extensions for GNU, the next bytes gives the
GNU protection mode - 1000. Defined modes are:
1001 - do not store the secret part at all
Usage of gdbm files for keyrings
================================
The key to store the keyblock is it's fingerprint, other records

64
doc/FAQ
View File

@ -342,3 +342,67 @@
where pgpkeyring is the original keyring and not the GnuPG one you
might have created in the first step.
Q: Are the headerlines of a cleartext signater part of the signed
material?
A: No. For example you can add or remove "Comment:" lines. They
have a purpose like the mail header lines. However a "Hash:"
line is needed for OpenPGG signatures to tell the parser which
hash algorithm to use.
Q: How can a get list of key IDs used to encrypt a message?
A: gpg --batch --decrypt --list-only --status-fd 1 2>/dev/null \
| awk '/^\[GNUPG:\] ENC_TO / { print $3 }'
Q: PGP 5.x, 6.x does not like my secret key.
A: PGP probably bails out on some private comment packets used by GnuPG.
These packets are fully in compliance with OpenPGP; however PGP is not
really OpenPGP aware. A workaround is to eport the secret keys with
this command:
gpg --export-secret-keys --no-comment -a your-key-id
Q: I can't decrypt my symmetrical only (-c) encrypted message with
a new version of GnuPG.
A: There used to be a bug in GnuPG < 1.0.1 which happens only if 3DES or
Twofish has been used for symmetric only encryption (this has never been
the default).
The bug has been fixed but to enable you to decrypt old messages, you
should run gpg with the option "--emulate-3des-s2k-bug", decrypt the
message and encrypt it again without this option. The option will
be removed in 1.1, so better re-encrypt your message now.
Q: How can I used GnuPG in an automated environment?
A: You should use the option --batch and don't use passphrases as
there is usually no way to store it more secure than the secret
keyring itself. The suggested way to create the keys for the
automated envirionment ist:
On a secure machine:
1. If you want to do automatic signing, create a signing subkey
for your key (edit menu, choose "addkey" and the DSA).
2. Make sure that you use a passphrase (Needed by the current
implementation)
3. gpg --export-secret-subkeys --no-comment foo >secring.auto
4. Copy secring.auto and the public keyring to a test directory.
5. Cd to this diectory
6. gpg --homedir . --edit foo
and use "passwd" to remove the passphrase from the subkeys.
You may also want to remove all unused subkeys.
7. copy secring.auto to a floppy and carry it to the
target box
On the target machine:
8. Install secring.auto as secret keyring.
9. Now you can start your new service. It is a good idea to
install some intrusion detection system so that you hopefully
get a notice of an successful intrusion, so that you in turn can
revoke all the subkeys installed on that machine and install new
subkeys.
Q: In the edit meu the trust values is not displayed correctly after
signing uids - why?
A: This happens because the some informations are stored immediately
in the trustdb, but the actual trust calculation can be done after
the save command. This is a not easy to fix design bug which will be
addressed in GnuPG 1.1

View File

@ -10,12 +10,12 @@ CVS Access
==========
Anonymous read-only CVS access is available:
cvs -z6 -d :pserver:anonymous@ftp.guug.de:/home/koch/cvs login
cvs -z6 -d :pserver:anonymous@cvs.guug.de:/home/koch/cvs login
use the password "anonymous". To check out the the complete
archive use:
cvs -z6 -d :pserver:anonymous@ftp.guug.de:/home/koch/cvs checkout gnupg
cvs -z6 -d :pserver:anonymous@cvs.guug.de:/home/koch/cvs checkout gnupg
This service is provided to help you in hunting bugs and not to deliver
stable snapshots; it may happen that it even does not compile, so please
@ -112,6 +112,72 @@ Directory Layout
./gcrypt Stuff needed to build libgcrypt (under construction)
Detailed Roadmap
----------------
g10/g10.c Main module with option parsing and all the stuff you have
to do on startup. Also has the exout handler and some
helper functions.
g10/sign.c
g10/parse-packet.c
g10/build-packet.c
g10/free-packet.c
Parsing and creating of OpenPGP message packets.
g10/getkey.c
g10/pkclist.c
g10/skclist.c
g10/ringedit.c
g10/keydb.h
g10/keyid.c Helper functions to get the keyid, fingerprint etc.
g10/trustdb.c
g10/trustdb.h
g10/tdbdump.c
g10/compress.c
g10/filter.h
g10/delkey.c
g10/kbnode.c
g10/main.h
g10/mainproc.c
g10/armor.c
g10/mdfilter.c
g10/textfilter.c
g10/cipher.c
g10/misc.c
g10/options.h
g10/openfile.c
g10/tdbio.c
g10/tdbio.h
g10/hkp.h
g10/hkp.c
g10/packet.h
g10/passphrase.c
g10/pubkey-enc.c
g10/seckey-cert.c
g10/seskey.c
g10/import.c
g10/export.c
g10/comment.c
g10/status.c
g10/status.h
g10/sign.c
g10/plaintext.c
g10/encr-data.c
g10/encode.c
g10/revoke.c
g10/keylist.c
g10/sig-check.c
g10/signal.c
g10/helptext.c
g10/verify.c
g10/decrypt.c
g10/keyedit.c
g10/dearmor.c
g10/keygen.c

View File

@ -1,8 +1,6 @@
## Process this file with automake to create Makefile.in
SUBDIRS = gph
EXTRA_DIST = DETAILS gpg.sgml gpg.1 FAQ HACKING OpenPGP
EXTRA_DIST = DETAILS gpg.sgml gpg.1 FAQ HACKING OpenPGP README.W32
man_MANS = gpg.1
@ -27,3 +25,7 @@ endif
-db2html $<
dist-hook:
@if test `wc -c < gpg.1` -lt 200; then \
echo 'ERROR: dummy man page'; false; fi

View File

@ -33,6 +33,15 @@
which can be considered to be in compliance with RFC1991; this
format is only created if a special option is active.
GnuPG uses a S2K mode of 101 for GNU extensions to the secret key
protection algorithms. This number is not defined in OpenPGP, but
given the fact that this number is in a range which used at many
other places in OpenPGP for private/experimenat algorithm identifiers,
this should be not a so bad choice. The 3 bytes "GNU" are used
to identify this as a GNU extension - see the file DETAILS for a
definition of the used data formats.
Some Notes on OpenPGP / PGP Compatibility:
==========================================

96
doc/README.W32 Normal file
View File

@ -0,0 +1,96 @@
This is a beta release of GnuPG for MS-Windows 95, 98 and WNT.
The random number generator should now work but has not undergone
a thorough testing, so we won't say anything about the quality of
the generated key and suggest that you don't use this version with
your production secret keys! It is however okay to verify signatures
or encrypt files using this version.
PLEASE READ THE FOLLOWING PARAGRAPH CAREFULLY:
If you have a bug report, please post it to the mailing list
<gnupg-devel@gnupg.org>. Please don't send me private mail
regarding this version of GnuPG; I am already spending too much
time on answering the same and same questions over and over.
I can improve GnuPG much faster if I don't have to answer
questions in private mail. You can post to the mailing list
without prior subscribing (but please request to CC you if you want
to get an answer).
Installation instructions:
--------------------------
1. Unpack the ZIP archive (alright, you already did this).
2. Copy "gpg.exe" to some place where you usually store your
binaries.
3. Create a directory "c:\gnupg" (or any other as you like)
4. If you did not use the default directory "c:\gnupg", you
should enter a string with the directory into the Registry
under the key:
\\HKEY_CURRENT_USER\Software\GNU\GnuPG\HomeDir
Please use forward slashes and not the backslashes when
setting filenames for GnuPG into the Registry.
5. Enter "gpg" and see what happens
6. Read the file README and the online HOWTOs
Internationalization support:
-----------------------------
1. Decide where to store the translation files for your language.
Here we assume the directory "c:/gnu/locale/fr"
2. Set the directory with the translations into the Registry under the key:
\\HKEY_CURRENT_USER\Control Panel\Mingw32\NLS\MODir
(Example entry: "c:/gnu/locale/fr")
3. Select which language to use and copy the currect translation file
under the name "gnupg.mo" into the directory set in step 2
(Example: "copy fr.mo c:\gnu\locale\fr\gnupg.mo")
4. Done.
Currently we only support the Codepages 437, 850 und Latin1. If you have
problems, either delete the gnupg.mo file or don't set the environment
variable
How to build it from the source:
--------------------------------
This version has been build with the Mingw32/CPD kit using the latest
stable version of GnuPG.
First get the source: It is available at
ftp://ftp.gnupg.org/pub/gcrypt/gnupg/gnupg-1.0.n.tar.gz
or for snapshots (with a letter appended to the version number)
ftp://ftp.gnupg.org/pub/gcrypt/devel/gnupg-1.0.nx.tar.gz
this is the same source as for the Unix version.
To build it, you need the MingW32/CPD kit, which is available at
ftp://ftp.openit.de/pub/cpd/mingw32-cpd-0.2.4.tar.gz
ftp://ftp.openit.de/pub/cpd/gcc-core-2.95.2.tar.gz
ftp://ftp.openit.de/pub/cpd/binutils-2.9.1.tar.gz
ftp://ftp.openit.de/pub/cpd/windows32api-0.1.2.tar.gz
gcc, binutils and windows32api are stock GNU source which are available
at every ftp.gnug.org mirror.
After you have installed this environment you should be able to do this:
$ ./configure --target=i386--mingw32
$ make
$ i386--mingw32-strip g10/gpg
$ cp g10/gpg /some_windows_drive/gpg.exe
And everything hopefully works.
Don't forget that MS-Windows ist just a temporary workaround until
you can switch to a GNU system ;-)
Be the source always with you.
Werner

View File

@ -27,7 +27,7 @@
-->
<!DOCTYPE RefEntry PUBLIC "-//Davenport//DTD DocBook V3.0//EN" [
<!DOCTYPE refentry PUBLIC "-//Davenport//DTD DocBook V3.0//EN" [
<!entity ParmDir "<parameter>directory</parameter>">
<!entity ParmFile "<parameter>file</parameter>">
<!entity OptParmFile "<optional>&ParmFile;</optional>">
@ -156,6 +156,15 @@ filename to force a read from stdin). With more than
and the remaining files are the signed stuff.
</para></listitem></varlistentry>
<varlistentry>
<term>--verify-files <optional><parameter/files/</optional></term>
<listitem><para>
This is a special version of the --verify command which does not work with
detached signatures. The command expects the files to bee verified either
on the commandline or reads the filenames from stdin; each anem muts be on
separate line. The command is intended for quick checking of many files.
</para></listitem></varlistentry>
<!--
B<-k> [I<username>] [I<keyring>]
Kludge to be somewhat compatible with PGP.
@ -226,8 +235,13 @@ useful for debugging.
<varlistentry>
<term>--gen-key</term>
<listitem><para>
Generate a new key pair. This command can only be
used interactive.
Generate a new key pair. This command is normally only used
interactive.
</para>
<para>
There is an experimental feature which allows to create keys
in batch mode. See the file <filename>doc/DETAILS</filename>
in the source distribution on how to use this.
</para></listitem></varlistentry>
@ -260,7 +274,7 @@ only in the local environment.</para></listitem></varlistentry>
<term>revsig</term>
<listitem><para>
Revoke a signature. GnuPG asks for every
every signature which has been done by one of
signature which has been done by one of
the secret keys, whether a revocation
certificate should be generated.</para></listitem></varlistentry>
<varlistentry>
@ -422,9 +436,14 @@ are not compatible to OpenPGP.
<varlistentry>
<term>--export-secret-keys &OptParmNames;</term>
<term>--export-secret-subkeys &OptParmNames;</term>
<listitem><para>
Same as --export, but does export the secret keys.
This is normally not very useful and a security risk.
the second form of the command has the special property to
render the secret part of the primary key useless; this is
a GNU extension to OpenPGP and other implementations can
not be expected to successful import such a key.
</para></listitem></varlistentry>
@ -676,6 +695,14 @@ Use batch mode. Never ask, do not allow interactive
commands.
</para></listitem></varlistentry>
<varlistentry>
<term>--no-tty</term>
<listitem><para>
Make sure that the TTY (terminal) is never used for any output.
This option is needed in some cases because GnuPG sometimes prints
warnings to the TTY if if --batch is used.
</para></listitem></varlistentry>
<varlistentry>
<term>--no-batch</term>
@ -723,6 +750,12 @@ balancing using round-robin DNS you may notice
that you get different key servers.
</para></listitem></varlistentry>
<varlistentry>
<term>--honor-http-proxy</term>
<listitem><para>
Try to access the keyserver over the proxy set with the variable
"http_proxy".
</para></listitem></varlistentry>
<varlistentry>
<term>--keyring &ParmFile;</term>
@ -734,7 +767,8 @@ does not contain a slash, it is assumed to be in the
home-directory ("~/.gnupg" if --homedir is not used).
The filename may be prefixed with a scheme:</para>
<para>"gnupg-ring:" is the default one.</para>
<para>"gnupg-gdbm:" may be used for a GDBM ring.</para>
<para>"gnupg-gdbm:" may be used for a GDBM ring. Note that GDBM
is experimental and likely to be removed in future versions.</para>
<para>It might make sense to use it together with --no-default-keyring.
</para></listitem></varlistentry>
@ -1074,6 +1108,16 @@ can only be used if only one passphrase is supplied.
Don't use this option if you can avoid it.
</para></listitem></varlistentry>
<varlistentry>
<term>--command-fd &ParmN;</term>
<listitem><para>
This is a replacement for the depreciated shared-memory IPC mode.
If this option is enabled, user input on questions is not expected
from the TTY but from the given file descriptor. It should be used
together with --status-fd. See the file doc/DETAILS in the source
distribution for details on how to use it.
</para></listitem></varlistentry>
<varlistentry>
<term>--rfc1991</term>
@ -1089,7 +1133,8 @@ Reset all packet, cipher and digest options to OpenPGP
behavior. Use this option to reset all previous
options like --rfc1991, --force-v3-sigs, --s2k-*,
--cipher-algo, --digest-algo and --compress-algo to
OpenPGP compliant values.
OpenPGP compliant values. All PGP workarounds are also
disabled.
</para></listitem></varlistentry>
@ -1124,6 +1169,16 @@ and encryption keys.
</para></listitem></varlistentry>
<varlistentry>
<term>--ignore-time-conflict</term>
<listitem><para>
GnuPG normally checks that the timestamps associated with keys and
signatures have plausible values. However, sometimes a signature seems to
be older than the key due to clock problems. This option makes these
checks just a warning.
</para></listitem></varlistentry>
<varlistentry>
<term>--lock-once</term>
<listitem><para>
@ -1141,6 +1196,25 @@ needed. Use this to override a previous --lock-once
from a config file.
</para></listitem></varlistentry>
<varlistentry>
<term>--lock-never</term>
<listitem><para>
Disable locking entirely. This option should be used only in very
special environments, where it can be assured that only one process
is accessing those files. A bootable floppy with a standalone
encryption system will probably use this. Improper usage of this
option may lead to data and key corruption.
</para></listitem></varlistentry>
<varlistentry>
<term>--no-random-seed-file</term>
<listitem><para>
GnuPG uses a file to store it's internal random pool over invocations.
This makes random generation faster; however sometimes write operations
are not desired. This option can be used to achive that with the cost of
slower random generation.
</para></listitem></varlistentry>
<varlistentry>
<term>--no-verbose</term>
@ -1207,6 +1281,25 @@ Same as the command --fingerprint but changes only the format of the output
and may be used together with another command.
</para></listitem></varlistentry>
<varlistentry>
<term>--fast-list-mode</term>
<listitem><para>
Changes the output of the list commands to work faster; this is achieved
by leaving some parts empty. Some applications don't need the user ID and
the trust information given in the listings. By using this options they
can get a faster listing. The excact behaviour of this option may change
in future versions.
</para></listitem></varlistentry>
<varlistentry>
<term>--list-only</term>
<listitem><para>
Changes the behaviour of some commands. This is like --dry-run but
different in some cases. The semantic of this command may be extended in
the future. Currently it does only skip the actual decryption pass and
therefore enables a fast listing of the encryption keys.
</para></listitem></varlistentry>
<varlistentry>
<term>--no-literal</term>
<listitem><para>
@ -1219,17 +1312,105 @@ This is not for normal use. Use the source to see for what it might be useful.
This is not for normal use. Use the source to see for what it might be useful.
</para></listitem></varlistentry>
<varlistentry>
<term>--entropy-dll-name &ParmFile;</term>
<listitem><para>
This option is only used for the Win32 version of GnuPG and changes the
default location (c:/gnupg/entropy.dll) of the Winseed DLL to &ParmFile;.
</para></listitem></varlistentry>
</variablelist>
</refsect1>
<refsect1>
<title>How to specify a user ID</title>
<para>
There are different ways on how to specify a user ID to GnuPG;
here are some examples:
</para>
<variablelist>
<varlistentry>
<term></term>
<listitem><para>Used to locate the default home directory.</para></listitem>
</varlistentry>
<varlistentry>
<term>234567C4</term>
<term>0F34E556E</term>
<term>01347A56A</term>
<term>0xAB123456</term>
<listitem><para>
Here the key ID is given in the usual short form.
</para></listitem>
</varlistentry>
<varlistentry>
<term>234AABBCC34567C4</term>
<term>0F323456784E56EAB</term>
<term>01AB3FED1347A5612</term>
<term>0x234AABBCC34567C4</term>
<listitem><para>
Here the key ID is given in the long form as used by OpenPGP.
</para></listitem>
</varlistentry>
<varlistentry>
<term>1234343434343434C434343434343434</term>
<term>123434343434343C3434343434343734349A3434</term>
<term>0E12343434343434343434EAB3484343434343434</term>
<term>0xE12343434343434343434EAB3484343434343434</term>
<listitem><para>
The best way to specify a key ID is by using the fingerprint of
the key. This avoids any ambiguities in case that there are duplicated
key IDs (which are really rare for the long key IDs).
</para></listitem>
</varlistentry>
<varlistentry>
<term>=Heinrich Heine &lt;heinrichh@uni-duesseldorf.de&gt;</term>
<listitem><para>
Using an exact to match string. The equal sign indicates this.
</para></listitem>
</varlistentry>
<varlistentry>
<term>&lt;heinrichh@uni-duesseldorf.de&gt;</term>
<listitem><para>
Using the email address part which must match exactly. The left angle bracket
indicates this email address mode.
</para></listitem>
</varlistentry>
<varlistentry>
<term>+Heinrich Heine duesseldorf</term>
<listitem><para>
All words must match exactly (not case sensitive) but can appear in
any order in the user ID. Words are any sequences of letters,
digits, the underscore and all characters with bit 7 set.
</para></listitem>
</varlistentry>
<varlistentry>
<term>#34</term>
<listitem><para>
Using the Local ID. This is a very low level method and should
only be used by applications which really need it. The hash character
indicates this method. An application should not assume that this is
only a number.
</para></listitem>
</varlistentry>
<varlistentry>
<term>Heine</term>
<term>*Heine</term>
<listitem><para>
By case insensitive substring matching. This is the default mode but
applications may want to explicitely indicate this by putting the asterisk
in front.
</para></listitem>
</varlistentry>
</variablelist>
</refsect1>
<refsect1>
<title>RETURN VALUE</title>
<para>
@ -1294,6 +1475,10 @@ constructed by cutting off the extension (".asc" or ".sig") of
<varlistentry>
<term>GNUPGHOME</term>
<listitem><para>If set directory used instead of "~/.gnupg".</para></listitem>
</varlistentry>
<varlistentry>
<term>http_proxy</term>
<listitem><para>Only honored when the option --honor-http-proxy is set.</para></listitem>
</varlistentry>
</variablelist>
@ -1333,6 +1518,11 @@ constructed by cutting off the extension (".asc" or ".sig") of
<listitem><para>and the lock file</para></listitem>
</varlistentry>
<varlistentry>
<term>~/.gnupg/random_seed</term>
<listitem><para>used to preserve the internal random pool</para></listitem>
</varlistentry>
<varlistentry>
<term>~/.gnupg/options</term>
<listitem><para>May contain options</para></listitem>
@ -1375,7 +1565,7 @@ is *very* easy to spy out your passphrase!
On many systems this program should be installed as setuid(root). This
is necessary to lock memory pages. Locking memory pages prevents the
operating system from writing memory pages to disk. If you get no
warning message about insecure memory your operating system supports
warning message about insecure memory 3our operating system supports
locking without being root. The program drops root privileges as soon
as locked memory is allocated.
</para>

View File

@ -11,7 +11,7 @@ all-local: ./signatures.jpg
./signatures.jpg: $(srcdir)/signatures.jpg.asc
../../g10/gpg --yes --dearmor \
-o ./signatures.jpg $(srcdir)/signatures.jpg.asc
test -d manual && cp ./signatures.jpg ./manual/signatures.jpg
-test -d manual && cp ./signatures.jpg ./manual/signatures.jpg
index.html: $(PARTS)
@ -27,7 +27,7 @@ index.html: $(PARTS)
echo '</body></html>' >>index.html
-rm -r manual.junk
-rm manual/signatures.jpg
(cd manual; rm -r stylesheet-images; ls | grep -v distfiles >distfiles)
## (cd manual; rm -r stylesheet-images; ls | grep -v distfiles >distfiles)
dist-hook: index.html

232
doc/gph/signatures.jpg.asc Normal file
View File

@ -0,0 +1,232 @@
-----BEGIN PGP ARMORED FILE-----
Version: GnuPG v0.9.11 (GNU/Linux)
Comment: For info see http://www.gnupg.org
Comment: Use "gpg --dearmor" for unpacking
/9j/4AAQSkZJRgABAQEAUABQAAD/2wBDAAgGBgcGBQgHBwcJCQgKDBQNDAsLDBkS
Ew8UHRofHh0aHBwgJC4nICIsIxwcKDcpLDAxNDQ0Hyc5PTgyPC4zNDL/2wBDAQkJ
CQwLDBgNDRgyIRwhMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIy
MjIyMjIyMjIyMjIyMjL/wAARCACxAogDASIAAhEBAxEB/8QAHwAAAQUBAQEBAQEA
AAAAAAAAAAECAwQFBgcICQoL/8QAtRAAAgEDAwIEAwUFBAQAAAF9AQIDAAQRBRIh
MUEGE1FhByJxFDKBkaEII0KxwRVS0fAkM2JyggkKFhcYGRolJicoKSo0NTY3ODk6
Q0RFRkdISUpTVFVWV1hZWmNkZWZnaGlqc3R1dnd4eXqDhIWGh4iJipKTlJWWl5iZ
mqKjpKWmp6ipqrKztLW2t7i5usLDxMXGx8jJytLT1NXW19jZ2uHi4+Tl5ufo6erx
8vP09fb3+Pn6/8QAHwEAAwEBAQEBAQEBAQAAAAAAAAECAwQFBgcICQoL/8QAtREA
AgECBAQDBAcFBAQAAQJ3AAECAxEEBSExBhJBUQdhcRMiMoEIFEKRobHBCSMzUvAV
YnLRChYkNOEl8RcYGRomJygpKjU2Nzg5OkNERUZHSElKU1RVVldYWVpjZGVmZ2hp
anN0dXZ3eHl6goOEhYaHiImKkpOUlZaXmJmaoqOkpaanqKmqsrO0tba3uLm6wsPE
xcbHyMnK0tPU1dbX2Nna4uPk5ebn6Onq8vP09fb3+Pn6/9oADAMBAAIRAxEAPwD3
+iiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiub8Z+MrbwRpaan
f6bqV1Zl9kktlGjiEnG3fudSAScA8jPBwSM5+i/Emx1bxBa6LcaH4g0i7vEka1/t
Sx8lZig3MqnceQvPpx1yQCAdpRXH6V4y1G7+Id74U1HQPsHk2kl7b3X2xZftEIlE
atsC/Lu5OCcjGMV0Gp67o+ieV/a2q2Nh52fL+13CRb8YzjcRnGR09RQBoUVyfi7x
NfWfgO78Q+EhpuqmBDN5jT7ovKQnzGUqcOQFPG4dDySNpuaF4x0fW7XTF/tCxh1O
+tIrn+zvtaNMm+ISbdvDHCnOcDjmgDoKKy9S8S6Do1wtvqmt6bYzsgdY7q6SJiuS
MgMQcZBGfY1qUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFF
FFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFF
FFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFF
FFABRRRQAVz/AIk8ceGvCPljXNXgtJJMFYcNJIQc4bYgLbflI3YxkYzmjxZ400Lw
Vpy3mtXflebuEEKKXkmZRkhVH4DJwoJGSMivnTxl4Z8X/EB5/Htr4TktLS6SDZbw
ytNPOu3YJQnUj5V6KvylSAw3PQB29/8AHy+1zVLPSfAnh2S5vLhwoOoDlj82VCI2
AAMNvL4ADZAAzXsmh2+o2mh2UGr3v23UliX7TOAoDyHltoVVG0HIHAOAM85Ncn8M
/hnY+ANLLuY7nWrhALq7A4A6+XHnkID36sRk9AF7ygDzf41zXlx4EuNDsNF1XUbr
Utux7G1MyReXLG58wjlcjOODnBrj/B2j6jL8XNI1a1s/GUlnFaTR3lx4qtlLxLtb
b5Up9WYDaoDD5uSrNj3iigDxf/hMLz/haf8AwlH/AAg/jL7D/Yn9n+X/AGSfM8zz
/MzjdjbjvnOe1SfFZtc1PWdHNrpF3Popsmljnh8ORalOJmYZR45sGIbQh6Kc5BBx
8vslFAHgfhNtS0n4UeNtKufDfiD7Xe3E4tUXRmiM32iLYpEacIF2EsB8qgqASSBR
4A0G58I+ILCDxD4Ru9bfUreyuLbVhYPLJpr4VRDJv4iEeOqkEBVyDwE98ooA+ZNZ
8JeKbbVNYg16DWdQnvLiVhfWvhi21EzxH5FcSl90JwvEYI2DGMZr2/4aWs1j8PNI
tJ21IvCkiD+0rcwThRIwUNGWbaAuAoyflA6dB1lFAGXrniPSPDVvbXGs30dnBcXC
20ckgO3zGBIBIGFGFJ3HAGOSK0IJ4bq3iuLeWOaCVA8ckbBldSMggjggjnNU9Z0P
S/EOnPYavYQXtq2TsmTO0kEblPVWwThhgjPBryufwV43+G1vLd+BdZk1bSYULtou
oqZGAA/5Z7cZO5nchPLJwB854oA9korh/B3xS0Lxdef2UVn0zXU3LLpt4hVwyAbw
p6Ng7hg4b5WJUAV3FABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFF
FABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFF
FABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUVz/izx
poXgrTlvNau/K83cIIUUvJMyjJCqPwGThQSMkZFAHQV5P4i+LFxq2oyeGvhxZ/2z
q7xSFr1SBDalTgsC4Cv3wxITJTBfO2stNN8afGZEm1dpPDfg6ZIporOMrJLd4bOS
2AcHkgsNv+rIRvvV6xoHhzSPC2lrpui2MdpaBy+xSWLMepZmJLHoMkngAdAKAOL8
J/Ce307WG8S+Kbz+3fEskq3H2iQERwOFxhFzhsHoSBgKm1UxXpFFFABRRRQAUUUU
AFFFFABRRRQAUUUUAFFFFAHJ+M/hz4c8dIjavbSLdxJsivLd9kqLuBxnBDDrwwON
zYwTmuHGpeP/AIWXDrrC3fi/wuqKft0Y/wBItuS0jMCWYgAN94lcbPnTla9kooAw
/C/i7RfGOlpf6PexzAorSwFgJYCcjbImcqcq3scZBI5rcrzPxR8G9IvnfVfC0knh
3Xo0YwTWMhhiLbQuGVfuAqCMpj7xJDdDn2fxQ1rwdqkGi/EzTo7QSI/kazaAvFOE
wMlFBOSQScYI3plFBzQB65RXPt458LLqOmWA16xkuNT3fYxFKHWXBK/eXKjLAqMk
ZYEDJGK6CgAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooA
KKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooA
KKKKACiiigAqnqt+2maXcXyWN3fGBN/2e0VWlcd9oYgE45xnJxgZOAblcf8AE7Vd
Y0vwNe/2BYX15qd1/osP2KF5Hh3A7pPkIZcKGww6MVoAj8D/ABP0Hx9cXlvpcd3B
PaortHdhFZ1JIyoV2JAIAJ7bl9aku/GWo2PxH07wxc6BssdS837JqX2xT5nlw+Y/
7oLkYJ28kZ6ivLLHTPEfw88S+FdYtLfWdetH0z7Pc2dtoP2d7W1Y71Rtu5TLvZnI
yGymGbDZro/FfiW8k+Jnh3UYfB3iua10CW+iuJItMLCbzEEatEQcMuRnJxwRQB6Z
4h1y28PaNPf3E1ojqjCCO6ukt1nl2krGHc4BbHXtye1WNJvW1LRrG/eKOJ7m3jma
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
AYEKRgfXIxg6i/Arw35EdvLquuS28Vo9msRuI0Xy2dpADsjBbEjeYNxI3BcggYrQ
tvhPZwa5purzeKvFd7dadL5tv9r1ASAZxuXlM7WAwwBGRxQB6BXz/wDEfxV/wlHx
FHgXWtT/AOEc8O2sqfapHOXvGO1lyVyqqdwI3EKv3m5AQfQFZ+s6HpfiHTnsNXsI
L21bJ2TJnaSCNynqrYJwwwRng0AGh2Ol6dodla6JHBHpiRKbYQNuQoeQwbndnOd2
TnOcnNaFeT3Pwj1Tw9uufh74rvtKk815fsF5J5toxbC9MHGFzyyuTheQRmo4Pit4
j8L3EUHxH8KyadBO4Eeo2A8yBNxwFYBmGQFkY4YtgDCd6APXKKx/D3irQvFdmbrQ
9TgvY1++EJDx5JA3IcMudpxkDOMjitigAooooAKKKKACiiigAooooAKp6tpsOs6N
faXcNIsF7byW8jRkBgrqVJGQRnB9DVyigDyv4H6lNDomreD7tYzd+G72S3aSEHY6
s7nIJOSd6ydhxt75r1SvF/G99b/D3426N4rnk8jTNYtHtdQMamR2KADcVPRRm3Py
c/u24Ofm9Y0TW9O8R6PBq2k3H2ixn3eXLsZN21ip4YAjkEcigDQooooAKKKKACii
igAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACii
igAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACii
igAooooAKKKKACiiigAooooAKKKKACiiigAooooA871v4N+HL6//ALU0WS78Oaoi
OI7jSpPKUMU2glBwAB1CFN25snnNYf8AaHxa8C/ubrToPGGkQdLmAlbtk+4ikD5i
wwrMdkn3jlz1HsFFAHD+GPi34O8VSw21rqf2W+m4W0vV8pyd20KDyjMSRhVYk56c
HHcVzfivwH4c8Z25TWdOjknCbY7uP5J4+GxhxyQCxO05XPJBrh5vBfj/AMDuJ/BP
iCTWtPRFQaPrD7iqqoVQjEgADczYUx8Ko+bpQB65RXlem/Gi00+4bS/HmlXfhzVI
kJZmieSCbBC7k2gtgsHxgMuF++a9Msb+z1OzjvLC7gu7WTOyaCQSI2CQcMODggj8
KALFFFFABRRRQAUUUUAfP/7QPgD/AJnTTo/7sephpf8AdSJ1U/gpwf7px941ufs3
zwt4F1O3WWMzpqbO8YYblVoowpI6gEqwB77T6V7BPBDdW8tvcRRzQSoUkjkUMrqR
ggg8EEcYrzf4deCz4E8a+KbCJJDp9+kF1YusMmxIw0oMTOcjeu5RgsSwIb1AAPTK
KKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAK
KKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAK
KKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAr
31hZ6nZyWd/aQXdrJjfDPGJEbBBGVPBwQD+FeZ3nwaXSXnvvAniDUvD94zpILfz2
ktZCinarg/MQW5JYuACw2kHFeqUUAeP/APCxPHPgj/kffDH2nTE/d/2rpWG+78u9
1ztG9imM+V1OAfuiSP8AaC8LnxZNp0qSLo4TMWrLvYM20HDRbA6jO5cjPIHGDkeu
V88az+zjrEu+6s/FMF/fTSl5jfQPFuzksxcM5LZx1HOSc+oB9BwTw3VvFcW8sc0E
qB45I2DK6kZBBHBBHOakrw/wj4S+KPw22/ZvsPiHTGzG2lR37J5edzB0aVVVPmPO
M7t3I6MvsF9Zf25oclrM99p7XMQyYJ/KngY4PDoSAwPoSpxjkHkA0KK+YPAq+JPG
9wNLi8WeK7O/fTxeLdT6jIIDtuvLkKJ1kXyyMfMv7xGBODx6n408W+OtA8Z2OlaP
pWjalb6qkw0+Eu6T7o4gzGRmYIAGbOB1UYyCc0AemUVwer+I/EvhbwHe6l4kvvDF
pqwuFS1dRcNaspK8MoBkZ8eYcKDwAegNY/w2+J2oeLfFV3ot7Jo12iWX2uO60tLi
NVIcIUZZgCT8wORgDHfPAB6pRXibfEn4g2Wia1r15Z+GJdP0PUzp97DD9oSWVldE
byySQAd4wT7/AC9j2ninxT4gj8W2XhTwpY2MupyWhv7i51JmEEUAYoOEO4sXAHHT
I4OSVAO4org9Kv8A4lXNv4gtb2x8Pw6haPAmn3AWcWs5YBpc5O8hVIAIAG7I5wcS
fCC4iu/hbo08NlBZRt5+IIC5RMTyDguzNz15J6+nFAHcUV4f4q+LnivRvEOo2EVr
odj5V2YLK01OG5Sa5j37BMJPlhEbHccllAAPJxk+4UAFFFFABRRRQAUUUUAFFFFA
BRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFA
BRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFA
BRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAVn63pX9t6PPp32++sPO2/6TYTe
VMmGDfK2DjOMH2JrQooA5PwZ4CtvA6PBp+tazc2bJtWzvZ0kijO4tuQBAVOS2cHB
zyCQCKfiH4ZWfiPxGNcm8R+I7S6j/wCPdLO+EaW2UCN5QKEpuA+bB5ya7iigDl9V
8D2et+F7LRNR1TVZmsZY57fUftAW7SRCdr7woBYAkZKk9/vfNWXpfwuttK8QLrie
KfE9xqCW72yy3d6k3yMDwd0fIVjvAORuAJBrvKKAPN/+FM6O2h6hpEniDxHJa6hd
peXO+8QmSRd2SfkwdxYFsgklEOflrY1r4c6XrkWkyS3+q22p6ZEIYdWtbnZeOm0q
Q8mDuzkk8dScY3MD2FFAHDp8M7ePTprdfFPisXU0sbyah/aZ+0siBwsW7bjywZHb
GOp68CpPCXw4tvBlxE2neIfEEtpGjILC6uke3wxycJsG07ucrg5z2JB7SigDzf8A
4UtoXkfYf7b8R/2N5vmf2R/aJ+ybd+/Zt2525993fOea9IoooAKKKKACiiigAooo
oAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooo
oAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooo
oAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooo
oAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooo
oAKKKKACiiigAooooAKKKKACiiigAooooA//2Q==
=ao7I
-----END PGP ARMORED FILE-----

View File

@ -1,15 +1,477 @@
Wed Sep 15 16:22:17 CEST 1999 Werner Koch <wk@isil.d.shuttle.de>
Thu May 18 11:38:54 CEST 2000 Werner Koch <wk@openit.de>
* keyedit.c (keyedit_menu): Add a keyword arg to the prompt.
* status.c, status.h: Added 3 new status tokens.
* status.c (do_get_from_fd): New.
(cpr_enabled,cpr_get,cpr_get_hidden,cpr_kill_prompt,
cpr_get_answer_is_yes,cpr_get_answer_yes_no_quit): Modified to work
with the new function.
* g10.c: Add new option --command-fd.
* status.c (progress_cb): New.
(set_status_fd): Register progress functions
Fri May 12 14:01:20 CEST 2000 Werner Koch <wk@openit.de>
* delkey.c (delete_key): Add 2 new status messages
* status.c, status.h (STATUS_DELETE_PROBLEM): New.
Fixed years of copyright in all source files.
Mon May 1 17:08:14 CEST 2000 Werner Koch <wk@openit.de>
* trustdb.c (propagate_validity): Fixed the bug that only one uid
gets fully trusted even when all are signed by an ultimate key.
Mon May 1 15:38:04 CEST 2000 Werner Koch <wk@openit.de>
* getkey.c (key_byname): Always returned a defined context. Fixed
a segv for invalid user id specifications. Reported by Walter Koch.
* getkey.c (get_user_id): I18ned "no user id" string. By Walter.
* pkclist.c (do_show_revocation_reason): Typo fixes.
* helptext.c: Ditto.
* armor.c (armor_filter): Fixed some CRLF issues. By Mike McEwan.
Fri Apr 14 19:37:08 CEST 2000 Werner Koch <wk@openit.de>
* pkclist.c (do_show_revocation_reason): New.
(show_revocation_reason): New and called at various places.
* g10.c (main): Fixed small typo.
* pkclist.c (do_we_trust): Act on always_trust but not for revoked
keys. Suggested by Chip Salzenberg.
* g10.c: New option --lock-never.
* ringedit.c (get_writable_keyblock_file): New.
* keygen.c (do_generate_keypair): Use this instead of the hardwired one.
* keygen.c (ask_user_id): Check that the email address is in the
correct field. Suggested by Christian Kurz.
Mon Apr 10 13:34:19 CEST 2000 Werner Koch <wk@openit.de>
* keyedit.c (show_key_with_all_names): s/sbb/ssb/
Tue Mar 28 14:26:58 CEST 2000 Werner Koch <wk@openit.de>
* trustdb.c (verify_own_keys): Do not print warning about unprotected
key when in quiet mode.
Wed Mar 22 13:50:24 CET 2000 Werner Koch <wk@openit.de>
* mainproc.c (print_userid): Do UTF8 conversion before printing.
* import.c (import_one): Ditto.
(import_secret_one): Ditto.
(delete_inv_parts): Ditto.
Thu Mar 16 16:20:23 CET 2000 Werner Koch <wk@openit.de>
* keylist.c (print_key_data): Handle a NULL pk gracefully.
* getkey.c (merge_one_pk_and_selfsig): Fixed silly code for
getting the primary keys keyID but kept using the one from the
subkey.
* pubkey-enc.c (get_it): Print a note for expired subkeys.
* getkey.c (has_expired): New.
(subkeys_expiretime): New.
(finish_lookup): Check for expired subkeys needed for encryption.
(merge_keys_and_selfsig): Fixed expiration date merging for subkeys.
* keylist.c (list_keyblock): Print expiration time for "sub".
(list_one): Add missing merging for public keys.
* mainproc.c (list_node): Ditto.
2000-03-14 13:49:38 Werner Koch (wk@habibti.openit.de)
* keygen.c (keyedit_menu): Do not allow to use certain commands
while the secret key is selected.
2000-03-09 12:53:09 Werner Koch (wk@habibti.openit.de)
* keygen.c (ask_expire_interval): Movede parsig to ...
(parse_expire_string): ... this new function. And some new control
commands.
(proc_parameter_file): Add expire date parsing.
(do_generate_keypair): Allow the use of specified output files.
2000-03-08 10:38:38 Werner Koch (wk@habibti.openit.de)
* keygen.c (ask_algo): Removed is_v4 return value and the commented
code to create Elg keys in a v3 packet. Removed the rounding
of key sizes here.
(do_create): Likewise removed arg v4_packet.
(gen_elg): Likewise removed arg version. Now rounding keysizes here.
(gen_dsa): Rounding keysize now here.
(release_parameter_list): New
(get_parameter*): New.
(proc_parameter_file): New.
(read_parameter_file): New.
(generate_keypair): Splitted. Now uses read_parameter_file when in
batch mode. Additional argument to specify a parameter file.
(do_generate_keypair): Main bulk of above fucntion and uses the
parameter list.
(do_create): Don't print long notice in batch mode.
* g10.c (main): Allow batched key generation.
Thu Mar 2 15:37:46 CET 2000 Werner Koch <wk@gnupg.de>
* pubkey-enc.c (get_it): Print a note about unknown cipher algos.
* g10.c (opts): Add a note to the help listing about the man page
and removed some options from the help listing.
* keyedit.c (print_and_check_one_sig): Use a new function to truncate
the output of the user ID. Suggested by Jan-Benedict Glaw.
Wed Feb 23 10:07:57 CET 2000 Werner Koch <wk@gnupg.de>
* helptext.c: typo fix.
Thu Feb 17 13:39:32 CET 2000 Werner Koch <wk@gnupg.de>
* revoke.c: Removed a bunch of commented code.
* packet.h (SIGSUBPKT_REVOC_REASON): New.
* build-packet.c (build_sig_subpkt): Support new sub packet.
* parse-packet.c (parse_one_sig_subpkt): Ditto.
(dump_sig_subpkt): Ditto.
* revoke.c (ask_revocation_reason): New.
(release_revocation_reason_info): New.
(revocation_reason_build_cb): New.
(gen_revoke): Ask for reason.
* main.h (struct revocation_reason_info): Add declaration.
* keyedit.c (menu_revsig): Add support for revocation reason.
(menu_revkey): Ditto.
(sign_uid_mk_attrib): Renamed to ...
(sign_mk_attrib): ... this, made static and add support for reasons.
Tue Feb 15 08:48:13 CET 2000 Werner Koch <wk@gnupg.de>
* build-packet.c (build_packet): Fixed fixing of old comment packets.
* import.c (import_keys): Fixed importing from stdin when called with
nnames set to zero as it normally happens.
Mon Feb 14 14:30:20 CET 2000 Werner Koch <wk@gnupg.de>
* sig-check.c (check_key_signature2): Add new arg r_expired.
(do_signature_check): New arg to pass it down to ...
(do_check): New arg r-expire which is set when the signature
has expired.
* trustdb.c (check_sig_record): Set SIGF_EXPIRED flag and set
the expiretime to zero so that thi signature will not be checked
anymore.
Fri Feb 11 17:44:40 CET 2000 Werner Koch <wk@gnupg.de>
* g10.c (g10_exit): Update the random seed_file.
(main): Set the random seed file. New option --no-random-seed-file.
Thu Feb 10 17:39:44 CET 2000 Werner Koch <wk@gnupg.de>
* keyedit.c (menu_expire): Fixed segv due to unitialized sub_pk.
By Rémi.
Thu Feb 10 11:39:41 CET 2000 Werner Koch <wk@gnupg.de>
* keylist.c (list_keyblock): Don't print warnings in the middle of
regulat output lines. By Rémi.
* sig-check.c: Include options.h
Wed Feb 9 15:33:44 CET 2000 Werner Koch <wk@gnupg.de>
* gpg.c: New option --ignore-time-conflict
* sig-check.c (do_check): Implemented this option.
* trustdb.c (check_trust): Ditto.
* sign.c (do_sign): Ditto.
* keygen.c (generate_subkeypair): Ditto.
* encode.c (encode_simple): use iobuf_cancel after open failure.
Reported by Huy Le.
Fri Jan 14 18:32:01 CET 2000 Werner Koch <wk@gnupg.de>
* packet.h (STRING2KEY): Changed mode from byte to int.
* parse-packet.c (parse_key): Add the special GNU protection stuff
* build-packet.c (so_secret_key): Ditto.
* seckey-cert.c (do_check): Ditto.
* keyedit.c (change_passphrase): Ditto.
* export.c (export_secsubkeys): New.
(do_export_stream): Hack to export the primary key using mode 1001.
* g10.c: New command --export-secret-subkeys
Thu Jan 13 19:31:58 CET 2000 Werner Koch <wk@gnupg.de>
* armor.c (is_armored): Check for 1-pass-sig packets. Reported by
David Hallinan <hallinan@rtd.com>.
(armor_filter): Replaced one LF by the LF macro. Reported by
Wolfgang Redtenbacher.
Wed Jan 5 11:51:17 CET 2000 Werner Koch <wk@gnupg.de>
* g10.c (main): Reset new global flag opt.pgp2_workarounds
when --openpgp is used.
* mainproc.c (proc_plaintext): Do the PGP2,5 workarounds only
when the global falg is set.
(proc_tree): Ditto.
* textfilter.c (copy_clearsig_text): Ditto.
* armor.c (armor_filter): Ditto.
* g10.c: New option --list-only
* mainproc.c (proc_tree): Don't do it if opt.list_only is active.
(proc_pubkey_enc): Implement option.
* status.h, status.c ({BEGIN,END}_{EN,DE}CRYPTION): New.
* cipher.c (cipher_filter): New status outputs.
* mainproc.c (proc_encrypted): New status outputs.
Fri Dec 31 14:08:15 CET 1999 Werner Koch <wk@gnupg.de>
* armor.c (armor_filter): Made the "Comment:" header translatable.
* hkp.c (hkp_import): Make sure that the program does not return
success when there is a connection problem. Reported by Phillip Jones.
Sun Dec 19 15:22:26 CET 1999 Werner Koch <wk@gnupg.de>
* armor.c (LF): Use this new macro at all places where a line LF
is needed. This way DOSish textfiles should be created when the
input data is also in dos mode.
* sign.c (LF): Ditto.
* textfilter.c (LF): Ditto.
(copy_clearsig_text): Disabled the forcing of CR,LF sequences
for DOS systems.
* plaintext.c (handle_plaintext): Fixes for line endings on DOS.
and react on a LF in cleartext.
* armor.c (fake_packet): Restore the original line ending after
removing trailing spaces.
* signal.c (got_fatal_signal): DOS fix.
Thu Dec 16 10:07:58 CET 1999 Werner Koch <wk@gnupg.de>
* mainproc.c (print_failed_pkenc): Fix for unknown algorithm.
Found by fygrave@epr0.org.
Thu Dec 9 10:31:05 CET 1999 Werner Koch <wk@gnupg.de>
* hkp.c: i18n the strings.
Sat Dec 4 15:32:20 CET 1999 Werner Koch <wk@gnupg.de>
* trustdb.c (verify_key): Shortcut for ultimately trusted keys.
Sat Dec 4 12:30:28 CET 1999 Werner Koch <wk@gnupg.de>
* pkclist.c (build_pk_list): Validate the trust using the namehash
if this one has been set by the key lookup.
* g10.c: Add --delete-secret-key to the help page.
* openfile.c (copy_options_file): Made static.
(try_make_homedir): New.
* ringedit.c (add_keyblock_resource): Use the try_make_hoemdir logic.
* tdbio.c (tdbio_set_dbname): Likewise.
* keygen.c (generate_user_id): Use m_alloc_clear() here. We should
better use an allocation function specific to the user_id packet.
* keygen.c (keygen_add_std_prefs): Changed symmetric preferences
to include Blowfish again. This is due to it's better speed compared
to CAST5.
* g10.c (strusage): Print the home directory.
* armor.c (armor_filter): Take action on the cancel control msg.
* filter.h (armor_filter_context_t): Add cancel flag.
Mon Nov 29 21:52:11 CET 1999 Werner Koch <wk@gnupg.de>
* g10.c: New option --fast-list-mode ..
* keylist.c (list_keyblock): .. and implemented.
* mainproc.c (list_node): Ditto.
* import.c (mark_non_selfsigned_uids_valid): Fixed the case that there
is a uid without any packet following.
Mon Nov 22 11:14:53 CET 1999 Werner Koch <wk@gnupg.de>
* mainproc.c (proc_plaintext): Never enable the hash processing
when skip_verify is active.
* armor.c (parse_header_line): Stop parsing on a WS line too.
Suggested by Aric Cyr.
* tdbdump.c (HEXTOBIN): Changed the name of the argument, so that
traditional cpp don't mess up the macros. Suggested by Jos Backus.
* mainproc.c (list_node): Print the PK algo in the --with-colon mode.
* keylist.c (list_keyblock): Ditto.
* signal.c (got_fatal_signal): Found the reason why exit(8) did not
work - it is better to set the disposition back to default before
raising the signal. Print the notice on stderr always.
Fri Nov 12 20:33:19 CET 1999 Werner Koch <wk@gnupg.de>
* g10.c (make_username): Swapped the logic.
* keylist.c (public_key_list): Now takes a STRLIST as arg and moved
the creation ot this list to the caller, so that he can copy with
UTF-conversion of user IDs. Changed all callers.
(secret_key_list): Likewise.
* getkey.c (get_user_id_string_native): New and ...
* encode.c (write_pubkey_enc_from_list): ... use it here.
* pubring.asc: Updated.
* packet.h (PKT_PHOTO_ID): New.
* parse-packet.c (parse_photo_id): New.
* build-packet.c (do_user_id: Handle photo IDs.
(build_packet): Change CTB for photo IDs
* free-packet.c (free_user_id): Release memory used for photo IDs
* sig-check.c (hash_uid_node): Handle photo IDs too.
* trustdb.c (print_uid_from_keyblock): Hash photo ID.
(make_uid_records): Ditto.
* getkey.c (find_by_name): Ditto.
* keyedit.c (show_prefs): Ditto.
* keylist.c (list_keyblock): Ditto.
Thu Oct 28 16:08:20 CEST 1999 Werner Koch <wk@gnupg.de>
* keygen.c (ask_expire_interval): Print a warning for systems
with a signed 32 time_t if the exiration time is beyoind 2038.
Fri Oct 8 20:40:50 CEST 1999 Werner Koch <wk@gnupg.de>
* ringedit.c (enum_keyblocks): The last fix way really stupid;
reverted and set rt to Unknown.
Fri Oct 8 20:32:01 CEST 1999 Werner Koch <wk@gnupg.de>
* ringedit.c (enum_keyblocks): Zero the entire kbpos out on open.
* g10.c (oEntropyDLL): Removed option.
(main): Made the warning on development versions more verbose.
* g10.c (oHonorHttpProxy): New option.
* hkp.c (hkp_ask_import,hkp_export): Implement this option.
* options.skel: Enable this option for new installations
Mon Oct 4 21:23:04 CEST 1999 Werner Koch <wk@gnupg.de>
* import.c (import_keys): Changed calling interface, adjusted caller.
(import): Moved printing of stats out ...
(print_stats): New. ... to here.
(import_keys_stream): Call stats print here.
(import_keys): Print stats as totals for all files.
* tdbio.h (DIRF_NEWKEYS): New
* tdbio.c (tdbio_dump_record): Print the new flag.
* trustdb.c (check_trust_record): New arg sigs_only. Adapted all
callers.
(do_update_trust_record): Removed recheck arg and add a new sigs_only
do we can later improve on the performance. Changed all callers too.
(check_trustdb): Evalutate the new flag and add a status output.
Do a check when the dir record has not been checked.
(build_cert_tree): Evaluate the new flag.
(check_trust): Ditto. Do a trust_record check, when the dir record
is not marked as checked.
(mark_fresh_keys): New.
(clear_lid_table): New.
(sync_trustdb): New.
* import.c (import_keys): Call sync_trustdb() after processing.
(import_keys_stream): Ditto.
* tdbdump.c (import_ownertrust): Ditto.
* import.c (import_revoke_cert): Notify the trust DB.
(do_update_trust_record): Use |= to set the REVOKED bit and not &=;
shame on me for this bad copy+paste introduced bug.
(do_we_trust): Add trustmask to allow revoked key override to work.
Chnaged are to allow return of a mofified trustlevel. Adapted the
one caller.
* g10.c: New options --emulate-3des-s2k-bug
* passphrase.c (hash_passphrase): Implemented above.
* mainproc.c (proc_tree): Check for standalone signatures.
(do_check_sig): Print a notice for a standalone revocation
(check_sig_and_print): Do not print an error for unchecked standalone
revocations.
Tue Sep 28 20:54:37 CEST 1999 Werner Koch <wk@gnupg.de>
* encode.c (encode_simple): Use new CTB when we don't have the
length of the file. This is somewhat strange as the comment above
indicates that this part is actually fixed for PGP 5 - maybe I simply
lost the source line, tsss.
* armor.c (armor_filter): Set a flag if no OpenPGP data has been found.
* verify.c (verify_signatures): Add an error helptext.
Thu Sep 23 19:24:30 CEST 1999 Werner Koch <wk@isil.d.shuttle.de>
* openfile.c (open_outfile): Fixed the 8dot3 handling.
* passphrase.c (passphrase_to_dek): Print uid using utf8 func.
* delkey.c (delete_key): Ditto.
* pkclist.c (show_paths,do_edit_ownertrust,do_we_trust): Ditto
(do_we_trust_pre): Ditto.
* trustdb.c (print_user_id,check_uidsigs): Ditto.
* revoke.c (gen_revoke,ask_revoke_sig): Ditto.
Thu Sep 23 09:52:58 CEST 1999 Werner Koch <wk@isil.d.shuttle.de>
* verify.c (print_file_status): New.
(verify_one_file): Moved status print to th new fnc. Add error status.
* status.c, status.h (STATUS_FILE_ERROR): New
Wed Sep 22 10:14:17 CEST 1999 Werner Koch <wk@isil.d.shuttle.de>
* openfile.c (make_outfile_name): Use case-insenstive compare for
DOS systems. Add ".pgp" to the list of know extensions.
(open_outfile): For DOS systems try to replace the suffiy instead of
appending it.
* status.c, status.h: Add STATUS_FILE_{START,DONE}.
* verify.c (verify_one_file): Emit these new stati.
* sign.c (clearsign_file): Avoid duplicated Entries in the "Hash:"
line. Those headers are now only _not_ printed when there are
only old-style keys _and_ all hashs are MD5.
Mon Sep 20 12:24:41 CEST 1999 Werner Koch <wk@isil.d.shuttle.de>
* verify.c (verify_files, ferify_one_file): New.
* g10.c: New command --verify-files
Fri Sep 17 12:56:42 CEST 1999 Werner Koch <wk@isil.d.shuttle.de>
* g10.c: Add UK spelling as alias for armor options ;-)
* import.c (append_uid): Fixed a SEGV when there is no selfsig and
no subkey.
(merge_sigs): Ditto. Removed the assertion.
Wed Sep 15 16:22:17 CEST 1999 Werner Koch <wk@isil.d.shuttle.de>
* g10.c: New option --entropy-dll-name
Mon Sep 13 10:51:29 CEST 1999 Werner Koch <wk@isil.d.shuttle.de>
* signal.c (got_fatal_signal): Print message using write(2) and
only for development versions.
Mon Sep 6 19:59:08 CEST 1999 Werner Koch <wk@isil.d.shuttle.de>
* tdbio.c (tdbio_set_dbname): Use mkdir macro

View File

@ -4,7 +4,7 @@ INCLUDES = -I$(top_srcdir)/include -I$(top_srcdir)/intl
EXTRA_DIST = OPTIONS pubring.asc options.skel
OMIT_DEPENDENCIES = zlib.h zconf.h
LDFLAGS = @LDFLAGS@ @DYNLINK_LDFLAGS@
needed_libs = ../cipher/libcipher.la ../mpi/libmpi.la ../util/libutil.la
needed_libs = ../cipher/libcipher.a ../mpi/libmpi.a ../util/libutil.a
#noinst_PROGRAMS = gpgd
bin_PROGRAMS = gpg

View File

@ -19,6 +19,6 @@ compress-sigs
run-as-shm-coprocess [request-locked-shm-size]
# very special :-)
# You will have to use "--status-fd" too
# Note: This option dioes only work if given on the command line.
# Note: This option does only work if given on the command line.

View File

@ -1,5 +1,5 @@
/* armor.c - Armor flter
* Copyright (C) 1998, 1999 Free Software Foundation, Inc.
* Copyright (C) 1998, 1999, 2000 Free Software Foundation, Inc.
*
* This file is part of GnuPG.
*
@ -37,6 +37,11 @@
#include "status.h"
#include "i18n.h"
#ifdef HAVE_DOSISH_SYSTEM
#define LF "\r\n"
#else
#define LF "\n"
#endif
#define MAX_LINELEN 20000
@ -162,6 +167,7 @@ is_armored( const byte *buf )
switch( pkttype ) {
case PKT_MARKER:
case PKT_SYMKEY_ENC:
case PKT_ONEPASS_SIG:
case PKT_PUBLIC_KEY:
case PKT_SECRET_KEY:
case PKT_PUBKEY_ENC:
@ -311,9 +317,15 @@ parse_header_line( armor_filter_context_t *afx, byte *line, unsigned len )
byte *p;
int hashes=0;
/* fixme: why this double check? I think the original code w/o the
* second check for an empty line was done from an early draft of
* of OpenPGP - or simply very stupid code */
if( *line == '\n' || ( len && (*line == '\r' && line[1]=='\n') ) )
return 0; /* empty line */
len = trim_trailing_ws( line, len );
if( !len )
return 0; /* WS only same as empty line */
p = strchr( line, ':');
if( !p || !p[1] ) {
log_error(_("invalid armor header: "));
@ -479,13 +491,26 @@ fake_packet( armor_filter_context_t *afx, IOBUF a,
if( !maxlen )
afx->truncated++;
if( !afx->not_dash_escaped ) {
int crlf;
p = afx->buffer;
n = afx->buffer_len;
crlf = n > 1 && p[n-2] == '\r' && p[n-1]=='\n';
/* PGP2 does not treat a tab as white space character */
afx->buffer_len =
trim_trailing_chars( afx->buffer, afx->buffer_len,
afx->buffer_len = trim_trailing_chars( p, n,
afx->pgp2mode ? " \r\n" : " \t\r\n");
/* the buffer is always allocated with enough space to append
* a CR, LF, Nul */
afx->buffer[afx->buffer_len++] = '\r';
* the removed [CR], LF and a Nul
* The reason for this complicated procedure is to keep at least
* the original tupe of lineending - handling of the removed
* trailing spaces seems to be impossible in our method
* of faking a packet; either we have to use a temporary file
* or calculate the hash here in this module and somehow find
* a way to send the hash down the processing line (well, a special
* faked packet could do the job).
*/
if( crlf )
afx->buffer[afx->buffer_len++] = '\r';
afx->buffer[afx->buffer_len++] = '\n';
afx->buffer[afx->buffer_len] = 0;
}
@ -813,7 +838,8 @@ armor_filter( void *opaque, int control,
hashes &= 1|2|4|8;
if( !hashes ) {
hashes |= 4; /* default to MD 5 */
afx->pgp2mode = 1;
if( opt.pgp2_workarounds )
afx->pgp2mode = 1;
}
n=0;
do {
@ -868,44 +894,45 @@ armor_filter( void *opaque, int control,
#endif
*ret_len = n;
}
else if( control == IOBUFCTRL_FLUSH ) {
else if( control == IOBUFCTRL_FLUSH && !afx->cancel ) {
if( !afx->status ) { /* write the header line */
const char *s;
if( afx->what >= DIM(head_strings) )
log_bug("afx->what=%d", afx->what);
iobuf_writestr(a, "-----");
iobuf_writestr(a, head_strings[afx->what] );
iobuf_writestr(a, "-----\n");
iobuf_writestr(a, "-----" LF );
if( !opt.no_version )
iobuf_writestr(a, "Version: GnuPG v" VERSION " ("
PRINTABLE_OS_NAME ")\n");
PRINTABLE_OS_NAME ")" LF );
if( opt.comment_string ) {
const char *s = opt.comment_string;
if( *s ) {
iobuf_writestr(a, "Comment: " );
for( ; *s; s++ ) {
if( *s == '\n' )
iobuf_writestr(a, "\\n" );
else if( *s == '\r' )
iobuf_writestr(a, "\\r" );
else if( *s == '\v' )
iobuf_writestr(a, "\\v" );
else
iobuf_put(a, *s );
}
iobuf_put(a, '\n' );
/* write the comment string or a default one */
s = opt.comment_string ? opt.comment_string
: _("For info see http://www.gnupg.org");
if( *s ) {
iobuf_writestr(a, "Comment: " );
for( ; *s; s++ ) {
if( *s == '\n' )
iobuf_writestr(a, "\\n" );
else if( *s == '\r' )
iobuf_writestr(a, "\\r" );
else if( *s == '\v' )
iobuf_writestr(a, "\\v" );
else
iobuf_put(a, *s );
}
iobuf_writestr(a, LF );
}
else
iobuf_writestr(a,
"Comment: For info see http://www.gnupg.org\n");
if( afx->hdrlines )
iobuf_writestr(a, afx->hdrlines);
iobuf_put(a, '\n');
iobuf_writestr(a, LF );
afx->status++;
afx->idx = 0;
afx->idx2 = 0;
afx->crc = CRCINIT;
}
crc = afx->crc;
idx = afx->idx;
@ -930,7 +957,7 @@ armor_filter( void *opaque, int control,
c = bintoasc[radbuf[2]&077];
iobuf_put(a, c);
if( ++idx2 >= (64/4) ) { /* pgp doesn't like 72 here */
iobuf_put(a, '\n');
iobuf_writestr(a, LF );
idx2=0;
}
}
@ -945,8 +972,13 @@ armor_filter( void *opaque, int control,
if( !is_initialized )
initialize();
}
else if( control == IOBUFCTRL_CANCEL ) {
afx->cancel = 1;
}
else if( control == IOBUFCTRL_FREE ) {
if( afx->status ) { /* pad, write cecksum, and bottom line */
if( afx->cancel )
;
else if( afx->status ) { /* pad, write cecksum, and bottom line */
crc = afx->crc;
idx = afx->idx;
idx2 = afx->idx2;
@ -969,13 +1001,13 @@ armor_filter( void *opaque, int control,
iobuf_put(a, '=');
}
if( ++idx2 >= (64/4) ) { /* pgp doesn't like 72 here */
iobuf_put(a, '\n');
iobuf_writestr(a, LF );
idx2=0;
}
}
/* may need a linefeed */
if( idx2 )
iobuf_put(a, '\n');
iobuf_writestr(a, LF );
/* write the CRC */
iobuf_put(a, '=');
radbuf[0] = crc >>16;
@ -989,16 +1021,17 @@ armor_filter( void *opaque, int control,
iobuf_put(a, c);
c = bintoasc[radbuf[2]&077];
iobuf_put(a, c);
iobuf_put(a, '\n');
iobuf_writestr(a, LF );
/* and the the trailer */
if( afx->what >= DIM(tail_strings) )
log_bug("afx->what=%d", afx->what);
iobuf_writestr(a, "-----");
iobuf_writestr(a, tail_strings[afx->what] );
iobuf_writestr(a, "-----\n");
iobuf_writestr(a, "-----" LF );
}
else if( !afx->any_data && !afx->inp_bypass ) {
log_error(_("no valid OpenPGP data found.\n"));
afx->no_openpgp_data = 1;
write_status_text( STATUS_NODATA, "1" );
}
if( afx->truncated )

View File

@ -1,5 +1,5 @@
/* build-packet.c - assemble packets and write them
* Copyright (C) 1998 Free Software Foundation, Inc.
* Copyright (C) 1998, 1999, 2000 Free Software Foundation, Inc.
*
* This file is part of GnuPG.
*
@ -67,25 +67,31 @@ int
build_packet( IOBUF out, PACKET *pkt )
{
int new_ctb=0, rc=0, ctb;
int pkttype;
if( DBG_PACKET )
log_debug("build_packet() type=%d\n", pkt->pkttype );
assert( pkt->pkt.generic );
switch( pkt->pkttype ) {
case PKT_OLD_COMMENT: pkt->pkttype = PKT_COMMENT; break;
switch( (pkttype = pkt->pkttype) ) {
case PKT_OLD_COMMENT: pkttype = pkt->pkttype = PKT_COMMENT; break;
case PKT_PLAINTEXT: new_ctb = pkt->pkt.plaintext->new_ctb; break;
case PKT_ENCRYPTED:
case PKT_ENCRYPTED_MDC: new_ctb = pkt->pkt.encrypted->new_ctb; break;
case PKT_COMPRESSED:new_ctb = pkt->pkt.compressed->new_ctb; break;
case PKT_USER_ID:
if( pkt->pkt.user_id->photo )
pkttype = PKT_PHOTO_ID;
break;
default: break;
}
if( new_ctb || pkt->pkttype > 15 ) /* new format */
ctb = 0xc0 | (pkt->pkttype & 0x3f);
if( new_ctb || pkttype > 15 ) /* new format */
ctb = 0xc0 | (pkttype & 0x3f);
else
ctb = 0x80 | ((pkt->pkttype & 15)<<2);
switch( pkt->pkttype ) {
ctb = 0x80 | ((pkttype & 15)<<2);
switch( pkttype ) {
case PKT_PHOTO_ID:
case PKT_USER_ID:
rc = do_user_id( out, ctb, pkt->pkt.user_id );
break;
@ -149,6 +155,7 @@ calc_packet_length( PACKET *pkt )
n = calc_plaintext( pkt->pkt.plaintext );
new_ctb = pkt->pkt.plaintext->new_ctb;
break;
case PKT_PHOTO_ID:
case PKT_USER_ID:
case PKT_COMMENT:
case PKT_PUBLIC_KEY:
@ -196,9 +203,16 @@ do_comment( IOBUF out, int ctb, PKT_comment *rem )
static int
do_user_id( IOBUF out, int ctb, PKT_user_id *uid )
{
write_header(out, ctb, uid->len);
if( iobuf_write( out, uid->name, uid->len ) )
return G10ERR_WRITE_FILE;
if( uid->photo ) {
write_header(out, ctb, uid->photolen);
if( iobuf_write( out, uid->photo, uid->photolen ) )
return G10ERR_WRITE_FILE;
}
else {
write_header(out, ctb, uid->len);
if( iobuf_write( out, uid->name, uid->len ) )
return G10ERR_WRITE_FILE;
}
return 0;
}
@ -357,19 +371,30 @@ do_secret_key( IOBUF out, int ctb, PKT_secret_key *sk )
else {
iobuf_put(a, 0xff );
iobuf_put(a, sk->protect.algo );
iobuf_put(a, sk->protect.s2k.mode );
iobuf_put(a, sk->protect.s2k.hash_algo );
if( sk->protect.s2k.mode >= 1000 ) {
iobuf_put(a, 101 );
iobuf_put(a, sk->protect.s2k.hash_algo );
iobuf_write(a, "GNU", 3 );
iobuf_put(a, sk->protect.s2k.mode - 1000 );
}
else {
iobuf_put(a, sk->protect.s2k.mode );
iobuf_put(a, sk->protect.s2k.hash_algo );
}
if( sk->protect.s2k.mode == 1
|| sk->protect.s2k.mode == 3 )
iobuf_write(a, sk->protect.s2k.salt, 8 );
if( sk->protect.s2k.mode == 3 )
iobuf_put(a, sk->protect.s2k.count );
iobuf_write(a, sk->protect.iv, sk->protect.ivlen );
if( sk->protect.s2k.mode != 1001 )
iobuf_write(a, sk->protect.iv, sk->protect.ivlen );
}
}
else
iobuf_put(a, 0 );
if( sk->is_protected && sk->version >= 4 ) {
if( sk->protect.s2k.mode == 1001 )
;
else if( sk->is_protected && sk->version >= 4 ) {
byte *p;
assert( mpi_is_opaque( sk->skey[npkey] ) );
p = mpi_get_opaque( sk->skey[npkey], &i );
@ -621,7 +646,6 @@ void
build_sig_subpkt( PKT_signature *sig, sigsubpkttype_t type,
const byte *buffer, size_t buflen )
{
byte *data;
size_t hlen, dlen, nlen;
int found=0;
@ -657,6 +681,7 @@ build_sig_subpkt( PKT_signature *sig, sigsubpkttype_t type,
case SIGSUBPKT_KEY_EXPIRE:
case SIGSUBPKT_NOTATION:
case SIGSUBPKT_POLICY:
case SIGSUBPKT_REVOC_REASON:
hashed = 1; break;
default: hashed = 0; break;
}

View File

@ -1,5 +1,5 @@
/* cipher.c - En-/De-ciphering filter
* Copyright (C) 1998,1999 Free Software Foundation, Inc.
* Copyright (C) 1998, 1999, 2000 Free Software Foundation, Inc.
*
* This file is part of GnuPG.
*
@ -33,6 +33,7 @@
#include "packet.h"
#include "options.h"
#include "main.h"
#include "status.h"
#define MIN_PARTIAL_SIZE 512
@ -54,7 +55,7 @@ write_header( cipher_filter_context_t *cfx, IOBUF a )
if( use_mdc ) {
ed.mdc_method = DIGEST_ALGO_SHA1;
cfx->mdc_hash = md_open( DIGEST_ALGO_SHA1, 0 );
md_start_debug( cfx->mdc_hash, "mdccreat" );
/*md_start_debug( cfx->mdc_hash, "mdccreat" );*/
}
init_packet( &pkt );
pkt.pkttype = use_mdc? PKT_ENCRYPTED_MDC : PKT_ENCRYPTED;
@ -101,6 +102,7 @@ cipher_filter( void *opaque, int control,
else if( control == IOBUFCTRL_FLUSH ) { /* encrypt */
assert(a);
if( !cfx->header ) {
write_status( STATUS_BEGIN_ENCRYPTION );
write_header( cfx, a );
}
if( cfx->mdc_hash )
@ -121,6 +123,7 @@ cipher_filter( void *opaque, int control,
md_close( cfx->mdc_hash ); cfx->mdc_hash = NULL;
}
cipher_close(cfx->cipher_hd);
write_status( STATUS_END_ENCRYPTION );
}
else if( control == IOBUFCTRL_DESC ) {
*(char**)buf = "cipher_filter";

View File

@ -1,5 +1,5 @@
/* compress.c - compress filter
* Copyright (C) 1998 Free Software Foundation, Inc.
* Copyright (C) 1998, 1999 Free Software Foundation, Inc.
*
* This file is part of GnuPG.
*

View File

@ -1,5 +1,5 @@
/* dearmor.c - Armor utility
* Copyright (C) 1998 Free Software Foundation, Inc.
* Copyright (C) 1998, 1999 Free Software Foundation, Inc.
*
* This file is part of GnuPG.
*

View File

@ -1,5 +1,5 @@
/* delkey.c - delete keys
* Copyright (C) 1998 Free Software Foundation, Inc.
* Copyright (C) 1998, 1999 Free Software Foundation, Inc.
*
* This file is part of GnuPG.
*
@ -62,6 +62,7 @@ delete_key( const char *username, int secret )
: find_keyblock_byname( &kbpos, username );
if( rc ) {
log_error(_("%s: user not found\n"), username );
write_status_text( STATUS_DELETE_PROBLEM, "1" );
goto leave;
}
@ -93,10 +94,12 @@ delete_key( const char *username, int secret )
"there is a secret key for this public key!\n"));
log_info(_(
"use option \"--delete-secret-key\" to delete it first.\n"));
write_status_text( STATUS_DELETE_PROBLEM, "2" );
rc = -1;
}
else if( rc != G10ERR_NO_SECKEY )
else if( rc != G10ERR_NO_SECKEY ) {
log_error("%s: get secret key: %s\n", username, g10_errstr(rc) );
}
else
rc = 0;
}
@ -124,7 +127,7 @@ delete_key( const char *username, int secret )
pubkey_letter( pk->pubkey_algo ),
keyid[1], datestr_from_pk(pk) );
p = get_user_id( keyid, &n );
tty_print_string( p, n );
tty_print_utf8_string( p, n );
m_free(p);
tty_printf("\n\n");

View File

@ -1,5 +1,5 @@
/* encode.c - encode data
* Copyright (C) 1998 Free Software Foundation, Inc.
* Copyright (C) 1998, 1999, 2000 Free Software Foundation, Inc.
*
* This file is part of GnuPG.
*
@ -116,7 +116,7 @@ encode_simple( const char *filename, int mode )
}
if( (rc = open_outfile( filename, opt.armor? 1:0, &out )) ) {
iobuf_close(inp);
iobuf_cancel(inp);
m_free(cfx.dek);
m_free(s2k);
return rc;
@ -177,6 +177,7 @@ encode_simple( const char *filename, int mode )
pt->timestamp = make_timestamp();
pt->mode = opt.textmode? 't' : 'b';
pt->len = filesize;
pt->new_ctb = !pt->len && !opt.rfc1991;
pt->buf = inp;
pkt.pkttype = PKT_PLAINTEXT;
pkt.pkt.plaintext = pt;
@ -478,7 +479,7 @@ write_pubkey_enc_from_list( PK_LIST pk_list, DEK *dek, IOBUF out )
log_error("pubkey_encrypt failed: %s\n", g10_errstr(rc) );
else {
if( opt.verbose ) {
char *ustr = get_user_id_string( enc->keyid );
char *ustr = get_user_id_string_native( enc->keyid );
log_info(_("%s/%s encrypted for: %s\n"),
pubkey_algo_to_string(enc->pubkey_algo),
cipher_algo_to_string(dek->algo), ustr );

View File

@ -1,5 +1,5 @@
/* encr-data.c - process an encrypted data packet
* Copyright (C) 1998, 1999 Free Software Foundation, Inc.
* Copyright (C) 1998, 1999, 2000 Free Software Foundation, Inc.
*
* This file is part of GnuPG.
*
@ -165,7 +165,7 @@ mdc_decode_filter( void *opaque, int control, IOBUF a,
}
if( n == 40 ) {
/* we have enough stuff - flush the deferred stuff */
/* (we have asserted that the buffer is large enough */
/* (we have asserted that the buffer is large enough) */
if( !dfx->defer_filled ) /* the first time */
memcpy(buf, buf+20, 20 );
else

View File

@ -1,5 +1,5 @@
/* export.c
* Copyright (C) 1998 Free Software Foundation, Inc.
* Copyright (C) 1998, 1999, 2000 Free Software Foundation, Inc.
*
* This file is part of GnuPG.
*
@ -71,6 +71,12 @@ export_seckeys( STRLIST users )
return do_export( users, 1, 0 );
}
int
export_secsubkeys( STRLIST users )
{
return do_export( users, 2, 0 );
}
static int
do_export( STRLIST users, int secret, int onlyrfc )
{
@ -168,6 +174,16 @@ do_export_stream( IOBUF out, STRLIST users, int secret, int onlyrfc, int *any )
}
}
/* we can't apply GNU mode 1001 on an unprotected key */
if( secret == 2
&& (node = find_kbnode( keyblock, PKT_SECRET_KEY ))
&& !node->pkt->pkt.secret_key->is_protected )
{
log_info(_("key %08lX: not protected - skipped\n"),
(ulong)keyid_from_sk( node->pkt->pkt.secret_key, NULL) );
continue;
}
/* and write it */
for( kbctx=NULL; (node = walk_kbnode( keyblock, &kbctx, 0 )); ) {
/* don't export any comment packets but those in the
@ -183,7 +199,20 @@ do_export_stream( IOBUF out, STRLIST users, int secret, int onlyrfc, int *any )
continue; /* not exportable */
}
if( (rc = build_packet( out, node->pkt )) ) {
if( secret == 2 && node->pkt->pkttype == PKT_SECRET_KEY ) {
/* we don't want to export the secret parts of the
* primary key, this is done by using GNU protection mode 1001
*/
int save_mode = node->pkt->pkt.secret_key->protect.s2k.mode;
node->pkt->pkt.secret_key->protect.s2k.mode = 1001;
rc = build_packet( out, node->pkt );
node->pkt->pkt.secret_key->protect.s2k.mode = save_mode;
}
else {
rc = build_packet( out, node->pkt );
}
if( rc ) {
log_error("build_packet(%d) failed: %s\n",
node->pkt->pkttype, g10_errstr(rc) );
rc = G10ERR_WRITE_FILE;

View File

@ -1,5 +1,5 @@
/* filter.h
* Copyright (C) 1998 Free Software Foundation, Inc.
* Copyright (C) 1998, 1999, 2000 Free Software Foundation, Inc.
*
* This file is part of GnuPG.
*
@ -35,6 +35,9 @@ typedef struct {
int only_keyblocks; /* skip all headers but ".... key block" */
const char *hdrlines; /* write these headerlines */
/* these fileds must be initialized to zero */
int no_openpgp_data; /* output flag: "No valid OpenPGP data found" */
/* the following fields must be initialized to zero */
int inp_checked; /* set if the input has been checked */
int inp_bypass; /* set if the input is not armored */
@ -56,6 +59,7 @@ typedef struct {
u32 crc;
int status; /* an internal state flag */
int cancel;
int any_data; /* any valid armored data seen */
int pending_lf; /* used together with faked */
} armor_filter_context_t;

View File

@ -1,5 +1,5 @@
/* free-packet.c - cleanup stuff for packets
* Copyright (C) 1998 Free Software Foundation, Inc.
* Copyright (C) 1998, 1999, 2000 Free Software Foundation, Inc.
*
* This file is part of GnuPG.
*
@ -220,6 +220,8 @@ free_comment( PKT_comment *rem )
void
free_user_id( PKT_user_id *uid )
{
if( uid->photo )
m_free( uid->photo );
m_free(uid);
}

188
g10/g10.c
View File

@ -1,5 +1,5 @@
/* g10.c - The GnuPG utility (main for gpg)
* Copyright (C) 1998, 1999 Free Software Foundation, Inc.
* Copyright (C) 1998, 1999, 2000 Free Software Foundation, Inc.
*
* This file is part of GnuPG.
*
@ -79,6 +79,7 @@ enum cmd_and_opt_values { aNull = 0,
aImport,
aFastImport,
aVerify,
aVerifyFiles,
aListKeys,
aListSigs,
aListSecretKeys,
@ -87,6 +88,7 @@ enum cmd_and_opt_values { aNull = 0,
aExport,
aExportAll,
aExportSecret,
aExportSecretSub,
aCheckKeys,
aGenRevoke,
aPrimegen,
@ -131,6 +133,7 @@ enum cmd_and_opt_values { aNull = 0,
oDigestAlgo,
oCompressAlgo,
oPasswdFD,
oCommandFD,
oQuickRandom,
oNoVerbose,
oTrustDBName,
@ -166,6 +169,7 @@ enum cmd_and_opt_values { aNull = 0,
oEscapeFrom,
oLockOnce,
oLockMultiple,
oLockNever,
oKeyServer,
oEncryptTo,
oNoEncryptTo,
@ -177,7 +181,12 @@ enum cmd_and_opt_values { aNull = 0,
oAllowNonSelfsignedUID,
oNoLiteral,
oSetFilesize,
oEntropyDLLName,
oHonorHttpProxy,
oFastListMode,
oListOnly,
oIgnoreTimeConflict,
oNoRandomSeedFile,
oEmu3DESS2KBug, /* will be removed in 1.1 */
aTest };
@ -193,6 +202,7 @@ static ARGPARSE_OPTS opts[] = {
{ aStore, "store", 256, N_("store only")},
{ aDecrypt, "decrypt", 256, N_("decrypt data (default)")},
{ aVerify, "verify" , 256, N_("verify a signature")},
{ aVerifyFiles, "verify-files" , 256, "@" },
{ aListKeys, "list-keys", 256, N_("list keys")},
{ aListKeys, "list-public-keys", 256, "@" },
{ aListSigs, "list-sigs", 256, N_("list keys and signatures")},
@ -201,6 +211,8 @@ static ARGPARSE_OPTS opts[] = {
{ aListSecretKeys, "list-secret-keys", 256, N_("list secret keys")},
{ aKeygen, "gen-key", 256, N_("generate a new key pair")},
{ aDeleteKey, "delete-key",256, N_("remove key from the public keyring")},
{ aDeleteSecretKey, "delete-secret-key",256,
N_("remove key from the secret keyring")},
{ aSignKey, "sign-key" ,256, N_("sign a key")},
{ aLSignKey, "lsign-key" ,256, N_("sign a key locally")},
{ aEditKey, "edit-key" ,256, N_("sign or edit a key")},
@ -210,6 +222,7 @@ static ARGPARSE_OPTS opts[] = {
{ aRecvKeys, "recv-keys" , 256, N_("import keys from a key server") },
{ aExportAll, "export-all" , 256, "@" },
{ aExportSecret, "export-secret-keys" , 256, "@" },
{ aExportSecretSub, "export-secret-subkeys" , 256, "@" },
{ aImport, "import", 256 , N_("import/merge keys")},
{ aFastImport, "fast-import", 256 , "@"},
{ aListPackets, "list-packets",256,N_("list only the sequence of packets")},
@ -223,7 +236,9 @@ static ARGPARSE_OPTS opts[] = {
"check-trustdb",0 , N_("|[NAMES]|check the trust database")},
{ aFixTrustDB, "fix-trustdb",0 , N_("fix a corrupted trust database")},
{ aDeArmor, "dearmor", 256, N_("De-Armor a file or stdin") },
{ aDeArmor, "dearmour", 256, "@" },
{ aEnArmor, "enarmor", 256, N_("En-Armor a file or stdin") },
{ aEnArmor, "enarmour", 256, "@" },
{ aPrintMD, "print-md" , 256, N_("|algo [files]|print message digests")},
{ aPrimegen, "gen-prime" , 256, "@" },
{ aGenRandom, "gen-random" , 256, "@" },
@ -231,6 +246,7 @@ static ARGPARSE_OPTS opts[] = {
{ 301, NULL, 0, N_("@\nOptions:\n ") },
{ oArmor, "armor", 0, N_("create ascii armored output")},
{ oArmor, "armour", 0, "@" },
{ oRecipient, "recipient", 2, N_("|NAME|encrypt for NAME")},
{ oRecipient, "remote-user", 2, "@"}, /* old option name */
{ oDefRecipient, "default-recipient" ,2,
@ -262,12 +278,12 @@ static ARGPARSE_OPTS opts[] = {
{ oCharset, "charset" , 2, N_("|NAME|set terminal charset to NAME") },
{ oOptions, "options" , 2, N_("read options from file")},
{ oDebug, "debug" ,4|16, N_("set debugging flags")},
{ oDebugAll, "debug-all" ,0, N_("enable full debugging")},
{ oDebug, "debug" ,4|16, "@"},
{ oDebugAll, "debug-all" ,0, "@"},
{ oStatusFD, "status-fd" ,1, N_("|FD|write status info to this FD") },
{ oNoComment, "no-comment", 0, N_("do not write comment packets")},
{ oCompletesNeeded, "completes-needed", 1, N_("(default is 1)")},
{ oMarginalsNeeded, "marginals-needed", 1, N_("(default is 3)")},
{ oNoComment, "no-comment", 0, "@"},
{ oCompletesNeeded, "completes-needed", 1, "@"},
{ oMarginalsNeeded, "marginals-needed", 1, "@"},
{ oMaxCertDepth, "max-cert-depth", 1, "@" },
{ oLoadExtension, "load-extension" ,2, N_("|FILE|load extension module FILE")},
{ oRFC1991, "rfc1991", 0, N_("emulate the mode described in RFC1991")},
@ -283,7 +299,11 @@ static ARGPARSE_OPTS opts[] = {
{ oThrowKeyid, "throw-keyid", 0, N_("throw keyid field of encrypted packets")},
{ oNotation, "notation-data", 2, N_("|NAME=VALUE|use this notation data")},
{ 302, NULL, 0, N_("@\nExamples:\n\n"
{ 302, NULL, 0, N_(
"@\n(See the man page for a complete listing of all commands and options)\n"
)},
{ 303, NULL, 0, N_("@\nExamples:\n\n"
" -se -r Bob [file] sign and encrypt for user Bob\n"
" --clearsign [file] make a clear text signature\n"
" --detach-sign [file] make a detached signature\n"
@ -297,12 +317,13 @@ static ARGPARSE_OPTS opts[] = {
{ aListTrustPath, "list-trust-path",0, "@"},
{ oKOption, NULL, 0, "@"},
{ oPasswdFD, "passphrase-fd",1, "@" },
{ aDeleteSecretKey, "delete-secret-key",0, "@" },
{ oCommandFD, "command-fd",1, "@" },
{ oQuickRandom, "quick-random", 0, "@"},
{ oNoVerbose, "no-verbose", 0, "@"},
{ oTrustDBName, "trustdb-name", 2, "@" },
{ oNoSecmemWarn, "no-secmem-warning", 0, "@" }, /* used only by regression tests */
{ oNoArmor, "no-armor", 0, "@"},
{ oNoArmor, "no-armour", 0, "@"},
{ oNoDefKeyring, "no-default-keyring", 0, "@" },
{ oNoGreeting, "no-greeting", 0, "@" },
{ oNoOptions, "no-options", 0, "@" }, /* shortcut for --options /dev/null */
@ -329,6 +350,7 @@ static ARGPARSE_OPTS opts[] = {
{ oEscapeFrom, "escape-from-lines", 0, "@" },
{ oLockOnce, "lock-once", 0, "@" },
{ oLockMultiple, "lock-multiple", 0, "@" },
{ oLockNever, "lock-never", 0, "@" },
{ oLoggerFD, "logger-fd",1, "@" },
{ oUseEmbeddedFilename, "use-embedded-filename", 0, "@" },
{ oUtf8Strings, "utf8-strings", 0, "@" },
@ -339,7 +361,12 @@ static ARGPARSE_OPTS opts[] = {
{ oAllowNonSelfsignedUID, "allow-non-selfsigned-uid", 0, "@" },
{ oNoLiteral, "no-literal", 0, "@" },
{ oSetFilesize, "set-filesize", 20, "@" },
{ oEntropyDLLName, "entropy-dll-name", 2, "@" },
{ oHonorHttpProxy,"honor-http-proxy", 0, "@" },
{ oFastListMode,"fast-list-mode", 0, "@" },
{ oListOnly, "list-only", 0, "@"},
{ oIgnoreTimeConflict, "ignore-time-conflict", 0, "@" },
{ oNoRandomSeedFile, "no-random-seed-file", 0, "@" },
{ oEmu3DESS2KBug, "emulate-3des-s2k-bug", 0, "@"},
{0} };
@ -381,26 +408,29 @@ strusage( int level )
"default operation depends on the input data\n");
break;
case 31: p = _("\nSupported algorithms:\n"); break;
case 32:
case 31: p = "\nHome: "; break;
case 32: p = opt.homedir; break;
case 33: p = _("\nSupported algorithms:\n"); break;
case 34:
if( !ciphers )
ciphers = build_list("Cipher: ", cipher_algo_to_string,
check_cipher_algo );
p = ciphers;
break;
case 33:
case 35:
if( !pubkeys )
pubkeys = build_list("Pubkey: ", pubkey_algo_to_string,
check_pubkey_algo );
p = pubkeys;
break;
case 34:
case 36:
if( !digests )
digests = build_list("Hash: ", digest_algo_to_string,
check_digest_algo );
p = digests;
break;
default: p = default_strusage(level);
}
return p;
@ -471,9 +501,9 @@ make_username( const char *string )
{
char *p;
if( utf8_strings )
p = native_to_utf8( string );
else
p = m_strdup(string);
else
p = native_to_utf8( string );
return p;
}
@ -543,6 +573,7 @@ main( int argc, char **argv )
int default_keyring = 1;
int greeting = 0;
int nogreeting = 0;
int use_random_seed = 1;
enum cmd_and_opt_values cmd = 0;
const char *trustdb_name = NULL;
char *def_cipher_string = NULL;
@ -567,6 +598,7 @@ main( int argc, char **argv )
init_signals();
create_dotlock(NULL); /* register locking cleanup */
i18n_init();
opt.command_fd = -1; /* no command fd */
opt.compress = -1; /* defaults to standard compress level */
/* note: if you change these lines, look at oOpenPGP */
opt.def_cipher_algo = 0;
@ -578,7 +610,12 @@ main( int argc, char **argv )
opt.completes_needed = 1;
opt.marginals_needed = 3;
opt.max_cert_depth = 5;
opt.pgp2_workarounds = 1;
#ifdef __MINGW32__
opt.homedir = read_w32_registry_string( NULL, "Software\\GNU\\GnuPG", "HomeDir" );
#else
opt.homedir = getenv("GNUPGHOME");
#endif
if( !opt.homedir || !*opt.homedir ) {
#ifdef HAVE_DRIVE_LETTERS
opt.homedir = "c:/gnupg";
@ -676,13 +713,16 @@ main( int argc, char **argv )
case aListKeys: set_cmd( &cmd, aListKeys); break;
case aListSigs: set_cmd( &cmd, aListSigs); break;
case aExportSecret: set_cmd( &cmd, aExportSecret); break;
case aExportSecretSub: set_cmd( &cmd, aExportSecretSub); break;
case aDeleteSecretKey: set_cmd( &cmd, aDeleteSecretKey);
greeting=1; break;
case aDeleteKey: set_cmd( &cmd, aDeleteKey); greeting=1; break;
case aDetachedSign: detached_sig = 1; set_cmd( &cmd, aSign ); break;
case aSym: set_cmd( &cmd, aSym); break;
case aDecrypt: set_cmd( &cmd, aDecrypt); break;
case aEncr: set_cmd( &cmd, aEncr); break;
case aSign: set_cmd( &cmd, aSign ); break;
case aKeygen: set_cmd( &cmd, aKeygen); greeting=1; break;
@ -693,6 +733,7 @@ main( int argc, char **argv )
case aClearsign: set_cmd( &cmd, aClearsign); break;
case aGenRevoke: set_cmd( &cmd, aGenRevoke); break;
case aVerify: set_cmd( &cmd, aVerify); break;
case aVerifyFiles: set_cmd( &cmd, aVerifyFiles); break;
case aPrimegen: set_cmd( &cmd, aPrimegen); break;
case aGenRandom: set_cmd( &cmd, aGenRandom); break;
case aPrintMD: set_cmd( &cmd, aPrintMD); break;
@ -785,6 +826,7 @@ main( int argc, char **argv )
break;
case oOpenPGP:
opt.rfc1991 = 0;
opt.pgp2_workarounds = 0;
opt.escape_from = 0;
opt.force_v3_sigs = 0;
opt.compress_keys = 0; /* not mandated but we do it */
@ -798,6 +840,7 @@ main( int argc, char **argv )
opt.s2k_cipher_algo = CIPHER_ALGO_BLOWFISH;
break;
case oEmuChecksumBug: opt.emulate_bugs |= EMUBUG_GPGCHKSUM; break;
case oEmu3DESS2KBug: opt.emulate_bugs |= EMUBUG_3DESS2K; break;
case oCompressSigs: opt.compress_sigs = 1; break;
case oRunAsShmCP:
#ifndef USE_SHM_COPROCESSING
@ -833,6 +876,7 @@ main( int argc, char **argv )
break;
case oCompress: opt.compress = pargs.r.ret_int; break;
case oPasswdFD: pwfd = pargs.r.ret_int; break;
case oCommandFD: opt.command_fd = pargs.r.ret_int; break;
case oCipherAlgo: def_cipher_string = m_strdup(pargs.r.ret_str); break;
case oDigestAlgo: def_digest_string = m_strdup(pargs.r.ret_str); break;
case oNoSecmemWarn: secmem_set_flags( secmem_get_flags() | 1 ); break;
@ -844,6 +888,7 @@ main( int argc, char **argv )
case oNotDashEscaped: opt.not_dash_escaped = 1; break;
case oEscapeFrom: opt.escape_from = 1; break;
case oLockOnce: opt.lock_once = 1; break;
case oLockNever: disable_dotlock(); break;
case oLockMultiple: opt.lock_once = 0; break;
case oKeyServer: opt.keyserver_name = pargs.r.ret_str; break;
case oNotation: add_notation_data( pargs.r.ret_str ); break;
@ -855,22 +900,14 @@ main( int argc, char **argv )
case oDisablePubkeyAlgo:
disable_pubkey_algo( string_to_pubkey_algo(pargs.r.ret_str) );
break;
case oAllowNonSelfsignedUID:
opt.allow_non_selfsigned_uid = 1;
break;
case oNoLiteral:
opt.no_literal = 1;
break;
case oSetFilesize:
opt.set_filesize = pargs.r.ret_ulong;
break;
case oEntropyDLLName:
#ifdef USE_STATIC_RNDW32
log_info("set dllname to `%s'\n", pargs.r.ret_str );
rndw32_set_dll_name( pargs.r.ret_str );
#endif
break;
case oAllowNonSelfsignedUID: opt.allow_non_selfsigned_uid = 1; break;
case oNoLiteral: opt.no_literal = 1; break;
case oSetFilesize: opt.set_filesize = pargs.r.ret_ulong; break;
case oHonorHttpProxy: opt.honor_http_proxy = 1; break;
case oFastListMode: opt.fast_list_mode = 1; break;
case oListOnly: opt.list_only=1; break;
case oIgnoreTimeConflict: opt.ignore_time_conflict = 1; break;
case oNoRandomSeedFile: use_random_seed = 0; break;
default : pargs.err = configfp? 1:2; break;
}
@ -893,8 +930,11 @@ main( int argc, char **argv )
fprintf(stderr, "%s\n", strusage(15) );
}
#ifdef IS_DEVELOPMENT_VERSION
if( !opt.batch )
log_info("NOTE: this is a development version!\n");
if( !opt.batch ) {
log_info("NOTE: THIS IS A DEVELOPMENT VERSION!\n");
log_info("It is only intended for test purposes and should NOT be\n");
log_info("used in a production environment or with production keys!\n");
}
#endif
if( opt.force_mdc ) {
log_info("--force-mdc ignored because"
@ -971,8 +1011,16 @@ main( int argc, char **argv )
if( log_get_errorcount(0) )
g10_exit(2);
if( !cmd && opt.fingerprint && !with_fpr )
/* set the random seed file */
if( use_random_seed ) {
char *p = make_filename(opt.homedir, "random_seed", NULL );
set_random_seed_file(p);
m_free(p);
}
if( !cmd && opt.fingerprint && !with_fpr ) {
set_cmd( &cmd, aListKeys);
}
if( cmd == aKMode || cmd == aKModeC ) { /* kludge to be compatible to pgp */
if( cmd == aKModeC ) {
@ -1112,6 +1160,11 @@ main( int argc, char **argv )
log_error("verify signatures failed: %s\n", g10_errstr(rc) );
break;
case aVerifyFiles:
if( (rc = verify_files( argc, argv ) ))
log_error("verify files failed: %s\n", g10_errstr(rc) );
break;
case aDecrypt:
if( argc > 1 )
wrong_args(_("--decrypt [filename]"));
@ -1170,15 +1223,28 @@ main( int argc, char **argv )
case aListSigs:
opt.list_sigs = 1;
case aListKeys:
public_key_list( argc, argv );
sl = NULL;
for( ; argc; argc--, argv++ )
add_to_strlist2( &sl, *argv, utf8_strings );
public_key_list( sl );
free_strlist(sl);
break;
case aListSecretKeys:
secret_key_list( argc, argv );
sl = NULL;
for( ; argc; argc--, argv++ )
add_to_strlist2( &sl, *argv, utf8_strings );
secret_key_list( sl );
free_strlist(sl);
break;
case aKMode: /* list keyring -- NOTE: This will be removed soon */
if( argc < 2 ) /* -kv [userid] */
public_key_list( (argc && **argv)? 1:0, argv );
if( argc < 2 ) { /* -kv [userid] */
sl = NULL;
if (argc && **argv)
add_to_strlist2( &sl, *argv, utf8_strings );
public_key_list( sl );
free_strlist(sl);
}
else if( argc == 2 ) { /* -kv userid keyring */
if( access( argv[1], R_OK ) ) {
log_error(_("can't open %s: %s\n"),
@ -1188,32 +1254,33 @@ main( int argc, char **argv )
/* add keyring (default keyrings are not registered in this
* special case */
add_keyblock_resource( argv[1], 0, 0 );
public_key_list( **argv?1:0, argv );
sl = NULL;
if (**argv)
add_to_strlist2( &sl, *argv, utf8_strings );
public_key_list( sl );
free_strlist(sl);
}
}
else
wrong_args(_("-k[v][v][v][c] [user-id] [keyring]") );
break;
case aKeygen: /* generate a key (interactive) */
if( argc )
wrong_args("--gen-key");
generate_keypair();
case aKeygen: /* generate a key */
if( opt.batch ) {
if( argc > 1 )
wrong_args("--gen-key [parameterfile]");
generate_keypair( argc? *argv : NULL );
}
else {
if( argc )
wrong_args("--gen-key");
generate_keypair(NULL);
}
break;
case aFastImport:
case aImport:
if( !argc ) {
rc = import_keys( NULL, (cmd == aFastImport) );
if( rc )
log_error("import failed: %s\n", g10_errstr(rc) );
}
for( ; argc; argc--, argv++ ) {
rc = import_keys( *argv, (cmd == aFastImport) );
if( rc )
log_error("import from `%s' failed: %s\n",
*argv, g10_errstr(rc) );
}
import_keys( argc? argv:NULL, argc, (cmd == aFastImport) );
break;
case aExport:
@ -1240,6 +1307,14 @@ main( int argc, char **argv )
free_strlist(sl);
break;
case aExportSecretSub:
sl = NULL;
for( ; argc; argc--, argv++ )
add_to_strlist2( &sl, *argv, utf8_strings );
export_secsubkeys( sl );
free_strlist(sl);
break;
case aGenRevoke:
if( argc != 1 )
wrong_args("--gen-revoke user-id");
@ -1379,7 +1454,7 @@ main( int argc, char **argv )
break;
case aFixTrustDB:
log_error("this command ist not yet implemented.\"\n");
log_error("this command is not yet implemented.\n");
log_error("A workaround is to use \"--export-ownertrust\", remove\n");
log_error("the trustdb file and do an \"--import-ownertrust\".\n" );
break;
@ -1449,6 +1524,7 @@ main( int argc, char **argv )
void
g10_exit( int rc )
{
update_random_seed_file();
if( opt.debug & DBG_MEMSTAT_VALUE ) {
m_print_stats("on exit");
random_dump_stats();

View File

@ -1,5 +1,5 @@
/* getkey.c - Get a key from the database
* Copyright (C) 1998, 1999 Free Software Foundation, Inc.
* Copyright (C) 1998, 1999, 2000 Free Software Foundation, Inc.
*
* This file is part of GnuPG.
*
@ -45,7 +45,11 @@
* that they are all valid.
* Note: We must use numerical values here in case that this program
* will be converted to those little blue HAL9000s with their strange
* EBCDIC character set (user ids are UTF-8). */
* EBCDIC character set (user ids are UTF-8).
* wk 2000-04-13: Hmmm, does this really make sense, given the fact that
* we can run gpg now on a S/390 running GNU/Linux, where the code
* translation is done by the device drivers?
*/
static const byte word_match_chars[256] = {
/* 00 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
/* 08 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
@ -154,6 +158,7 @@ static int uid_cache_entries; /* number of entries in uid cache */
static char* prepare_word_match( const byte *name );
static int lookup_pk( GETKEY_CTX ctx, PKT_public_key *pk, KBNODE *ret_kb );
static int lookup_sk( GETKEY_CTX ctx, PKT_secret_key *sk, KBNODE *ret_kb );
static u32 subkeys_expiretime( KBNODE node, u32 *mainkid );
#if 0
@ -696,6 +701,8 @@ key_byname( GETKEY_CTX *retctx, STRLIST namelist,
STRLIST r;
GETKEY_CTX ctx;
if( retctx ) /* reset the returned context in case of error */
*retctx = NULL;
assert( !pk ^ !sk );
/* build the search context */
@ -1150,7 +1157,7 @@ merge_one_pk_and_selfsig( KBNODE keyblock, KBNODE knode,
k = find_kbnode( keyblock, PKT_PUBLIC_KEY );
if( !k )
BUG(); /* keyblock without primary key!!! */
keyid_from_pk( knode->pkt->pkt.public_key, kid );
keyid_from_pk( k->pkt->pkt.public_key, kid );
}
else
keyid_from_pk( pk, kid );
@ -1208,6 +1215,10 @@ merge_keys_and_selfsig( KBNODE keyblock )
pk = NULL; /* not needed for old keys */
else if( k->pkt->pkttype == PKT_PUBLIC_KEY )
keyid_from_pk( pk, kid );
else if( !pk->expiredate ) { /* and subkey */
/* insert the expiration date here */
pk->expiredate = subkeys_expiretime( k, kid );
}
sigdate = 0;
}
else if( k->pkt->pkttype == PKT_SECRET_KEY
@ -1222,8 +1233,11 @@ merge_keys_and_selfsig( KBNODE keyblock )
else if( (pk || sk ) && k->pkt->pkttype == PKT_SIGNATURE
&& (sig=k->pkt->pkt.signature)->sig_class >= 0x10
&& sig->sig_class <= 0x30 && sig->version > 3
&& !(sig->sig_class == 0x18 || sig->sig_class == 0x28)
&& sig->keyid[0] == kid[0] && sig->keyid[1] == kid[1] ) {
/* okay this is a self-signature which can be used.
* This is not used for subkey binding signature, becuase this
* is done above.
* FIXME: We should only use this if the signature is valid
* but this is time consuming - we must provide another
* way to handle this
@ -1279,9 +1293,14 @@ find_by_name( KBNODE keyblock, PKT_public_key *pk, const char *name,
u32 aki[2];
keyid_from_pk( kk->pkt->pkt.public_key, aki );
cache_user_id( k->pkt->pkt.user_id, aki );
rmd160_hash_buffer( namehash,
k->pkt->pkt.user_id->name,
k->pkt->pkt.user_id->len );
if( k->pkt->pkt.user_id->photo )
rmd160_hash_buffer( namehash,
k->pkt->pkt.user_id->photo,
k->pkt->pkt.user_id->photolen );
else
rmd160_hash_buffer( namehash,
k->pkt->pkt.user_id->name,
k->pkt->pkt.user_id->len );
*use_namehash = 1;
return kk;
}
@ -1516,6 +1535,56 @@ find_by_fpr_sk( KBNODE keyblock, PKT_secret_key *sk,
}
/****************
* Return the expiretime of a subkey.
*/
static u32
subkeys_expiretime( KBNODE node, u32 *mainkid )
{
KBNODE k;
PKT_signature *sig;
u32 expires = 0, sigdate = 0;
assert( node->pkt->pkttype == PKT_PUBLIC_SUBKEY );
for(k=node->next; k; k = k->next ) {
if( k->pkt->pkttype == PKT_SIGNATURE
&& (sig=k->pkt->pkt.signature)->sig_class == 0x18
&& sig->keyid[0] == mainkid[0]
&& sig->keyid[1] == mainkid[1]
&& sig->version > 3
&& sig->timestamp > sigdate ) {
/* okay this is a key-binding which can be used.
* We use the latest self-signature.
* FIXME: We should only use this if the binding signature is valid
* but this is time consuming - we must provide another
* way to handle this
*/
const byte *p;
u32 ed;
p = parse_sig_subpkt( sig->hashed_data, SIGSUBPKT_KEY_EXPIRE, NULL );
ed = p? node->pkt->pkt.public_key->timestamp + buffer_to_u32(p):0;
sigdate = sig->timestamp;
expires = ed;
}
else if( k->pkt->pkttype == PKT_PUBLIC_SUBKEY )
break; /* stop at the next subkey */
}
return expires;
}
/****************
* Check whether the subkey has expired. Node must point to the subkey
*/
static int
has_expired( KBNODE node, u32 *mainkid, u32 cur_time )
{
u32 expires = subkeys_expiretime( node, mainkid );
return expires && expires <= cur_time;
}
static void
finish_lookup( KBNODE keyblock, PKT_public_key *pk, KBNODE k, byte *namehash,
int use_namehash, int primary )
@ -1534,6 +1603,10 @@ finish_lookup( KBNODE keyblock, PKT_public_key *pk, KBNODE k, byte *namehash,
pk->pubkey_usage ) == G10ERR_WR_PUBKEY_ALGO ) {
/* if the usage is not correct, try to use a subkey */
KBNODE save_k = k;
u32 mainkid[2];
u32 cur_time = make_timestamp();
keyid_from_pk( keyblock->pkt->pkt.public_key, mainkid );
k = NULL;
/* kludge for pgp 5: which doesn't accept type 20:
@ -1545,7 +1618,8 @@ finish_lookup( KBNODE keyblock, PKT_public_key *pk, KBNODE k, byte *namehash,
== PUBKEY_ALGO_ELGAMAL_E
&& !check_pubkey_algo2(
k->pkt->pkt.public_key->pubkey_algo,
pk->pubkey_usage ) )
pk->pubkey_usage )
&& !has_expired(k, mainkid, cur_time) )
break;
}
}
@ -1555,7 +1629,10 @@ finish_lookup( KBNODE keyblock, PKT_public_key *pk, KBNODE k, byte *namehash,
if( k->pkt->pkttype == PKT_PUBLIC_SUBKEY
&& !check_pubkey_algo2(
k->pkt->pkt.public_key->pubkey_algo,
pk->pubkey_usage ) )
pk->pubkey_usage )
&& ( pk->pubkey_usage != PUBKEY_USAGE_ENC
|| !has_expired( k, mainkid, cur_time ) )
)
break;
}
}
@ -1887,6 +1964,18 @@ get_user_id_string( u32 *keyid )
return p;
}
char*
get_user_id_string_native( u32 *keyid )
{
char *p = get_user_id_string( keyid );
char *p2 = utf8_to_native( p, strlen(p) );
m_free(p);
return p2;
}
char*
get_long_user_id_string( u32 *keyid )
{
@ -1914,6 +2003,7 @@ get_user_id( u32 *keyid, size_t *rn )
user_id_db_t r;
char *p;
int pass=0;
/* try it two times; second pass reads from key resources */
do {
for(r=user_id_db; r; r = r->next )
@ -1924,9 +2014,8 @@ get_user_id( u32 *keyid, size_t *rn )
return p;
}
} while( ++pass < 2 && !get_pubkey( NULL, keyid ) );
p = m_alloc( 19 );
memcpy(p, "[User id not found]", 19 );
*rn = 19;
p = m_strdup( _("[User id not found]") );
*rn = strlen(p);
return p;
}

View File

@ -1,5 +1,5 @@
/* helptext.c - English help texts
* Copyright (C) 1998 Free Software Foundation, Inc.
* Copyright (C) 1998, 1999, 2000 Free Software Foundation, Inc.
*
* This file is part of GnuPG.
*
@ -224,6 +224,29 @@ static struct helptexts { const char *key; const char *help; } helptexts[] = {
"file (which is shown in brackets) will be used."
)},
/* revoke.c (ask_revocation_reason) */
{ "ask_revocation_reason.code", N_(
"You should specify a reason for the certification. Depending on the\n"
"context you have the ability to choose from this list:\n"
" \"Key has been compromised\"\n"
" Use this if you have a reason to believe that unauthorized persons\n"
" got access to your secret key.\n"
" \"Key is superseeded\"\n"
" Use this if you have replaced this key with a newer one.\n"
" \"Key is no longer used\"\n"
" Use this if you have retired this key.\n"
" \"User ID is no longer valid\"\n"
" Use this to state that the user ID should not longer be used;\n"
" this is normally used to mark an email address invalid.\n"
)},
/* revoke.c (ask_revocation_reason) */
{ "ask_revocation_reason.text", N_(
"If you like, you can enter a text describing why you issue this\n"
"revocation certificate. Please keep this text concise.\n"
"An empty line ends the text.\n"
)},
/* end of list */
{ NULL, NULL } };

View File

@ -55,19 +55,24 @@ hkp_ask_import( u32 *keyid )
struct http_context hd;
char *request;
int rc;
unsigned int hflags = opt.honor_http_proxy? HTTP_FLAG_TRY_PROXY : 0;
if( !opt.keyserver_name )
return -1;
log_info("requesting key %08lX from %s ...\n", (ulong)keyid[1],
log_info(_("requesting key %08lX from %s ...\n"), (ulong)keyid[1],
opt.keyserver_name );
request = m_alloc( strlen( opt.keyserver_name ) + 100 );
/* hkp does not accept the long keyid - we should really write a
* nicer one */
* nicer one :-)
* FIXME: request binary mode - need to pass no_armor mode
* down to the import function. Marc told that there is such a
* binary mode ... how?
*/
sprintf( request, "x-hkp://%s:11371/pks/lookup?op=get&search=0x%08lX",
opt.keyserver_name, (ulong)keyid[1] );
rc = http_open_document( &hd, request, 0 );
rc = http_open_document( &hd, request, hflags );
if( rc ) {
log_info("can't get key from keyserver: %s\n",
log_info(_("can't get key from keyserver: %s\n"),
rc == G10ERR_NETWORK? strerror(errno)
: g10_errstr(rc) );
}
@ -90,7 +95,7 @@ hkp_import( STRLIST users )
return -1;
#else
if( !opt.keyserver_name ) {
log_error("no keyserver known (use option --keyserver)\n");
log_error(_("no keyserver known (use option --keyserver)\n"));
return -1;
}
@ -98,10 +103,15 @@ hkp_import( STRLIST users )
u32 kid[2];
int type = classify_user_id( users->d, kid, NULL, NULL, NULL );
if( type != 10 && type != 11 ) {
log_info("%s: not a valid key ID\n", users->d );
log_info(_("%s: not a valid key ID\n"), users->d );
continue;
}
hkp_ask_import( kid );
/* because the function may use log_info in some situations, the
* errorcounter ist not increaed and the program will return
* with success - which is not good when this function is used.
*/
if( hkp_ask_import( kid ) )
log_inc_errorcount();
}
return 0;
#endif
@ -120,9 +130,10 @@ hkp_export( STRLIST users )
struct http_context hd;
char *request;
unsigned int status;
unsigned int hflags = opt.honor_http_proxy? HTTP_FLAG_TRY_PROXY : 0;
if( !opt.keyserver_name ) {
log_error("no keyserver known (use option --keyserver)\n");
log_error(_("no keyserver known (use option --keyserver)\n"));
return -1;
}
@ -142,9 +153,9 @@ hkp_export( STRLIST users )
request = m_alloc( strlen( opt.keyserver_name ) + 100 );
sprintf( request, "x-hkp://%s:11371/pks/add", opt.keyserver_name );
rc = http_open( &hd, HTTP_REQ_POST, request , 0 );
rc = http_open( &hd, HTTP_REQ_POST, request , hflags );
if( rc ) {
log_error("can't connect to `%s': %s\n",
log_error(_("can't connect to `%s': %s\n"),
opt.keyserver_name,
rc == G10ERR_NETWORK? strerror(errno)
: g10_errstr(rc) );
@ -168,7 +179,7 @@ hkp_export( STRLIST users )
rc = http_wait_response( &hd, &status );
if( rc ) {
log_error("error sending to `%s': %s\n",
log_error(_("error sending to `%s': %s\n"),
opt.keyserver_name, g10_errstr(rc) );
}
else {
@ -180,10 +191,10 @@ hkp_export( STRLIST users )
}
#endif
if( (status/100) == 2 )
log_info("success sending to `%s' (status=%u)\n",
log_info(_("success sending to `%s' (status=%u)\n"),
opt.keyserver_name, status );
else
log_error("failed sending to `%s': status=%u\n",
log_error(_("failed sending to `%s': status=%u\n"),
opt.keyserver_name, status );
}
http_close( &hd );

View File

@ -1,5 +1,5 @@
/* hkp.h - Horrowitz Keyserver Protocol
* Copyright (C) 1999 Free Software Foundation, Inc.
* Copyright (C) 1999, 2000 Free Software Foundation, Inc.
*
* This file is part of GnuPG.
*

View File

@ -1,5 +1,5 @@
/* import.c
* Copyright (C) 1998, 1999 Free Software Foundation, Inc.
* Copyright (C) 1998, 1999, 2000 Free Software Foundation, Inc.
*
* This file is part of GnuPG.
*
@ -38,6 +38,7 @@
static struct {
ulong count;
ulong no_user_id;
ulong imported;
ulong imported_rsa;
@ -53,6 +54,7 @@ static struct {
static int import( IOBUF inp, int fast, const char* fname );
static void print_stats(void);
static int read_block( IOBUF a, PACKET **pending_pkt, KBNODE *ret_root );
static int import_one( const char *fname, KBNODE keyblock, int fast );
static int import_secret_one( const char *fname, KBNODE keyblock );
@ -105,30 +107,51 @@ static int merge_keysigs( KBNODE dst, KBNODE src, int *n_sigs,
* Key revocation certificates have special handling.
*
*/
int
import_keys( const char *fname, int fast )
void
import_keys( char **fnames, int nnames, int fast )
{
IOBUF inp = NULL;
int rc;
int i;
inp = iobuf_open(fname);
if( !fname )
fname = "[stdin]";
if( !inp ) {
log_error(_("can't open `%s': %s\n"), fname, strerror(errno) );
return G10ERR_OPEN_FILE;
/* fixme: don't use static variables */
memset( &stats, 0, sizeof( stats ) );
if( !fnames && !nnames )
nnames = 1; /* Ohh what a ugly hack to jump into the loop */
for(i=0; i < nnames; i++ ) {
const char *fname = fnames? fnames[i] : NULL;
IOBUF inp = iobuf_open(fname);
if( !fname )
fname = "[stdin]";
if( !inp )
log_error(_("can't open `%s': %s\n"), fname, strerror(errno) );
else {
int rc = import( inp, fast, fname );
iobuf_close(inp);
if( rc )
log_error("import from `%s' failed: %s\n", fname,
g10_errstr(rc) );
}
if( !fname )
break;
}
rc = import( inp, fast, fname );
iobuf_close(inp);
return rc;
print_stats();
if( !fast )
sync_trustdb();
}
int
import_keys_stream( IOBUF inp, int fast )
{
return import( inp, fast, "[stream]" );
int rc = 0;
/* fixme: don't use static variables */
memset( &stats, 0, sizeof( stats ) );
rc = import( inp, fast, "[stream]" );
print_stats();
if( !fast )
sync_trustdb();
return rc;
}
static int
@ -137,10 +160,6 @@ import( IOBUF inp, int fast, const char* fname )
PACKET *pending_pkt = NULL;
KBNODE keyblock;
int rc = 0;
ulong count=0;
/* fixme: don't use static variables */
memset( &stats, 0, sizeof( stats ) );
getkey_disable_caches();
@ -165,16 +184,23 @@ import( IOBUF inp, int fast, const char* fname )
release_kbnode(keyblock);
if( rc )
break;
if( !(++count % 100) && !opt.quiet )
log_info(_("%lu keys so far processed\n"), count );
if( !(++stats.count % 100) && !opt.quiet )
log_info(_("%lu keys so far processed\n"), stats.count );
}
if( rc == -1 )
rc = 0;
else if( rc && rc != G10ERR_INV_KEYRING )
log_error( _("error reading `%s': %s\n"), fname, g10_errstr(rc));
return rc;
}
static void
print_stats()
{
if( !opt.quiet ) {
log_info(_("Total number processed: %lu\n"), count );
log_info(_("Total number processed: %lu\n"), stats.count );
if( stats.no_user_id )
log_info(_(" w/o user IDs: %lu\n"), stats.no_user_id );
if( stats.imported || stats.imported_rsa ) {
@ -202,9 +228,9 @@ import( IOBUF inp, int fast, const char* fname )
}
if( is_status_enabled() ) {
char buf[12*16];
char buf[12*20];
sprintf(buf, "%lu %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu",
count,
stats.count,
stats.no_user_id,
stats.imported,
stats.imported_rsa,
@ -218,8 +244,6 @@ import( IOBUF inp, int fast, const char* fname )
stats.secret_dups);
write_status_text( STATUS_IMPORT_RES, buf );
}
return rc;
}
@ -354,8 +378,8 @@ import_one( const char *fname, KBNODE keyblock, int fast )
pubkey_letter( pk->pubkey_algo ),
(ulong)keyid[1], datestr_from_pk(pk) );
if( uidnode )
print_string( stderr, uidnode->pkt->pkt.user_id->name,
uidnode->pkt->pkt.user_id->len, 0 );
print_utf8_string( stderr, uidnode->pkt->pkt.user_id->name,
uidnode->pkt->pkt.user_id->len );
putc('\n', stderr);
}
if( !uidnode ) {
@ -545,8 +569,8 @@ import_secret_one( const char *fname, KBNODE keyblock )
pubkey_letter( sk->pubkey_algo ),
(ulong)keyid[1], datestr_from_sk(sk) );
if( uidnode )
print_string( stderr, uidnode->pkt->pkt.user_id->name,
uidnode->pkt->pkt.user_id->len, 0 );
print_utf8_string( stderr, uidnode->pkt->pkt.user_id->name,
uidnode->pkt->pkt.user_id->len );
putc('\n', stderr);
}
stats.secret_read++;
@ -678,6 +702,15 @@ import_revoke_cert( const char *fname, KBNODE node )
log_info( _("key %08lX: revocation certificate imported\n"),
(ulong)keyid[1]);
stats.n_revoc++;
if( clear_trust_checked_flag( pk ) ) {
/* seems that we have to insert the record first */
rc = insert_trust_record( keyblock );
if( rc )
log_error("key %08lX: trustdb insert failed: %s\n",
(ulong)keyid[1], g10_errstr(rc) );
else
rc = clear_trust_checked_flag( pk );
}
leave:
release_kbnode( keyblock );
@ -764,7 +797,8 @@ mark_non_selfsigned_uids_valid( KBNODE keyblock, u32 *kid )
KBNODE node;
for(node=keyblock->next; node; node = node->next ) {
if( node->pkt->pkttype == PKT_USER_ID && !(node->flag & 1) ) {
if( node->next && node->next->pkt->pkttype == PKT_SIGNATURE ) {
if( (node->next && node->next->pkt->pkttype == PKT_SIGNATURE)
|| !node->next ) {
node->flag |= 1;
log_info( _("key %08lX: accepted non self-signed user ID '"),
(ulong)kid[1]);
@ -797,8 +831,8 @@ delete_inv_parts( const char *fname, KBNODE keyblock, u32 *keyid )
if( opt.verbose ) {
log_info( _("key %08lX: skipped user ID '"),
(ulong)keyid[1]);
print_string( stderr, node->pkt->pkt.user_id->name,
node->pkt->pkt.user_id->len, 0 );
print_utf8_string( stderr, node->pkt->pkt.user_id->name,
node->pkt->pkt.user_id->len );
fputs("'\n", stderr );
}
delete_kbnode( node ); /* the user-id */
@ -1124,7 +1158,7 @@ append_uid( KBNODE keyblock, KBNODE node, int *n_sigs,
KBNODE n, n_where=NULL;
assert(node->pkt->pkttype == PKT_USER_ID );
if( node->next->pkt->pkttype == PKT_USER_ID ) {
if( !node->next || node->next->pkt->pkttype == PKT_USER_ID ) {
log_error( _("key %08lX: our copy has no self-signature\n"),
(ulong)keyid[1]);
return G10ERR_GENERAL;
@ -1177,9 +1211,7 @@ merge_sigs( KBNODE dst, KBNODE src, int *n_sigs,
assert(dst->pkt->pkttype == PKT_USER_ID );
assert(src->pkt->pkttype == PKT_USER_ID );
/* at least a self signature comes next to the user IDs */
assert(src->next->pkt->pkttype != PKT_USER_ID );
if( dst->next->pkt->pkttype == PKT_USER_ID ) {
if( !dst->next || dst->next->pkt->pkttype == PKT_USER_ID ) {
log_error( _("key %08lX: our copy has no self-signature\n"),
(ulong)keyid[1]);
return 0;

View File

@ -1,5 +1,5 @@
/* kbnode.c - keyblock node utility functions
* Copyright (C) 1998 Free Software Foundation, Inc.
* Copyright (C) 1998, 1999, 2000 Free Software Foundation, Inc.
*
* This file is part of GnuPG.
*
@ -165,7 +165,7 @@ find_prev_kbnode( KBNODE root, KBNODE node, int pkttype )
KBNODE n1;
for(n1=NULL ; root && root != node; root = root->next )
if( !pkttype || root->pkt->pkttype == pkttype )
if( !pkttype || root->pkt->pkttype == pkttype )
n1 = root;
return n1;
}

View File

@ -1,5 +1,5 @@
/* keydb.h - Key database
* Copyright (C) 1998 Free Software Foundation, Inc.
* Copyright (C) 1998, 1999, 2000 Free Software Foundation, Inc.
*
* This file is part of GnuPG.
*
@ -158,6 +158,7 @@ void get_seckey_end( GETKEY_CTX ctx );
int enum_secret_keys( void **context, PKT_secret_key *sk, int with_subkeys );
void merge_keys_and_selfsig( KBNODE keyblock );
char*get_user_id_string( u32 *keyid );
char*get_user_id_string_native( u32 *keyid );
char*get_long_user_id_string( u32 *keyid );
char*get_user_id( u32 *keyid, size_t *rn );
@ -199,6 +200,7 @@ const char *enum_keyblock_resources( int *sequence, int secret );
int add_keyblock_resource( const char *resname, int force, int secret );
const char *keyblock_resource_name( KBPOS *kbpos );
int get_keyblock_handle( const char *filename, int secret, KBPOS *kbpos );
char *get_writable_keyblock_file( int secret );
int locate_keyblock_by_fpr( KBPOS *kbpos, const byte *fpr,
int fprlen, int secret );
int locate_keyblock_by_keyid( KBPOS *kbpos, u32 *keyid,

View File

@ -1,5 +1,5 @@
/* keyedit.c - keyedit stuff
* Copyright (C) 1998, 1999 Free Software Foundation, Inc.
* Copyright (C) 1998, 1999, 2000 Free Software Foundation, Inc.
*
* This file is part of GnuPG.
*
@ -74,8 +74,9 @@ static int enable_disable_key( KBNODE keyblock, int disable );
#define NODFLG_SELSIG (1<<10) /* indicate a selected signature */
struct sign_uid_attrib {
struct sign_attrib {
int non_exportable;
struct revocation_reason_info *reason;
};
@ -157,7 +158,7 @@ print_and_check_one_sig( KBNODE keyblock, KBNODE node,
else {
size_t n;
char *p = get_user_id( sig->keyid, &n );
tty_print_utf8_string( p, n > 40? 40 : n );
tty_print_utf8_string2( p, n, 40 );
m_free(p);
}
tty_printf("\n");
@ -239,16 +240,18 @@ check_all_keysigs( KBNODE keyblock, int only_selected )
int
sign_uid_mk_attrib( PKT_signature *sig, void *opaque )
static int
sign_mk_attrib( PKT_signature *sig, void *opaque )
{
struct sign_uid_attrib *attrib = opaque;
struct sign_attrib *attrib = opaque;
byte buf[8];
if( attrib->non_exportable ) {
buf[0] = 0; /* not exportable */
build_sig_subpkt( sig, SIGSUBPKT_EXPORTABLE, buf, 1 );
}
if( attrib->reason )
revocation_reason_build_cb( sig, attrib->reason );
return 0;
}
@ -353,7 +356,7 @@ sign_uids( KBNODE keyblock, STRLIST locusr, int *ret_modified, int local )
&& (node->flag & NODFLG_MARK_A) ) {
PACKET *pkt;
PKT_signature *sig;
struct sign_uid_attrib attrib;
struct sign_attrib attrib;
assert( primary_pk );
memset( &attrib, 0, sizeof attrib );
@ -364,7 +367,7 @@ sign_uids( KBNODE keyblock, STRLIST locusr, int *ret_modified, int local )
NULL,
sk,
0x10, 0,
sign_uid_mk_attrib,
sign_mk_attrib,
&attrib );
if( rc ) {
log_error(_("signing failed: %s\n"), g10_errstr(rc));
@ -407,6 +410,7 @@ change_passphrase( KBNODE keyblock )
KBNODE node;
PKT_secret_key *sk;
char *passphrase = NULL;
int no_primary_secrets = 0;
node = find_kbnode( keyblock, PKT_SECRET_KEY );
if( !node ) {
@ -423,10 +427,16 @@ change_passphrase( KBNODE keyblock )
tty_printf(_("This key is not protected.\n"));
break;
default:
tty_printf(_("Key is protected.\n"));
rc = check_secret_key( sk, 0 );
if( !rc )
passphrase = get_last_passphrase();
if( sk->protect.s2k.mode == 1001 ) {
tty_printf(_("Secret parts of primary key are not available.\n"));
no_primary_secrets = 1;
}
else {
tty_printf(_("Key is protected.\n"));
rc = check_secret_key( sk, 0 );
if( !rc )
passphrase = get_last_passphrase();
}
break;
}
@ -436,6 +446,8 @@ change_passphrase( KBNODE keyblock )
PKT_secret_key *subsk = node->pkt->pkt.secret_key;
set_next_passphrase( passphrase );
rc = check_secret_key( subsk, 0 );
if( !rc && !passphrase )
passphrase = get_last_passphrase();
}
}
@ -465,9 +477,12 @@ change_passphrase( KBNODE keyblock )
break;
}
else { /* okay */
sk->protect.algo = dek->algo;
sk->protect.s2k = *s2k;
rc = protect_secret_key( sk, dek );
rc = 0;
if( !no_primary_secrets ) {
sk->protect.algo = dek->algo;
sk->protect.s2k = *s2k;
rc = protect_secret_key( sk, dek );
}
for(node=keyblock; !rc && node; node = node->next ) {
if( node->pkt->pkttype == PKT_SECRET_SUBKEY ) {
PKT_secret_key *subsk = node->pkt->pkt.secret_key;
@ -558,41 +573,42 @@ keyedit_menu( const char *username, STRLIST locusr, STRLIST commands,
static struct { const char *name;
enum cmdids id;
int need_sk;
int not_with_sk;
int signmode;
const char *desc;
} cmds[] = {
{ N_("quit") , cmdQUIT , 0,1, N_("quit this menu") },
{ N_("q") , cmdQUIT , 0,1, NULL },
{ N_("save") , cmdSAVE , 0,1, N_("save and quit") },
{ N_("help") , cmdHELP , 0,1, N_("show this help") },
{ "?" , cmdHELP , 0,1, NULL },
{ N_("fpr") , cmdFPR , 0,1, N_("show fingerprint") },
{ N_("list") , cmdLIST , 0,1, N_("list key and user IDs") },
{ N_("l") , cmdLIST , 0,1, NULL },
{ N_("uid") , cmdSELUID , 0,1, N_("select user ID N") },
{ N_("key") , cmdSELKEY , 0,0, N_("select secondary key N") },
{ N_("check") , cmdCHECK , 0,1, N_("list signatures") },
{ N_("c") , cmdCHECK , 0,1, NULL },
{ N_("sign") , cmdSIGN , 0,1, N_("sign the key") },
{ N_("s") , cmdSIGN , 0,1, NULL },
{ N_("lsign") , cmdLSIGN , 0,1, N_("sign the key locally") },
{ N_("debug") , cmdDEBUG , 0,0, NULL },
{ N_("adduid") , cmdADDUID , 1,0, N_("add a user ID") },
{ N_("deluid") , cmdDELUID , 0,0, N_("delete user ID") },
{ N_("addkey") , cmdADDKEY , 1,0, N_("add a secondary key") },
{ N_("delkey") , cmdDELKEY , 0,0, N_("delete a secondary key") },
{ N_("delsig") , cmdDELSIG , 0,0, N_("delete signatures") },
{ N_("expire") , cmdEXPIRE , 1,0, N_("change the expire date") },
{ N_("toggle") , cmdTOGGLE , 1,0, N_("toggle between secret "
"and public key listing") },
{ N_("t" ) , cmdTOGGLE , 1,0, NULL },
{ N_("pref") , cmdPREF , 0,0, N_("list preferences") },
{ N_("passwd") , cmdPASSWD , 1,0, N_("change the passphrase") },
{ N_("trust") , cmdTRUST , 0,0, N_("change the ownertrust") },
{ N_("revsig") , cmdREVSIG , 0,0, N_("revoke signatures") },
{ N_("revkey") , cmdREVKEY , 1,0, N_("revoke a secondary key") },
{ N_("disable") , cmdDISABLEKEY, 0,0, N_("disable a key") },
{ N_("enable") , cmdENABLEKEY , 0,0, N_("enable a key") },
{ N_("quit") , cmdQUIT , 0,0,1, N_("quit this menu") },
{ N_("q") , cmdQUIT , 0,0,1, NULL },
{ N_("save") , cmdSAVE , 0,0,1, N_("save and quit") },
{ N_("help") , cmdHELP , 0,0,1, N_("show this help") },
{ "?" , cmdHELP , 0,0,1, NULL },
{ N_("fpr") , cmdFPR , 0,0,1, N_("show fingerprint") },
{ N_("list") , cmdLIST , 0,0,1, N_("list key and user IDs") },
{ N_("l") , cmdLIST , 0,0,1, NULL },
{ N_("uid") , cmdSELUID , 0,0,1, N_("select user ID N") },
{ N_("key") , cmdSELKEY , 0,0,0, N_("select secondary key N") },
{ N_("check") , cmdCHECK , 0,0,1, N_("list signatures") },
{ N_("c") , cmdCHECK , 0,0,1, NULL },
{ N_("sign") , cmdSIGN , 0,1,1, N_("sign the key") },
{ N_("s") , cmdSIGN , 0,1,1, NULL },
{ N_("lsign") , cmdLSIGN , 0,1,1, N_("sign the key locally") },
{ N_("debug") , cmdDEBUG , 0,1,0, NULL },
{ N_("adduid") , cmdADDUID , 1,1,0, N_("add a user ID") },
{ N_("deluid") , cmdDELUID , 0,1,0, N_("delete user ID") },
{ N_("addkey") , cmdADDKEY , 1,1,0, N_("add a secondary key") },
{ N_("delkey") , cmdDELKEY , 0,1,0, N_("delete a secondary key") },
{ N_("delsig") , cmdDELSIG , 0,1,0, N_("delete signatures") },
{ N_("expire") , cmdEXPIRE , 1,1,0, N_("change the expire date") },
{ N_("toggle") , cmdTOGGLE , 1,0,0, N_("toggle between secret "
"and public key listing") },
{ N_("t" ) , cmdTOGGLE , 1,0,0, NULL },
{ N_("pref") , cmdPREF , 0,1,0, N_("list preferences") },
{ N_("passwd") , cmdPASSWD , 1,1,0, N_("change the passphrase") },
{ N_("trust") , cmdTRUST , 0,1,0, N_("change the ownertrust") },
{ N_("revsig") , cmdREVSIG , 0,1,0, N_("revoke signatures") },
{ N_("revkey") , cmdREVKEY , 1,1,0, N_("revoke a secondary key") },
{ N_("disable") , cmdDISABLEKEY, 0,1,0, N_("disable a key") },
{ N_("enable") , cmdENABLEKEY , 0,1,0, N_("enable a key") },
{ NULL, cmdNONE } };
enum cmdids cmd = 0;
@ -678,7 +694,7 @@ keyedit_menu( const char *username, STRLIST locusr, STRLIST commands,
have_commands = 0;
}
if( !have_commands ) {
answer = cpr_get("", _("Command> "));
answer = cpr_get("keyedit.prompt", _("Command> "));
cpr_kill_prompt();
}
trim_spaces(answer);
@ -711,6 +727,10 @@ keyedit_menu( const char *username, STRLIST locusr, STRLIST commands,
tty_printf(_("Need the secret key to do this.\n"));
cmd = cmdNOP;
}
else if( cmds[i].not_with_sk && sec_keyblock && toggle ) {
tty_printf(_("Please use the command \"toggle\" first.\n"));
cmd = cmdNOP;
}
else
cmd = cmds[i].id;
}
@ -763,6 +783,11 @@ keyedit_menu( const char *username, STRLIST locusr, STRLIST commands,
if( !sign_uids( keyblock, locusr, &modified, cmd == cmdLSIGN )
&& sign_mode )
goto do_cmd_save;
/* Actually we should do a update_trust_record() here so that
* the trust gets displayed correctly. however this is not possible
* because we would have to save the keyblock first - something
* we don't want to do without an explicit save command.
*/
break;
case cmdDEBUG:
@ -1005,7 +1030,10 @@ show_prefs( KBNODE keyblock, PKT_user_id *uid )
return;
}
rmd160_hash_buffer( namehash, uid->name, uid->len );
if( uid->photo )
rmd160_hash_buffer( namehash, uid->photo, uid->photolen );
else
rmd160_hash_buffer( namehash, uid->name, uid->len );
p = get_pref_data( pk->local_id, namehash, &n );
if( !p )
@ -1076,7 +1104,7 @@ show_key_with_all_names( KBNODE keyblock, int only_marked,
|| (with_subkeys && node->pkt->pkttype == PKT_SECRET_SUBKEY) ) {
PKT_secret_key *sk = node->pkt->pkt.secret_key;
tty_printf("%s%c %4u%c/%08lX created: %s expires: %s\n",
node->pkt->pkttype == PKT_SECRET_KEY? "sec":"sbb",
node->pkt->pkttype == PKT_SECRET_KEY? "sec":"ssb",
(node->flag & NODFLG_SELKEY)? '*':' ',
nbits_from_sk( sk ),
pubkey_letter( sk->pubkey_algo ),
@ -1471,7 +1499,8 @@ menu_expire( KBNODE pub_keyblock, KBNODE sec_keyblock )
}
else if( node->pkt->pkttype == PKT_USER_ID )
uid = node->pkt->pkt.user_id;
else if( main_pk && node->pkt->pkttype == PKT_SIGNATURE ) {
else if( main_pk && node->pkt->pkttype == PKT_SIGNATURE
&& sub_pk != NULL ) {
PKT_signature *sig = node->pkt->pkt.signature;
if( keyid[0] == sig->keyid[0] && keyid[1] == sig->keyid[1]
&& ( (mainkey && uid && (sig->sig_class&~3) == 0x10)
@ -1535,6 +1564,7 @@ menu_expire( KBNODE pub_keyblock, KBNODE sec_keyblock )
m_free( sn->pkt );
sn->pkt = newpkt;
}
sub_pk = NULL;
}
}
}
@ -1735,6 +1765,7 @@ menu_revsig( KBNODE keyblock )
int changed = 0;
int upd_trust = 0;
int rc, any;
struct revocation_reason_info *reason = NULL;
/* FIXME: detect duplicates here */
tty_printf(_("You have signed these user IDs:\n"));
@ -1797,6 +1828,10 @@ menu_revsig( KBNODE keyblock )
_("Really create the revocation certificates? (y/N)")) )
return 0; /* forget it */
reason = ask_revocation_reason( 0, 1, 0 );
if( !reason ) { /* user decided to cancel */
return 0;
}
/* now we can sign the user ids */
reloop: /* (must use this, because we are modifing the list) */
@ -1804,7 +1839,7 @@ menu_revsig( KBNODE keyblock )
for( node=keyblock; node; node = node->next ) {
KBNODE unode;
PACKET *pkt;
struct sign_uid_attrib attrib;
struct sign_attrib attrib;
PKT_secret_key *sk;
if( !(node->flag & NODFLG_MARK_A)
@ -1814,6 +1849,8 @@ menu_revsig( KBNODE keyblock )
assert( unode ); /* we already checked this */
memset( &attrib, 0, sizeof attrib );
attrib.reason = reason;
node->flag &= ~NODFLG_MARK_A;
sk = m_alloc_secure_clear( sizeof *sk );
if( get_seckey( sk, node->pkt->pkt.signature->keyid ) ) {
@ -1825,11 +1862,12 @@ menu_revsig( KBNODE keyblock )
NULL,
sk,
0x30, 0,
sign_uid_mk_attrib,
sign_mk_attrib,
&attrib );
free_secret_key(sk);
if( rc ) {
log_error(_("signing failed: %s\n"), g10_errstr(rc));
release_revocation_reason_info( reason );
return changed;
}
changed = 1; /* we changed the keyblock */
@ -1844,7 +1882,7 @@ menu_revsig( KBNODE keyblock )
if( upd_trust )
clear_trust_checked_flag( primary_pk );
release_revocation_reason_info( reason );
return changed;
}
@ -1861,6 +1899,13 @@ menu_revkey( KBNODE pub_keyblock, KBNODE sec_keyblock )
int changed = 0;
int upd_trust = 0;
int rc;
struct revocation_reason_info *reason = NULL;
reason = ask_revocation_reason( 1, 0, 0 );
if( !reason ) { /* user decided to cancel */
return 0;
}
reloop: /* (better this way because we are modifing the keyring) */
mainpk = pub_keyblock->pkt->pkt.public_key;
@ -1871,14 +1916,20 @@ menu_revkey( KBNODE pub_keyblock, KBNODE sec_keyblock )
PKT_signature *sig;
PKT_secret_key *sk;
PKT_public_key *subpk = node->pkt->pkt.public_key;
struct sign_attrib attrib;
memset( &attrib, 0, sizeof attrib );
attrib.reason = reason;
node->flag &= ~NODFLG_SELKEY;
sk = copy_secret_key( NULL, sec_keyblock->pkt->pkt.secret_key );
rc = make_keysig_packet( &sig, mainpk, NULL, subpk, sk, 0x28, 0,
NULL, NULL );
sign_mk_attrib,
&attrib );
free_secret_key(sk);
if( rc ) {
log_error(_("signing failed: %s\n"), g10_errstr(rc));
release_revocation_reason_info( reason );
return changed;
}
changed = 1; /* we changed the keyblock */
@ -1897,6 +1948,7 @@ menu_revkey( KBNODE pub_keyblock, KBNODE sec_keyblock )
if( upd_trust )
clear_trust_checked_flag( mainpk );
release_revocation_reason_info( reason );
return changed;
}

File diff suppressed because it is too large Load Diff

View File

@ -1,5 +1,5 @@
/* keyid.c - jeyid and fingerprint handling
* Copyright (C) 1998 Free Software Foundation, Inc.
* Copyright (C) 1998, 1999, 2000 Free Software Foundation, Inc.
*
* This file is part of GnuPG.
*

View File

@ -1,5 +1,5 @@
/* keylist.c
* Copyright (C) 1998 Free Software Foundation, Inc.
* Copyright (C) 1998, 1999, 2000 Free Software Foundation, Inc.
*
* This file is part of GnuPG.
*
@ -43,34 +43,24 @@ static void fingerprint( PKT_public_key *pk, PKT_secret_key *sk );
/****************
* List the keys
* If NNAMES is 0; all available keys are listed
* If list is NULL, all available keys are listed
*/
void
public_key_list( int nnames, char **names )
public_key_list( STRLIST list )
{
if( !nnames )
if( !list )
list_all(0);
else { /* List by user id */
STRLIST list = NULL;
for( ; nnames ; nnames--, names++ )
add_to_strlist( &list, *names );
else
list_one( list, 0 );
free_strlist( list );
}
}
void
secret_key_list( int nnames, char **names )
secret_key_list( STRLIST list )
{
if( !nnames )
if( !list )
list_all(1);
else { /* List by user id */
STRLIST list = NULL;
for( ; nnames ; nnames--, names++ )
add_to_strlist( &list, *names );
else /* List by user id */
list_one( list, 1 );
free_strlist( list );
}
}
@ -145,6 +135,7 @@ list_one( STRLIST names, int secret )
return;
}
do {
merge_keys_and_selfsig( keyblock );
list_keyblock( keyblock, 0 );
release_kbnode( keyblock );
} while( !get_pubkey_next( ctx, NULL, &keyblock ) );
@ -155,7 +146,7 @@ list_one( STRLIST names, int secret )
static void
print_key_data( PKT_public_key *pk, u32 *keyid )
{
int n = pubkey_get_npkey( pk->pubkey_algo );
int n = pk ? pubkey_get_npkey( pk->pubkey_algo ) : 0;
int i;
for(i=0; i < n; i++ ) {
@ -211,21 +202,26 @@ list_keyblock( KBNODE keyblock, int secret )
sk = NULL;
keyid_from_pk( pk, keyid );
if( opt.with_colons ) {
trustletter = query_trust_info( pk, NULL );
if( trustletter == 'u' )
ulti_hack = 1;
printf("pub:%c:%u:%d:%08lX%08lX:%s:%s:",
trustletter,
if ( opt.fast_list_mode ) {
fputs( "pub::", stdout );
trustletter = 0;
}
else {
trustletter = query_trust_info( pk, NULL );
if( trustletter == 'u' )
ulti_hack = 1;
printf("pub:%c:", trustletter );
}
printf("%u:%d:%08lX%08lX:%s:%s:",
nbits_from_pk( pk ),
pk->pubkey_algo,
(ulong)keyid[0],(ulong)keyid[1],
datestr_from_pk( pk ),
pk->expiredate? strtimestamp(pk->expiredate):""
);
pk->expiredate? strtimestamp(pk->expiredate):"" );
if( pk->local_id )
printf("%lu", pk->local_id );
putchar(':');
if( pk->local_id )
if( pk->local_id && !opt.fast_list_mode )
putchar( get_ownertrust_info( pk->local_id ) );
putchar(':');
}
@ -237,15 +233,20 @@ list_keyblock( KBNODE keyblock, int secret )
}
for( kbctx=NULL; (node=walk_kbnode( keyblock, &kbctx, 0)) ; ) {
if( node->pkt->pkttype == PKT_USER_ID ) {
if( node->pkt->pkttype == PKT_USER_ID && !opt.fast_list_mode ) {
if( any ) {
if( opt.with_colons ) {
if ( opt.with_colons ) {
byte namehash[20];
if( pk && !ulti_hack ) {
rmd160_hash_buffer( namehash,
node->pkt->pkt.user_id->name,
node->pkt->pkt.user_id->len );
if( node->pkt->pkt.user_id->photo )
rmd160_hash_buffer( namehash,
node->pkt->pkt.user_id->name,
node->pkt->pkt.user_id->len );
else
rmd160_hash_buffer( namehash,
node->pkt->pkt.user_id->name,
node->pkt->pkt.user_id->len );
trustletter = query_trust_info( pk, namehash );
}
else
@ -288,8 +289,13 @@ list_keyblock( KBNODE keyblock, int secret )
keyid_from_pk( pk2, keyid2 );
if( opt.with_colons ) {
printf("sub:%c:%u:%d:%08lX%08lX:%s:%s:",
trustletter,
if ( opt.fast_list_mode ) {
fputs( "sub::", stdout );
}
else {
printf("sub:%c:", trustletter );
}
printf("%u:%d:%08lX%08lX:%s:%s:",
nbits_from_pk( pk2 ),
pk2->pubkey_algo,
(ulong)keyid2[0],(ulong)keyid2[1],
@ -303,11 +309,16 @@ list_keyblock( KBNODE keyblock, int secret )
putchar(':');
putchar('\n');
}
else
printf("sub %4u%c/%08lX %s\n", nbits_from_pk( pk2 ),
else {
printf("sub %4u%c/%08lX %s", nbits_from_pk( pk2 ),
pubkey_letter( pk2->pubkey_algo ),
(ulong)keyid2[1],
datestr_from_pk( pk2 ) );
if( pk2->expiredate ) {
printf(_(" [expires: %s]"), expirestr_from_pk( pk2 ) );
}
putchar('\n');
}
if( opt.fingerprint > 1 )
fingerprint( pk2, NULL );
if( opt.with_key_data )
@ -346,6 +357,7 @@ list_keyblock( KBNODE keyblock, int secret )
else if( opt.list_sigs && node->pkt->pkttype == PKT_SIGNATURE ) {
PKT_signature *sig = node->pkt->pkt.signature;
int sigrc;
char *sigstr;
if( !any ) { /* no user id, (maybe a revocation follows)*/
if( sig->sig_class == 0x20 )
@ -363,11 +375,11 @@ list_keyblock( KBNODE keyblock, int secret )
if( sig->sig_class == 0x20 || sig->sig_class == 0x28
|| sig->sig_class == 0x30 )
fputs("rev", stdout);
sigstr = "rev";
else if( (sig->sig_class&~3) == 0x10 )
fputs("sig", stdout);
sigstr = "sig";
else if( sig->sig_class == 0x18 )
fputs("sig", stdout);
sigstr = "sig";
else {
if( opt.with_colons )
printf("sig::::::::::%02x:\n",sig->sig_class );
@ -390,11 +402,13 @@ list_keyblock( KBNODE keyblock, int secret )
rc = 0;
sigrc = ' ';
}
fputs( sigstr, stdout );
if( opt.with_colons ) {
putchar(':');
if( sigrc != ' ' )
putchar(sigrc);
printf(":::%08lX%08lX:%s::::", (ulong)sig->keyid[0],
printf("::%d:%08lX%08lX:%s::::", sig->pubkey_algo,
(ulong)sig->keyid[0],
(ulong)sig->keyid[1], datestr_from_sig(sig));
}
else
@ -404,7 +418,7 @@ list_keyblock( KBNODE keyblock, int secret )
printf("[%s] ", g10_errstr(rc) );
else if( sigrc == '?' )
;
else {
else if ( !opt.fast_list_mode ) {
size_t n;
char *p = get_user_id( sig->keyid, &n );
if( opt.with_colons )

View File

@ -1,5 +1,5 @@
/* ks-proto.h
* Copyright (C) 1998 Free Software Foundation, Inc.
* Copyright (C) 1998, 1999, 2000 Free Software Foundation, Inc.
*
* This file is part of GnuPG.
*

View File

@ -1,5 +1,5 @@
/* main.h
* Copyright (C) 1998 Free Software Foundation, Inc.
* Copyright (C) 1998, 1999, 2000 Free Software Foundation, Inc.
*
* This file is part of GnuPG.
*
@ -81,7 +81,7 @@ int clearsign_file( const char *fname, STRLIST locusr, const char *outfile );
/*-- sig-check.c --*/
int check_key_signature( KBNODE root, KBNODE node, int *is_selfsig );
int check_key_signature2( KBNODE root, KBNODE node,
int *is_selfsig, u32 *r_expire );
int *is_selfsig, u32 *r_expiredate, int *r_expired );
/*-- delkey.c --*/
int delete_key( const char *username, int secure );
@ -92,7 +92,7 @@ void keyedit_menu( const char *username, STRLIST locusr, STRLIST cmds,
/*-- keygen.c --*/
u32 ask_expiredate(void);
void generate_keypair(void);
void generate_keypair( const char *fname );
int keygen_add_key_expire( PKT_signature *sig, void *opaque );
int keygen_add_std_prefs( PKT_signature *sig, void *opaque );
int generate_subkeypair( KBNODE pub_keyblock, KBNODE sec_keyblock );
@ -103,7 +103,7 @@ char *make_outfile_name( const char *iname );
char *ask_outfile_name( const char *name, size_t namelen );
int open_outfile( const char *iname, int mode, IOBUF *a );
IOBUF open_sigfile( const char *iname );
void copy_options_file( const char *destdir );
void try_make_homedir( const char *fname );
/*-- seskey.c --*/
void make_session_key( DEK *dek );
@ -116,7 +116,7 @@ KBNODE make_comment_node( const char *s );
KBNODE make_mpi_comment_node( const char *s, MPI a );
/*-- import.c --*/
int import_keys( const char *filename, int fast );
void import_keys( char **fnames, int nnames, int fast );
int import_keys_stream( IOBUF inp, int fast );
int collapse_uids( KBNODE *keyblock );
@ -124,20 +124,27 @@ int collapse_uids( KBNODE *keyblock );
int export_pubkeys( STRLIST users, int onlyrfc );
int export_pubkeys_stream( IOBUF out, STRLIST users, int onlyrfc );
int export_seckeys( STRLIST users );
int export_secsubkeys( STRLIST users );
/* dearmor.c --*/
int dearmor_file( const char *fname );
int enarmor_file( const char *fname );
/*-- revoke.c --*/
struct revocation_reason_info;
int gen_revoke( const char *uname );
int revocation_reason_build_cb( PKT_signature *sig, void *opaque );
struct revocation_reason_info *
ask_revocation_reason( int key_rev, int cert_rev, int hint );
void release_revocation_reason_info( struct revocation_reason_info *reason );
/*-- keylist.c --*/
void public_key_list( int nnames, char **names );
void secret_key_list( int nnames, char **names );
void public_key_list( STRLIST list );
void secret_key_list( STRLIST list );
/*-- verify.c --*/
int verify_signatures( int nfiles, char **files );
int verify_files( int nfiles, char **files );
/*-- decrypt.c --*/
int decrypt_message( const char *filename );

View File

@ -1,5 +1,5 @@
/* maPPPPinproc.c - handle packets
* Copyright (C) 1998, 1999 Free Software Foundation, Inc.
/* mainproc.c - handle packets
* Copyright (C) 1998, 1999, 2000 Free Software Foundation, Inc.
*
* This file is part of GnuPG.
*
@ -225,10 +225,14 @@ proc_pubkey_enc( CTX c, PACKET *pkt )
|| is_RSA(enc->pubkey_algo) ) {
if ( !c->dek && ((!enc->keyid[0] && !enc->keyid[1])
|| !seckey_available( enc->keyid )) ) {
c->dek = m_alloc_secure( sizeof *c->dek );
if( (result = get_session_key( enc, c->dek )) ) {
/* error: delete the DEK */
m_free(c->dek); c->dek = NULL;
if( opt.list_only )
result = -1;
else {
c->dek = m_alloc_secure( sizeof *c->dek );
if( (result = get_session_key( enc, c->dek )) ) {
/* error: delete the DEK */
m_free(c->dek); c->dek = NULL;
}
}
}
else
@ -268,6 +272,8 @@ print_failed_pkenc( struct kidlist_item *list )
PKT_public_key *pk = m_alloc_clear( sizeof *pk );
const char *algstr = pubkey_algo_to_string( list->pubkey_algo );
if( !algstr )
algstr = "[?]";
pk->pubkey_algo = list->pubkey_algo;
if( !get_pubkey( pk, list->kid ) ) {
size_t n;
@ -310,10 +316,14 @@ proc_encrypted( CTX c, PACKET *pkt )
print_failed_pkenc( c->failed_pkenc );
write_status( STATUS_BEGIN_DECRYPTION );
/*log_debug("dat: %sencrypted data\n", c->dek?"":"conventional ");*/
if( !c->dek && !c->last_was_session_key ) {
if( opt.list_only )
result = -1;
else if( !c->dek && !c->last_was_session_key ) {
/* assume this is old conventional encrypted data
* Actually we should use IDEA and MD5 in this case, but becuase
* Actually we should use IDEA and MD5 in this case, but because
* IDEA is patented we can't do so */
c->dek = passphrase_to_dek( NULL, 0,
opt.def_cipher_algo ? opt.def_cipher_algo
@ -345,6 +355,7 @@ proc_encrypted( CTX c, PACKET *pkt )
}
free_packet(pkt);
c->last_was_session_key = 0;
write_status( STATUS_END_DECRYPTION );
}
@ -397,12 +408,14 @@ proc_plaintext( CTX c, PACKET *pkt )
clearsig = 1;
}
}
if( !any ) { /* no onepass sig packet: enable all standard algos */
if( !any && !opt.skip_verify ) {
/* no onepass sig packet: enable all standard algos */
md_enable( c->mfx.md, DIGEST_ALGO_RMD160 );
md_enable( c->mfx.md, DIGEST_ALGO_SHA1 );
md_enable( c->mfx.md, DIGEST_ALGO_MD5 );
}
if( only_md5 ) {
if( opt.pgp2_workarounds && only_md5 && !opt.skip_verify ) {
/* This is a kludge to work around a bug in pgp2. It does only
* catch those mails which are armored. To catch the non-armored
* pgp mails we could see whether there is the signature packet
@ -507,6 +520,11 @@ do_check_sig( CTX c, KBNODE node, int *is_selfsig )
|| c->list->pkt->pkttype == PKT_PUBLIC_SUBKEY ) {
return check_key_signature( c->list, node, is_selfsig );
}
else if( sig->sig_class == 0x20 ) {
log_info(_("standalone revocation - "
"use \"gpg --import\" to apply\n"));
return G10ERR_NOT_PROCESSED;
}
else {
log_error("invalid root packet for sigclass %02x\n",
sig->sig_class);
@ -534,8 +552,12 @@ print_userid( PACKET *pkt )
printf("ERROR: unexpected packet type %d", pkt->pkttype );
return;
}
print_string( stdout, pkt->pkt.user_id->name, pkt->pkt.user_id->len,
opt.with_colons );
if( opt.with_colons )
print_string( stdout, pkt->pkt.user_id->name,
pkt->pkt.user_id->len, ':');
else
print_utf8_string( stdout, pkt->pkt.user_id->name,
pkt->pkt.user_id->len );
}
@ -638,11 +660,13 @@ list_node( CTX c, KBNODE node )
keyid_from_pk( pk, keyid );
if( mainkey ) {
c->local_id = pk->local_id;
c->trustletter = query_trust_info( pk, NULL );
c->trustletter = opt.fast_list_mode?
0 : query_trust_info( pk, NULL );
}
printf("%s:%c:%u:%d:%08lX%08lX:%s:%s:",
mainkey? "pub":"sub",
c->trustletter,
printf("%s:", mainkey? "pub":"sub" );
if( c->trustletter )
putchar( c->trustletter );
printf(":%u:%d:%08lX%08lX:%s:%s:",
nbits_from_pk( pk ),
pk->pubkey_algo,
(ulong)keyid[0],(ulong)keyid[1],
@ -651,7 +675,7 @@ list_node( CTX c, KBNODE node )
if( c->local_id )
printf("%lu", c->local_id );
putchar(':');
if( c->local_id )
if( c->local_id && !opt.fast_list_mode )
putchar( get_ownertrust_info( c->local_id ) );
putchar(':');
if( node->next && node->next->pkt->pkttype == PKT_RING_TRUST) {
@ -669,6 +693,7 @@ list_node( CTX c, KBNODE node )
pubkey_letter( pk->pubkey_algo ),
(ulong)keyid_from_pk( pk, NULL ),
datestr_from_pk( pk ) );
if( mainkey ) {
/* and now list all userids with their signatures */
for( node = node->next; node; node = node->next ) {
@ -711,6 +736,10 @@ list_node( CTX c, KBNODE node )
}
}
}
else if( pk->expiredate ) { /* of subkey */
printf(_(" [expires: %s]"), expirestr_from_pk( pk ) );
}
if( !any )
putchar('\n');
if( !mainkey && opt.fingerprint > 1 )
@ -823,7 +852,8 @@ list_node( CTX c, KBNODE node )
putchar(':');
if( sigrc != ' ' )
putchar(sigrc);
printf(":::%08lX%08lX:%s::::", (ulong)sig->keyid[0],
printf("::%d:%08lX%08lX:%s::::", sig->pubkey_algo,
(ulong)sig->keyid[0],
(ulong)sig->keyid[1], datestr_from_sig(sig));
}
else
@ -840,7 +870,7 @@ list_node( CTX c, KBNODE node )
if( opt.with_colons )
putchar(':');
}
else {
else if( !opt.fast_list_mode ) {
p = get_user_id( sig->keyid, &n );
print_string( stdout, p, n, opt.with_colons );
m_free(p);
@ -1114,7 +1144,8 @@ check_sig_and_print( CTX c, KBNODE node )
buf[16] = 0;
write_status_text( STATUS_NO_PUBKEY, buf );
}
log_error(_("Can't check signature: %s\n"), g10_errstr(rc) );
if( rc != G10ERR_NOT_PROCESSED )
log_error(_("Can't check signature: %s\n"), g10_errstr(rc) );
}
return rc;
}
@ -1129,7 +1160,7 @@ proc_tree( CTX c, KBNODE node )
KBNODE n1;
int rc;
if( opt.list_packets )
if( opt.list_packets || opt.list_only )
return;
c->local_id = 0;
@ -1174,12 +1205,17 @@ proc_tree( CTX c, KBNODE node )
else if( node->pkt->pkttype == PKT_SIGNATURE ) {
PKT_signature *sig = node->pkt->pkt.signature;
if( !c->have_data ) {
if( sig->sig_class != 0x00 && sig->sig_class != 0x01 )
log_info(_("standalone signature of class 0x%02x\n"),
sig->sig_class);
else if( !c->have_data ) {
/* detached signature */
free_md_filter_context( &c->mfx );
c->mfx.md = md_open(sig->digest_algo, 0);
if( sig->digest_algo == DIGEST_ALGO_MD5
&& is_RSA( sig->pubkey_algo ) ) {
if( !opt.pgp2_workarounds )
;
else if( sig->digest_algo == DIGEST_ALGO_MD5
&& is_RSA( sig->pubkey_algo ) ) {
/* enable a workaround for a pgp2 bug */
c->mfx.md2 = md_open( DIGEST_ALGO_MD5, 0 );
}

View File

@ -1,5 +1,5 @@
/* mdfilter.c - filter data and calculate a message digest
* Copyright (C) 1998 Free Software Foundation, Inc.
* Copyright (C) 1998, 1999, 2000 Free Software Foundation, Inc.
*
* This file is part of GnuPG.
*

View File

@ -1,5 +1,5 @@
/* misc.c - miscellaneous functions
* Copyright (C) 1998, 1999 Free Software Foundation, Inc.
* Copyright (C) 1998, 1999, 2000 Free Software Foundation, Inc.
*
* This file is part of GnuPG.
*

View File

@ -1,5 +1,5 @@
/* openfile.c
* Copyright (C) 1998 Free Software Foundation, Inc.
* Copyright (C) 1998, 1999, 2000 Free Software Foundation, Inc.
*
* This file is part of GnuPG.
*
@ -24,6 +24,9 @@
#include <string.h>
#include <assert.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include "util.h"
#include "memory.h"
@ -39,6 +42,17 @@
#define SKELEXT ".skel"
#endif
#ifdef HAVE_DRIVE_LETTERS
#define CMP_FILENAME(a,b) stricmp( (a), (b) )
#else
#define CMP_FILENAME(a,b) strcmp( (a), (b) )
#endif
#ifdef MKDIR_TAKES_ONE_ARG
# undef mkdir
# define mkdir(a,b) mkdir(a)
#endif
/* FIXME: Implement opt.interactive. */
/****************
@ -82,13 +96,11 @@ make_outfile_name( const char *iname )
if( (!iname || (*iname=='-' && !iname[1]) ))
return m_strdup("-");
#ifdef HAVE_DRIVE_LETTERS
#warning add case insensitive compare
#endif
n = strlen(iname);
if( n > 4 && ( !strcmp(iname+n-4,".gpg")
|| !strcmp(iname+n-4,".sig")
|| !strcmp(iname+n-4,".asc") ) ) {
if( n > 4 && ( !CMP_FILENAME(iname+n-4,".gpg")
|| !CMP_FILENAME(iname+n-4,".pgp")
|| !CMP_FILENAME(iname+n-4,".sig")
|| !CMP_FILENAME(iname+n-4,".asc") ) ) {
char *buf = m_strdup( iname );
buf[n-4] = 0;
return buf;
@ -169,11 +181,33 @@ open_outfile( const char *iname, int mode, IOBUF *a )
name = opt.outfile;
else {
#ifdef USE_ONLY_8DOT3
#warning please implement 8.3 files
#endif
/* It is quite common DOS system to have only one dot in a
* a filename So if we have something like this, we simple
* replace the suffix execpt in cases where the suffix is
* larger than 3 characters and not the same as.
* We should really map the filenames to 8.3 but this tends to
* be more complicated and is probaly a duty of the filesystem
*/
char *dot;
const char *newsfx = mode==1 ? ".asc" :
mode==2 ? ".sig" : ".gpg";
buf = m_alloc(strlen(iname)+4+1);
strcpy(buf,iname);
dot = strchr(buf, '.' );
if( dot && dot > buf && dot[1] && strlen(dot) <= 4
&& CMP_FILENAME(newsfx, dot) ) {
strcpy(dot, newsfx );
}
else if( dot && !dot[1] ) /* don't duplicate a dot */
strcpy( dot, newsfx+1 );
else
strcat( buf, newsfx );
#else
buf = m_alloc(strlen(iname)+4+1);
strcpy(stpcpy(buf,iname), mode==1 ? ".asc" :
mode==2 ? ".sig" : ".gpg");
#endif
name = buf;
}
@ -204,9 +238,6 @@ open_sigfile( const char *iname )
IOBUF a = NULL;
size_t len;
#ifdef USE_ONLY_8DOT3
#warning please implement 8.3 files
#endif
if( iname && !(*iname == '-' && !iname[1]) ) {
len = strlen(iname);
if( len > 4 && ( !strcmp(iname + len - 4, ".sig")
@ -227,7 +258,7 @@ open_sigfile( const char *iname )
/****************
* Copy the option file skeleton to the given directory.
*/
void
static void
copy_options_file( const char *destdir )
{
const char *datadir = GNUPG_DATADIR;
@ -270,3 +301,23 @@ copy_options_file( const char *destdir )
m_free(fname);
}
void
try_make_homedir( const char *fname )
{
if( opt.dry_run )
return;
if( strlen(fname) >= 7
&& !strcmp(fname+strlen(fname)-7, "/.gnupg" ) ) {
if( mkdir( fname, S_IRUSR|S_IWUSR|S_IXUSR ) )
log_fatal( _("%s: can't create directory: %s\n"),
fname, strerror(errno) );
else if( !opt.quiet )
log_info( _("%s: directory created\n"), fname );
copy_options_file( fname );
log_info(_("you have to start GnuPG again, "
"so it can read the new options file\n") );
g10_exit(1);
}
}

View File

@ -1,5 +1,5 @@
/* options.h
* Copyright (C) 1998 Free Software Foundation, Inc.
* Copyright (C) 1998, 1999, 2000 Free Software Foundation, Inc.
*
* This file is part of GnuPG.
*
@ -33,6 +33,7 @@ struct {
int compress;
char *outfile;
int dry_run;
int list_only;
int textmode;
int batch; /* run in batch mode */
int answer_yes; /* answer yes on most questions */
@ -63,6 +64,7 @@ struct {
int compress_sigs;
int always_trust;
int rfc1991;
int pgp2_workarounds;
unsigned emulate_bugs; /* bug emulation flags EMUBUG_xxxx */
int shm_coprocess;
const char *set_filename;
@ -83,10 +85,15 @@ struct {
int allow_non_selfsigned_uid;
int no_literal;
ulong set_filesize;
int honor_http_proxy;
int fast_list_mode;
int ignore_time_conflict;
int command_fd;
} opt;
#define EMUBUG_GPGCHKSUM 1
#define EMUBUG_3DESS2K 2
#define DBG_PACKET_VALUE 1 /* debug packet reading/writing */
#define DBG_MPI_VALUE 2 /* debug mpi details */

View File

@ -79,3 +79,8 @@ lock-once
# Use "host -l pgp.net | grep www" to figure out a keyserver.
#keyserver wwwkeys.eu.pgp.net
# The environment variable http_proxy is only used when the
# this option is set.
honor-http-proxy

View File

@ -1,5 +1,5 @@
/* packet.h - packet read/write stuff
* Copyright (C) 1998 Free Software Foundation, Inc.
* Copyright (C) 1998, 1999, 2000 Free Software Foundation, Inc.
*
* This file is part of GnuPG.
*
@ -46,6 +46,7 @@ typedef enum {
PKT_USER_ID =13, /* user id packet */
PKT_PUBLIC_SUBKEY =14, /* public subkey (OpenPGP) */
PKT_OLD_COMMENT =16, /* comment packet from an OpenPGP draft */
PKT_PHOTO_ID =17, /* PGP's photo ID */
PKT_COMMENT =61, /* new comment packet (private) */
PKT_ENCRYPTED_MDC =62, /* test: encrypted data with MDC */
} pkttype_t;
@ -53,7 +54,7 @@ typedef enum {
typedef struct packet_struct PACKET;
typedef struct {
byte mode;
int mode;
byte hash_algo;
byte salt[8];
u32 count;
@ -155,6 +156,8 @@ typedef struct {
typedef struct {
int len; /* length of the name */
char *photo; /* if this is not NULL, the packet is a photo ID */
int photolen; /* and the length of the photo */
char name[1];
} PKT_user_id;
@ -236,6 +239,7 @@ typedef enum {
SIGSUBPKT_POLICY =26, /* policy URL */
SIGSUBPKT_KEY_FLAGS =27, /* key flags */
SIGSUBPKT_SIGNERS_UID =28, /* signer's user id */
SIGSUBPKT_REVOC_REASON =29, /* reason for revocation */
SIGSUBPKT_PRIV_ADD_SIG =101,/* signatur is also valid for this uid */
SIGSUBPKT_FLAG_CRITICAL=128

View File

@ -1,5 +1,5 @@
/* parse-packet.c - read packets
* Copyright (C) 1998, 1999 Free Software Foundation, Inc.
* Copyright (C) 1998, 1999, 2000 Free Software Foundation, Inc.
*
* This file is part of GnuPG.
*
@ -61,6 +61,8 @@ static int parse_key( IOBUF inp, int pkttype, unsigned long pktlen,
byte *hdr, int hdrlen, PACKET *packet );
static int parse_user_id( IOBUF inp, int pkttype, unsigned long pktlen,
PACKET *packet );
static int parse_photo_id( IOBUF inp, int pkttype, unsigned long pktlen,
PACKET *packet );
static int parse_comment( IOBUF inp, int pkttype, unsigned long pktlen,
PACKET *packet );
static void parse_trust( IOBUF inp, int pkttype, unsigned long pktlen,
@ -417,6 +419,10 @@ parse( IOBUF inp, PACKET *pkt, int reqtype, ulong *retpos,
case PKT_USER_ID:
rc = parse_user_id(inp, pkttype, pktlen, pkt );
break;
case PKT_PHOTO_ID:
pkt->pkttype = pkttype = PKT_USER_ID; /* must fix it */
rc = parse_photo_id(inp, pkttype, pktlen, pkt);
break;
case PKT_OLD_COMMENT:
case PKT_COMMENT:
rc = parse_comment(inp, pkttype, pktlen, pkt);
@ -805,6 +811,13 @@ dump_sig_subpkt( int hashed, int type, int critical,
case SIGSUBPKT_SIGNERS_UID:
p = "signer's user ID";
break;
case SIGSUBPKT_REVOC_REASON:
if( length ) {
printf("revocation reason 0x%02x (", *buffer );
print_string( stdout, buffer+1, length-1, ')' );
p = ")";
}
break;
case SIGSUBPKT_PRIV_ADD_SIG:
p = "signs additional user ID";
break;
@ -842,6 +855,10 @@ parse_one_sig_subpkt( const byte *buffer, size_t n, int type )
if( n < 8 ) /* minimum length needed */
break;
return 0;
case SIGSUBPKT_REVOC_REASON:
if( !n )
break;
return 0;
case SIGSUBPKT_PREF_SYM:
case SIGSUBPKT_PREF_HASH:
case SIGSUBPKT_PREF_COMPR:
@ -879,7 +896,7 @@ can_handle_critical( const byte *buffer, size_t n, int type )
case SIGSUBPKT_PREF_COMPR:
return 1;
case SIGSUBPKT_POLICY: /* Is enough to show the policy? */
case SIGSUBPKT_POLICY: /* Is it enough to show the policy? */
default:
return 0;
}
@ -1318,6 +1335,24 @@ parse_key( IOBUF inp, int pkttype, unsigned long pktlen,
sk->protect.algo = iobuf_get_noeof(inp); pktlen--;
sk->protect.s2k.mode = iobuf_get_noeof(inp); pktlen--;
sk->protect.s2k.hash_algo = iobuf_get_noeof(inp); pktlen--;
/* check for the special GNU extension */
if( is_v4 && sk->protect.s2k.mode == 101 ) {
for(i=0; i < 4 && pktlen; i++, pktlen-- )
temp[i] = iobuf_get_noeof(inp);
if( i < 4 || memcmp( temp, "GNU", 3 ) ) {
if( list_mode )
printf( "\tunknown S2K %d\n",
sk->protect.s2k.mode );
rc = G10ERR_INVALID_PACKET;
goto leave;
}
/* here we know that it is a gnu extension
* What follows is the GNU protection mode:
* All values have special meanings
* and they are mapped in the mode with a base of 1000.
*/
sk->protect.s2k.mode = 1000 + temp[3];
}
switch( sk->protect.s2k.mode ) {
case 1:
case 3:
@ -1333,10 +1368,13 @@ parse_key( IOBUF inp, int pkttype, unsigned long pktlen,
break;
case 3: if( list_mode ) printf( "\titer+salt S2K" );
break;
case 1001: if( list_mode ) printf( "\tgnu-dummy S2K" );
break;
default:
if( list_mode )
printf( "\tunknown S2K %d\n",
sk->protect.s2k.mode );
printf( "\tunknown %sS2K %d\n",
sk->protect.s2k.mode < 1000? "":"GNU ",
sk->protect.s2k.mode );
rc = G10ERR_INVALID_PACKET;
goto leave;
}
@ -1389,6 +1427,9 @@ parse_key( IOBUF inp, int pkttype, unsigned long pktlen,
default:
sk->protect.ivlen = 8;
}
if( sk->protect.s2k.mode == 1001 )
sk->protect.ivlen = 0;
if( pktlen < sk->protect.ivlen ) {
rc = G10ERR_INVALID_PACKET;
goto leave;
@ -1409,7 +1450,12 @@ parse_key( IOBUF inp, int pkttype, unsigned long pktlen,
* If the user is so careless, not to protect his secret key,
* we can assume, that he operates an open system :=(.
* So we put the key into secure memory when we unprotect it. */
if( is_v4 && sk->is_protected ) {
if( sk->protect.s2k.mode == 1001 ) {
/* better set some dummy stuff here */
sk->skey[npkey] = mpi_set_opaque(NULL, m_strdup("dummydata"), 10);
pktlen = 0;
}
else if( is_v4 && sk->is_protected ) {
/* ugly; the length is encrypted too, so we read all
* stuff up to the end of the packet into the first
* skey element */
@ -1475,6 +1521,8 @@ parse_user_id( IOBUF inp, int pkttype, unsigned long pktlen, PACKET *packet )
packet->pkt.user_id = m_alloc(sizeof *packet->pkt.user_id + pktlen);
packet->pkt.user_id->len = pktlen;
packet->pkt.user_id->photo = NULL;
packet->pkt.user_id->photolen = 0;
p = packet->pkt.user_id->name;
for( ; pktlen; pktlen--, p++ )
*p = iobuf_get_noeof(inp);
@ -1496,6 +1544,31 @@ parse_user_id( IOBUF inp, int pkttype, unsigned long pktlen, PACKET *packet )
}
/****************
* PGP generates a packet of type 17. We assume this is a photo ID and
* simply store it here as a comment packet.
*/
static int
parse_photo_id( IOBUF inp, int pkttype, unsigned long pktlen, PACKET *packet )
{
byte *p;
packet->pkt.user_id = m_alloc(sizeof *packet->pkt.user_id + 30);
sprintf( packet->pkt.user_id->name, "[image of size %lu]", pktlen );
packet->pkt.user_id->len = strlen(packet->pkt.user_id->name);
packet->pkt.user_id->photo = m_alloc(sizeof *packet->pkt.user_id + pktlen);
packet->pkt.user_id->photolen = pktlen;
p = packet->pkt.user_id->photo;
for( ; pktlen; pktlen--, p++ )
*p = iobuf_get_noeof(inp);
if( list_mode ) {
printf(":photo_id packet: %s\n", packet->pkt.user_id->name );
}
return 0;
}
static int
parse_comment( IOBUF inp, int pkttype, unsigned long pktlen, PACKET *packet )

View File

@ -1,5 +1,5 @@
/* passphrase.c - Get a passphrase
* Copyright (C) 1998 Free Software Foundation, Inc.
* Copyright (C) 1998, 1999, 2000 Free Software Foundation, Inc.
*
* This file is part of GnuPG.
*
@ -159,7 +159,7 @@ passphrase_to_dek( u32 *keyid, int pubkey_algo,
tty_printf(_("\nYou need a passphrase to unlock the secret key for\n"
"user: \"") );
p = get_user_id( keyid, &n );
tty_print_string( p, n );
tty_print_utf8_string( p, n );
m_free(p);
tty_printf("\"\n");
@ -242,7 +242,13 @@ hash_passphrase( DEK *dek, char *pw, STRING2KEY *s2k, int create )
md = md_open( s2k->hash_algo, 1);
for(pass=0; used < dek->keylen ; pass++ ) {
if( pass ) {
md_reset(md);
if( (opt.emulate_bugs & EMUBUG_3DESS2K)) {
int tmp = md->finalized;
md_reset( md );
md->finalized = tmp;
}
else
md_reset(md);
for(i=0; i < pass; i++ ) /* preset the hash context */
md_putc(md, 0 );
}

View File

@ -1,5 +1,5 @@
/* pkclist.c
* Copyright (C) 1998 Free Software Foundation, Inc.
* Copyright (C) 1998, 1999, 2000 Free Software Foundation, Inc.
*
* This file is part of GnuPG.
*
@ -96,6 +96,112 @@ fpr_info( PKT_public_key *pk )
}
/****************
* Show the revocation reason as it is stored with the given signature
*/
static void
do_show_revocation_reason( PKT_signature *sig )
{
size_t n, nn;
const byte *p, *pp;
int seq = 0;
const char *text;
while( (p = enum_sig_subpkt( sig->hashed_data, SIGSUBPKT_REVOC_REASON,
&n, &seq )) ) {
if( !n )
continue; /* invalid - just skip it */
if( *p == 0 )
text = _("No reason specified");
else if( *p == 0x01 )
text = _("Key is superseeded");
else if( *p == 0x02 )
text = _("Key has been compromised");
else if( *p == 0x03 )
text = _("Key is no longer used");
else if( *p == 0x20 )
text = _("User ID is no longer valid");
else
text = NULL;
log_info( _("Reason for revocation: ") );
if( text )
fputs( text, log_stream() );
else
fprintf( log_stream(), "code=%02x", *p );
putc( '\n', log_stream() );
n--; p++;
pp = NULL;
do {
/* We don't want any empty lines, so skip them */
while( n && *p == '\n' ) {
p++;
n--;
}
if( n ) {
pp = memchr( p, '\n', n );
nn = pp? pp - p : n;
log_info( _("Revocation comment: ") );
print_string( log_stream(), p, nn, 0 );
putc( '\n', log_stream() );
p += nn; n -= nn;
}
} while( pp );
}
}
static void
show_revocation_reason( PKT_public_key *pk )
{
/* Hmmm, this is not so easy becuase we have to duplicate the code
* used in the trustbd to calculate the keyflags. We need to find
* a clean way to check revocation certificates on keys and signatures.
* And there should be no duplicate code. Because we enter this function
* only when the trustdb toldus, taht we have a revoked key, we could
* simplylook for a revocation cert and display this one, when there is
* only one. Let's try to do this until we have a better solution.
*/
KBNODE node, keyblock = NULL;
byte fingerprint[MAX_FINGERPRINT_LEN];
size_t fingerlen;
int rc;
/* get the keyblock */
fingerprint_from_pk( pk, fingerprint, &fingerlen );
rc = get_keyblock_byfprint( &keyblock, fingerprint, fingerlen );
if( rc ) { /* that should never happen */
log_debug( "failed to get the keyblock\n");
return;
}
for( node=keyblock; node; node = node->next ) {
if( ( node->pkt->pkttype == PKT_PUBLIC_KEY
|| node->pkt->pkttype == PKT_PUBLIC_SUBKEY )
&& !cmp_public_keys( node->pkt->pkt.public_key, pk ) )
break;
}
if( !node ) {
log_debug("Oops, PK not in keyblock\n");
release_kbnode( keyblock );
return;
}
/* now find the revocation certificate */
for( node = node->next; node ; node = node->next ) {
if( node->pkt->pkttype == PKT_PUBLIC_SUBKEY )
break;
if( node->pkt->pkttype == PKT_SIGNATURE
&& (node->pkt->pkt.signature->sig_class == 0x20
|| node->pkt->pkt.signature->sig_class == 0x28 ) ) {
/* FIXME: we should check the signature here */
do_show_revocation_reason ( node->pkt->pkt.signature );
}
}
release_kbnode( keyblock );
}
static void
show_paths( ulong lid, int only_first )
@ -149,7 +255,7 @@ show_paths( ulong lid, int only_first )
putchar(' ');
p = get_user_id( keyid, &n );
tty_print_string( p, n ),
tty_print_utf8_string( p, n ),
m_free(p);
tty_printf("\"\n");
free_public_key( pk );
@ -194,7 +300,7 @@ do_edit_ownertrust( ulong lid, int mode, unsigned *new_trust, int defer_help )
for(;;) {
/* a string with valid answers */
char *ans = _("sSmMqQ");
const char *ans = _("sSmMqQ");
if( !did_help ) {
if( !mode ) {
@ -203,7 +309,7 @@ do_edit_ownertrust( ulong lid, int mode, unsigned *new_trust, int defer_help )
nbits_from_pk( pk ), pubkey_letter( pk->pubkey_algo ),
(ulong)keyid[1], datestr_from_pk( pk ) );
p = get_user_id( keyid, &n );
tty_print_string( p, n ),
tty_print_utf8_string( p, n ),
m_free(p);
tty_printf("\"\n");
print_fpr( pk );
@ -337,38 +443,53 @@ _("Could not find a valid trust path to the key. Let's see whether we\n"
/****************
* Check whether we can trust this pk which has a trustlevel of TRUSTLEVEL
* Returns: true if we trust.
* Returns: true if we trust. Might change the trustlevel
*/
static int
do_we_trust( PKT_public_key *pk, int trustlevel )
do_we_trust( PKT_public_key *pk, int *trustlevel )
{
int rc;
int did_add = 0;
int trustmask = 0;
retry:
if( (trustlevel & TRUST_FLAG_REVOKED) ) {
if( (*trustlevel & TRUST_FLAG_REVOKED) ) {
log_info(_("key %08lX: key has been revoked!\n"),
(ulong)keyid_from_pk( pk, NULL) );
show_revocation_reason( pk );
if( opt.batch )
return 0;
if( !cpr_get_answer_is_yes("revoked_key.override",
_("Use this key anyway? ")) )
return 0;
trustmask |= TRUST_FLAG_REVOKED;
}
else if( (trustlevel & TRUST_FLAG_SUB_REVOKED) ) {
else if( (*trustlevel & TRUST_FLAG_SUB_REVOKED) ) {
log_info(_("key %08lX: subkey has been revoked!\n"),
(ulong)keyid_from_pk( pk, NULL) );
show_revocation_reason( pk );
if( opt.batch )
return 0;
if( !cpr_get_answer_is_yes("revoked_key.override",
_("Use this key anyway? ")) )
return 0;
trustmask |= TRUST_FLAG_SUB_REVOKED;
}
*trustlevel &= ~trustmask;
if( opt.always_trust) {
if( opt.verbose )
log_info("No trust check due to --always-trust option\n");
/* The problem with this, is that EXPIRE can't be checked as
* this needs to insert a ne key into the trustdb first and
* we don't want that */
return 1;
}
switch( (trustlevel & TRUST_MASK) ) {
switch( (*trustlevel & TRUST_MASK) ) {
case TRUST_UNKNOWN: /* No pubkey in trustDB: Insert and check again */
rc = insert_trust_record_by_pk( pk );
if( rc ) {
@ -376,11 +497,12 @@ do_we_trust( PKT_public_key *pk, int trustlevel )
g10_errstr(rc) );
return 0; /* no */
}
rc = check_trust( pk, &trustlevel, NULL, NULL, NULL );
rc = check_trust( pk, trustlevel, NULL, NULL, NULL );
*trustlevel &= ~trustmask;
if( rc )
log_fatal("trust check after insert failed: %s\n",
g10_errstr(rc) );
if( trustlevel == TRUST_UNKNOWN || trustlevel == TRUST_EXPIRED ) {
if( *trustlevel == TRUST_UNKNOWN || *trustlevel == TRUST_EXPIRED ) {
log_debug("do_we_trust: oops at %d\n", __LINE__ );
return 0;
}
@ -398,7 +520,8 @@ do_we_trust( PKT_public_key *pk, int trustlevel )
else {
int quit;
rc = add_ownertrust( pk, &quit, &trustlevel );
rc = add_ownertrust( pk, &quit, trustlevel );
*trustlevel &= ~trustmask;
if( !rc && !did_add && !quit ) {
did_add = 1;
goto retry;
@ -444,7 +567,7 @@ do_we_trust_pre( PKT_public_key *pk, int trustlevel )
{
int rc;
rc = do_we_trust( pk, trustlevel );
rc = do_we_trust( pk, &trustlevel );
if( (trustlevel & TRUST_FLAG_REVOKED) && !rc )
return 0;
@ -460,7 +583,7 @@ do_we_trust_pre( PKT_public_key *pk, int trustlevel )
nbits_from_pk( pk ), pubkey_letter( pk->pubkey_algo ),
(ulong)keyid[1], datestr_from_pk( pk ) );
p = get_user_id( keyid, &n );
tty_print_string( p, n ),
tty_print_utf8_string( p, n ),
m_free(p);
tty_printf("\"\n");
print_fpr( pk );
@ -527,10 +650,12 @@ check_signatures_trust( PKT_signature *sig )
write_status( STATUS_KEYREVOKED );
log_info(_("WARNING: This key has been revoked by its owner!\n"));
log_info(_(" This could mean that the signature is forgery.\n"));
show_revocation_reason( pk );
}
else if( (trustlevel & TRUST_FLAG_SUB_REVOKED) ) {
write_status( STATUS_KEYREVOKED );
log_info(_("WARNING: This subkey has been revoked by its owner!\n"));
show_revocation_reason( pk );
}
@ -769,7 +894,8 @@ build_pk_list( STRLIST remusr, PK_LIST *ret_pk_list, unsigned use )
else {
int trustlevel;
rc = check_trust( pk, &trustlevel, NULL, NULL, NULL );
rc = check_trust( pk, &trustlevel, pk->namehash,
NULL, NULL );
if( rc ) {
log_error("error checking pk of `%s': %s\n",
answer, g10_errstr(rc) );
@ -843,7 +969,7 @@ build_pk_list( STRLIST remusr, PK_LIST *ret_pk_list, unsigned use )
else if( !(rc=check_pubkey_algo2(pk->pubkey_algo, use )) ) {
int trustlevel;
rc = check_trust( pk, &trustlevel, NULL, NULL, NULL );
rc = check_trust( pk, &trustlevel, pk->namehash, NULL, NULL );
if( rc ) {
free_public_key( pk ); pk = NULL;
log_error(_("%s: error checking key: %s\n"),

View File

@ -1,5 +1,5 @@
/* plaintext.c - process an plaintext packet
* Copyright (C) 1998, 1999 Free Software Foundation, Inc.
* Copyright (C) 1998, 1999, 2000 Free Software Foundation, Inc.
*
* This file is part of GnuPG.
*
@ -107,8 +107,10 @@ handle_plaintext( PKT_plaintext *pt, md_filter_context_t *mfx,
}
if( mfx->md )
md_putc(mfx->md, c );
if( c == '\r' )
continue; /* fixme: this hack might be too simple */
#ifndef HAVE_DOSISH_SYSTEM
if( c == '\r' ) /* convert to native line ending */
continue; /* fixme: this hack might be too simple */
#endif
if( fp ) {
if( putc( c, fp ) == EOF ) {
log_error("Error writing to `%s': %s\n",
@ -152,8 +154,10 @@ handle_plaintext( PKT_plaintext *pt, md_filter_context_t *mfx,
while( (c = iobuf_get(pt->buf)) != -1 ) {
if( mfx->md )
md_putc(mfx->md, c );
#ifndef HAVE_DOSISH_SYSTEM
if( convert && c == '\r' )
continue; /* fixme: this hack might be too simple */
#endif
if( fp ) {
if( putc( c, fp ) == EOF ) {
log_error("Error writing to `%s': %s\n",
@ -169,10 +173,10 @@ handle_plaintext( PKT_plaintext *pt, md_filter_context_t *mfx,
int eof;
for( eof=0; !eof; ) {
/* Why do we check for len < 32768:
* If we won´ we would practically read 2 EOFS but
* If we won't, we would practically read 2 EOFs but
* the first one has already popped the block_filter
* off and therefore we don't catch the boundary.
* Always assume EOF if iobuf_read returns less bytes
* So, always assume EOF if iobuf_read returns less bytes
* then requested */
int len = iobuf_read( pt->buf, buffer, 32768 );
if( len == -1 )
@ -217,6 +221,8 @@ handle_plaintext( PKT_plaintext *pt, md_filter_context_t *mfx,
if( !state ) {
if( c == '\r' )
state = 1;
else if( c == '\n' )
state = 2;
else
md_putc(mfx->md, c );
}
@ -308,7 +314,7 @@ ask_for_detached_datafile( MD_HANDLE md, MD_HANDLE md2,
fp = open_sigfile( inname ); /* open default file */
if( !fp && !opt.batch ) {
int any=0;
tty_printf("Detached signature.\n");
tty_printf(_("Detached signature.\n"));
do {
m_free(answer);
answer = cpr_get("detached_signature.filename",

View File

@ -1,5 +1,5 @@
/* pubkey-enc.c - public key encoded packet handling
* Copyright (C) 1998 Free Software Foundation, Inc.
* Copyright (C) 1998, 1999, 2000 Free Software Foundation, Inc.
*
* This file is part of GnuPG.
*
@ -152,6 +152,10 @@ get_it( PKT_pubkey_enc *k, DEK *dek, PKT_secret_key *sk, u32 *keyid )
write_status(STATUS_RSA_OR_IDEA);
rc = check_cipher_algo( dek->algo );
if( rc ) {
if( !opt.quiet && rc == G10ERR_CIPHER_ALGO ) {
log_info(_("cipher algorithm %d is unknown or disabled\n"),
dek->algo);
}
dek->algo = 0;
goto leave;
}
@ -172,7 +176,7 @@ get_it( PKT_pubkey_enc *k, DEK *dek, PKT_secret_key *sk, u32 *keyid )
}
if( DBG_CIPHER )
log_hexdump("DEK is:", dek->key, dek->keylen );
/* check that the algo is in the preferences */
/* check that the algo is in the preferences and whether it has expired */
{
PKT_public_key *pk = m_alloc_clear( sizeof *pk );
if( (rc = get_pubkey( pk, keyid )) )
@ -191,10 +195,25 @@ get_it( PKT_pubkey_enc *k, DEK *dek, PKT_secret_key *sk, u32 *keyid )
"NOTE: cipher algorithm %d not found in preferences\n"),
dek->algo );
}
if( !rc && pk->expiredate && pk->expiredate <= make_timestamp() ) {
log_info(_("NOTE: secret key %08lX expired at %s\n"),
(ulong)keyid[1], asctimestamp( pk->expiredate) );
}
/* FIXME: check wheter the key has been revoked and display
* the revocation reason. Actually the user should know this himself,
* but the sender might not know already and therefor the user
* should get a notice that an revoked key has been used to decode
* the message. The user can than watch out for snakes send by
* one of those Eves outside his paradise :-)
*/
free_public_key( pk );
rc = 0;
}
leave:
mpi_free(plain_dek);
m_free(frame);

View File

@ -1,225 +1,458 @@
-----BEGIN PGP PUBLIC KEY BLOCK-----
Version: GnuPG v0.9.9 (GNU/Linux)
Version: GnuPG v1.0.0e (GNU/Linux)
Comment: For info see http://www.gnupg.org
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
AJkBDI7hajSe1D6Krh2j0zf8VMWOIA==
=TbxO
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
kYsbA3vZWotYO1o9jyfAZTj0MeALzGEmxBeGUNiKUEnbBU0Lg+c8iEYEEBECAAYF
AjfjadIACgkQAJxC28xc8YI7iQCfboS4b2tqYvml31ouMT6XPHhTsYMAnRGQId+W
7mOHlWHvrddjwu8JHms6mQGiBDbYl60RBACxaonXMHpbmyzoQyxn7wYXGpEJZnKc
IWRc/sE++XSebUZMJOk09qkKhtg1TQ8D0Siv1/EjuqjoKP2f9+EOIW55+55vQsti
XwevF6pJBFYGGRluQPoFbUilDzCDmismFv0xwIEoOLftxvyvlmmw4Upx3/8TY83f
dQGzxSDvNbPEtwCguK4ARxZub/SQgLMy6S9/7itEfHcD/RXRVGmz3dDxXtgdAqwV
mY7RI+FOPQdn+DiFaaTjmqgP+NR6w5v72+jE5cdn/OnYmXQcERXc/4nZgWHdKmso
eLvLs0hpk9zFhgHkSufCWlo0ZYemaWRYrRI5mukGFIMbPdPEaySNQEqC78Rgj2wm
FJ2ttbAQlSRi332xTwFbzY4XA/9RppZOE9hGCh+2P4FgtHMgf7L8JUJVgR9tIKUv
GXjDkSWEqIMeyKeXFoPk5QdxNVM5sRYf6gmV6U3zHUOfEzlOf5GUJyPkmwl9RADE
6uyk4ySlW2d6+glsM0/Fd9Pyyzb0v6xfAPDFyTYU1X6vUDp0FyzPUijhbrdj4Fwm
fAVf3LQeTWljaGFlbCBSb3RoIDxtcm90aEBnbnVwZy5vcmc+iFsEExECABsFAjfi
yIQFCQlnNJ8DCwoDAxUDAgMWAgECF4AACgkQAJxC28xc8YKnHACeMFOdlg4xjXgE
FzyA7MQFxyXmyuoAnRCcbQ4bvEm/fxaaBFRnJgavm25LiQCVAwUQN+NpSnMIZX+n
fdq9AQF72gP7ByZG6W8yTz+1nv+CMvGIGLa4otN812X5lXvvIpH7bNgoWWD70xvH
5GP/Q5e3yUh4aGGN59uOVVQ5uoa3VFYl1ufWt2LvxaSW2q7f0FcvEref/5biu3gx
2O296DWENYPP3xZtaD+htaDP4h18RFBIvbZz9Ryp9C8myGEPQGcOxw+IRgQQEQIA
BgUCN+NqjQAKCRDKFfq6GxOtQfhaAJ9bMyNoYhAf3jkeMy1cnXoyr9ZbwQCfeWjK
xnAa+++nbYVEnuPP2gUdume0Hk1pY2hhZWwgUm90aCA8bXJvdGhAbmVzc2llLmRl
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
JxUE7yxNTPT7aA==
=gKwz
-----END PGP PUBLIC KEY BLOCK-----

View File

@ -1,5 +1,5 @@
/* revoke.c
* Copyright (C) 1998 Free Software Foundation, Inc.
* Copyright (C) 1998, 1999, 2000 Free Software Foundation, Inc.
*
* This file is part of GnuPG.
*
@ -24,6 +24,7 @@
#include <string.h>
#include <errno.h>
#include <assert.h>
#include <ctype.h>
#include "options.h"
#include "packet.h"
@ -37,6 +38,38 @@
#include "i18n.h"
struct revocation_reason_info {
int code;
char *desc;
};
int
revocation_reason_build_cb( PKT_signature *sig, void *opaque )
{
struct revocation_reason_info *reason = opaque;
char *ud = NULL;
byte *buffer;
size_t buflen = 1;
if( reason->desc ) {
ud = native_to_utf8( reason->desc );
buflen += strlen(ud);
}
buffer = m_alloc( buflen );
*buffer = reason->code;
if( ud ) {
memcpy(buffer+1, ud, strlen(ud) );
m_free( ud );
}
build_sig_subpkt( sig, SIGSUBPKT_REVOC_REASON, buffer, buflen );
m_free( buffer );
return 0;
}
/****************
* Generate a revocation certificate for UNAME
*/
@ -55,6 +88,7 @@ gen_revoke( const char *uname )
KBNODE keyblock = NULL;
KBNODE node;
KBPOS kbpos;
struct revocation_reason_info *reason = NULL;
if( opt.batch ) {
log_error(_("sorry, can't do this in batch mode\n"));
@ -62,19 +96,6 @@ gen_revoke( const char *uname )
}
/* FIXME: ask for the reason of revocation
0x00 - No reason specified (key revocations or cert revocations)
Does not make sense!
0x01 - Key is superceded (key revocations)
0x02 - Key material has been compromised (key revocations)
0x03 - Key is no longer used (key revocations)
0x20 - User id information is no longer valid (cert revocations)
Following the revocation code is a string of octets which gives
information about the reason for revocation in human-readable form
*/
memset( &afx, 0, sizeof afx);
memset( &zfx, 0, sizeof zfx);
init_packet( &pkt );
@ -113,7 +134,7 @@ gen_revoke( const char *uname )
{
size_t n;
char *p = get_user_id( sk_keyid, &n );
tty_print_string( p, n );
tty_print_utf8_string( p, n );
m_free(p);
tty_printf("\n");
}
@ -136,6 +157,13 @@ gen_revoke( const char *uname )
goto leave;
}
/* get the reason for the revocation */
reason = ask_revocation_reason( 1, 0, 1 );
if( !reason ) { /* user decided to cancel */
rc = 0;
goto leave;
}
switch( is_secret_key_protected( sk ) ) {
case -1:
log_error(_("unknown protection algorithm\n"));
@ -163,7 +191,9 @@ gen_revoke( const char *uname )
iobuf_push_filter( out, armor_filter, &afx );
/* create it */
rc = make_keysig_packet( &sig, pk, NULL, NULL, sk, 0x20, 0, NULL, NULL);
rc = make_keysig_packet( &sig, pk, NULL, NULL, sk, 0x20, 0,
revocation_reason_build_cb,
reason );
if( rc ) {
log_error(_("make_keysig_packet failed: %s\n"), g10_errstr(rc));
goto leave;
@ -198,193 +228,127 @@ gen_revoke( const char *uname )
iobuf_cancel(out);
else
iobuf_close(out);
release_revocation_reason_info( reason );
return rc;
}
#if 0 /* The code is not complete but anyway, now we use */
/* the edit menu to revoke signature */
/****************
* Return true if there is already a revocation signature for KEYID
* in KEYBLOCK at point node.
*/
static int
already_revoked( const KBNODE keyblock, const KBNODE node, u32 *keyid ) ) {
{
const KBNODE n = find_prev_kbnode( keyblock, node, PKT_USER_ID );
for( ; n; n = n->next ) {
PKT_signature *sig;
if( n->pkt->pkttype == PKT_SIGNATURE
&& (sig = node->pkt->pkt.signature)->sig_class == 0x30
&& sig->keyid[0] == keyid[0]
&& sig->keyid[1] == keyid[1] )
return 1;
struct revocation_reason_info *
ask_revocation_reason( int key_rev, int cert_rev, int hint )
{
int code;
char *description = NULL;
struct revocation_reason_info *reason;
const char *text_1 = _("Key has been compromised");
const char *text_2 = _("Key is superseded");
const char *text_3 = _("Key is no longer used");
const char *text_4 = _("User ID is non longer valid");
const char *code_text = NULL;
do {
m_free(description);
description = NULL;
tty_printf(_("Please select the reason for the revocation:\n"));
if( key_rev )
tty_printf(" 1 = %s\n", text_1 );
if( key_rev )
tty_printf(" 2 = %s\n", text_2 );
if( key_rev )
tty_printf(" 3 = %s\n", text_3 );
if( cert_rev )
tty_printf(" 4 = %s\n", text_4 );
tty_printf( " 0 = %s\n", _("Cancel") );
if( hint )
tty_printf(_("(Probably you want to select %d here)\n"), hint );
for(code = 0; !code;) {
int n;
char *answer = cpr_get("ask_revocation_reason.code",
_("Your decision? "));
trim_spaces( answer );
cpr_kill_prompt();
if( *answer == 'q' || *answer == 'Q' )
n = 0;
else if( !isdigit( *answer ) )
n = -1;
else if( hint && !*answer )
n = hint;
else
n = atoi(answer);
m_free(answer);
if( !n )
return NULL; /* cancel */
else if( key_rev && n == 1 ) {
code = 0x02; /* key has been compromised */
code_text = text_1;
}
else if( key_rev && n == 2 ) {
code = 0x01; /* key is superseded */
code_text = text_2;
}
else if( key_rev && n == 3 ) {
code = 0x03; /* key is no longer used */
code_text = text_3;
}
else if( cert_rev && n == 4 ) {
code = 0x20; /* uid is non longer valid */
code_text = text_4;
}
else
tty_printf(_("Invalid selection.\n"));
}
else if( n->pkt->pkttype == PKT_USER_ID
break;
else if( n->pkt->pkttype == PKT_PUBLIC_SUBKEY
break;
}
return 0;
tty_printf(_("Enter an optional description; "
"end it with an empty line:\n") );
for(;;) {
char *answer = cpr_get("ask_revocation_reason.text", "> " );
trim_trailing_ws( answer, strlen(answer) );
cpr_kill_prompt();
if( !*answer ) {
m_free(answer);
break;
}
{
char *p = make_printable_string( answer, strlen(answer), 0 );
m_free(answer);
answer = p;
}
if( !description )
description = m_strdup(answer);
else {
char *p = m_alloc( strlen(description) + strlen(answer) + 2 );
strcpy(stpcpy(stpcpy( p, description),"\n"),answer);
m_free(description);
description = p;
}
m_free(answer);
}
tty_printf(_("Reason for revocation: %s\n"), code_text );
if( !description )
tty_printf(_("(No description given)\n") );
else
tty_printf("%s\n", description );
} while( !cpr_get_answer_is_yes("ask_revocation_reason.okay",
_("Is this okay? ")) );
reason = m_alloc( sizeof *reason );
reason->code = code;
reason->desc = description;
return reason;
}
/****************
* Ask whether the signature should be revoked. If the user commits this,
* flag bit 0 is set.
*/
static void
ask_revoke_sig( KBNODE keyblock, KBNODE node, PKT_signature *sig ) ) {
void
release_revocation_reason_info( struct revocation_reason_info *reason )
{
KBNODE unode = find_prev_kbnode( keyblock, node, PKT_USER_ID );
if( !unode ) {
log_error("Oops: no user ID for signature\n");
return;
}
tty_printf(_("user ID: \""));
tty_print_string( unode->pkt->pkt.user_id->name,
unode->pkt->pkt.user_id->len, 0 );
tty_printf(_("\"\nsigned with your key %08lX at %s\n"),
sig->keyid[1], datestr_from_sig(sig) );
if( cpr_get_answer_is_yes("ask_revoke_sig.one",
_("Create a revocation certificate for this signature? (y/N)")) ) {
node->flag |= 1;
if( reason ) {
m_free( reason->desc );
m_free( reason );
}
}
/****************
* Generate a signature revocation certificate for UNAME
*/
int
gen_sig_revoke( const char *uname )
{
int rc = 0;
armor_filter_context_t afx;
compress_filter_context_t zfx;
PACKET pkt;
IOBUF out = NULL;
KBNODE keyblock = NULL;
KBNODE node;
KBPOS kbpos;
int uidchg;
if( opt.batch ) {
log_error(_("sorry, can't do this in batch mode\n"));
return G10ERR_GENERAL;
}
memset( &afx, 0, sizeof afx);
memset( &zfx, 0, sizeof zfx);
init_packet( &pkt );
/* get the keyblock */
rc = find_keyblock_byname( &kbpos, uname );
if( rc ) {
log_error(_("public key for user `%s' not found\n"), uname );
goto leave;
}
/* read the keyblock */
rc = read_keyblock( &kbpos, &keyblock );
if( rc ) {
log_error(_("error reading the certificate: %s\n"), g10_errstr(rc) );
goto leave;
}
/* get the keyid from the keyblock */
node = find_kbnode( keyblock, PKT_PUBLIC_KEY );
if( !node ) {
log_error(_("Oops; public key lost!\n"));
rc = G10ERR_GENERAL;
goto leave;
}
if( (rc = open_outfile( NULL, 0, &out )) )
goto leave;
if( opt.armor ) {
afx.what = 1;
iobuf_push_filter( out, armor_filter, &afx );
}
/* Now walk over all signatures which we did with one of
* our secret keys. Hmmm: Should we check for duplicate signatures */
clear_kbnode_flags( flags );
for( node = keyblock; node; node = node->next ) {
PKT_signature *sig;
if( node->pkt->pkttype == PKT_SIGNATURE
&& ((sig = node->pkt->pkt.signature)->sig_class&~3) == 0x10
&& seckey_available( sig->keyid )
&& !already_revoked( keyblock, node, sig->keyid ) ) { ) {
ask_revoke_sig( keyblock, node, sig )
}
else if( node->pkt->pkttype == PKT_PUBLIC_SUBKEY
break;
}
for( node = keyblock; node; node = node->next ) { {
if( (node->flag & 1) )
break;
}
if( !node ) {
log_info(_("nothing to revoke\n"));
iobuf_cancel(out);
out = NULL;
goto leave;
}
init_packet( &pkt );
pkt.pkttype = PKT_PUBLIC_KEY;
pkt.pkt.public_key = keyblock->pkt->pkt.public_key;
rc = build_packet( out, &pkt );
if( rc ) {
log_error(_("build_packet failed: %s\n"), g10_errstr(rc) );
goto leave;
}
uidchg = 1;
for( node = keyblock; node; node = node->next ) {
if( node->pkt->pkttype == PKT_USER_ID )
uidchg = 1;
if( !(node->flag & 1) )
continue;
if( uidchg ) {
/* create a user ID packet */
.......
uidchg = 0;
}
/* create it */
rc = make_keysig_packet( &sig, pk, NULL, NULL, sk, 0x30, 0, NULL, NULL);
if( rc ) {
log_error(_("make_keysig_packet failed: %s\n"), g10_errstr(rc));
goto leave;
}
init_packet( &pkt );
pkt.pkttype = PKT_SIGNATURE;
pkt.pkt.signature = sig;
rc = build_packet( out, &pkt );
if( rc ) {
log_error(_("build_packet failed: %s\n"), g10_errstr(rc) );
goto leave;
}
}
leave:
release_kbnode( keyblock );
if( !out )
;
else if( rc )
iobuf_cancel(out);
else
iobuf_close(out);
return rc;
}
#endif /* unused code */

View File

@ -1,5 +1,5 @@
/* ringedit.c - Function for key ring editing
* Copyright (C) 1998 Free Software Foundation, Inc.
* Copyright (C) 1998, 2000 Free Software Foundation, Inc.
*
* This file is part of GnuPG.
*
@ -63,10 +63,6 @@
#include "i18n.h"
#ifdef MKDIR_TAKES_ONE_ARG
# undef mkdir
# define mkdir(a,b) mkdir(a)
#endif
struct resource_table_struct {
@ -185,7 +181,6 @@ enum_keyblock_resources( int *sequence, int secret )
}
/****************
* Register a resource (which currently may only be a keyring file).
* The first keyring which is added by this function is
@ -291,24 +286,13 @@ add_keyblock_resource( const char *url, int force, int secret )
*last_slash_in_filename = 0;
if( access(filename, F_OK) ) {
if( strlen(filename) >= 7
&& !strcmp(filename+strlen(filename)-7, "/.gnupg") ) {
if( mkdir(filename, S_IRUSR|S_IWUSR|S_IXUSR) )
{
log_error( _("%s: can't create directory: %s\n"),
filename, strerror(errno));
rc = G10ERR_OPEN_FILE;
goto leave;
}
else if( !opt.quiet )
log_info( _("%s: directory created\n"), filename );
copy_options_file( filename );
}
else
{
rc = G10ERR_OPEN_FILE;
goto leave;
}
/* on the first time we try to create the default homedir and
* in this case the process will be terminated, so that on the
* next invocation it can read the options file in on startup
*/
try_make_homedir( filename );
rc = G10ERR_OPEN_FILE;
goto leave;
}
*last_slash_in_filename = '/';
@ -435,6 +419,35 @@ get_keyblock_handle( const char *filename, int secret, KBPOS *kbpos )
}
/****************
* Return the filename of the firstkeyblock resource which is intended
* for write access. This will either be the default resource or in
* case this is not writable one of the others. If no writable is found,
* the default filename in the homedirectory will be returned.
* Caller must free, will never return NULL.
*/
char *
get_writable_keyblock_file( int secret )
{
int i = secret? default_secret_resource : default_public_resource;
if( resource_table[i].used && !resource_table[i].secret == !secret ) {
if( !access( resource_table[i].fname, R_OK|W_OK ) ) {
return m_strdup( resource_table[i].fname );
}
}
for(i=0; i < MAX_RESOURCES; i++ ) {
if( resource_table[i].used && !resource_table[i].secret == !secret ) {
if( !access( resource_table[i].fname, R_OK|W_OK ) ) {
return m_strdup( resource_table[i].fname );
}
}
}
/* Assume the home dir is always writable */
return make_filename(opt.homedir, secret? "secring.gpg"
: "pubring.gpg", NULL );
}
/****************
* Search a keyblock which starts with the given packet and puts all
@ -737,7 +750,9 @@ enum_keyblocks( int mode, KBPOS *kbpos, KBNODE *ret_root )
if( !mode || mode == 5 || mode == 100 ) {
int i;
kbpos->fp = NULL;
kbpos->rt = rt_UNKNOWN;
if( !mode ) {
kbpos->secret = 0;
i = 0;

View File

@ -1,5 +1,5 @@
/* seckey-cert.c - secret key certificate packet handling
* Copyright (C) 1998, 1999 Free Software Foundation, Inc.
* Copyright (C) 1998, 1999, 2000 Free Software Foundation, Inc.
*
* This file is part of GnuPG.
*
@ -49,6 +49,10 @@ do_check( PKT_secret_key *sk )
CIPHER_HANDLE cipher_hd=NULL;
PKT_secret_key *save_sk;
if( sk->protect.s2k.mode == 1001 ) {
log_info(_("secret key parts are not available\n"));
return G10ERR_GENERAL;
}
if( sk->protect.algo == CIPHER_ALGO_NONE )
BUG();
if( check_cipher_algo( sk->protect.algo ) ) {

View File

@ -1,5 +1,5 @@
/* seskey.c - make sesssion keys etc.
* Copyright (C) 1998 Free Software Foundation, Inc.
* Copyright (C) 1998, 1999, 2000 Free Software Foundation, Inc.
*
* This file is part of GnuPG.
*

View File

@ -1,5 +1,5 @@
/* sig-check.c - Check a signature
* Copyright (C) 1998 Free Software Foundation, Inc.
* Copyright (C) 1998, 1999, 2000 Free Software Foundation, Inc.
*
* This file is part of GnuPG.
*
@ -32,6 +32,7 @@
#include "main.h"
#include "status.h"
#include "i18n.h"
#include "options.h"
struct cmp_help_context_s {
PKT_signature *sig;
@ -40,9 +41,9 @@ struct cmp_help_context_s {
static int do_signature_check( PKT_signature *sig, MD_HANDLE digest,
u32 *r_expire );
u32 *r_expiredate, int *r_expired );
static int do_check( PKT_public_key *pk, PKT_signature *sig,
MD_HANDLE digest );
MD_HANDLE digest, int *r_expired );
/****************
@ -54,11 +55,13 @@ int
signature_check( PKT_signature *sig, MD_HANDLE digest )
{
u32 dummy;
return do_signature_check( sig, digest, &dummy );
int dum2;
return do_signature_check( sig, digest, &dummy, &dum2 );
}
static int
do_signature_check( PKT_signature *sig, MD_HANDLE digest, u32 *r_expire )
do_signature_check( PKT_signature *sig, MD_HANDLE digest,
u32 *r_expiredate, int *r_expired )
{
PKT_public_key *pk = m_alloc_clear( sizeof *pk );
int rc=0;
@ -66,12 +69,12 @@ do_signature_check( PKT_signature *sig, MD_HANDLE digest, u32 *r_expire )
if( is_RSA(sig->pubkey_algo) )
write_status(STATUS_RSA_OR_IDEA);
*r_expire = 0;
*r_expiredate = 0;
if( get_pubkey( pk, sig->keyid ) )
rc = G10ERR_NO_PUBKEY;
else {
*r_expire = pk->expiredate;
rc = do_check( pk, sig, digest );
*r_expiredate = pk->expiredate;
rc = do_check( pk, sig, digest, r_expired );
}
free_public_key( pk );
@ -284,13 +287,15 @@ cmp_help( void *opaque, MPI result )
static int
do_check( PKT_public_key *pk, PKT_signature *sig, MD_HANDLE digest )
do_check( PKT_public_key *pk, PKT_signature *sig, MD_HANDLE digest,
int *r_expired )
{
MPI result = NULL;
int rc=0;
struct cmp_help_context_s ctx;
u32 cur_time;
*r_expired = 0;
if( pk->version == 4 && pk->pubkey_algo == PUBKEY_ALGO_ELGAMAL_E ) {
log_info(_("this is a PGP generated "
"ElGamal key which is NOT secure for signatures!\n"));
@ -303,7 +308,8 @@ do_check( PKT_public_key *pk, PKT_signature *sig, MD_HANDLE digest )
? _("public key is %lu second newer than the signature\n")
: _("public key is %lu seconds newer than the signature\n"),
d );
return G10ERR_TIME_CONFLICT; /* pubkey newer than signature */
if( !opt.ignore_time_conflict )
return G10ERR_TIME_CONFLICT; /* pubkey newer than signature */
}
cur_time = make_timestamp();
@ -313,13 +319,15 @@ do_check( PKT_public_key *pk, PKT_signature *sig, MD_HANDLE digest )
"in future (time warp or clock problem)\n")
: _("key has been created %lu seconds "
"in future (time warp or clock problem)\n"), d );
return G10ERR_TIME_CONFLICT;
if( !opt.ignore_time_conflict )
return G10ERR_TIME_CONFLICT;
}
if( pk->expiredate && pk->expiredate < cur_time ) {
log_info(_("NOTE: signature key expired %s\n"),
asctimestamp( pk->expiredate ) );
write_status(STATUS_SIGEXPIRED);
*r_expired = 1;
}
@ -390,16 +398,30 @@ hash_uid_node( KBNODE unode, MD_HANDLE md, PKT_signature *sig )
PKT_user_id *uid = unode->pkt->pkt.user_id;
assert( unode->pkt->pkttype == PKT_USER_ID );
if( sig->version >=4 ) {
byte buf[5];
buf[0] = 0xb4; /* indicates a userid packet */
buf[1] = uid->len >> 24; /* always use 4 length bytes */
buf[2] = uid->len >> 16;
buf[3] = uid->len >> 8;
buf[4] = uid->len;
md_write( md, buf, 5 );
if( uid->photo ) {
if( sig->version >=4 ) {
byte buf[5];
buf[0] = 0xd1; /* packet of type 17 */
buf[1] = uid->photolen >> 24; /* always use 4 length bytes */
buf[2] = uid->photolen >> 16;
buf[3] = uid->photolen >> 8;
buf[4] = uid->photolen;
md_write( md, buf, 5 );
}
md_write( md, uid->photo, uid->photolen );
}
else {
if( sig->version >=4 ) {
byte buf[5];
buf[0] = 0xb4; /* indicates a userid packet */
buf[1] = uid->len >> 24; /* always use 4 length bytes */
buf[2] = uid->len >> 16;
buf[3] = uid->len >> 8;
buf[4] = uid->len;
md_write( md, buf, 5 );
}
md_write( md, uid->name, uid->len );
}
md_write( md, uid->name, uid->len );
}
/****************
@ -411,11 +433,13 @@ int
check_key_signature( KBNODE root, KBNODE node, int *is_selfsig )
{
u32 dummy;
return check_key_signature2(root, node, is_selfsig, &dummy );
int dum2;
return check_key_signature2(root, node, is_selfsig, &dummy, &dum2 );
}
int
check_key_signature2( KBNODE root, KBNODE node, int *is_selfsig, u32 *r_expire)
check_key_signature2( KBNODE root, KBNODE node, int *is_selfsig,
u32 *r_expiredate, int *r_expired )
{
MD_HANDLE md;
PKT_public_key *pk;
@ -425,7 +449,8 @@ check_key_signature2( KBNODE root, KBNODE node, int *is_selfsig, u32 *r_expire)
if( is_selfsig )
*is_selfsig = 0;
*r_expire = 0;
*r_expiredate = 0;
*r_expired = 0;
assert( node->pkt->pkttype == PKT_SIGNATURE );
assert( root->pkt->pkttype == PKT_PUBLIC_KEY );
@ -445,7 +470,7 @@ check_key_signature2( KBNODE root, KBNODE node, int *is_selfsig, u32 *r_expire)
if( sig->sig_class == 0x20 ) {
md = md_open( algo, 0 );
hash_public_key( md, pk );
rc = do_check( pk, sig, md );
rc = do_check( pk, sig, md, r_expired );
md_close(md);
}
else if( sig->sig_class == 0x28 ) { /* subkey revocation */
@ -455,7 +480,7 @@ check_key_signature2( KBNODE root, KBNODE node, int *is_selfsig, u32 *r_expire)
md = md_open( algo, 0 );
hash_public_key( md, pk );
hash_public_key( md, snode->pkt->pkt.public_key );
rc = do_check( pk, sig, md );
rc = do_check( pk, sig, md, r_expired );
md_close(md);
}
else {
@ -477,7 +502,7 @@ check_key_signature2( KBNODE root, KBNODE node, int *is_selfsig, u32 *r_expire)
md = md_open( algo, 0 );
hash_public_key( md, pk );
hash_public_key( md, snode->pkt->pkt.public_key );
rc = do_check( pk, sig, md );
rc = do_check( pk, sig, md, r_expired );
md_close(md);
}
else {
@ -498,10 +523,10 @@ check_key_signature2( KBNODE root, KBNODE node, int *is_selfsig, u32 *r_expire)
if( keyid[0] == sig->keyid[0] && keyid[1] == sig->keyid[1] ) {
if( is_selfsig )
*is_selfsig = 1;
rc = do_check( pk, sig, md );
rc = do_check( pk, sig, md, r_expired );
}
else
rc = do_signature_check( sig, md, r_expire );
rc = do_signature_check( sig, md, r_expiredate, r_expired );
md_close(md);
}
else {

View File

@ -1,5 +1,5 @@
/* sign.c - sign data
* Copyright (C) 1998 Free Software Foundation, Inc.
* Copyright (C) 1998, 1999, 2000 Free Software Foundation, Inc.
*
* This file is part of GnuPG.
*
@ -39,6 +39,12 @@
#include "i18n.h"
#ifdef HAVE_DOSISH_SYSTEM
#define LF "\r\n"
#else
#define LF "\n"
#endif
/****************
* Create a notation. It is assumed that the stings in STRLIST
@ -106,7 +112,8 @@ do_sign( PKT_secret_key *sk, PKT_signature *sig,
"in future (time warp or clock problem)\n")
: _("key has been created %lu seconds "
"in future (time warp or clock problem)\n"), d );
return G10ERR_TIME_CONFLICT;
if( !opt.ignore_time_conflict )
return G10ERR_TIME_CONFLICT;
}
@ -582,7 +589,7 @@ clearsign_file( const char *fname, STRLIST locusr, const char *outfile )
else if( (rc = open_outfile( fname, 1, &out )) )
goto leave;
iobuf_writestr(out, "-----BEGIN PGP SIGNED MESSAGE-----\n" );
iobuf_writestr(out, "-----BEGIN PGP SIGNED MESSAGE-----" LF );
for( sk_rover = sk_list; sk_rover; sk_rover = sk_rover->next ) {
PKT_secret_key *sk = sk_rover->sk;
@ -594,21 +601,28 @@ clearsign_file( const char *fname, STRLIST locusr, const char *outfile )
}
}
if( old_style || only_md5 )
if( old_style && only_md5 )
iobuf_writestr(out, "\n" );
else {
const char *s;
int any = 0;
byte hashs_seen[256];
memset( hashs_seen, 0, sizeof hashs_seen );
iobuf_writestr(out, "Hash: " );
for( sk_rover = sk_list; sk_rover; sk_rover = sk_rover->next ) {
PKT_secret_key *sk = sk_rover->sk;
s = digest_algo_to_string( hash_for(sk->pubkey_algo) );
if( s ) {
if( any )
iobuf_put(out, ',' );
iobuf_writestr(out, s );
any = 1;
int i = hash_for(sk->pubkey_algo);
if( !hashs_seen[ i & 0xff ] ) {
s = digest_algo_to_string( i );
if( s ) {
hashs_seen[ i & 0xff ] = 1;
if( any )
iobuf_put(out, ',' );
iobuf_writestr(out, s );
any = 1;
}
}
}
assert(any);

View File

@ -1,5 +1,5 @@
/* signal.c - signal handling
* Copyright (C) 1998, 1999 Free Software Foundation, Inc.
* Copyright (C) 1998, 1999, 2000 Free Software Foundation, Inc.
*
* This file is part of GnuPG.
*
@ -59,14 +59,23 @@ got_fatal_signal( int sig )
caught_fatal_sig = 1;
secmem_term();
#ifdef IS_DEVELOPMENT_VERSION
/* better don't transtale these messages */
write(2, "\n", 1 );
s = log_get_name(); if( s ) write(2, s, strlen(s) );
write(2, ": ", 2 );
s = get_signal_name(sig); write(2, s, strlen(s) );
write(2, " caught ... exiting\n", 21 );
#ifndef HAVE_DOSISH_SYSTEM
{ /* reset action to default action and raise signal again */
struct sigaction nact;
nact.sa_handler = SIG_DFL;
sigemptyset( &nact.sa_mask );
nact.sa_flags = 0;
sigaction( sig, &nact, NULL);
}
#endif
exit(8); /* Hmmm, for some reasons rais2e does not work */
raise( sig );
}

View File

@ -1,5 +1,5 @@
/* skclist.c
* Copyright (C) 1998 Free Software Foundation, Inc.
* Copyright (C) 1998, 1999, 2000 Free Software Foundation, Inc.
*
* This file is part of GnuPG.
*

View File

@ -1,5 +1,5 @@
/* status.c
* Copyright (C) 1998 Free Software Foundation, Inc.
* Copyright (C) 1998, 1999, 2000 Free Software Foundation, Inc.
*
* This file is part of GnuPG.
*
@ -44,6 +44,7 @@
#include "options.h"
#include "main.h"
#include "i18n.h"
#include "cipher.h" /* for progress functions */
static int fd = -1;
#ifdef USE_SHM_COPROCESSING
@ -53,10 +54,29 @@ static int fd = -1;
static int shm_is_locked;
#endif /*USE_SHM_COPROCESSING*/
static void
progress_cb ( void *ctx, int c )
{
char buf[50];
if ( c == '\n' )
sprintf ( buf, "%.20s X 100 100", (char*)ctx );
else
sprintf ( buf, "%.20s %c 0 0", (char*)ctx, c );
write_status_text ( STATUS_PROGRESS, buf );
}
void
set_status_fd ( int newfd )
{
fd = newfd;
if ( fd != -1 ) {
register_primegen_progress ( progress_cb, "primegen" );
register_pk_dsa_progress ( progress_cb, "pk_dsa" );
register_pk_elg_progress ( progress_cb, "pk_elg" );
}
}
int
@ -95,6 +115,10 @@ write_status_text ( int no, const char *text)
case STATUS_TRUST_MARGINAL : s = "TRUST_MARGINAL\n"; break;
case STATUS_TRUST_FULLY : s = "TRUST_FULLY\n"; break;
case STATUS_TRUST_ULTIMATE : s = "TRUST_ULTIMATE\n"; break;
case STATUS_GET_BOOL : s = "GET_BOOL\n"; break;
case STATUS_GET_LINE : s = "GET_LINE\n"; break;
case STATUS_GET_HIDDEN : s = "GET_HIDDEN\n"; break;
case STATUS_GOT_IT : s = "GOT_IT\n"; break;
case STATUS_SHM_INFO : s = "SHM_INFO\n"; break;
case STATUS_SHM_GET : s = "SHM_GET\n"; break;
case STATUS_SHM_GET_BOOL : s = "SHM_GET_BOOL\n"; break;
@ -117,6 +141,15 @@ write_status_text ( int no, const char *text)
case STATUS_ERRMDC : s = "ERRMDC\n"; break;
case STATUS_IMPORTED : s = "IMPORTED\n"; break;
case STATUS_IMPORT_RES : s = "IMPORT_RES\n"; break;
case STATUS_FILE_START : s = "FILE_START\n"; break;
case STATUS_FILE_DONE : s = "FILE_DONE\n"; break;
case STATUS_FILE_ERROR : s = "FILE_ERROR\n"; break;
case STATUS_BEGIN_DECRYPTION:s = "BEGIN_DECRYPTION\n"; break;
case STATUS_END_DECRYPTION : s = "END_DECRYPTION\n"; break;
case STATUS_BEGIN_ENCRYPTION:s = "BEGIN_ENCRYPTION\n"; break;
case STATUS_END_ENCRYPTION : s = "END_ENCRYPTION\n"; break;
case STATUS_DELETE_PROBLEM : s = "DELETE_PROBLEM\n"; break;
case STATUS_PROGRESS : s = "PROGRESS\n"; break;
default: s = "?\n"; break;
}
@ -268,10 +301,50 @@ do_shm_get( const char *keyword, int hidden, int bool )
#endif /* USE_SHM_COPROCESSING */
/****************
* Request a string from the client over the command-fd
* If bool, returns static string on true (do not free) or NULL for false
*/
static char *
do_get_from_fd( const char *keyword, int hidden, int bool )
{
int i, len;
char *string;
write_status_text( bool? STATUS_GET_BOOL :
hidden? STATUS_GET_HIDDEN : STATUS_GET_LINE, keyword );
for( string = NULL, i = len = 200; ; i++ ) {
if( i >= len-1 ) {
char *save = string;
len += 100;
string = hidden? m_alloc_secure ( len ) : m_alloc ( len );
if( save )
memcpy(string, save, i );
else
i=0;
}
/* Hmmm: why not use our read_line function here */
if( read( fd, string+i, 1) != 1 || string[i] == '\n' )
break;
}
string[i] = 0;
write_status( STATUS_GOT_IT );
if( bool ) /* Fixme: is this correct??? */
return string[0] == 'Y' ? "" : NULL;
return string;
}
int
cpr_enabled()
{
if( opt.command_fd != -1 )
return 1;
#ifdef USE_SHM_COPROCESSING
if( opt.shm_coprocess )
return 1;
@ -284,6 +357,8 @@ cpr_get( const char *keyword, const char *prompt )
{
char *p;
if( opt.command_fd != -1 )
return do_get_from_fd ( keyword, 0, 0 );
#ifdef USE_SHM_COPROCESSING
if( opt.shm_coprocess )
return do_shm_get( keyword, 0, 0 );
@ -317,6 +392,8 @@ cpr_get_hidden( const char *keyword, const char *prompt )
{
char *p;
if( opt.command_fd != -1 )
return do_get_from_fd ( keyword, 1, 0 );
#ifdef USE_SHM_COPROCESSING
if( opt.shm_coprocess )
return do_shm_get( keyword, 1, 0 );
@ -335,6 +412,8 @@ cpr_get_hidden( const char *keyword, const char *prompt )
void
cpr_kill_prompt(void)
{
if( opt.command_fd != -1 )
return;
#ifdef USE_SHM_COPROCESSING
if( opt.shm_coprocess )
return;
@ -349,6 +428,8 @@ cpr_get_answer_is_yes( const char *keyword, const char *prompt )
int yes;
char *p;
if( opt.command_fd != -1 )
return !!do_get_from_fd ( keyword, 0, 1 );
#ifdef USE_SHM_COPROCESSING
if( opt.shm_coprocess )
return !!do_shm_get( keyword, 0, 1 );
@ -375,6 +456,8 @@ cpr_get_answer_yes_no_quit( const char *keyword, const char *prompt )
int yes;
char *p;
if( opt.command_fd != -1 )
return !!do_get_from_fd ( keyword, 0, 1 );
#ifdef USE_SHM_COPROCESSING
if( opt.shm_coprocess )
return !!do_shm_get( keyword, 0, 1 );

View File

@ -1,5 +1,5 @@
/* status.h
* Copyright (C) 1998 Free Software Foundation, Inc.
* Copyright (C) 1998, 1999, 2000 Free Software Foundation, Inc.
*
* This file is part of GnuPG.
*
@ -65,7 +65,21 @@
#define STATUS_ERRMDC 35
#define STATUS_IMPORTED 36
#define STATUS_IMPORT_RES 37
#define STATUS_FILE_START 38
#define STATUS_FILE_DONE 39
#define STATUS_FILE_ERROR 40
#define STATUS_BEGIN_DECRYPTION 41
#define STATUS_END_DECRYPTION 42
#define STATUS_BEGIN_ENCRYPTION 43
#define STATUS_END_ENCRYPTION 44
#define STATUS_DELETE_PROBLEM 45
#define STATUS_GET_BOOL 46
#define STATUS_GET_LINE 47
#define STATUS_GET_HIDDEN 48
#define STATUS_GOT_IT 49
#define STATUS_PROGRESS 50
/*-- status.c --*/
void set_status_fd ( int fd );

View File

@ -1,5 +1,5 @@
/* tdbdump.c
* Copyright (C) 1999 Free Software Foundation, Inc.
* Copyright (C) 1999, 2000 Free Software Foundation, Inc.
*
* This file is part of GnuPG.
*
@ -43,8 +43,8 @@
#include "tdbio.h"
#define HEXTOBIN(a) ( (a) >= '0' && (a) <= '9' ? ((a)-'0') : \
(a) >= 'A' && (a) <= 'F' ? ((a)-'A'+10) : ((a)-'a'+10))
#define HEXTOBIN(x) ( (x) >= '0' && (x) <= '9' ? ((x)-'0') : \
(x) >= 'A' && (x) <= 'F' ? ((x)-'A'+10) : ((x)-'a'+10))
/****************
* Read a record but die if it does not exist
@ -520,5 +520,6 @@ import_ownertrust( const char *fname )
if( !is_stdin )
fclose(fp);
do_sync();
sync_trustdb();
}

Some files were not shown because too many files have changed in this diff Show More